這篇文章將為大家詳細(xì)講解有關(guān)怎么在nginx中實(shí)現(xiàn)共享內(nèi)存,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對相關(guān)知識(shí)有一定的了解。

成都創(chuàng)新互聯(lián)-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比南山網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式南山網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋南山地區(qū)。費(fèi)用合理售后完善,10多年實(shí)體公司更值得信賴。
ngx_shmem的使用
ngx_shmem.c/h文件只是對mmap()/munmap()系統(tǒng)調(diào)用或者shmget()/shmdt()的一個(gè)很簡單的封裝。實(shí)現(xiàn)了ngx風(fēng)格的基礎(chǔ)庫,可以申請和釋放一段連續(xù)的共享內(nèi)存空間。一般用于固定長度的共享數(shù)據(jù)使用,使用過程中數(shù)據(jù)長度固定不會(huì)伸縮。
typedef struct {
u_char *addr;
size_t size;
...
} ngx_shm_t;
ngx_int_t ngx_shm_alloc(ngx_shm_t *shm);
void ngx_shm_free(ngx_shm_t *shm);在ngxin中共享內(nèi)存的使用流程,一般是由master進(jìn)程創(chuàng)建,worker進(jìn)程通過繼承的方式獲得內(nèi)存指針。
關(guān)于ngx_shmem的使用,可以參考ngx_event_module_init()中部分片段,這部分代碼在共享內(nèi)存中創(chuàng)建了若干個(gè)變量,用于記錄各個(gè)狀態(tài)(accepted/reading/writing...)的請求數(shù)量,并在ngx_event_module中的幾個(gè)關(guān)鍵事件入口對這幾個(gè)變量進(jìn)行加減統(tǒng)計(jì)操作。實(shí)現(xiàn)統(tǒng)計(jì)所有worker進(jìn)程當(dāng)前的請求狀態(tài)。
shm.size = size;
ngx_str_set(&shm.name, "nginx_shared_zone");
shm.log = cycle->log;
if (ngx_shm_alloc(&shm) != NGX_OK) {
return NGX_ERROR;
}
shared = shm.addr;
...
ngx_stat_accepted = (ngx_atomic_t *) (shared + 3 * cl);
ngx_stat_handled = (ngx_atomic_t *) (shared + 4 * cl);
ngx_stat_requests = (ngx_atomic_t *) (shared + 5 * cl);
ngx_stat_active = (ngx_atomic_t *) (shared + 6 * cl);
ngx_stat_reading = (ngx_atomic_t *) (shared + 7 * cl);
ngx_stat_writing = (ngx_atomic_t *) (shared + 8 * cl);
ngx_stat_waiting = (ngx_atomic_t *) (shared + 9 * cl);關(guān)于這個(gè)功能的更多細(xì)節(jié),可以查看代碼中的NGX_STAT_STUB宏定義相關(guān)代碼與ngx_http_stub_status_module。
ngx_slab的使用
ngx_shmem是一層極簡的封裝,實(shí)現(xiàn)了共享內(nèi)存的基本功能。但我們程序中大部分的場景共享數(shù)據(jù)并不會(huì)一個(gè)固定大小的結(jié)構(gòu),而更多是像ngx_array、ngx_list、ngx_queue、ngx_rbtree這類大小可以變化的數(shù)據(jù)結(jié)構(gòu)。
我們期望能有像ngx_pool_t一樣可以動(dòng)態(tài)申請釋放空間一個(gè)內(nèi)存池。ngx_slab正是一個(gè)這樣的結(jié)構(gòu)體,原理上與系統(tǒng)的malloc()有相識(shí)之處都是通過一系列算法實(shí)現(xiàn)對一段段內(nèi)存片段的申請與釋放。只不過ngx_slab操作的對象是基于ngx_shmem的共享內(nèi)存。
先看一下ngx_slab的接口
typedef struct {
ngx_shmtx_t mutex;
...
void *data; /* 一般存放從pool中申請獲得的根數(shù)據(jù)地址(pool中第一個(gè)申請的數(shù)據(jù)接口) */
void *addr; /* 使用ngx_shmem申請獲得的共享內(nèi)存基地址 */
} ngx_slab_pool_t;
void ngx_slab_init(ngx_slab_pool_t *pool);
void *ngx_slab_alloc(ngx_slab_pool_t *pool, size_t size);
void *ngx_slab_alloc_locked(ngx_slab_pool_t *pool, size_t size);
void *ngx_slab_calloc(ngx_slab_pool_t *pool, size_t size);
void *ngx_slab_calloc_locked(ngx_slab_pool_t *pool, size_t size);
void ngx_slab_free(ngx_slab_pool_t *pool, void *p);
void ngx_slab_free_locked(ngx_slab_pool_t *pool, void *p);可以看到接口并不復(fù)雜,alloc與calloc的區(qū)別在于是否對申請獲得的內(nèi)存段清零,_locked結(jié)尾的接口表示操作的pool已經(jīng)是獲取到鎖的。在ngx_slab_pool_t的結(jié)構(gòu)體有一個(gè)ngx_shmtx_t的互斥鎖用于同步多進(jìn)程同時(shí)訪問pool的并發(fā)場景。注意ngx_slab_alloc()會(huì)先獲取鎖、然后申請空間、最后釋放鎖。而ngx_slab_alloc_locked()則直接申請空間,認(rèn)為程序已經(jīng)在其他邏輯中獲得鎖了。
在nginx的開發(fā)中使用ngx_shmem一般需要遵循以下初始化流程:
模塊在配置解析過程中調(diào)用ngx_shared_memory_add()接口,注冊一段共享內(nèi)存。提供共享內(nèi)存大小與內(nèi)存初始化的回調(diào)函數(shù)。
框架在ngx_init_cycle()中使用ngx_shmem申請內(nèi)存,并初始化ngx_slab,然后回調(diào)模塊注冊的初始化函數(shù)
模塊使用ngx_slab的申請/是否接口
在這個(gè)流程中,涉及到ngx_shared_memory_add()接口與對應(yīng)的ngx_shm_zone_t結(jié)構(gòu)體。
struct ngx_shm_zone_s {
void *data;
ngx_shm_t shm;
ngx_shm_zone_init_pt init;
void *tag;
void *sync;
ngx_uint_t noreuse; /* unsigned noreuse:1; */
};
ngx_shm_zone_t *ngx_shared_memory_add(ngx_conf_t *cf, ngx_str_t *name,
size_t size, void *tag);其中值得一提的是noreuse屬性,這個(gè)屬性控制了在nginx的reload過程中是否會(huì)重新申請共享內(nèi)存。
關(guān)于怎么在nginx中實(shí)現(xiàn)共享內(nèi)存就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。
網(wǎng)頁標(biāo)題:怎么在nginx中實(shí)現(xiàn)共享內(nèi)存
當(dāng)前路徑:http://www.chinadenli.net/article14/iphige.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)網(wǎng)站建設(shè)、網(wǎng)站建設(shè)、網(wǎng)站營銷、小程序開發(fā)、面包屑導(dǎo)航、Google
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)