【问题标题】:systemd not waiting for my service unit to finish before starting the next onesystemd 在开始下一个之前没有等待我的服务单元完成
【发布时间】:2014-11-21 00:34:52
【问题描述】:

这是我的两个单位:

 - name: percona_db.service
   command: start
   enable: true
   content: |
     [Unit]
     Description=Percona db
     After=docker.service
     Requires=docker.service

     [Service]
     ExecStartPre=/bin/bash -c '/usr/bin/docker start -a mysql_datastore || /usr/bin/docker run -d -v /var/lib/mysql --name mysql_datastore -p 23:23 busybox'
     ExecStart=/bin/bash -c '/usr/bin/docker start -a mypercona || /usr/bin/docker run -i -t --volumes-from mysql_datastore --name="mypercona" -p 3306:3306 --rm percona'
     ExecStop=/usr/bin/docker stop mypercona

     [Install]
     WantedBy=multi-user.target
 - name: php_fpm.service
   command: start
   enable: true
   content: |
     [Unit]
     Description=php fpm
     After=percona_db.service
     Requires=percona_db.service

     [Service]
     ExecStart=/bin/bash -c '/usr/bin/docker start -a myphpfpm_53 || /usr/bin/docker run --name myphpfpm_53 -dit -p 9000:9000  --link mypercona:db phpfpm_53'
     ExecStop=/usr/bin/docker stop myphpfpm_53

     [Install]
     WantedBy=multi-user.target

我的问题如下: percona_db.service 启动的 docker 容器有时会需要很长时间才能加载(如果是第一次加载,它会创建 db 并添加数据,可能需要一些时间)。 当我将它们链接在一起时,php_fpm 服务需要 percona 服务才能启动。 而且,即使我指定了:

 After=percona_db.service
 Requires=percona_db.service

systemd 尝试在 percona_db 服务完成之前启动 phpfpm 服务并抛出错误说 percona 容器不存在:/。

我做错了什么? 或者我该怎么做才能让它发挥作用? (也许人为让phpfpm服务等待?systemd可以吗?)

谢谢!

【问题讨论】:

  • 您是否只在/etc/systemd/system/multi-user.target.wants 中列出了php_fpm.service,还是同时列出了percona_db.servicephp_fpm.service。没关系,因为php_fpm.service 中的After=percona_db.service 应该控制它们的启动顺序(如果两者都列出),但是值得尝试从multi-user.target.wants 中删除percona_db.service 以查看这是否会强制正确的顺序。

标签: docker systemd


【解决方案1】:

每个 .service 文件都有一个 Type=[1] 字段。 Type= 字段告诉 systemd 何时应该接受您的服务已准备就绪,以便启动后续服务。

您没有在 [Service] 部分下的服务文件中指定 Type=。因为 systemd 设置了默认类型,即 Type=simple。在简单的情况下,systemd 将启动您使用 ExecStart 指定的进程,并假设一切正常。此时 systemd 认为您的服务已准备就绪。

您可能希望在 percona_db.service 中设置 Type=oneshot。

[1] - http://www.freedesktop.org/software/systemd/man/systemd.service.html

【讨论】:

    【解决方案2】:

    您的 percona_db 是一个长时间运行的进程,因此 systemd 会派生一个子进程并让它运行,并假设一切正常,然后继续启动 php_fpm。

    这对于很多服务也很常见,即在应用程序实际准备好之前返回的启动脚本。最好的方法是编写一个程序来检查 percona_db 的状态,它会一直等到 percona_db 准备好,然后在您的 php_fpm 服务文件中添加一行 ExecStartPre= ..。

    【讨论】:

    • 这个答案提供了一种解决方法。要了解实际发生的情况,请阅读@Umut 答案及其提供的链接。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-24
    • 1970-01-01
    • 2012-01-17
    • 1970-01-01
    • 2020-06-18
    • 2017-09-14
    • 1970-01-01
    相关资源
    最近更新 更多