linux ulimit 調(diào)優(yōu)

在 Linux 系統(tǒng)中匈勋,在每個進(jìn)程中都有一組資源限制,進(jìn)程默認(rèn)打開的最大文件數(shù)個數(shù)為 1024 個衬吆,可以通過如下配置查看:

#ulimit-n

1024

在應(yīng)用程序開發(fā)過程中俱恶,比如向 server 發(fā)起連接的客戶端超過 1024 個時比搭,server 由于 1024 個最大的文件個數(shù)限制而出現(xiàn)打開文件失敗,進(jìn)而出現(xiàn)Too many open files 錯誤爹凹。

在linux中這些限制是分為軟限制 (soft limit) 和 硬限制 ( hard limit )厨诸。他們的區(qū)別就是軟限制可以在程序的進(jìn)程中自行改變(突破限制),而硬限制則不行(除非有 root 權(quán)限)禾酱。

軟限制是內(nèi)核實(shí)際執(zhí)行的限制微酬,任何進(jìn)程都可以將軟限制設(shè)置為任意小于等于對進(jìn)程限制的硬限制的值。

硬限制充當(dāng)軟限制的上限:非特權(quán)進(jìn)程只能將其軟限制設(shè)置為從 0 到硬限制的范圍內(nèi)的值颤陶,只有超級用戶進(jìn)程可以提高硬限制的值颗管。

任何一個進(jìn)程都可以降低其硬限制的值,但它必須大于或等于其軟限制的值滓走。

查看軟限制的命令

#ulimit-Sn

1024

查看硬限制的命令

#ulimit-Hn

4096

那么如何設(shè)置這些限制呢垦江?

1、可以通過 getrlimit 和 setrlimit 系統(tǒng)調(diào)用的方式進(jìn)行獲取和設(shè)置資源限制搅方。

#include<sys/resource.h>

intgetrlimit(intresource,?struct?rlimit?*rlim);

intsetrlimit(intresource,conststruct?rlimit?*rlim);

對于這 2 個函數(shù)的每一次調(diào)用都會指定一個資源以及一個指向下列結(jié)構(gòu)的指針比吭。

structrlimit{

rlim_trlim_cur;/*?Soft?limit?*/

rlim_trlim_max;/*?Hard?limit?(ceiling?for?rlim_cur)?*/

};

比如在應(yīng)用程序啟動過程中绽族,通過調(diào)用 setrlimit 的方法進(jìn)行設(shè)置。

structrlimitrlim;

rlim.rlim_cur?=5000;

rlim.rlim_cur?=5000;

if(setrlimit(RLIMIT_NOFILE,?&rlim)?!=0)

{

printf("failed?to?set?rlimit?for?open?files\n");

return0;

}

2梗逮、可以在啟動服務(wù)腳本中進(jìn)行設(shè)置

#!/bin/bash

ulimit-c?unlimited

ulimit-n?5000

./exec&

對于通過命令行修改的 ulimit 配置是臨時生效的项秉。

3、也可以修改配置文件(永久生效)慷彤,如下

#?vi?/etc/security/limits.conf

...

//在文件末尾添加如下2行

*????soft??????nofile????5000

*????hard??????nofile????5000

配置完后娄蔼,重啟系統(tǒng),使之生效底哗。

4岁诉、當(dāng)服務(wù)已經(jīng)啟動時,這個時候修改 unlimt 是無效的跋选,可以通過如下命令進(jìn)行動態(tài)調(diào)整

//?centos?7?環(huán)境

1涕癣、通過ps命令獲取服務(wù)的pid

2、先查看其配置信息

#?cat?/proc/{pid}/limits

...

Max?open?files50005000files

...

3前标、修改配置

//centos?7 下

#?prlimit??--nofile=6000:6000??--pid?{pid}

//centos?6 下

#?echo?-n"Max?open?files=6000:6000">?/proc/{pid}/limits

setrlimit? 原理分析

接下里通過源碼的方式進(jìn)行分析下當(dāng)使用 setrlimit ?系統(tǒng)調(diào)用設(shè)置最大打開文件個數(shù)時發(fā)生了什么坠韩。

asmlinkagelongsys_setrlimit(unsignedintresource,structrlimit?__user?*rlim)

{

structrlimit?new_rlim,?*old_rlim;

unsignedlongit_prof_secs;

intretval;

if(resource?>=?RLIM_NLIMITS)

return-EINVAL;

if(copy_from_user(&new_rlim,?rlim,sizeof(*rlim)))

return-EFAULT;

if(new_rlim.rlim_cur?>?new_rlim.rlim_max)

return-EINVAL;

//獲取舊的資源配置

old_rlim?=?current->signal->rlim?+?resource;

if((new_rlim.rlim_max?>?old_rlim->rlim_max)?&&

!capable(CAP_SYS_RESOURCE))

return-EPERM;

if(resource?==?RLIMIT_NOFILE?&&?new_rlim.rlim_max?>?NR_OPEN)

return-EPERM;

...

task_lock(current->group_leader);

//把新的配置設(shè)置上去

*old_rlim?=?new_rlim;

task_unlock(current->group_leader);

if(resource?!=?RLIMIT_CPU)

gotoout;

...

out:

return0;

}

該方法就是把新的配置信息替換掉當(dāng)前進(jìn)程舊的資源限制信息。

當(dāng)系統(tǒng)打開一個文件時炼列,需要獲取一個未使用的文件描述符只搁,其過程如下

int?get_unused_fd_flags(int?flags)

{

struct?files_struct?*?files?=?current->files;

int?fd,?error;

struct?fdtable?*fdt;

error?=?-EMFILE;

spin_lock(&files->file_lock);

repeat:

fdt?=?files_fdtable(files);

//查找一個未使用的文件描述符

fd?=?find_next_zero_bit(fdt->open_fds->fds_bits,?fdt->max_fds,

files->next_fd);

/*

*?N.B.?For?clone?tasks?sharing?a?files?structure,?this?test

*?will?limit?the?total?number?of?files?that?can?be?opened.

*/

//?查看描述符是否超過資源限制,返回錯誤

if(fd?>=?current->signal->rlim[RLIMIT_NOFILE].rlim_cur)

gotoout;

/*?Do?we?need?to?expand?the?fd?array?or?fd?set???*/

//根據(jù)fd進(jìn)行判斷是否需要擴(kuò)展文件描述表

error?=?expand_files(files,?fd);

if(error?<0)

gotoout;

if(error)?{

/*

*?If?we?needed?to?expand?the?fs?array?we

*?might?have?blocked?-?try?again.

*/

error?=?-EMFILE;

gotorepeat;

}

//設(shè)置fd的使用標(biāo)志

FD_SET(fd,?fdt->open_fds);

...

error?=?fd;

out:

spin_unlock(&files->file_lock);

returnerror;

}

從上述代碼可知俭尖,每當(dāng)打開一個文件時氢惋,都會判斷打開的文件描述符是否超過資源限制,若超過資源限制稽犁,則返回失敗焰望,錯誤碼為 Too many open files。


關(guān)注微信公眾號?Linux碼農(nóng) 獲取更多干貨

原文鏈接

linux ulimit 調(diào)優(yōu)

推薦閱讀:

Linux GDB的實(shí)現(xiàn)原理

進(jìn)程間通信(IPC) 系列 | mmap

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末已亥,一起剝皮案震驚了整個濱河市熊赖,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌虑椎,老刑警劉巖秫舌,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異绣檬,居然都是意外死亡足陨,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進(jìn)店門娇未,熙熙樓的掌柜王于貴愁眉苦臉地迎上來墨缘,“玉大人,你說我怎么就攤上這事∧魉希” “怎么了宽涌?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蝶棋。 經(jīng)常有香客問我卸亮,道長,這世上最難降的妖魔是什么玩裙? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任兼贸,我火速辦了婚禮,結(jié)果婚禮上吃溅,老公的妹妹穿的比我還像新娘溶诞。我一直安慰自己,他們只是感情好决侈,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布螺垢。 她就那樣靜靜地躺著,像睡著了一般赖歌。 火紅的嫁衣襯著肌膚如雪枉圃。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天庐冯,我揣著相機(jī)與錄音讯蒲,去河邊找鬼。 笑死肄扎,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的赁酝。 我是一名探鬼主播犯祠,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼酌呆!你這毒婦竟也來了衡载?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤隙袁,失蹤者是張志新(化名)和其女友劉穎痰娱,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體菩收,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡梨睁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了娜饵。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片坡贺。...
    茶點(diǎn)故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出遍坟,到底是詐尸還是另有隱情拳亿,我是刑警寧澤,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布愿伴,位于F島的核電站肺魁,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏隔节。R本人自食惡果不足惜鹅经,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望官帘。 院中可真熱鬧瞬雹,春花似錦、人聲如沸刽虹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽涌哲。三九已至胖缤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間阀圾,已是汗流浹背哪廓。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留初烘,地道東北人涡真。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像肾筐,于是被迫代替她去往敵國和親哆料。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評論 2 359

推薦閱讀更多精彩內(nèi)容