根据你提供的 cfgsvc.service
文件内容和执行 systemctl restart cfgsvc.service
后有两个 cfgsvc
进程的现象,我们可以分析如下:
服务文件分析
Description: 提供了服务的简短描述,即 “5GC Configuration Service”。
After: 指定此服务在网络目标启动后才会启动,这意味着它依赖于网络可用性。
Type: 设置为
simple
,这表示服务在执行命令后被认为已启动。也就是说,ExecStart
中指定的命令不会 fork 出新的进程。ExecStart: 指定服务启动时要执行的命令。在这种情况下,是
/usr/local/sbin/cfgsvc/cfgsvc
。Restart: 设置为
no
,这意味着如果服务失败,它不会自动重启。RestartSec: 当服务失败且设置了重启时,此参数指定重启前等待的秒数,但由于 Restart 为
no
,此设置不适用。LimitCORE: 将核心转储限制设置为无限制。这通常用于调试目的,以便在程序崩溃时能够获取完整的内存映像。
Environment: 设置环境变量,这里是将 Go 程序中的跟踪回溯设置为崩溃模式。
KillMode: 设置为
process
,表示只有主进程会被杀死,而不是其子进程。[Install] 部分:定义了该服务何时启动,这里是多用户目标 (
multi-user.target
) 下启动。
两个进程原因
出现两个 cfgsvc
进程可能有以下几种原因:
主进程和工作线程/子进程:
- 如果这个程序本身设计成能够生成多个工作线程或子进程(即它内部使用了多线程或创建了子进程),则会导致多个相同的 PID 存在。虽然从 systemd 的角度看,它只管理一个父级,但父级可能会产生多个子级。
错误配置或代码问题:
- 某些情况下,如果程序没有正确处理自身的生命周期管理,也可能导致意外情况,例如未能清理之前已运行的实例。如果某个实例未完全终止,新启动的实例可能与之共存。
手动干预或者其他触发事件:
- 也有可能之前该服务仍然处于活动状态,你再次调用重启命令可能并没有结束旧实例,从而造成同时存在两个实例。在 service 配置中将 Restart 设置为
no
意味着系统不会尝试重新启动先前故障的实例,因此确保所有现有实例都已停止非常重要。
- 也有可能之前该服务仍然处于活动状态,你再次调用重启命令可能并没有结束旧实例,从而造成同时存在两个实例。在 service 配置中将 Restart 设置为
建议操作
确认是否真的需要两个并行运行的实例,如果不需要,请检查如何修改代码以避免不必要的额外进程生成。
可以尝试以下步骤确保仅保留一个运行中的实例:
sudo systemctl stop cfgsvc.service sudo systemctl start cfgsvc.service
检查日志以了解更多信息:
journalctl -u cfgsvc.service
如果希望调整其行为,可以考虑更改 service 文件类型,例如将其更改为
forking
类型(如果应用程序确实是这样的)并相应地处理 ExecStart 命令。但这通常取决于应用程序本身如何设计和实现。
内容由零声教学AI助手提供,问题来源于学员提问