Homebrew镜像源加速

执行 brew 命令安装软件的时候,跟以下 3 个仓库地址有关 brew.git homebrew-core.git homebrew-bottles Alibaba镜像源 替换brew仓库 cd "$(brew --repo)" git remote set-url origin https://mirrors.aliyun.com/homebrew/brew.git 替换homebrew-core仓库 cd "$(brew --repo)/Library/Taps/homebrew/homebrew-core" git remote set-url origin https://mirrors.aliyun.com/homebrew/homebrew-core.git 替换homebrew-bottles仓库,这个步骤跟MacOS 系统使用的 shell 版本有关系 先查看当前使用的 shell 版本 echo $SHELL 如果输出结果是 /bin/zsh,参考zsh 终端操作方式 如果输出结果是 /bin/bash,参考bash 终端操作方式 zsh 终端操作方式 替换homebrew-bottles 访问地址: echo 'export HOMEBREW_BOTTLE_DOMAIN=https://mirrors.aliyun.com/homebrew/homebrew-bottles' >> ~/.zshrc source ~/.zshrc bash 终端操作方式 替换 homebrew-bottles 访问地址: [Read More]

JDK管理-MacOS

随着JDK生成数量的增加和发布节奏的越来越频繁,我发现很难跟踪我在MacOS中安装的内容并即时进行切换,这就需要通过某种方式来进行有效的管理,减轻平时使用过程中的重复劳动。为此需要花上点时间来整理这块的内容来帮助我即时管理与多版本之间的更加丝滑的切换。下面通过三种方式进行管理配置说明: sh取别名 自定义sh脚本 开源管理工具(jEvn,jabba,SDKMAN) sh取别名 查看已经安装的版本 ➜ ~ /usr/libexec/java_home -V Matching Java Virtual Machines (1): 11.0.9, x86_64: "Java SE 11.0.9" /Library/Java/JavaVirtualMachines/jdk-11.0.9.jdk/Contents/Home /Library/Java/JavaVirtualMachines/jdk-11.0.9.jdk/Contents/Home 修改配置文件bash(.bash_profile)/zsh(.zshrc),写入如下内容 export JAVA_8_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_xxx.jdk/Contents/Home export JAVA_9_HOME=/Library/Java/JavaVirtualMachines/jdk-9.0.4jdk/Contents/Home export JAVA_11_HOME=/Library/Java/JavaVirtualMachines/jdk-11.0.4.jdk/Contents/Home export JAVA_12_HOME=/Library/Java/JavaVirtualMachines/jdk-12.0.2.jdk/Contents/Home alias jdk8="export JAVA_HOME=$JAVA_8_HOME" #编辑一个命令jdk8,输入则转至jdk1.8 alias jdk9="export JAVA_HOME=$JAVA_9_HOME" #编辑一个命令jdk9,输入则转至jdk1.9 alias jdk11="export JAVA_HOME=$JAVA_11_HOME" #编辑一个命令jdk11,输入则转至jdk1.11 alias jdk12="export JAVA_HOME=$JAVA_12_HOME" #编辑一个命令jdk12,输入则转至jdk1.12 export JAVA_HOME=`/usr/libexec/java_home` #最后安装的版本,这样当自动更新时,始终指向最新版本 生效配置 # zsh source .zshrc # bash source .bash_profile 版本切换 [Read More]
Setting  JDK 

延迟任务

延迟任务 什么是延迟任务 顾明思议,把需要延迟执行的任务叫做延迟任务 延迟任务得使用场景 订单下单之后 30 分钟后,用户如果没有付钱,系统需要自动取消订单,并退还库存 如何定期检查处于退款状态的订单是否已经退款成功 重试机制实现:把调用失败的接口放入一个固定延时的队列,到期后再重试 新创建的店铺:如果在十天内都没有上传过商品,则自动发送消息提醒 用户发起退款:如果三天内没有得到处理则通知相关运营人员 预定会议后:需要在预定的时间点前十分钟通知各个与会人员参加会议 关闭空闲连接:服务器中,有很多客户端的连接,空闲一段时间之后需要关闭之 清理过期数据业务:比如缓存中的对象,超过了空闲时间,需要从缓存中移出 多考生考试:到期全部考生必须交卷,要求时间非常准确的场景 任务超时处理:在网络协议滑动窗口请求应答式交互时,处理超时未响应的请求 订餐通知:下单成功后60s之后给用户发送短信通知 红包 24 小时未被查收,需要延迟执退还业务 每个月账单日,需要给用户发送当月的对账单 延迟任务实现思路 延迟任务实现的关键是在某个时间节点执行某个任务。基于这个信息可以想到实现延迟任务的手段有以下两个: 自己手写一个“死循环”一直判断当前时间节点有没有要执行的任务 借助 JDK 或者第三方提供的工具类来实现延迟任务 通过 JDK 实现延迟任务能想到的关键词是:DelayQueue、Timer、ScheduledExecutorService 第三方提供的延迟任务执行方法就有很多了,例如:Redis、Netty、MQ 等手段 实现方式 定期轮询(数据库等) JDK(DelayQueue、Timer、ScheduledExecutorService周期性线程池) 时间轮(Kafka、Netty的HashedWheelTimer) Redis有序集合(zset) Zookeeper之curator MQ(RabbitMQ) Quartz,xxxjob等定时任务框架 Koala(考拉) JCronTab(仿crontab的java调度器) SchedulerX(阿里) 有赞延迟队列 …… 轮询 特点:定期轮训数据库,设置状态 优点:实现简单 缺点: 对服务器内存消耗大 存在轮询延迟 数据量过大时会消耗太多的IO资源,效率太低 DelayQueue 特点:无界、延迟、阻塞队列 优点:JDK自带,轻量级,使用简单 缺点: [Read More]
arch 

RPC框架的发展

定义 RPC(Remote Procedure Call)是一种远程调用协议,简单地说就是能使应用像调用本地方法一样的调用远程的过程或服务,可以应用在分布式服务、分布式计算、远程服务调用等许多场景。说起 RPC 大家并不陌生,业界有很多开源的优秀 RPC 框架 Dubbo Thrift gRPC Hprose RPC 与其它远程调用方式比较,RPC 与 HTTP、RMI、Web Service 都能完成远程调用,但是实现方式和侧重点各有不同 RPC与RMI RPC跨语言,RMI只支持Java RMI(Remote Method Invocation)是指 Java 语言中的远程方法调用,RMI 中的每个方法都具有方法签名,RMI 客户端和服务器端通过方法签名进行远程方法调用。RMI 只能在 Java 语言中使用,可以把 RMI 看作面向对象的 Java RPC RMI调用远程对象方法,允许方法返回Java对象以及基本数据类型,而RPC不支持对象的概念,传送到RPC服务的消息由外部数据表示 (External Data Representation, XDR) 语言表示,这种语言抽象了字节序类和数据类型结构之间的差异。只有由 XDR 定义的数据类型才能被传递,可以说 RMI 是面向对象方式的Java RPC。 在方法调用上,RMI中,远程接口使每个远程方法都具有方法签名。如果一个方法在服务器上执行,但是没有相匹配的签名被添加到这个远程接口上,那么这个新方法就不能被RMI客户方所调用。在RPC中,当一个请求到达RPC服务器时,这个请求就包含了一个参数集和一个文本值,通常形成“classname.methodname”的形式。这就向RPC服务器表明,被请求的方法在为 “classname”的类中,名叫“methodname”。然后RPC服务器就去搜索与之相匹配的类和方法,并把它作为那种方法参数类型的输入。这里的参数类型是与RPC请求中的类型是匹配的。一旦匹配成功,这个方法就被调用了,其结果被编码后返回客户方。 RPC本身没有规范,但基本的工作机制是一样的,即:serialization/deserialization+stub+skeleton,宽泛的讲,只要能实现远程调用,都是RPC,如:rmi .net-remoting ws/soap/rest hessian xmlrpc thrift potocolbuffer。 在Java里提供了完整的sockets通讯接口,但sockets要求客户端和服务端必须进行应用级协议的编码交换数据,采用sockets是非常麻烦的。一个代替Sockets的协议是RPC(Remote Procedure Call), 它抽象出了通讯接口用于过程调用,使得编程者调用一个远程过程和调用本地过程同样方便。RPC 系统采用XDR来编码远程调用的参数和返回值。但RPC并不支持对象,所以,面向对象的远程调用RMI(Remote Method Invocation)成为必然选择。采用RMI,调用远程对象和调用本地对象同样方便。RMI 采用JRMP(Java Remote Method Protocol)通讯协议,是构建在TCP/IP协议上的一种远程调用方法。 RPC与HTTP HTTP(HyperText Transfer Protocol)是应用层通信协议,使用标准语义访问指定资源(图片、接口等),网络中的中转服务器能识别协议内容。HTTP 协议是一种资源访问协议,通过 HTTP 协议可以完成远程请求并返回请求结果。 [Read More]
arch  rpc 

Elastic Stack

Packetbeat

简介

  • 实时抓取网络包
  • 自动解析应用层协议
    • ICMP (v4 and v6)
    • DHCP (v4)
    • DNS
    • HTTP
    • AMQP 0.9.1
    • Cassandra
    • Mysql
    • PostgreSQL
    • Redis
    • Thrift-RPC
    • MongoDB
    • Memcache
    • NFS
    • TLS
  • Wireshark

运行

[root@localhost fiebeat]# sudo ./packetbeat -e -c elasticsearch.yml -strict.perms=false

sudo:获取执行权限

strict.perms:跳过对执行配置文件的权限检查

Elastic Stack

Filebeat

处理流程 input 输入 类型支持:log和stdin filter 处理 input时处理 output前处理 – process include_lines exclude_linesexclude_files drop_evetdrop_fieldsdecode_json_fieldsinclude_fields output 输出 Console Elasticsearch Logstash Kafka Redis File … 调试 通过stdin收集日志 通过console输出结果 #=========================== Filebeat inputs =============================# List of inputs to fetch data. [Read More]

Elastic Stack

Elasticsearch

配置说明

配置相关文件位于${ELASTICSEARCH_HOME}/config目录下

  • elasticsearch.yml es相关配置项
  • jvm.options jvm相关参数配置
  • log4j2.properties 日志相关配置

Development与Production模式

  • 以transport的地址是否绑定在localhost为标准判断network.host启用那种模式
  • Development模式下在启动时会以warning的方式提示配置检查异常
  • Production模式下在启动时会以error的方式提示配置检查异常并退出
ELK 

Beats简介

Beats

官方定义

Lightweight Data Shipper:轻量级的数据传输者

  • Filebeat 日志文件
  • Metricbeat 度量数据(CPU,内存,磁盘,常用软件(Nginx,Mysql))
  • Packectbeat 网络数据
  • Winlogbeat windows数据
  • Heartbeat 健康检查

Beats在Elastic Stack中的地位

beats-platform

ELK 

并发-传统同步机制

Go学习笔记

在CSP模型下尽量少用传统同步机制,尽量使用chanel进行通信。Go语言中原子操作由内置的标准库sync/atomic提供。

sync.Mutex

互斥量是一种常用的控制共享资源访问的方法,它能够保证同时只有一个goroutine可以访问共享资源。Go语言中使用sync包的Mutex类型来实现互斥量

import (
	"fmt"
	"sync"
	"time"
)

type atomicInt struct {
	value int
	lock  sync.Mutex
}

func (a *atomicInt) increment() {
	fmt.Println("safe increment")
	func() {
		a.lock.Lock()
		defer a.lock.Unlock()

		a.value++
	}()
}

func (a *atomicInt) get() int {
	a.lock.Lock()
	defer a.lock.Unlock()

	return a.value
}

func main() {
	var a atomicInt
	a.increment()
	go func() {
		a.increment()
	}()
	time.Sleep(time.Millisecond)
	fmt.Println(a.get())
}

lock.Lock():加锁

lock.Unlock():解锁

通过运行时查看数据访问冲突

go run -race atomic.go

Go 

并发-Select

Go学习笔记

官方文档有关select的描述 A “select” statement chooses which of a set of possible send or receive operations will proceed. It looks similar to a “switch” statement but with the cases all referring to communication operations. 一个select语句用来选择哪个case中的发送或接收操作可以被立即执行。它类似于switch语句,但是它的case涉及到channel有关的I/O操作。 select就是用来监听和channel有关的IO操作,当 IO 操作发生时,触发相应的动作,功能与epoll(nginx)/poll/select的功能类似。 select是Go在语言层面提供的多路IO复用的机制,其可以检测多个channel是否ready(即是否可读或可写) 概述 select语句中除default外,每个case操作必须是一个channel,要么读要么写 如果有多个case都可以运行,Go运行时系统会针对select随机公平地选出一个执行,其他不会执行 select语句中如果没有default语句,且没有任意可运行case,则会一直阻塞等待任一case 分支选择执行规则 官方文档描述 Execution of a “select” statement proceeds in several steps: 1.For all the cases in the statement, the channel operands of receive operations and the channel and right-hand-side expressions of send statements are evaluated exactly once, in source order, upon entering the “select” statement. [Read More]
Go