6

这是我的两个单位:

 - 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可以吗?)

谢谢你 !

4

2 回答 2

10

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

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

于 2014-09-29T04:15:25.320 回答
9

每个 .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

于 2014-11-14T22:00:28.470 回答