V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
sankooc
V2EX  ›  Java

大家的 Java 服务的进程管理是如何做到的

  •  
  •   sankooc ·
    sankooc · 2023-09-21 09:36:18 +08:00 · 3961 次点击
    这是一个创建于 460 天前的主题,其中的信息可能已经有所发展或是发生改变。

    本人原来是做 nodejs 的今年开始帮忙朋友的 java 项目做做运维 由于我自己的技术栈限制当前的 java 项目是靠 pm2 管理的 随着部署服务的数量增多现在有监控各个服务器 pm2 状态和报警的需求 我看了下 pm2 的 monitor 功能是收费且不能 selfhost 的 大家有没有 pm2 monitor 的竞品推荐 或者说 java 的进程管理工具主要的功能需求是 服务的自动重启 报警等等

    37 条回复    2023-09-26 21:29:29 +08:00
    securityCoding
        1
    securityCoding  
       2023-09-21 09:48:17 +08:00 via Android
    感觉你要的是 docker
    aladdinding
        2
    aladdinding  
       2023-09-21 09:50:30 +08:00
    systemctl
    k8s
    salmon5
        3
    salmon5  
       2023-09-21 09:55:45 +08:00
    supervisor
    tgyday
        4
    tgyday  
       2023-09-21 09:55:49 +08:00
    supervisord 可以实现进程管理和自动重启异常重启报警等
    imzcc
        5
    imzcc  
       2023-09-21 10:00:11 +08:00
    supervisor +1
    sankooc
        6
    sankooc  
    OP
       2023-09-21 10:01:41 +08:00
    @securityCoding @aladdinding 由于服务器资源是已经分配好的一个服务器部署一个服务 所以不好说服他们服务器里装个 docker 跑一个 java 服务 systemctl 有启动失败 发送警告的模块么?
    wind1986
        7
    wind1986  
       2023-09-21 10:08:56 +08:00
    uptime kuma + 健康检查, 适合任何项目
    dsioahui2
        8
    dsioahui2  
       2023-09-21 10:11:08 +08:00
    @sankooc 以下基于文心一言的回答:
    要使用 systemctl 管理进程并在启动失败时发送告警邮件,你可以遵循以下步骤:

    创建一个服务单元文件,该文件描述了要管理的进程。你可以使用 systemctl 命令创建一个新的服务单元文件,例如:

    bash
    sudo nano /etc/systemd/system/myservice.service
    在服务单元文件中,输入以下内容:

    plaintext
    [Unit]
    Description=My Service
    After=network.target

    [Service]
    ExecStart=/path/to/your/program
    Restart=always

    [Install]
    WantedBy=multi-user.target
    替换/path/to/your/program 为你要管理的进程的实际路径。
    3. 保存并关闭文件。

    重新加载 systemd 以加载新的服务单元:

    bash
    sudo systemctl daemon-reload
    启用服务,使其在系统启动时自动启动:

    bash
    sudo systemctl enable myservice
    启动服务:

    bash
    sudo systemctl start myservice
    检查服务状态以确认是否成功启动:

    bash
    sudo systemctl status myservice
    如果服务启动失败,你可以查看日志以获取更多信息:

    bash
    sudo journalctl -u myservice
    配置告警邮件。你可以使用 OnFailure 指令在服务单元文件中指定一个脚本,该脚本将在服务启动失败时执行。这个脚本可以发送告警邮件。例如,创建一个名为 send_alert.sh 的脚本,并在其中编写发送邮件的代码。然后,将脚本的路径添加到服务单元文件中:

    plaintext
    [Unit]
    Description=My Service
    After=network.target
    OnFailure=/path/to/send_alert.sh

    [Service]
    ExecStart=/path/to/your/program
    Restart=always

    [Install]
    WantedBy=multi-user.target
    重新加载 systemd 并重新启动服务:

    bash
    sudo systemctl daemon-reload
    sudo systemctl restart myservice
    如果服务启动失败,OnFailure 中指定的脚本将被执行,并发送告警邮件。
    salmon5
        9
    salmon5  
       2023-09-21 10:20:46 +08:00
    没用 systemd 的原因是,业务 java 和系统的管理有耦合,管理起来有一些噪音
    salmon5
        10
    salmon5  
       2023-09-21 10:22:25 +08:00
    健康检查肯定是 k8s 的功能最完善,但是如果是几个单体应用,用 k8s 有点重
    chendy
        11
    chendy  
       2023-09-21 10:50:37 +08:00
    虽然但是一个 & 好像就够了
    除非写得差有内存泄露,或者服务器内存短缺被 oomkill 否则 java 进程基本不会死
    darkengine
        12
    darkengine  
       2023-09-21 11:42:18 +08:00
    我们有个项目就是 nohup java -server 起的。。。
    kpingdd
        13
    kpingdd  
       2023-09-21 11:46:37 +08:00 via Android
    或许可以看看 zabbix 之类的
    zliea
        14
    zliea  
       2023-09-21 19:30:45 +08:00
    如果节点不多 docker swarm 也可以的
    Pursue9
        15
    Pursue9  
       2023-09-22 01:07:46 +08:00
    @sankooc 你这个太适合 docker compose 部署了, 有版本管控,每次更新也只用拉取下镜像 up -d --build
    julyclyde
        16
    julyclyde  
       2023-09-23 18:38:28 +08:00
    pm2 、supervisorD 、nohup 之类的肯定是不对的
    容器、systemd 是仅有的正确答案


    @salmon5
    @tgyday
    @imzcc
    supervisorD 本身的存活,又由谁来保证呢?
    supervisorD 重启动之后,上辈子启动的下属服务会脱离管理,造成端口占用之类的问题


    @kpingdd 这事和 zabbix 没啥关系吧?

    @darkengine nohup.out 把硬盘装满之后,你会删除它吗?
    salmon5
        17
    salmon5  
       2023-09-24 22:18:50 +08:00
    @julyclyde supervisor 本身不处理业务,相当稳定;重启后子进程也会跟着重启,子进程不会成为孤儿进程。
    它有一些不足,健康检查不支持 k8s 类似 startupProbes 的逻辑;不支持 cgroup 。
    管理非容器的 java springboot 应用还是很实用的。
    julyclyde
        18
    julyclyde  
       2023-09-25 19:31:19 +08:00
    @salmon5 它自己如果是正常重启,会连累被管理的服务一起(白白多一次)重启;它自己如果是 SIGKILL 的话,里面的进程就漏出去了
    salmon5
        19
    salmon5  
       2023-09-26 09:39:31 +08:00
    @julyclyde supervisor 安装好后,需要调大下 minfds=,默认 1024 太小会被子进程继承,然后不太需要重启;它自己不处理业务,内存占用 10 多 M ,被 OOM 的概率也极低;
    这 2 种情况概率极低,比上层业务的 bug 概率低多了,瑕不掩瑜吧,个人觉得是个不错的进程管理工具。
    当然容器和 systemd 都是不错的选择,看需求和时间。
    darkengine
        20
    darkengine  
       2023-09-26 12:50:38 +08:00
    @julyclyde nohup.out 把硬盘装满之后,你会删除它吗?
    ------
    搞了个定时任务删
    julyclyde
        21
    julyclyde  
       2023-09-26 16:44:52 +08:00
    @darkengine 但是删了 nohup.out 之后并不会腾出来空间
    我那么问就是设陷阱等你掉进去呢
    julyclyde
        22
    julyclyde  
       2023-09-26 16:46:06 +08:00
    @salmon5 supervisorD 如果是非特权身份启动的,那它自己都没资格扩大 MinFDs
    如果有特权身份去启动 supervisorD ,那我干嘛不直接特权身份调 systemd 去管理服务呢?何必多穿一层裤子再放屁?
    darkengine
        23
    darkengine  
       2023-09-26 16:53:39 +08:00
    @julyclyde 嗯,特意查了脚本,没有存到 nohup.out ,直接丢 /dev/null 了。定期把 log 库产生的文件转移到第二块硬盘,这块硬盘里的日志文件保留一周。
    julyclyde
        24
    julyclyde  
       2023-09-26 16:55:27 +08:00
    @darkengine 但是放 null 就很难查询日志了呀
    darkengine
        25
    darkengine  
       2023-09-26 17:03:01 +08:00
    @julyclyde 日志用 logstash 输出到 logs 目录了,转存的是这个目录下的日志文件
    julyclyde
        26
    julyclyde  
       2023-09-26 17:03:59 +08:00
    @darkengine 不错不错
    salmon5
        27
    salmon5  
       2023-09-26 17:17:52 +08:00
    @julyclyde 你想用 systemd 是你的事情,每种软件都有自己的使用场景。争强好胜带脏话,你可以闭嘴。
    julyclyde
        28
    julyclyde  
       2023-09-26 17:18:41 +08:00
    @salmon5 我没必要闭嘴。你水平不行那是你的问题,应该多学习
    salmon5
        29
    salmon5  
       2023-09-26 17:20:24 +08:00
    @julyclyde 用 systemd 水平就好了?这是入门级的
    julyclyde
        30
    julyclyde  
       2023-09-26 17:21:50 +08:00
    @salmon5 考虑到绝大多数人都到不了这个入门级,确实是选了 systemd 就等于水平好
    salmon5
        31
    salmon5  
       2023-09-26 17:36:44 +08:00
    @julyclyde 看你多年网上老人了,应该也工作很多年了,没想到这么张狂
    salmon5
        32
    salmon5  
       2023-09-26 17:37:20 +08:00
    上来就出言不逊
    julyclyde
        33
    julyclyde  
       2023-09-26 17:39:03 +08:00
    @salmon5 为什么你能把技术上的正确总结为态度问题呢
    是不是说明你看重态度的程度超过看重技术?
    salmon5
        34
    salmon5  
       2023-09-26 17:43:30 +08:00
    @julyclyde 我前面说了,k8s 和 systemd 都是不错的选择,supervisor 比较轻量;
    每个人的偏好不同,OP 这个需求看上去轻量,我个人觉得 supervisor 更合适
    julyclyde
        35
    julyclyde  
       2023-09-26 17:49:03 +08:00
    @salmon5 仅仅是轻啊
    supervisorD 解决不了“它自己的存活”这个根本的问题。你不能因为这种事很少发生就不去考虑吧
    java 进程也很少崩溃,就需要考虑,为什么 supervisorD 的存活就不需要考虑呢?

    以及,日志收集的问题。supervisorD 收集下属服务的日志,是按长度切断的,这个功能确实存在,但需要配置才能用。否则就和 nohup 一样持续往后写,容易占满存储空间。这不仅仅是消耗人力写一句配置语句的问题,而是很有可能忘记写导致事故的问题

    选用 systemd 就没这俩问题。systemd 自己是 init ,一号进程天然神圣;用 journald 收集日志,不需要自己操心 rotate ,而且这个功能是免配置的
    james122333
        36
    james122333  
       2023-09-26 20:42:29 +08:00 via Android
    没有对与不对 只有会不会用
    给我选当然就 shell 写个 daemon
    当然单纯 nohup 是不够的 shell 本身就有 job control 功能 给 pid 1 可以作为 init 程序 至于讯息怎么处理看你自己 有人提到什么 log 档太大 其实用 ulimit 限制大小可以搞定
    给我选我是不选 systemd 毕竞老是在出漏洞 外加配置档又是个 dsl 而且我需要可以控制其行为的东西 当然公司用什么就用什么
    james122333
        37
    james122333  
       2023-09-26 21:29:29 +08:00 via Android
    我很像讲太多了...
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2970 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 13:31 · PVG 21:31 · LAX 05:31 · JFK 08:31
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.