Minder:一个分布式启停进程服务

关于

打算造个轮子,先备份下简单的设计手册吧。Minder是一个分布式启停进程服务,主要用于以下目的。

  • 命令或远程RPC调用启动和停止进程
  • 当进程挂掉,可以拉起来进程
  • 获得机器对应的系统信息,如CPU,内存,硬盘等等

设计

方案一(不采用)

分为Server和Client端

Server

Server在每台机器上都需要安装,Server是个常驻进程,负责真正的启停进程,同时需要一个Check线程,用于判断进程状态,当程序挂掉以便重启进程,重启进程可以在配置里有个次数限制。

Client

Client就是一个工具,用于向指定的Server发送请求,Server收到请求,启动进程。因为协议使用RPC,为了方便,使用脚本语言编写更好。

程序流程

Client发送请求,根据Client命令,判断是启动还是停止进程,假设是start进程,那么通过RPC的stub_client发送到Server的stub_server,之后调用对应的startProcess函数,通过fork+exec启动进程,同时Server需要有个Loop线程,判断进程的状态,以便重启进程。因为一个Server需要启动不同的服务,同时Server也可能会挂掉,所以Server需要持久化进程的信息,以便Server挂掉后恢复这些进程信息。

细节

  • 想象下我们启动进程都需要哪些参数?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"processInfos": [
{
"isDaemon": true, // 是否是守护进程
"processName": "app", // 进程名字
"restartInterval": 10, // 重启时间间隔
"restartCountLimit": 10, // 重启次数
"signal": 9, // 停止进程的信号值,kill函数对应的值
"parameters": "-m cluster -n 1", // 进程需要的参数
"environmentVariable" : { // 需要的环境变量
"key" : "key",
"value" : "value"
}
}
]
}

因为我们请求是Client工具向Server发送请求的,通信方式为RPC,所以上述参数都为PB格式。

  • Server端启动进程方式为fork+exec,停止进程为kill发送信号。

  • Client只是个工具,发送请求的方式可以为以下命令: minder_client -m start -s \”10.10.10.10:8888\” -p /bin/sleep 大意就是向Server发送请求,请求启动sleep进程。

架构图

方案二

分为Manager、Slave和Tools,第一版本只有一个Manager,Slave在每台机器都有。如果看懂方案一,方案二许多细节就可以不用说了,只见到说下每个模块干啥的吧。

Manager

只有Manager给用户打交道,用户向Manager提交需要启动的机器ip,进程信息,Manager向Slave发送消息。同时如果用户需要获取Slave机器的机器状态,如CPU,内存以及磁盘信息等,也是通过Manager获取的。

Slave

用户Slave是不与用户打交道的,Slave用于接受Manager的请求,启停进程,获取Slave机器状态,然后将对应的信息返回给Manager。

Tools

封装了对应的RPC请求,用户向Manager发送请求。

程序流程

Manager接受用户的请求,根据请求,Manager向Slave发送请求,Slave接受到请求后执行对应的操作。同时Manager持久化对应的信息。因为Manger必须知道Slave的机器ip,如果这个需要Slave主动汇报给Manager,四层心跳既可以。

架构图

当然,这个设计也是有很多改进的方法,比如Manager挂了怎么办,Manager存在单点问题,既然启动进程,怎么可以改善下搞成灰度发布,等等。因为时间问题,我工作也非常忙,这个我就不细说了。轮子有空造,其实写出来方案,思路基本上就清晰了。

另外,其实写这篇文字时候,与微信朋友圈里与朋友们交流了下想法,发现了2个系统是可以参考的,一个是Hadoop Ambari,另一个是Cloudera Manager。