[toc]php
systemd 是一個屬於用戶空間的系統服務管理程序,在紅帽 RHEL7 上採用,替代了原來 RHEL6 上的 systemVinit。 其做用是,在內核啓動完成後,初始化用戶空間的進程,進程號爲 1 、管理操做系統的運行級別,系統的服務啓動和關閉,系統的掛載點。html
systemctl get-default
systemctl isolate multi-user.target 或 systemctl isolate runlevel3.target
systemctl set-default multi-user.target
systemd target | 解釋 |
---|---|
runlevel0.target, poweroff.target | 關閉系統 —> 0 |
runlevel1.target, rescue.target | 單用戶模式 —> 1 |
runlevel2.target, runlevel4.target, multi-user.target | 用戶定義/域特定運行級別。默認等同於 3 —> 2,4 |
runlevel3.target, multi-user.target | 最經常使用模式,非圖形化多用戶 —> 3 |
runlevel5.target, graphical.target | 多用戶圖形化 —> 5 |
runlevel6.target, reboot.target | 重啓 —> 6 |
/etc/systemd/system/
在 Systemd 下 unit 文件用於配置對資源的控制,每種資源對應不一樣的 unit 文件類型,好比後臺服務(service)、套接字(socket)、設備(device)、掛載點(mount) 等。 全部 unit 文件都包含兩個通用段 [Unit] 、[Install] 和一個資源類型段,如 [Service] 就表示後臺服務。java
service :守護進程的啓動、中止、重啓和重載是此類 unit 中最爲明顯的幾個類型。nginx
socket :此類 unit 封裝系統和互聯網中的一個socket。當下,systemd支持流式, 數據報和連續包的AF_INET,AF_INET6,AF_UNIXsocket 。也支持傳統的 FIFOs 傳輸模式。每個 socket unit 都有一個相應的服務 unit 。相應的服務在第一個「鏈接」進入 socket 或 FIFO 時就會啓動(例如:nscd.socket 在有新鏈接後便啓動 nscd.service)。shell
device :此類 unit 封裝一個存在於 Linux設備樹中的設備。每個使用 udev 規則標記的設備都將會在 systemd 中做爲一個設備 unit 出現。udev 的屬性設置能夠做爲配置設備 unit 依賴關係的配置源。centos
mount:此類 unit 封裝系統結構層次中的一個掛載點。api
automount :此類 unit 封裝系統結構層次中的一個自掛載點。每個自掛載 unit 對應一個已掛載的掛載 unit (須要在自掛載目錄能夠存取的狀況下儘早掛載)。安全
target :此類 unit 爲其餘 unit 進行邏輯分組。它們自己實際上並不作什麼,只是引用其餘 unit 而已。這樣即可以對 unit 作一個統一的控制。(例如:multi-user.target 至關於在傳統使用 SysV 的系統中運行級別5);bluetooth.target 只有在藍牙適配器可用的狀況下才調用與藍牙相關的服務,如:bluetooth 守護進程、obex 守護進程等)bash
對應到 centos6 其實就是 /etc/init.d/ 下面的服務腳本,只是到了 systemd 裏面叫作 service unit 文件,命名必須以 .service 結尾。網絡
service unit(服務腳本) 文件在系統中的存放路徑
/usr/lib/systemd/system
[Unit] Description=nginx After=network.target [Service] Type=forking PIDFile=/alidata/server/nginx/logs/nginx.pid ExecStart=/alidata/server/nginx/sbin/nginx -c /alidata/server/nginx/conf/nginx.conf ExecReload=/alidata/server/nginx/sbin/nginx -s reload ExecStop=/alidata/server/nginx/sbin/nginx -s stop PrivateTmp=true [Install] WantedBy=multi-user.target
[Unit] :記錄文件的通用信息,如描述,開機啓動順序
[Service] :記錄 unit 文件類型,服務控制的相關指令
[Install] :安裝信息
Description:對本service的描述。
Before, After:定義啓動順序,Before=xxx.service,表明本服務在xxx.service啓動以前啓動。After=xxx.service,表明本服務在xxx以後啓動。
Requires: 這個單元啓動了,那麼它「須要」的單元也會被啓動; 它「須要」的單元被中止了,它本身也活不了。可是請注意,這個設定並不能控制某單元與它「須要」的單元的啓動順序(啓動順序是另外控制的),即 Systemd 不是先啓動 Requires 再啓動本單元,而是在本單元被激活時,並行啓動二者。因而會產生爭分奪秒的問題,若是 Requires 先啓動成功,那麼皆大歡喜; 若是 Requires 啓動得慢,那本單元就會失敗(Systemd 沒有自動重試)。因此爲了系統的健壯性,不建議使用這個標記,而建議使用 Wants 標記。可使用多個 Requires。
Wants:推薦使用。本單元啓動了,它「想要」的單元也會被啓動。可是啓動不成功,對本單元沒有影響。
Type:service的種類,包含下列幾種類型:
RemainAfterExit :當該服務的全部進程所有退出以後, 是否依然將此服務視爲活動(active)狀態。 默認值爲 no
PIDFile :指定守護進程的 PID 文件,強烈建議在 Type=forking 的狀況下明確設置此選項。由於有些服務啓動以後會派生多個進程,systemd 將會不知道哪個纔是該服務的主進程,指定 PID 文件有助於 Systemd 準確的找到服務的主進程。 systemd 不會寫入此文件, 但會在此服務中止後刪除它。 該指令要放在 ExecStart 上面。
ExecStart :啓動服務時須要執行的命令,能夠用 $變量名 引用 Environment 設置的進程環境變量 和 操做系統的環境變量 如 $USER
ExecStop :可選指令,用於設置服務被要求中止前所執行的指令,此處指令執行完後,該服務剩餘的進程都會被 kill 掉。 若是該指令沒填寫,在中止服務時會直接 kill 該服務下的全部進程。
ExecStartPre :設置在 ExecStart 指令執行以前執行的命令
ExecStartPost :設置在 ExecStart 指令執行成功以後執行的命令
ExecStopPost :設置該服務中止以後執行的命令
Environment :設置進程的環境變量, 值是一個空格分隔的 VAR=VALUE 列表。 能夠屢次使用此選項以增長新的變量或者修改已有的變量 (同一個變量以最後一次的設置爲準)。 若設爲空, 則表示清空先前全部已設置的變量。 注意: (1)不會在字符串內部進行變量展開(也就是"$"沒有特殊含義); (2)若是值中包含空格或者等號, 那麼必須在字符串兩邊使用雙引號(")界定。 例如: Environment="VAR1=word1 word2" VAR2=word3 "VAR3=$word 5 6" 設置了 "VAR1", "VAR2", "VAR3" 三個變量,其值分別爲 "word1 word2", "word3", "$word 5 6"
Alias : 啓用時使用的別名,能夠設爲一個空格分隔的別名列表。 每一個別名的後綴(也就是單元類型)都必須與該單元自身的後綴相同。systemctl enable 命令將會爲每一個別名建立一個指向該單元文件的軟鏈接。 注意,由於 mount, slice, swap, automount 單元不支持別名,因此不要在這些類型的單元中使用此選項。
[Unit] Description=簡單的Foo服務 [Service] ExecStart=/usr/sbin/foo-daemon [Install] WantedBy=multi-user.target
該單元文件建立了一個運行 /usr/sbin/foo-daemon 守護進程的服務,未設置 Type= 等價於 Type=simple 默認設置。 注意,本例中的 /usr/sbin/foo-daemon 必須在啓動後持續運行到服務被中止。 若是該進程只是爲了派生守護進程,那麼應該使用 Type=forking
[Unit] Description=清理老舊的 Foo 數據 [Service] Type=oneshot ExecStart=/usr/sbin/foo-cleanup [Install] WantedBy=multi-user.target
Type=oneshot 用於只須要執行一次,不須要持久運行的單元,例如文件系統檢查或者清理磁盤文件。此單元會啓動後一直等待指定的動做完成, 而後再回到中止狀態。 在 /usr/sbin/foo-cleanup 執行結束前, 該服務一直處於"啓動中"(activating)狀態,而一旦執行結束,該服務又當即變爲"中止"(inactive)狀態。 也就是說,對於 Type=oneshot 類型的服務,不存在"活動"(active)狀態。 這意味着,若是再一次啓動該服務,將會再一次執行該服務定義的動做。 注意,在前後順序上晚於該服務的單元, 將會一直等到該服務變成"中止"(inactive)狀態後, 纔會開始啓動。
Type=oneshot 是惟一能夠設置多個 ExecStart= 指令的服務類型。 多個 ExecStart= 指令將按照它們出現的順序依次執行, 一旦遇到錯誤,就會當即中止,再也不繼續執行, 同時該服務也將進入"失敗"(failed)狀態。
[Unit] Description=簡單的靜態防火牆 [Service] Type=oneshot RemainAfterExit=yes ExecStart=/usr/local/sbin/simple-firewall-start ExecStop=/usr/local/sbin/simple-firewall-stop [Install] WantedBy=multi-user.target
有時候,單元須要執行一個程序以完成某個設置(啓動), 而後又須要再執行另外一個程序以撤消先前的執行(中止)。 而第一次執行以後,該單元應該處於 活動(active) 狀態,但實際上並沒有任何進程在運行。網絡配置服務就是一個典型的例子,只須要執行一次的服務。
能夠經過設置 RemainAfterExit=yes 來知足這種需求。 在這種狀況下,systemd 將會在啓動成功後將該單元視爲處於"活動"(active)狀態(而不是"中止"(inactive)狀態)。 RemainAfterExit=yes 雖然能夠用於全部 Type= 類型, 可是在實踐中主要用於 Type=oneshot 和 Type=simple 類型。 對於 Type=oneshot 類型, systemd 一直等到服務啓動成功以後,纔會將該服務置於"活動"(active)狀態。 因此,依賴於該服務的其餘單元必須等待該服務啓動成功以後,才能啓動。 可是對於 Type=simple 類型, 依賴於該服務的其餘單元無需等待,將會和該服務同時並行啓動。
[Unit] Description=nginx After=network.target [Service] Type=forking PIDFile=/alidata/server/nginx/logs/nginx.pid ExecStart=/alidata/server/nginx/sbin/nginx -c /alidata/server/nginx/conf/nginx.conf ExecReload=/alidata/server/nginx/sbin/nginx -s reload ExecStop=/alidata/server/nginx/sbin/nginx -s stop PrivateTmp=true [Install] WantedBy=multi-user.target
PrivateTmp 設爲 yes 表示在進程的文件系統名字空間中掛載私有的 /tmp 與 /var/tmp 目錄, 也就是不與名字空間外的其餘進程共享臨時目錄。 這樣作會增長進程的臨時文件安全性,但同時也讓進程之間沒法經過 /tmp 或 /var/tmp 目錄進行通訊。 同時,當服務中止以後,全部先前在臨時目錄中建立的文件都將被刪除。
[Unit] Description=PHP7.0.8 start file [Service] Type=forking PIDFile=/alidata/server/php7.0.8/var/run/php-fpm.pid ExecStart=/alidata/server/php7.0.8/sbin/php-fpm --daemonize --fpm-config /alidata/server/php7.0.8/etc/php-fpm.conf --pid /alidata/server/php7.0.8/var/run/php-fpm.pid ExecStartPost=/usr/bin/chown www.www /alidata/server/php7.0.8/var/run/php7-fpm.sock StandardOutput=syslog StandardError=inherit [Install] WantedBy=multi-user.target
設置進程的標準輸出(STDOUT)。 可設爲 inherit, null, tty, journal, syslog, kmsg, journal+console, syslog+console, kmsg+console, socket, fd 之一。 syslog 表示 syslog 日誌服務。 注意,此時全部日誌都會隱含的複製一份到 journal 中。
設置進程的標準錯誤(STDERR)。 取值範圍及含義與 StandardOutput= 相同。 但有以下例外:(1) inherit 表示使用 StandardOutput= 的值。 (2) fd 的文件描述符名稱的默認值爲 "stderr" 此值默認爲 inherit
[Unit] Description=Filebeat sends log files to Logstash or directly to Elasticsearch. Documentation=https://www.elastic.co/products/beats/filebeat Wants=network-online.target After=network-online.target [Service] ExecStart=/usr/share/filebeat/bin/filebeat -c /etc/filebeat/filebeat.yml -path.home /usr/share/filebeat -path.config /etc/filebeat -path.data /var/lib/filebeat -path.logs /var/log/filebeat -E serverip=$serverip Restart=always [Install] WantedBy=multi-user.target
注意,在 Centos7 使用 Systemd 啓動 filebeat 時是不會傳遞系統環境變量的。 filebeat 若是在配置文件中引用了系統的環境變量,那麼會致使服務啓動失敗。 報錯大概是找不到那個引用了系統變量自定義的那個字段。 有兩個解決方法:
一、在 unit 文件中使用 Environment 相關參數,定義要使用的環境變量,在 ExecStart 啓動命令時引用。 -E serverip=$serverip
二、在 /etc/profile.d/ 目錄下建立定義系統環境變量的文件,裏面的內容相似
export serverip=ifconfig eth0 | grep 'inet' | awk '{print $2}' | cut -d':' -f2
,而後在啓動命令時直接用 $變量名 引用系統環境變量。
# /usr/lib/systemd/system/logstash.service # 自定義環境變量的寫法 [Unit] Description=Logstash start program [Service] Type=simple Environment=LOGDIR=/alidata/log/logstash CONF=/alidata/logstash-6.5.2/ngx_app_api_log_analyze.conf DATA=/alidata/logstash-6.5.2/data ExecStartPre=/usr/bin/rm -rf $DATA ExecStartPre=/usr/bin/rm -rf $LOGDIR ExecStart=/alidata/logstash-6.5.2/bin/logstash -f $CONF -l $LOGDIR [Install] WantedBy=multi-user.target
# /etc/systemd/system/logstash.service [Unit] Description=logstash [Service] Type=simple User=logstash Group=logstash # Load env vars from /etc/default/ and /etc/sysconfig/ if they exist. # Prefixing the path with '-' makes it try to load, but if the file doesn't # exist, it continues onward. EnvironmentFile=-/etc/default/logstash EnvironmentFile=-/etc/sysconfig/logstash ExecStart=/usr/share/logstash/bin/logstash "--path.settings" "/etc/logstash" Restart=always WorkingDirectory=/ Nice=19 LimitNOFILE=16384 [Install] WantedBy=multi-user.target
# /etc/default/logstash LS_HOME="/usr/share/logstash" LS_SETTINGS_DIR="/etc/logstash" LS_PIDFILE="/var/run/logstash.pid" LS_USER="logstash" LS_GROUP="logstash" LS_GC_LOG_FILE="/var/log/logstash/gc.log" LS_OPEN_FILES="16384" LS_NICE="19" SERVICE_NAME="logstash" SERVICE_DESCRIPTION="logstash" JAVA_HOME="/usr/java/jdk1.8.0_162"
'''查看系統全部已安裝的服務項''' systemctl list-unit-files --type=service '''查看系統全部運行的服務項''' systemctl list-units --type=service '''查看系統全部開機自啓動的服務項''' systemctl list-unit-files --type=service | grep enabled '''查看出錯的服務''' systemctl list-units --type=service --state=failed '''啓動服務''' systemctl start nginx.service '''中止服務''' systemctl stop nginx.service '''重載服務的配置文件''' systemctl reload nginx.service '''查看服務的狀態''' systemctl status nginx.service '''設置服務開機啓動''' systemctl enable nginx.service '''禁用服務的開機啓動''' systemctl disable nginx.service '''禁止服務的啓動,用於防止服務被其餘服務間接啓動,也沒法經過 start 或 restart 命令來啓動''' systemctl mask nginx.service '''取消對服務的啓動禁止''' systemctl unmask nginx.service '''從新讀取全部服務項,修改或添加服務單元文件以後須要執行''' systemctl daemon-reload '''查看系統啓動耗時''' systemd-analyze '''查看各項服務啓動耗時''' systemd-analyze blame | grep .service