由于新的项目需要用到分布式配置管理系统,在调研zookeeper及etcd后,觉得etcd相对轻量级,并且之前对raft协议也有所了解,因此最终选择使用etcd。公司使用的系统自身带有守护进程,因此需要考虑编写一个工具启动etcd,然后由守护进程启动该工具,这样可以不用考虑etcd挂后自动恢复的问题。
1.编写工具通过子进程调用etcd
网上提供的etcd启动脚本比较复杂,并且涉及到多机配置及启动问题,一般网上提供的启动例子为
1 | #!/bin/bash |
如果通过工具创建子进程方式去启动etcd,则只需在公司系统的配置文件中加上哪些机器需要启动etcd,然后由工具自动生成各项参数,最终生成调用etcd命令。
当通过子进程使用execve方式调用etcd后,会遇到输出日志的问题,由于etcd默认只输出到stdout,虽然通过systemd方式启动时可以把日志输出到journald对应的日志,但是我们的程序是通过守护进程启动,因此这些日志会直接输出到stdout,当时考虑有两个解决方案
工具不是通过子进程方式调用etcd,而是通过system方式调用,然后把etcd日志重定向到一个日志文件中
在这种方式下,虽然可以把日志重定向到一个文件,但是无法与公司系统自动切割的日志兼容,并且还需要定时运行程序把etcd的输出文件进行改名工具通过子进程中使用execve方式调用etcd,但是在执行前时,通过dup2系统调用,把stdout/stderr重定向到一个日志文件
通过execve方式执行命令后,该子进程已经完成进入etcd的执行流程,虽然可以把日志输出到文件,但是一旦其他程序把该日志文件改名,etcd的日志还是输出到该文件。如果把日志文件删除,则etcd不会输出日志到新的文件
2. 通过管道方式把etcd的输出内容发送回父进程,由父进程输出日志
由于父进程是使用相关的代码编写工具,因此只要在工具运行的进程输出日志即可自动支持切割功能。
工具最后的业务流程图如下
1 | +------------------------+ |