首頁 運維 Nginx nginx中的共享記憶體如何使用

nginx中的共享記憶體如何使用

May 14, 2023 pm 03:55 PM
nginx

ngx_shmem的使用

ngx_shmem.c/h檔案只是對mmap()/munmap()系統呼叫或shmget()/shmdt()的一個很簡單的封裝。實現了ngx風格的基礎庫,可以申請並釋放一段連續的共享記憶體空間。一般用於固定長度的共享資料使用,使用過程中資料長度固定不會伸縮。

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中共享記憶體的使用流程,一般是由master進程創建,worker進程透過繼承的方式獲得記憶體指標。

關於ngx_shmem的使用,可以參考ngx_event_module_init()中部分片段,這部分程式碼在共享記憶體中創建了若干個變量,用於記錄各個狀態(accepted/reading/writing...)的請求數量,並在ngx_event_module中的幾個關鍵事件入口對這幾個變數進行加減統計操作。實作統計所有worker進程目前的請求狀態。

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);
登入後複製

關於這個功能的更多細節,可以查看程式碼中的ngx_stat_stub巨集定義相關程式碼與ngx_http_stub_status_module。

ngx_slab的使用

ngx_shmem是一層極簡的封裝,實作了共享記憶體的基本功能。但我們程式中大部分的場景共享資料並不會一個固定大小的結構,而更多是像ngx_array、ngx_list、ngx_queue、ngx_rbtree這類大小可以變化的資料結構。

我們預期能有像ngx_pool_t一樣可以動態申請釋放空間一個記憶體池。 ngx_slab正是一個這樣的結構體,原理上與系統的malloc()有相識之處都是透過一系列演算法實現對一段段記憶體片段的申請與釋放。只不過ngx_slab操作的物件是基於ngx_shmem的共享記憶體。

先看一下ngx_slab的介面

typedef struct {
  ngx_shmtx_t    mutex;
  ...
  void       *data; /* 一般存放从pool中申请获得的根数据地址(pool中第一个申请的数据接口) */
  void       *addr; /* 使用ngx_shmem申请获得的共享内存基地址 */
} 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);
登入後複製

可以看到介面並不復雜,alloc與calloc的區別在於是否對申請獲得的記憶體段清零,_locked結尾的介面表示操作的pool已經是取得到鎖定的。在ngx_slab_pool_t的結構體有一個ngx_shmtx_t的互斥鎖用於同步多進程同時存取pool的並發場景。注意ngx_slab_alloc()會先取得鎖定、然後申請空間、最後釋放鎖定。而ngx_slab_alloc_locked()則直接申請空間,認為程式已經在其他邏輯中獲得鎖定了。

在nginx的開發中使用ngx_shmem一般需要遵循以下初始化流程:

  • 模組在配置解析過程中調用ngx_shared_memory_add()接口,註冊一段共享記憶體。提供共享記憶體大小與記憶體初始化的回呼函數。

  • 框架在ngx_init_cycle()中使用ngx_shmem申請內存,並初始化ngx_slab,然後回調模組註冊的初始化函數

  • #模組使用ngx_slab的申請/是否介面

在這個流程中,涉及ngx_shared_memory_add()介面與對應的ngx_shm_zone_t結構體。

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屬性,這個屬性控制了在nginx的reload過程中是否會重新申請共享記憶體。

由於關於ngx_init_cycle()函數較長,這個流程可以透過尋找/* create shared memory */這個註解或cycle->shared_memory這個物件查看相關程式碼。

以上是nginx中的共享記憶體如何使用的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1669
14
CakePHP 教程
1428
52
Laravel 教程
1329
25
PHP教程
1273
29
C# 教程
1256
24
nginx在windows中怎麼配置 nginx在windows中怎麼配置 Apr 14, 2025 pm 12:57 PM

如何在 Windows 中配置 Nginx?安裝 Nginx 並創建虛擬主機配置。修改主配置文件並包含虛擬主機配置。啟動或重新加載 Nginx。測試配置並查看網站。選擇性啟用 SSL 並配置 SSL 證書。選擇性設置防火牆允許 80 和 443 端口流量。

docker怎麼啟動容器 docker怎麼啟動容器 Apr 15, 2025 pm 12:27 PM

Docker 容器啟動步驟:拉取容器鏡像:運行 "docker pull [鏡像名稱]"。創建容器:使用 "docker create [選項] [鏡像名稱] [命令和參數]"。啟動容器:執行 "docker start [容器名稱或 ID]"。檢查容器狀態:通過 "docker ps" 驗證容器是否正在運行。

docker容器名稱怎麼查 docker容器名稱怎麼查 Apr 15, 2025 pm 12:21 PM

可以通過以下步驟查詢 Docker 容器名稱:列出所有容器(docker ps)。篩選容器列表(使用 grep 命令)。獲取容器名稱(位於 "NAMES" 列中)。

怎麼查看nginx是否啟動 怎麼查看nginx是否啟動 Apr 14, 2025 pm 01:03 PM

確認 Nginx 是否啟動的方法:1. 使用命令行:systemctl status nginx(Linux/Unix)、netstat -ano | findstr 80(Windows);2. 檢查端口 80 是否開放;3. 查看系統日誌中 Nginx 啟動消息;4. 使用第三方工具,如 Nagios、Zabbix、Icinga。

docker怎麼創建容器 docker怎麼創建容器 Apr 15, 2025 pm 12:18 PM

在 Docker 中創建容器: 1. 拉取鏡像: docker pull [鏡像名] 2. 創建容器: docker run [選項] [鏡像名] [命令] 3. 啟動容器: docker start [容器名]

nginx怎麼查版本 nginx怎麼查版本 Apr 14, 2025 am 11:57 AM

可以查詢 Nginx 版本的方法有:使用 nginx -v 命令;查看 nginx.conf 文件中的 version 指令;打開 Nginx 錯誤頁,查看頁面的標題。

nginx怎麼配置雲服務器域名 nginx怎麼配置雲服務器域名 Apr 14, 2025 pm 12:18 PM

在雲服務器上配置 Nginx 域名的方法:創建 A 記錄,指向雲服務器的公共 IP 地址。在 Nginx 配置文件中添加虛擬主機塊,指定偵聽端口、域名和網站根目錄。重啟 Nginx 以應用更改。訪問域名測試配置。其他注意事項:安裝 SSL 證書啟用 HTTPS、確保防火牆允許 80 端口流量、等待 DNS 解析生效。

nginx服務器掛了怎麼辦 nginx服務器掛了怎麼辦 Apr 14, 2025 am 11:42 AM

當 Nginx 服務器宕機時,可執行以下故障排除步驟:檢查 nginx 進程是否正在運行。查看錯誤日誌以獲取錯誤消息。檢查 nginx 配置語法正確性。確保 nginx 具有訪問文件所需的權限。檢查文件描述符打開限制。確認 nginx 正在偵聽正確的端口。添加防火牆規則以允許nginx流量。檢查反向代理設置,包括後端服務器可用性。如需進一步幫助,請聯繫技術支持。

See all articles