OceanBase云平台(OCP)作为OceanBase分布式数据库的 全生命周期综合运维管理平台,其核心服务以Java进程形式运行在容器环境中,这带来了进程稳定性、高可用性和自动化运维的全新需求。本文通过分析,展示OCP容器中Supervisor的进程守护机制。
OCP 云平台的本质是一个运行在容器中的Java进程,具体表现为
ocp-server-4.4.1-20260212105850.jar 这样的 jar 包执行体。 在容器环境中,该Java进程通过特定的JVM参数配置运行,以满足企业级应用对性能和稳定性的高要求。
# 登录 ocp 容器
# docker exec -it ocp sh
# 查看容器中的JAVA进程
# ps -ef|grep -v grep|grep java
admin 12 133 2.3 745050368 25132288 ? Sl 14:51 5:16 /usr/lib/jvm/java-17/bin/java
-server -XX:+UseZGC -Xms14336m -Xmx14336m -Xss512k -XX:MetaspaceSize=1024m -XX:MaxMetaspaceSize=1024m
-Xlog:gc*,gc+stats=off,safepoint=off:file=/home/admin/ocp-server/bin/../
log/gc.log:time:filecount=2,filesize=50M
-XX:+ExitOnOutOfMemoryError -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/admin/ocp-server/bin/../
log/
-Dfile.encoding=UTF-8
--add-exports=java.xml/jdk.xml.internal=ALL-UNNAMED
--add-opens=java.base/java.io=ALL-UNNAMED
--add-opens=java.base/java.lang.reflect=ALL-UNNAMED
--add-opens=java.base/java.lang=ALL-UNNAMED
--add-opens=java.base/java.math=ALL-UNNAMED
--add-opens=java.base/java.net=ALL-UNNAMED
--add-opens=java.base/java.nio.charset=ALL-UNNAMED
--add-opens=java.base/java.nio=ALL-UNNAMED
--add-opens=java.base/java.nio.file=ALL-UNNAMED
--add-opens=java.base/java.security=ALL-UNNAMED
--add-opens=java.base/java.text=ALL-UNNAMED
--add-opens=java.base/java.time.format=ALL-UNNAMED
--add-opens=java.base/java.time=ALL-UNNAMED
--add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED
--add-opens=java.base/java.util.concurrent=ALL-UNNAMED
--add-opens=java.base/java.util.regex=ALL-UNNAMED
--add-opens=java.base/java.util.stream=ALL-UNNAMED
--add-opens=java.base/java.util=ALL-UNNAMED
--add-opens=java.base/sun.net.www.protocol.https=ALL-UNNAMED
--add-opens=java.base/sun.net=ALL-UNNAMED
--add-opens=java.base/sun.nio.cs=ALL-UNNAMED
--add-opens=java.base/sun.nio.fs=ALL-UNNAMED
--add-opens=java.base/sun.security.jca=ALL-UNNAMED
--add-opens=java.base/sun.security.ssl=ALL-UNNAMED
--add-opens=java.base/sun.security.util=ALL-UNNAMED
--add-opens=java.base/jdk.internal.util=ALL-UNNAMED
--add-opens=java.logging/java.util.logging=ALL-UNNAMED
--add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
-Daliyun.rass.enabled=
false
-jar /home/admin/ocp-server/bin/../lib/ocp-server-4.4.1-20260212105850.jar --bootstrap
在传统的物理机或虚拟机部署中,系统服务通常由systemd或init系统管理。然而,在Docker容器环境中,每个容器默认只运行一个前台进程,当这个进程退出时容器也随之终止。对于OCP这样的复杂企业级应用,需要确保其核心Java服务在意外崩溃时能够自动恢复,同时还需要管理可能存在的其他辅助进程。这种需求催生了在容器内部引入进程管理工具的必要性,而Supervisor正是这一场景下的理想选择。
Supervisord 是一个用 Python 编写的进程控制系统,用于在类 Unix 系统(如 Linux)上监控和管理后台进程,确保它们守护的进程在意外退出时自动重启 。
Supervisor 是一个 C/S(客户端/服务器)架构的工具。在此架构中:
supervisord:是服务端(server)守护进程,也是整个系统的核心。它负责启动配置中指定的子进程,响应客户端的命令,监控子进程状态,并在其崩溃或退出时按策略自动重启,同时负责记录子进程的标准输出和错误输出。supervisorctl:是命令行客户端(client)工具,为用户提供了一个与 supervisord 交互的接口。通过它,用户可以查看进程状态、启动、停止、重启进程或重新加载配置文件。Supervisord 的设计宗旨在于简化多进程管理,其主要功能包括:
查看容器中 supervisord 进程信息,发现
supervisord 进程是通过
/usr/bin/supervisord -c /etc/supervisor/supervisord.conf 命令启动而来,其父进程号为 1。
# ps -ef|grep -v grep|grep -i supervisor
root 1 0 0 14:51 ? 00:00:00 /bin/bash -c chmod u+s /usr/sbin/clockdiff;
setcap
'cap_net_raw+ep' /usr/sbin/clockdiff; /usr/bin/supervisord -c /etc/supervisor/supervisord.conf
root 9 1 0 14:51 ? 00:00:04 /usr/bin/python2 /usr/bin/supervisord -c /etc/supervisor/supervisord.conf
在OCP的容器化部署中,Supervisor被配置为容器的1号进程(PID 1),这意味着它伴随着容器的启动而启动,并负责管理容器内的所有其他进程。通过分析OCP容器的启动命令可以发现,容器入口点是一个包含多个命令的bash脚本,其中最后一步就是启动
supervisord 服务:
# docker ps -f "name=ocp" --no-trunc --format '{{.Names}} {{.Command}}'
ocp
"/bin/bash -c 'chmod u+s /usr/sbin/clockdiff; setcap 'cap_net_raw+ep' /usr/sbin/clockdiff; /usr/bin/supervisord -c /etc/supervisor/supervisord.conf'"
这种设计确保了Supervisor作为容器生命周期管理器,当它退出时整个容器也会终止,从而实现了对容器内所有进程的统一管控。
# ls -l /etc/supervisor
drwxr-xr-x 2 admin admin 22 2月 12 11:21 conf.d
-rw-r--r-- 1 admin admin 1009 2月 12 11:19 supervisord.conf
# ls -l /etc/supervisor/conf.d/
-rw-r--r-- 1 admin admin 369 2月 12 11:19 ocp.conf
主配置文件(
/etc/supervisor/supervisord.conf)定义了Supervisor服务本身的全局设置,包括日志文件路径、PID文件位置、日志级别等关键参数。特别值得注意的是
nodaemon = true这一配置,它使supervisord以前台模式运行,这是容器环境中确保supervisord作为1号进程的必要条件。
程序配置文件(
/etc/supervisor/conf.d/ocp.conf)专门定义OCP Java进程的管理规则。该配置文件包含了进程名称、启动命令、工作目录、运行用户、日志文件路径等关键信息。确保了OCP进程在意外退出时能够自动重启,这是实现高可用性的核心机制。
# cat /etc/supervisor/supervisord.conf
[unix_http_server]
file = /dev/supervisor.sock ; (the path to the socket file)
[supervisord]
logfile = /home/admin/logs/ocp_supervisord.log ; (main
log file;default
$CWD/supervisord.log)
logfile_maxbytes = 50MB ; (max main logfile bytes b4 rotation;default 50MB)
logfile_backups = 10 ; (num of main logfile rotation backups;default 10)
loglevel = info ; (
log level;default info; others: debug,warn,trace)
pidfile = /run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
nodaemon =
true ; (start
in foreground
if
true;default
false)
minfds = 1024 ; (min. avail startup file descriptors;default 1024)
minprocs = 200 ; (min. avail process descriptors;default 200)
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl = unix:///dev/supervisor.sock ; use a unix:// URL
for a unix socket
[include]
# cat /etc/supervisor/conf.d/ocp.conf
[program:ocp-server]
process_name = %(program_name)s_%(process_num)02d <-- 程序名称:ocp-server:ocp-server_00
command = /home/admin/ocp-server/bin/ocp-server --bootstrap <-- ocp 启动命令
directory = /home/admin <-- 执行命令前切换的目录
user = admin <-- 启动用户
numprocs = 1
stopsignal=INT
killasgroup =
true
stdout_logfile = /home/admin/logs/ocp-server.%(process_num)s.out
stderr_logfile = /home/admin/logs/ocp-server.%(process_num)s.err
redirect_stderr =
false
当手动终止OCP的Java进程(
kill -9)后,观察发现该进程会被自动重新拉起,且进程ID发生变化。这一现象正是Supervisor的
autorestart 机制在起作用,它持续监控被管理进程的状态,一旦发现进程异常退出,便根据配置策略重新启动该进程。
# kill -9 12 <--- 杀掉ocp进程
# ps -ef|grep -v grep|grep java <-- 发现ocp进程重新拉起,进程号由原来的12,变为29796
admin 29796 9 99 15:02 ? 00:00:31 /usr/lib/jvm/java-17/bin/java -server -XX:+UseZGC -Xms14336m ...
进一步分析进程关系可以发现,OCP Java进程的父进程正是
supervisord 进程(PID 9),而
supervisord 的父进程是容器的1号进程(PID 1)。这种进程层级关系清晰地展示了Supervisor作为进程管理器的角色定位。
# ps -ef|grep -v grep|grep supervisor
root 1 0 0 14:51 ? 00:00:00 /bin/bash -c chmod u+s /usr/sbin/clockdiff;
setcap
'cap_net_raw+ep' /usr/sbin/clockdiff; /usr/bin/supervisord -c /etc/supervisor/supervisord.conf
root 9 1 0 14:51 ? 00:00:08 /usr/bin/python2 /usr/bin/supervisord -c /etc/supervisor/supervisord.conf
Supervisor提供了
supervisorctl 命令行工具,能够方便地查看和管理被监控的进程。通过supervisorctl手动停止的进程不会自动重启,这与进程意外崩溃时的自动重启行为形成对比。这种差异化的行为控制为运维操作提供了灵活性,既保证了生产环境的高可用性,又支持了必要的维护操作。
# supervisorctl status
ocp-server:ocp-server_00 RUNNING pid 29796, uptime 0:22:49
# supervisorctl stop ocp-server:ocp-server_00
ocp-server:ocp-server_00: stopped
# supervisorctl status
ocp-server:ocp-server_00 STOPPED Mar 05 03:25 PM
# ps -ef|grep -v grep|grep java
使用supervisorctl停止的进程,不会自动拉起。
ocp 进程启动后,监测 8080 端口,成功监听后,ocp 才能对外提供服务。
# supervisorctl start ocp-server:ocp-server_00
ocp-server:ocp-server_00: started
# supervisorctl status
ocp-server:ocp-server_00 RUNNING pid 101997, uptime 0:00:07
# ps -ef|grep -v grep|grep java
admin 101997 9 99 15:27 ? 00:00:30 /usr/lib/jvm/java-17/bin/java -server -XX:+UseZGC -Xms14336m ...
# netstat -tnlp|grep 8080
tcp6 0 0 :::8080 :::* LISTEN
如果你在实际操作中遇到问题,可以在评论区留言交流。后续我们会持续分享更多运维干货,记得 关注不迷路 ,下次见~
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70047467/viewspace-3172453/ ,如需转载,请注明出处,否则将追究法律责任。