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.