国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Linux Systemd type=simple和type=forking的區(qū)別

這篇具有很好參考價值的文章主要介紹了Linux Systemd type=simple和type=forking的區(qū)別。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

  1. Type=forking

使用Type=forking時,要求ExecStart啟動的命令自身就是以daemon模式運行的。

而以daemon模式運行的進程都有一個特性:總是會有一個瞬間退出的中間父進程,例如,nginx命令默認以daemon模式運行,所以可直接將其配置為forking類型:

Type=simple是一種最常見的通過systemd服務系統(tǒng)運行用戶自定義命令的類型,也是省略Type指令時的默認類型。

例如,nginx命令默認以daemon模式運行,所以可直接將其配置為forking類型:

systemd type,ubuntu,linux,運維,服務器

注意上面status報告的信息中,ExecStart啟動的nginx的進程PID=7912,且該進程的狀態(tài)是已退出,退出狀態(tài)碼為0,這個進程是daemon類進程創(chuàng)建過程中瞬間退出的中間父進程。在forking類型中,該進程稱為初始化進程。同時還有一行Main PID: 7913 (nginx),這是systemd真正監(jiān)控的nginx服務主進程,其PID=7913,是PID=7912進程的子進程。

Type=forking類型代表什么呢?要解釋清楚該type,需從進程創(chuàng)建開始說起。

因為systemd service啟動的服務進程都是systemd的子進程,所以,在服務進程啟動時,總是由pid=1的systemd進程fork()一個子進程(子systemd進程),再在此進程分支中通過systemd.exec配置該子進程的環(huán)境,最后使用exec()去調(diào)用ExecStart指定的服務啟動命令。Exec()調(diào)用程序時會替換當前進程,所以啟動后的服務進程將會替代子systemd進程,于是服務進程自身成為pid=1 systemd進程的子進程。

對于Type=forking來說,pid=1的systemd進程fork出來的子進程正是瞬間退出的中間父進程,且systemd會在中間父進程退出后就認為服務啟動成功,此時systemd可以立即去啟動后續(xù)需要啟動的服務。

如果Type=forking服務中的啟動命令是一個前臺 命令會如何呢?比如將sleep配置為forking模式,將nginx daemon off配置為forking模式等。

答案是systemd會一直等待中間ExecStart啟動的進程作為中間父進程退出,在等待過程中個,systemctl start會一直卡住,直到等待超時而失敗,在此階段中,systemctl status將會查看到服務處于activating狀態(tài)。

systemd type,ubuntu,linux,運維,服務器

回到forking類型的服務。由于daemon類的進程會有一個瞬間退出的中間父進程(如上面的PID=7913的nginx進程),systemd是如何知道哪個進程是應該被監(jiān)控的服務主進程(Main PID)呢?

答案是靠猜。沒錯,systemd真的就是靠猜的。當設(shè)置Type=forking時,有一個GuessMainPID指令其默認值為Yes,它表示systemd會通過一些算法去猜測Main PID。當systemd的猜測無法確定哪個是主進程時,后果是嚴重的:systemd將不可靠。因為systemd無法正確探測服務是否真的失敗,當systemd誤認為服務失敗時,如果本服務器配置了自動重啟(配置了Restart指令),重啟服務器時可能會和當前正在運行但是systemd誤認為失敗的服務沖突(比如出現(xiàn)端口已被占用問題)。

多數(shù)情況下的猜測過程很簡單,systemd只需去找目前存活的屬于本服務的leader進程即可。但有些服務(少數(shù))情況可能比較復雜,在多進程之間做簡單的猜測并非總是可靠。

好在,Type=forking時的systemd提供了PIDFile指令(Type=forking通常都會結(jié)合PIDFile指令),systemd會從PIDFile指令所指定的PID文件中獲取服務的主進程PID。例如,編寫一個nginx的服務配置文件:

systemd type,ubuntu,linux,運維,服務器

GuessMainPID=Takes a boolean value that specifies whether systemd should try to guess the main PID of a service if it cannot be determined reliably. This option is ignored unless Type=forking is set and PIDFile= is unset because for the other types or with an explicitly configured PID file, the main PID is always known. The guessing algorithm might come to incorrect conclusions if a daemon consists of more than one process. If the main PID cannot be determined, failure detection and automatic restarting of a service will not work reliably. Defaults to yes.

該參數(shù)只有在啟動類型為forking,且沒有指定PIDFile參數(shù)時才有效。

  1. Type=forking時PIDFile指令的坑

關(guān)于PIDFile,有必要去了解一些注意事項,否則它們可能就會成為你的坑。

首先,PIDFile只適合在Type=forking模式下使用,其它時候沒必要使用,因為其它類型的Service主進程的PID都是確定的。systemd推薦PIDFile指定的PID文件在/run目錄下,所以,可能需要修改服務程序的配置文件,將其PID文件路徑修改為/run目錄之下,當然這并非必須。

但有一點必須注意,PIDFile指令的值要和服務程序的PID文件路徑保持一致。例如nginx的相關(guān)配置:

systemd type,ubuntu,linux,運維,服務器

其次,systemd會在中間父進程退出后立即讀取這個PID文件,讀取成功后就認為該服務已經(jīng)啟動成功。但是,systemd讀取PIDFile的時候,服務主進程可能還未將PID寫入到PID文件中,這時systemd將出現(xiàn)問題。所以,對于服務程序的開發(fā)人員來說,應盡早將主進程寫入到PID文件中,比如可以在中間父進程fork完之后立即寫入PID文件,然后再退出,而不是在fork出來的服務主進程內(nèi)部由主進程負責寫入。

上面的nginx服務配置文件是某個nginx版本yum包提供的,但卻是有問題的,我曾經(jīng)踩過這個坑,網(wǎng)上甚至將其報告為一個Bug。

上面的nginx.service文件可以正常啟動服務,但無法systemctl reload,只要reload就報錯,而且報錯時提示kill命令語法錯誤。kill語法錯誤顯然是因為沒有獲取到$MAINPID變量的值,而這正是因為systemd在nginx寫入PID文件之前先去讀取了PID文件,因為沒有讀取到內(nèi)容,所以$MAINPID變量為空值。

解決辦法是使用ExecStartPost=/usr/bin/sleep 0.1,讓systemd在初始化進程(即中間父進程)退出之后耽擱0.1秒再繼續(xù)向下執(zhí)行,即推遲了systemd讀取PID的過程,保證能讓systemd從PID文件中讀取到值。

最后,systemd只會讀PIDFile文件而不會寫,也不會創(chuàng)建它。但是,在停止服務的時候,systemd會嘗試刪除PID文件。因為服務進程可能會異常終止,導致已終止的服務進程的PID文件仍然保留著,所以在使用PIDFile指令時,通常還會使用ExecStartPre指令來刪除可能已經(jīng)存在的PID文件。正如上面給出的nginx配置文件一樣。

  1. Type=simple

Type=simple類型的服務只適合那些在shell下運行在前臺的命令。也就是說,當一個命令本身會以daemon模式運行時,將不能使用simple,而應該使用Type=forking。比如ls命令、sleep命令、非daemon模式運行的nginx進程以及那些以前臺調(diào)試模式運行的進程,在理論上都可以定義為simple類型的服務。

例如,編寫一個/usr/lib/systemd/system/test.service運行sleep進程:

systemd type,ubuntu,linux,運維,服務器

使用daemon-reload重載并啟動該服務進程:

systemd type,ubuntu,linux,運維,服務器

10秒內(nèi),sleep進程以daemon模式運行在后臺,就像一個服務進程一樣。10秒之后,sleep退出,于是systemd將該進程從監(jiān)控隊列中踢出。再次查看進程的狀態(tài)將是inactive:

systemd type,ubuntu,linux,運維,服務器

再來分析上面的服務配置文件中的指令。

ExecStart指令指定啟動本服務時執(zhí)行的命令,即啟動一個本該前臺運行的sleep進程作為服務進程在后臺運行。

需注意,systemd service的命令行中必須使用絕對路徑,且只能編寫單條命令(Type=oneshot時除外),如果要命令續(xù)行,可在尾部使用反斜線符號\等。

此外,命令行中支持部分類似Shell的特殊符號,但不支持重定向> >> << <、管道|、后臺符號&,具體可參考man systemd.service中command line段落的解釋說明。

對于Type=simple來說,systemd系統(tǒng)在fork出子systemd進程后就認為服務已經(jīng)啟動完成了,所以systemd可以緊跟著啟動排在該服務之后啟動的服務。它的偽代碼模型大概是這樣的:

systemd type,ubuntu,linux,運維,服務器

例如,先后連續(xù)啟動兩個Type=simple的服務,進程流程圖大概如下:

換句話說,當Type=simple時,systemd只在乎fork階段是否成功,只要fork子進程成功,這個子進程就受systemd監(jiān)管,systemd就認為該Unit已經(jīng)啟動。

因為子進程已成功被systemd監(jiān)控,無論子進程是否啟動成功,在子進程退出時,systemd都會將其從監(jiān)控隊列中踢掉,同時殺掉所有附屬進程(默認行為是如此,殺進程的方式由systemd.kill中的KillMode指令控制)。所以,查看服務的狀態(tài)將是inactive(dead)。

例如,下面的配置種,睡眠1秒后,該服務的狀態(tài)將變?yōu)閕nactive(dead)。

systemd type,ubuntu,linux,運維,服務器

這沒什么疑問。但考慮一下,如果simple類型下ExecStart啟動的命令本身就是以daemon模式運行的呢?其結(jié)果是systemd默認會立刻殺掉所有屬于服務的進程。

原因也很簡單,daemon類進程總是會有一個瞬間退出的中間父進程,而在simple類型下,systemd所fork出來的子進程正是這個中間父進程,所以systemd會立即發(fā)現(xiàn)這個中間父進程的退出,于是殺掉其它所有服務進程。

例如,以運行bash -c '(sleep 3000 &)'的simple類型的服務,被systemd監(jiān)控的bash進程會在啟動sleep后立即退出,于是systemd會立即殺掉屬于該服務的sleep進程。

systemd type,ubuntu,linux,運維,服務器

再例如,nginx命令默認是以daemon模式運行的,simple類型下直接使用nginx命令啟動服務,systemd會立刻殺掉所有nginx,即nginx無法啟動成功。

  1. Systemd Service:其它Type類型

  • simple:在fork出子systemd進程后,systemd就認為該服務啟動成功了

  • exec:在fork出子systemd進程且子systemd進程exec()調(diào)用ExecStart命令成功后,systemd認為該服務啟動成功

  • oneshot:在ExecStart命令執(zhí)行完成退出后,systemd才認為該服務啟動成功

  1. 因為服務進程退出后systemd才繼續(xù)工作,所以在未配置RemainAfterExit 指令時,oneshot類型的服務永遠無法出現(xiàn)active狀態(tài),它直接從啟動狀態(tài)到activating到deactivating再到dead狀態(tài)

  1. 當結(jié)合RemainAfterExit指令時,在服務進程退出后,systemd會繼續(xù)監(jiān)控該Unit,所以服務的狀態(tài)為active(exited),通過這個狀態(tài)可以讓用戶知道,該服務曾經(jīng)已經(jīng)運行成功,而不是從未運行過

  1. 通常來說,對于那些執(zhí)行單次但無需長久運行的進程來說,可以采用type=oneshot,比如啟動iptables,掛載文件系統(tǒng)的操作、關(guān)機或重啟的服務等文章來源地址http://www.zghlxwxcb.cn/news/detail-769173.html

到了這里,關(guān)于Linux Systemd type=simple和type=forking的區(qū)別的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務器費用

相關(guān)文章

  • Linux systemd 定時任務

    哈嘍大家好,我是咸魚。 說到 Linux 定時任務,大家用得最多的就是 crond 服務,但其實 systemd 也有類似的功能。我們不但可以通過 systemd 來管理服務,還能設(shè)置定時任務,那就是 systemd timer。 與 crond 相比,systemd 定時任務具有以下優(yōu)點: 更高的精度:systemd 定時任務可以精確

    2024年04月15日
    瀏覽(24)
  • 在 Linux 中使用 systemd 注冊服務

    Systemd 是一種現(xiàn)代的 Linux 系統(tǒng)初始化系統(tǒng)和服務管理器。它旨在管理系統(tǒng)服務的初始化、配置和控制。Systemd 的一個關(guān)鍵特性是它可以管理服務,這些服務是為系統(tǒng)提供特定功能的后臺進程。在本指南中,我們將探討如何使用 systemd 在 Linux 中注冊服務。 在 Linux 系統(tǒng)中,system

    2024年02月13日
    瀏覽(20)
  • Linux systemd的概述與發(fā)展歷程

    systemd是一個系統(tǒng)和服務管理器,廣泛用于現(xiàn)代Linux系統(tǒng)。它的設(shè)計目標是取代傳統(tǒng)的SysVinit作為Linux系統(tǒng)的初始化系統(tǒng),提供更快的啟動速度、更好的并行性和更多的功能。本文將對systemd進行概述,并探討其發(fā)展歷程。 初始化系統(tǒng) systemd負責啟動Linux系統(tǒng),并管理系統(tǒng)進程。它

    2024年01月19日
    瀏覽(15)
  • 將Linux init進程設(shè)置為systemd

    在Linux操作系統(tǒng)中,init進程是系統(tǒng)啟動的第一個進程。然而,隨著系統(tǒng)的發(fā)展,新的init進程systemd已經(jīng)逐漸取代了舊的init進程。如果想要將Linux init進程設(shè)置為systemd,可以按照以下步驟操作: 首先,需要檢查當前系統(tǒng)是否已經(jīng)安裝了systemd??梢酝ㄟ^以下命令進行檢查: 如果

    2024年02月15日
    瀏覽(15)
  • Linux 管理 Systemd 服務的命令行工具

    systemctl 是用于管理 Systemd 服務的命令行工具。下面是一些常用的 systemctl 命令及其功能: 1. `systemctl enable service`:啟用一個服務,使其在系統(tǒng)啟動時自動啟動。 2. `systemctl start service`:啟動一個服務。 3. `systemctl stop service`:停止一個服務。 4. `systemctl restart service`:重新啟動一

    2024年01月16日
    瀏覽(28)
  • 【Linux】使用systemd設(shè)置開機自啟動命令

    【Linux】使用systemd設(shè)置開機自啟動命令

    systemd是Linux系統(tǒng)中現(xiàn)代化的初始化系統(tǒng),可以使用它來實現(xiàn)開機自動運行命令。在systemd中,可以通過創(chuàng)建一個service文件,把要執(zhí)行的命令放在其中,然后將其添加到systemd的自啟動項中。 具體操作步驟如下: 首先在終端中使用sudo權(quán)限創(chuàng)建一個.service文件,用于存儲service配置

    2024年02月08日
    瀏覽(28)
  • linux下通過systemd配置開機自啟

    1.創(chuàng)建對應服務的啟動腳本,放在/etc/systemd/system,名字為服務名.service 2.賦予權(quán)限 chmod 777 自啟腳本絕對路徑 3.重新加載systemd配置 systemctl daemon-reload 4.使用以下命令啟用Kafka服務,使其在系統(tǒng)啟動時自動運行: systemctl enable kafka 5.使用以下命令啟動Kafka服務: systemctl start kafka

    2024年02月10日
    瀏覽(23)
  • Linux 系統(tǒng)服務日志查詢 journalctl:查詢 systemd 日記

    Linux 系統(tǒng)服務日志查詢 journalctl:查詢 systemd 日記

    systemd 在取代 SUSE Linux Enterprise 12 中的傳統(tǒng) init 腳本時(參見第 13 章 “systemd 守護程序”),引入了自身的稱為日記的日志記錄系統(tǒng)。由于所有系統(tǒng)事件都將寫入到日記中,因此,用戶不再需要運行基于 syslog 的服務。 日記本身是 systemd 管理的系統(tǒng)服務,全名為 systemd-journal

    2024年02月07日
    瀏覽(21)
  • linux目錄/usr/lib/systemd/system目錄詳解

    linux目錄/usr/lib/systemd/system目錄詳解

    init 的進化經(jīng)歷了這么幾個階段: CentOS 5: SysV init,串行 CentOS 6:Upstart,并行,借鑒ubuntu CentOS 7:Systemd,并行,借鑒MAC 今天我們一起來看看systemd的使用 Systemd 新特性: (1)系統(tǒng)引導時實現(xiàn)服務并行啟動:服務間無依賴關(guān)系會并行啟動 (2)按需激活進程:若服務非立刻使用,不會立刻

    2024年02月01日
    瀏覽(21)
  • 將java項目打包部署在linux系統(tǒng)上(配置成systemd)

    1.前置條件 1.0一些一些小問題 1.1mysql安裝 1.2redis安裝 1.3nginx安裝 1.4jdk安裝 2.打包部署 接下來就是打包,將打包文件拉上來 還有nginx的配置 還有前端包打包上傳小命令 這些下期再寫...

    2024年03月09日
    瀏覽(23)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包