项目地址: https://github.com/jkstack/libagent
最新版本:
流程图
Agent启动过程
- 加载配置文件
- 初始化logging模块,设置rotate等参数
- 初始化limit模块
- 若当前系统为linux操作系统则通过cgroups进行资源限制
- 若当前系统为windows操作系统则通过go语言的runtime库进行CPU和内存的资源限制
- 启动monitor模块,定时上报监控数据
- 创建WebSocket连接,交换AgentID和当前操作系统信息
- 启动异步读/写协程处理从服务端收到的任务
- 启动keepalive模块,定时发送心跳
技术实现细节
公共配置
精鲲Agent产品在经过了若干个版本的迭代后,提炼出了一些每一类Agent都会有的公共配置信息如下:
id = <agent-id>
server = <server-addr>
log.target = stdout,file # log写入目标,目前仅支持stdout和file
log.dir = <dir> # log文件保存路径
log.size = 10M # log文件滚动生成时的文件大小
log.rotate = 7 # log文件滚动生成时的保留数量
monitor.enabled = true # 是否开启监控信息上报
monitor.interval = 30s # 监控数据上报频率
limit.cpu_quota = 100 # CPU最大使用率,100表示一个CPU核心
limit.memory_limit = 512M # 内存最大使用容量
# 以下配置项的内容为一个json数组,其中的字段含义如下:
# dev: 磁盘设备号,可通过lsblk命令查询
# read_bytes: 每秒读取字节数
# write_bytes: 每秒写入字节数
# read_iops: 每秒读取次数
# write_iops: 每秒写入次数
# 注意: 该配置项只支持linux操作系统,且支持cgroups时有效
limit.disk_limit = [{"dev":"8:0","read_bytes":"10M","write_bytes":"10M","read_iops":1000,"write_iops":1000}]
WebSocket连接
本地Agent与服务器端使用WebSocket协议进行RPC通信,在连接过程中双方会交换当前节点的AgentID,若本地Agent未指定AgentID时将由服务器端自动分配。
创建WebSocket链接时需要进行一次握手,握手请求由Agent端发起,数据格式如下:
type ComePayload struct {
ID string `json:"id"` // agent-id
Name string `json:"name"`
Version string `json:"version"` // 版本号
IP net.IP `json:"ip"` // ip地址
MAC string `json:"mac"` // mac地址
HostName string `json:"host_name"` // 主机名
OS string `json:"os"` // 操作系统名称,windows或linux
Platform string `json:"platform"` // 操作系统名称,debian、centos等
PlatformVersion string `json:"platform_version"` // 操作系统版本号,如7.7.1908
KernelVersion string `json:"kernel_version"` // 内核版本号,如3.10.0-1062.el7.x86_64
Arch string `json:"arch"` // 操作系统位数,amd64、i386等
CPU string `json:"cpu"` // CPU型号,如AMD Ryzen 7 4800U with Radeon Graphics
CPUCore uint64 `json:"cpu_core"` // CPU核心数
Memory uint64 `json:"memory"` // 内存大小
}
服务端在创建WebSocket链接时会等待本次的握手报文,超时时间为1分钟,若客户端一直未发送握手报文则将断开该链接。后续处理逻辑如下:
- 当握手报文中未包含AgentID时,自动生成一个随机的AgentID并返回给Agent
- 若指定AgentID在当前链接列表中已存在时,将会返回
agent id conflict
的错误 - 返回链接成功报文
其中返回数据的报文格式如下:
type HandshakePayload struct {
OK bool `json:"ok"` // 握手是否成功
ID string `json:"id"` // 被分配的agent id
Msg string `json:"msg"` // 错误信息
Redirect []string `json:"redirect,omitempty"` // 重定向地址
}
通过以上连接过程即可实现Agent端程序与服务器端程序的正常连接,并可在后续操作中实现任务的下发与调度执行。
断线重连
当Agent端程序发生链接断开时(如服务器端升级重启),LibAgent将会进行断线重连,重连过程中以1s、2s、4s的间隔时间进行尝试,最多间隔4s,详情可见start中的循环处理逻辑。
监控数据
Agent运行时会上报一些基础的监控信息,可通过配置文件中的monitor.enabled
字段进行关闭,该数据由Prometheus定义,可通过服务器端的/metrics
接口获取,内容如下:
# HELP agent_info
# TYPE agent_info gauge
agent_info{agent_type="example-agent",id="example-agent",tag="cpu_usage"} 0.1730158030986786
agent_info{agent_type="example-agent",id="example-agent",tag="gc_0"} 1.0801e-05
agent_info{agent_type="example-agent",id="example-agent",tag="gc_0.25"} 1.0801e-05
agent_info{agent_type="example-agent",id="example-agent",tag="gc_0.5"} 1.6512e-05
agent_info{agent_type="example-agent",id="example-agent",tag="gc_0.75"} 1.6512e-05
agent_info{agent_type="example-agent",id="example-agent",tag="gc_1"} 1.6512e-05
agent_info{agent_type="example-agent",id="example-agent",tag="heap_in_use"} 1.9652608e+07
agent_info{agent_type="example-agent",id="example-agent",tag="in_bytes"} 0
agent_info{agent_type="example-agent",id="example-agent",tag="in_packets"} 0
agent_info{agent_type="example-agent",id="example-agent",tag="memory_usage"} 0.9135397672653198
agent_info{agent_type="example-agent",id="example-agent",tag="out_bytes"} 0
agent_info{agent_type="example-agent",id="example-agent",tag="out_packets"} 0
agent_info{agent_type="example-agent",id="example-agent",tag="read_chan_size"} 0
agent_info{agent_type="example-agent",id="example-agent",tag="reconnect_count"} 0
agent_info{agent_type="example-agent",id="example-agent",tag="report_time"} 1.668065623e+09
agent_info{agent_type="example-agent",id="example-agent",tag="routines"} 10
agent_info{agent_type="example-agent",id="example-agent",tag="startup"} 1.668065613e+09
agent_info{agent_type="example-agent",id="example-agent",tag="threads"} 10
agent_info{agent_type="example-agent",id="example-agent",tag="write_chan_size"} 0
# HELP agent_version
# TYPE agent_version gauge
agent_version{go_version="go1.19.3",id="example-agent",version="1.0.0"} 1
埋点代码,字段定义如下:
startup
: 该Agent的启动时间戳report_time
: 最后一次上报时的时间戳cpu_usage
: 该Agent进程的CPU占用率(百分比)memory_usage
: 该Agent进程的内存占用率(百分比)heap_in_use
: 占用的内存字节数gc_0
: GC耗时的0分位数(秒)gc_0.25
: GC耗时的25分位数(秒)gc_0.5
: GC耗时的50分位数(秒)gc_0.75
: GC耗时的75分位数(秒)gc_1
: GC耗时的100分位数(秒)in_bytes
: 收到的数据包字节数in_packets
: 收到的数据包数量out_bytes
: 发送的数据包字节数out_packets
: 发送的数据包数量read_chan_size
: 接收队列当前长度write_chan_size
: 发送队列当前长度reconnect_count
: 重连次数threads
: 当前线程数routines
: 当前协程数go_version
: 该Agent编译的GO版本号version
: 该Agent的版本号
linux/windows系统服务注册
目前LibAgent通过service库进行Agent程序的系统服务注册与控制,目前已测试通过的操作系统列表如下:
系统 | 版本号 | 内核版本 |
ubuntu | 12.04 | 3.2 |
ubuntu | 14.04 | 3.13 |
ubuntu | 16.04 | 4.4 |
ubuntu | 18.04 | 4.15 |
ubuntu | 20.04 | 5.4 |
ubuntu | 22.04 | 5.15 |
suse | 11(SP4) | 3.0.101-108.135.1 |
suse | 12(SP5) | 4.12.14-122.130.1 |
suse | 15(SP4) | 5.14.21-150400.24.18.1 |
redhat | 6.1 | 2.6.32-754 |
redhat | 7.9 | 3.10.0-1160 |
redhat | 8.6 | 4.18.0-372.9.1 |
centos | 6.1 | 2.6.32-754 |
centos | 7.9-2009 | 3.10.0-1160 |
centos | 8.5.2111 | 4.18.0-348 |
windows | 7 Enterprise with Service Pack 1 | |
windows | 7 Professional with Service Pack 1, VL Build | |
windows | 10 Enterprise LTSC 2021 | |
windows | 2008 R2 Enterprise | |
windows | 2008 R2 Datacenter | |
windows | 2016 VL | |
windows | 2016(Updated Feb 2018) | |
windows | 2016 Essentials | |
windows | 2019(Updated July 2020) | |
windows | 2022(updated Aug 2022) |