1. 程式人生 > >How can I start a systemd service only after mysql has started?

How can I start a systemd service only after mysql has started?

在 centos 裡,如果 service 執行順序有問題,會造成程式無法啟動,有些程式必需等 database service 先啟動後,才能執行,寫法如下:

Add After=mysql.service to your service file (or change it to the correct service name), e.g:

[Unit]
Description=Boardies Email Server Startup Script
After=mysql.service

[Service]
ExecStart=/home/bits/EmailServer/start.email
Restart=always

[Install]
WantedBy=multi-user.target

Please note that you don’t have to put your service file into /lib/systemd/system, it is a user provided file and you should only copy it to /etc/systemd/system.

To get a list of all service files you can use systemctl list-unit-files and determine the correct name for your database service (it is probably either mysql.service or mysqld.service)

After a lot more reading I found the solution that works for me.

This will ensure that all configured network devices are up and have an IP address assigned before boot continues.

This is exactly what I wanted so I enabled this service and set the a dependency rule in the service file for crond:

[
[email protected]
]# systemctl enable NetworkManager-wait-online [[email protected]]# vi /lib/systemd/system/crond.service Requires=network.target After=syslog.target auditd.service systemd-user-sessions.service time-sync.target network.target mysqld.service

As mysqld is still based on the old init.d I needed to create a systemd service as suggested here, systemctl enable differs from systemctl start:

[[email protected]]# vi /lib/systemd/system/mysqld.service
  [Unit]
  Description=MySQL Server
  After=network.target
  [Service]
  Type=forking
  ExecStart=/etc/rc.d/init.d/mysql start
  ExecStop=/etc/rc.d/init.d/mysql stop
  [Install]
  WantedBy=multi-user.target

[[email protected]]# systemctl daemon-reload
[[email protected]]# chkconfig mysql off
[[email protected]]# systemctl enable mysqld

And finally setup the Apache service to startup after MySQL:

[[email protected]]# vi /lib/systemd/system/httpd.service
  Requires=mysqld.service
  After=network.target remote-fs.target nss-lookup.target mysqld.service

This works for me at least.

I have used these commands to check it afterwards where I clearly can see that network is started up prior to at least MySQL and Apache. I though cannot see the crond anywhere but I can see it is working in my scripts:

[[email protected]]# systemd-analyze critical-chain
  multi-user.target @10.510s
    + httpd.service @10.344s +165ms
      + mysqld.service @9.277s +1.065s
        + network.target @9.273s
          + network.service @8.917s +355ms
            + iptables.service @444ms +157ms
              + basic.target @443ms
                [CUT]

A couple of other useful commands I used are:

# See exactly what takes how long (who to blame for the delay)
[[email protected]]# systemd-analyze blame

# Check available names that can be used in the service files
[[email protected]]# systemctl list-unit-files

If any one can see any better way to do this then please share.

瞭解一下在 [Service] 當中有哪些專案可以使用!

[Service] 部份
設定引數 引數意義說明
Type 說明這個 daemon 啟動的方式,會影響到 ExecStart 喔!一般來說,有下面幾種型別 simple:預設值,這個 daemon 主要由 ExecStart 接的指令串來啟動,啟動後常駐於記憶體中。forking:由 ExecStart 啟動的程式通過 spawns 延伸出其他子程式來作為此 daemon 的主要服務。原生的父程式在啟動結束後就會終止執行。 傳統的 unit 服務大多屬於這種專案,例如 httpd 這個 WWW 服務,當 httpd 的程式因為執行過久因此即將終結了,則 systemd 會再重新生出另一個子程式持續執行後, 再將父程式刪除。據說這樣的效能比較好!!oneshot:與 simple 類似,不過這個程式在工作完畢後就結束了,不會常駐在記憶體中。dbus:與 simple 類似,但這個 daemon 必須要在取得一個 D-Bus 的名稱後,才會繼續執行!因此設定這個專案時,通常也要設定 BusName= 才行!idle:與 simple 類似,意思是,要執行這個 daemon 必須要所有的工作都順利執行完畢後才會執行。這類的 daemon 通常是開機到最後才執行即可的服務!比較重要的專案大概是 simple, forking 與 oneshot 了!畢竟很多服務需要子程式 (forking),而有更多的動作只需要在開機的時候執行一次(oneshot),例如檔案系統的檢查與掛載啊等等的。
EnvironmentFile 可以指定啟動指令碼的環境配置檔案!例如 sshd.service 的配置檔案寫入到 /etc/sysconfig/sshd 當中!你也可以使用 Environment= 後面接多個不同的 Shell 變數來給予設定!
ExecStart 就是實際執行此 daemon 的指令或指令碼程式。你也可以使用 ExecStartPre (之前) 以及 ExecStartPost (之後) 兩個設定專案來在實際啟動服務前,進行額外的指令行為。 但是你得要特別注意的是,指令串僅接受“指令 引數 引數…”的格式,不能接受 <, >, >>, |, & 等特殊字元,很多的 bash 語法也不支援喔! 所以,要使用這些特殊的字元時,最好直接寫入到指令腳本里面去!不過,上述的語法也不是完全不能用,亦即,若要支援比較完整的 bash 語法,那你得要使用 Type=oneshot 才行喔! 其他的 Type 才不能支援這些字元。
ExecStop 與 systemctl stop 的執行有關,關閉此服務時所進行的指令。
ExecReload 與 systemctl reload 有關的指令行為
Restart 當設定 Restart=1 時,則當此 daemon 服務終止後,會再次的啟動此服務。舉例來說,如果你在 tty2 使用文字介面登陸,操作完畢後登出,基本上,這個時候 tty2 就已經結束服務了。 但是你會看到螢幕又立刻產生一個新的 tty2 的登陸畫面等待你的登陸!那就是 Restart 的功能!除非使用 systemctl 強制將此服務關閉,否則這個服務會源源不絕的一直重複產生!
RemainAfterExit 當設定為 RemainAfterExit=1 時,則當這個 daemon 所屬的所有程式都終止之後,此服務會再嘗試啟動。這對於 Type=oneshot 的服務很有幫助!
TimeoutSec 若這個服務在啟動或者是關閉時,因為某些緣故導致無法順利“正常啟動或正常結束”的情況下,則我們要等多久才進入“強制結束”的狀態!
KillMode 可以是 process, control-group, none 的其中一種,如果是 process 則 daemon 終止時,只會終止主要的程式 (ExecStart 接的後面那串指令),如果是 control-group 時, 則由此 daemon 所產生的其他 control-group 的程式,也都會被關閉。如果是 none 的話,則沒有程式會被關閉喔!
RestartSec 與 Restart 有點相關性,如果這個服務被關閉,然後需要重新啟動時,大概要 sleep 多少時間再重新啟動的意思。預設是 100ms (毫秒)。

最後,再來看看那麼 Install 內還有哪些專案可用?

[Install] 部份
設定引數 引數意義說明
WantedBy 這個設定後面接的大部分是 *.target unit !意思是,這個 unit 本身是附掛在哪一個 target unit 下面的!一般來說,大多的服務性質的 unit 都是附掛在 multi-user.target 下面!
Also 當目前這個 unit 本身被 enable 時,Also 後面接的 unit 也請 enable 的意思!也就是具有相依性的服務可以寫在這裡呢!
Alias 進行一個連結的別名的意思!當 systemctl enable 相關的服務時,則此服務會進行連結檔案的建立!以 multi-user.target 為例,這個傢伙是用來作為預設操作環境 default.target 的規劃, 因此當你設定用成 default.target 時,這個 /etc/systemd/system/default.target 就會連結到 /usr/lib/systemd/system/multi-user.target 囉!

如果 Type 設成 forking, service可能會產生下面的錯誤:

service start operation timed out. Terminating.

解法:

you made the service type forking, but this service does not fork. It just runs directly. Thus systemd waited five minutes for the program to daemonize itself, and it never did. The correct type for such a service is simple.

It seems like Nagios is not properly forking into background -d option, what systemd expects here due to type=forking.

So systemd counts a non-fork as a timeout during start.