運(yùn)維人必收藏的最全Linux服務(wù)器程序規(guī)范

發(fā)表于 討論求助 2023-05-10 14:56:27

除了網(wǎng)絡(luò)通信外,服務(wù)器程序還必須考慮許多其他細(xì)節(jié)問(wèn)題,零碎,但基本上都是模板式的。

  • Linux服務(wù)器程序一般以后臺(tái)形式運(yùn)行。后臺(tái)程序又稱守護(hù)進(jìn)程。它沒(méi)有控制終端,因而也不會(huì)意外接受用戶輸入。守護(hù)進(jìn)程的父進(jìn)程一般是init進(jìn)程(pid=1)。

  • Linux服務(wù)器程序通常有一套日志系統(tǒng),它至少能輸出日志到文件,有的高級(jí)服務(wù)器可以輸出日志到專(zhuān)門(mén)的UDP服務(wù)器。大部分后臺(tái)進(jìn)程都在/var/log下有自己的日志目錄。

  • Linux服務(wù)器程序一般以某個(gè)專(zhuān)門(mén)的非root身份運(yùn)行。mysqld, httpd, syslogd等后臺(tái)進(jìn)程,并分別有自己的運(yùn)行賬戶mysql, apache, syslog?!?/span>

  • Linux服務(wù)器通常時(shí)可配置的。服務(wù)器程序通常處理很多命令選項(xiàng),如果一次運(yùn)行的選項(xiàng)太多,則克拉一用配置文件來(lái)管理。絕大多數(shù)服務(wù)器程序都有配置文件并存放在/etc下。

  • Linux服務(wù)器程序通常在啟動(dòng)時(shí)生成一個(gè)PID文件并存入/var/run目錄中,以記錄該后臺(tái)進(jìn)程的PID。

  • Linux服務(wù)器程序通常需要考慮系統(tǒng)資源和限制,以預(yù)測(cè)自身能承受多大負(fù)荷,比如進(jìn)程可用文件描述符總數(shù)和內(nèi)存總量等。

01 日志

1.Linux系統(tǒng)日志:

Linux提供一個(gè)守護(hù)進(jìn)程來(lái)處理系統(tǒng)日志–syslogd, 升級(jí)版–rsyslogd。

rsyslogd守護(hù)進(jìn)程可以接收用戶進(jìn)程輸出日志,可以接受內(nèi)核日志。

用戶進(jìn)程時(shí)通過(guò)調(diào)用syslog函數(shù)生成系統(tǒng)日志的。

該函數(shù)將日志輸出到一個(gè)unix本地域socket類(lèi)型(AF_UNIX)的文件/dev/log中,rsyslogd則監(jiān)聽(tīng)該文件以獲取用戶進(jìn)程的輸出。

內(nèi)核日志在以前的系統(tǒng)上時(shí)通過(guò)另一個(gè)守護(hù)進(jìn)程rklogd來(lái)管理的,rsyslogd利用額外的模塊實(shí)現(xiàn)了相同的功能。內(nèi)核日志由printk等換樹(shù)打印至內(nèi)核環(huán)狀緩存中。環(huán)狀緩存的內(nèi)容直接映射到/proc/kmsg。

rsyslogd通過(guò)讀取該文件獲得內(nèi)核日志,默認(rèn)調(diào)試信息保存在/var/log/debug,普通信息保存至/var/log/messages,內(nèi)核信息:/var/log/kern.log。配置文件:/etc/rsyslog.conf,主要設(shè)置內(nèi)核日志輸入路徑,是否接受UDP日志,及其監(jiān)聽(tīng)端口(默認(rèn)514 /etc/services)是否接受TCP日志及其監(jiān)聽(tīng)端口,日志文件權(quán)限,包含哪些配置文件。

2.syslog()

應(yīng)用程序使用syslog()與守護(hù)進(jìn)程rsyslogd通信。

該函數(shù)采用可變參數(shù)(第二個(gè)參數(shù)message和第三個(gè)參數(shù)。。。)來(lái)結(jié)構(gòu)化輸出。

priority:設(shè)施值 (按位異或) 日志級(jí)別。設(shè)施值默認(rèn):LOG_USER,下面針對(duì)默認(rèn)設(shè)施值,討論日志級(jí)別。

2.1下面這個(gè)函數(shù)可以改變syslog的默認(rèn)輸出方式,進(jìn)一步結(jié)構(gòu)化日志內(nèi)容

(1)ident:指定字符串將被添加到日志消息的日期和時(shí)間之后,通常設(shè)為程序的名字。

(2)logopt:對(duì)后續(xù)syslog調(diào)用的行為進(jìn)行配置,它可取下列值的按位異或

(3)facility: 用來(lái)修改ysyslog默認(rèn)設(shè)施值

此外,日志過(guò)濾也很重要,程序再開(kāi)發(fā)階段可能需要輸出很多調(diào)試信息,而發(fā)布之后,我們又要將這些調(diào)試信息關(guān)閉,解決這個(gè)問(wèn)題的方法并不是再程序發(fā)布之后,刪除調(diào)試代碼(日后可能還會(huì)用到),而是緝拿但地設(shè)置日志掩碼,使日志級(jí)別大于日志掩碼的日志被系統(tǒng)忽略。

2.2下面這個(gè)函數(shù)用于設(shè)置syslog的日志掩碼。

maskpri:指定日志掩碼值,該函數(shù)始終回成功,它返回調(diào)用進(jìn)程先前的日志掩碼值。

2.3關(guān)閉日志功能:

02 用戶信息

1.UID, EUID, GID, EGID

用戶信息對(duì)于服務(wù)器安全很重要,大多說(shuō)服務(wù)器以root啟動(dòng), 非root運(yùn)行

基礎(chǔ)知識(shí):

一個(gè)進(jìn)程擁有兩個(gè)用戶ID, UID, EUID, EUID存在的目的是為了方便資源的訪問(wèn), 它使得運(yùn)行程序的用戶擁有該程序的有效用戶權(quán)限,比如,su用來(lái)更改賬戶信息,但修改賬戶時(shí)su程序的所有者是root,在普通用戶運(yùn)行su程序時(shí),其有效用戶就是該程序的所有者root, 有效用戶為root的進(jìn)程稱為特權(quán)進(jìn)程,EGID與EUID類(lèi)似,下面演示uid, euid區(qū)別:

將生成的可執(zhí)行文件,所有者設(shè)置為root,并設(shè)置該文件set-user-id標(biāo)志,然后運(yùn)行。

從測(cè)試輸出結(jié)果看,進(jìn)程的uid是啟動(dòng)程序的用戶id, 而euid是root。

2.切換用戶

03 進(jìn)程間關(guān)系

1.進(jìn)程組:

Linux下每一個(gè)進(jìn)程都屬于一個(gè)進(jìn)程組,因此他們除了pid之外,還有進(jìn)程組ID(PGID)。我們用如下函數(shù)獲取指定進(jìn)程組PGID.

成功返回pid, 失敗-1,設(shè)置errno。

如果pid與pgid相同,則由pid指定的進(jìn)程別設(shè)置為進(jìn)程組首領(lǐng):如果pid為0, 表示當(dāng)前進(jìn)程的PGID為pgid;如果pgid為0, 則使用pid作為目標(biāo)pgid。setpid函數(shù)成功時(shí)返回0, 失敗-1, 設(shè)置errno。

一個(gè)進(jìn)程只能設(shè)置自己或者其子進(jìn)程的PGID。并且, 當(dāng)子進(jìn)程調(diào)用exec系列函數(shù)后,我們也不能再在父進(jìn)程中對(duì)他設(shè)置PGID。

2.會(huì)話

(1)一些有關(guān)聯(lián)的進(jìn)程將組成一個(gè)會(huì)話, 下面的函數(shù)用于創(chuàng)建一個(gè)會(huì)話:

該函數(shù)不能由進(jìn)程組的首領(lǐng)進(jìn)程調(diào)用,否則將產(chǎn)生一個(gè)錯(cuò)誤。對(duì)于非首領(lǐng)的進(jìn)程, 調(diào)用該函數(shù)不僅創(chuàng)建新會(huì)話, 而且有如下額外效果。

調(diào)用進(jìn)程成為會(huì)話的首領(lǐng),此時(shí)該進(jìn)程時(shí)新會(huì)話的唯一成員。

新建一個(gè)進(jìn)程組,其PGID就是調(diào)用進(jìn)程的PID, 調(diào)用進(jìn)程成為該組的首領(lǐng)。

調(diào)用進(jìn)程將甩開(kāi)終端(如果有)

該函數(shù)成功時(shí)返回新的進(jìn)程組PGID, 失敗-1, errno。

Linux進(jìn)程并未提供所謂會(huì)話ID的概念, 但Linux系統(tǒng)認(rèn)為它等于會(huì)話首領(lǐng)所在的進(jìn)程組的PGID,

(2)并提供了如下函數(shù)讀取SID

3.用ps命令查看進(jìn)程關(guān)系

執(zhí)行ps命令可查看進(jìn)程,進(jìn)程組和會(huì)話之間的關(guān)系。

在bash_shell 下執(zhí)行ps和less命令,所以ps和less命令的父進(jìn)程時(shí)bash命令,這個(gè)可以從PPID(父進(jìn)程PID)一列看出。

這三條命令創(chuàng)建了一個(gè)會(huì)話(SID是2962)和兩個(gè)進(jìn)程組(PGID:2962, 3102)bash命令的PID,PGID和SID都相同,顯然它時(shí)會(huì)話的首領(lǐng), 也就是組2962的首領(lǐng)。ps時(shí)3102的首領(lǐng),

04 系統(tǒng)資源限制

Linux上運(yùn)行的程序都會(huì)受到資源限制的影響,比如物理設(shè)備限制(cpu數(shù)量,內(nèi)存數(shù)量等),系統(tǒng)策略限制(cup時(shí)間等),以及具體實(shí)現(xiàn)的限制(文件名最大長(zhǎng)度)Linux系統(tǒng)資源限制可以通過(guò)如下一對(duì)函數(shù)來(lái)讀取和設(shè)置:

getrlimit , setrlimit

rlimit 結(jié)構(gòu)體定義如下:

成功返回0, 失敗-1, 置errno

rlim_t 是一個(gè)整數(shù)類(lèi)型,它描述資源級(jí)別

rlim_cur 成員指定資源的軟限制,建議性的,最好不要超越的限制,如果超越,系統(tǒng)可能向進(jìn)程發(fā)送信號(hào),并終止運(yùn)行,如果當(dāng)前進(jìn)程CPU時(shí)間超過(guò)軟限制,系統(tǒng)將向進(jìn)程發(fā)送SIGXCPU信號(hào);當(dāng)文件尺寸超過(guò)其軟限制時(shí),系統(tǒng)將向進(jìn)程發(fā)送SIZEXFSZ信號(hào)。

rlim_max 成員指定資源的硬限制。硬限制一般是軟限制的上限,普通程序可以減小應(yīng)限制,而只有以root身份運(yùn)行的程序才能增加硬限制,此外我們可以使用ulimit命令修改當(dāng)前shell環(huán)境下的資源限制(軟/硬)這種修改對(duì)該shell啟動(dòng)的所有后續(xù)程序都有效,我們也可以通過(guò)修改配置文件來(lái)改變系統(tǒng)軟限制和應(yīng)限制,而這種修改時(shí)永久的。

resource參數(shù)指定資源限制類(lèi)型。如下表

05 改變工作目錄和根目錄

有些服務(wù)器程序好需要改變工作目錄和根目錄(web /var/www)

獲取當(dāng)前進(jìn)程工作目錄和改變進(jìn)程的工作目錄的函數(shù):

buf參數(shù)指向的內(nèi)存用于存儲(chǔ)當(dāng)前工作目錄的絕對(duì)路徑,size指定其大小

如果當(dāng)前目錄的絕對(duì)路徑超度(+1 (‘’))超過(guò)了size,則getcwd返回NULL,errno:ERANG。

chdir中path指向要切換到的目錄。成功0, 失敗-1 置errno。

改變進(jìn)程根目錄:chroot

chroot并不改變進(jìn)程的當(dāng)前工作目錄,調(diào)用chroot之后,仍需要調(diào)用chdir(“/”)來(lái)將工作轉(zhuǎn)至新的工作目錄,之后原來(lái)的文件描述符依然生效。所以可以利用早先打開(kāi)的文件描述符來(lái)訪問(wèn)調(diào)用chroot之后不能直接訪問(wèn)的文件(目錄).

06 服務(wù)器程序后臺(tái)化

最后,如何在代碼中讓一個(gè)進(jìn)程以守護(hù)進(jìn)程的防止運(yùn)行,守護(hù)進(jìn)程的編寫(xiě)遵循一定的步驟,下面一個(gè)實(shí)例。

實(shí)際上,linux提供了完成同樣功能的庫(kù)函數(shù):

nochdir:傳0則工作目錄將被設(shè)置為”/”,否則繼續(xù)使用當(dāng)前工作目錄。

noclose:傳0標(biāo)準(zhǔn)輸入輸出,標(biāo)準(zhǔn)錯(cuò)誤輸出都被重定向到,dev/null,否則繼續(xù)使用原來(lái)的設(shè)備,成功0, 失敗-1 置error。

干貨分享

  • 這20個(gè)好用的 Unix/Linux 命令技巧 送給你

  • Pythoy 之 with ... as 語(yǔ)句的來(lái)龍去脈

  • 小白工程師必備:如何在 Git 中克隆、修改、添加和刪除文件?

  • 原來(lái)運(yùn)維不僅僅是 Linux,竟然還要知道這么這么這么多?

  • 利用Python網(wǎng)絡(luò)爬蟲(chóng)抓取微信好友的所在省位和城市分布及其可視化

  • 基于 Docker 搭建 MySQL 主從復(fù)制

  • 微信朋友圈千億訪問(wèn)量背后的技術(shù)挑戰(zhàn)和實(shí)踐總結(jié)

  • Python之MySQL及SQLAlchemy操作總結(jié)

  • 運(yùn)維必會(huì)基本功之:touch的這些玩法你都會(huì)麼

  • 運(yùn)維必會(huì)基本功之:awk從入門(mén)到大神

  • Python 中的 functools 是干嘛使的?

  • 運(yùn)維注意啦:Redis漏洞利用與防御

  • 運(yùn)維開(kāi)發(fā)來(lái)答:從輸入U(xiǎn)RL到頁(yè)面展示到底發(fā)生了什么

  • Python最簡(jiǎn)編碼規(guī)范

  • Shell腳本:你不知道的玩法

  • 可用于企業(yè)的 7 個(gè)最佳開(kāi)源 Web 服務(wù)器

  • 你知道怎么查看Linux發(fā)行版名稱和版本號(hào)嗎?

  • 常見(jiàn)MySQL高可用方案選型解讀

  • 為什么學(xué)習(xí)Linux?

  • 高可用架構(gòu)的6大常規(guī)方案

  • Ubuntu 18.04 LTS正式發(fā)布了,但我們來(lái)說(shuō)說(shuō)RHEL

  • 喪失先機(jī),沒(méi)有自研操作系統(tǒng)的大國(guó)之痛

  • Python技能進(jìn)階:冒泡算法排序,面試80%會(huì)問(wèn)到的問(wèn)題

  • Linux系統(tǒng)中尋求幫助,該找誰(shuí)?找“男人”??!

  • Linux中netstat與端口的那些事

  • 國(guó)際運(yùn)維圈粗大事了:Twitter遭遇世界范圍宕機(jī),有網(wǎng)友怨稱若“世界末日”

  • 運(yùn)維安全的那些事

  • Git 上菜了:Git 12 歲,送上 Git 技巧 12 招

  • Linux命令行也能玩Wi-Fi

  • Red Hat Enterprise Linux 7.5 正式版來(lái)了

  • Linux下GitHub的玩法分享

  • 給 “rm” 命令添加個(gè)“回收站”

  • 聽(tīng)說(shuō)墻外又出了個(gè) DNS 是 1.1.1.1 ?

  • MySQL運(yùn)維:索引與查詢性能優(yōu)化

發(fā)表
26906人 簽到看排名