systemd在开始下一个服务单元之前没有等待我的服务单元完成

时间:2014-09-26 04:31:58

标签: docker systemd

以下是我的两个单位:

 - 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服务finsihed之前启动phpfpm服务并抛出一个错误,说percona容器不存在:/。

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

谢谢你!

2 个答案:

答案 0 :(得分:8)

你的percona_db是一个长时间运行的进程,所以systemd会分叉一个子进程并让它运行,并假设一切正常,然后继续启动php_fpm。

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

答案 1 :(得分:3)

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

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

您需要在percona_db.service中设置Type = oneshot。

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