在高并发 HTTP 反向代理服务器 Nginx 中,存在着一个跟性能息息相关的模块 - 文件缓存。
经常访问到的文件会被 nginx 从磁盘缓存到内存,这样可以极大的提高 Nginx 的并发能力,不过因为 内存的限制,当缓存的文件数达到一定程度的时候就会采取淘汰机制,优先淘汰进入时间比较久或是最近 访问很少(LRU)的队列文件。
具体实现方案:
完整代码:
nginx_queue.h
#ifndef _NGX_QUEUE_H_INCLUDED_ #define _NGX_QUEUE_H_INCLUDED_ typedef struct ngx_queue_s ngx_queue_t; struct ngx_queue_s { ngx_queue_t *prev; ngx_queue_t *next; }; #define ngx_queue_init(q) (q)->prev = q; (q)->next = q; #define ngx_queue_empty(h) (h == (h)->prev) #define ngx_queue_insert_head(h, x) (x)->next = (h)->next; (x)->next->prev = x; (x)->prev = h; (h)->next = x; #define ngx_queue_insert_after ngx_queue_insert_head #define ngx_queue_insert_tail(h, x) (x)->prev = (h)->prev; (x)->prev->next = x; (x)->next = h; (h)->prev = x; #define ngx_queue_head(h) (h)->next; #define ngx_queue_last(h) (h)->prev #define ngx_queue_sentinel(h) (h) #define ngx_queue_next(q) (q)->next #define ngx_queue_prev(q) (q)->prev #define ngx_queue_remove(x) (x)->next->prev = (x)->prev; (x)->prev->next = (x)->next #define ngx_queue_data(q, type, link) (type *) ((char *) q - offsetof(type, link)) #endif
Nginx_双向循环队列.cpp
#include <Windows.h> #include <stdlib.h> #include <iostream> #include "nginx_queue.h" #include <time.h> using namespace std; typedef struct ngx_cached_open_file_s { //其它属性省略... int fd; ngx_queue_t queue; }ngx_cached_file_t; typedef struct { //其它属性省略... ngx_queue_t expire_queue; //其它属性省略... } ngx_open_file_cache_t; int main(void) { ngx_open_file_cache_t *cache = new ngx_open_file_cache_t; ngx_queue_t *q; ngx_queue_init(&cache->expire_queue); //1. 模拟文件模块,增加打开的文件到缓存中 for(int i=0; i<10; i++) { ngx_cached_file_t *e = new ngx_cached_file_t; e->fd = i; ngx_queue_insert_head(&cache->expire_queue, &e->queue); } //遍历队列 for(q=cache->expire_queue.next; q!=ngx_queue_sentinel(&cache->expire_queue); q=q->next) { printf("队列中的元素:%d\n", (ngx_queue_data(q,ngx_cached_file_t, queue))->fd); } //模拟缓存的文件到期,执行出列操作 while(!ngx_queue_empty(&cache->expire_queue)) { q=ngx_queue_last(&cache->expire_queue); ngx_cached_file_t *cached_file = ngx_queue_data(q, ngx_cached_file_t, queue); printf("出队列中的元素:%d\n", cached_file->fd); ngx_queue_remove(q); delete(cached_file); } system("pause"); return 0; }