在高并发 HTTP 反向代理服务器 Nginx 中,存在着一个跟性能息息相关的模块 - 文件缓存。

                              

经常访问到的文件会被 nginx 从磁盘缓存到内存,这样可以极大的提高 Nginx 的并发能力,不过因为内存的限制,当缓存的文件数达到一定程度的时候就会采取淘汰机制,优先淘汰进入时间比较久或是最近访问很少(LRU)的队列文件。

具体实现方案:

1. 使用双向循环队列保存缓存的文件节点,这样可以实现多种淘汰策略:

比如:如果采用淘汰进入时间比较久的策略,就可以使用队列的特性,先进先出

如果要采用按照 LRU,就遍历链表,找到节点删除。

源码实现:

nginx_queue.h

 1 #ifndef _NGX_QUEUE_H_INCLUDED_
2 #define _NGX_QUEUE_H_INCLUDED_
3 typedef struct ngx_queue_s ngx_queue_t;
4
5 struct ngx_queue_s
6 {
7 ngx_queue_t* prev;
8 ngx_queue_t* next;
9 };
10
11 #define ngx_queue_init(q)    \
12 (q)->prev = q;   \
13 (q)->next = q
14 #define ngx_queue_empty(h)    \
15 (h == (h)->prev)
16 #define ngx_queue_insert_head(h, x)\
17 (x)->next = (h)->next;     \
18 (x)->next->prev = x;      \
19 (x)->prev = h;          \
20 (h)->next = x
21 #define ngx_queue_insert_after ngx_queue_insert_head
22 #define ngx_queue_insert_tail(h, x)\
23 (x)->prev = (h)->prev;      \
24 (x)->prev->next = x;       \
25 (x)->next = h;          \
26 (h)->prev = x
27 #define ngx_queue_head(h) \
28 (h)->next
29 #define ngx_queue_last(h) \
30 (h)->prev
31 #define ngx_queue_sentinel(h) \
32 (h)
33 #define ngx_queue_next(q) \
34 (q)->next
35 #define ngx_queue_prev(q) \
36 (q)->prev
37 #define ngx_queue_remove(x) \
38 (x)->next->prev = (x)->prev; \
39 (x)->prev->next = (x)->next
40 #define ngx_queue_data(q, type, link)
41 (type*)((char*)q - offsetof(type, link))
42 #endif

Nginx_双向循环队列.cpp

 1 #include <Windows.h>
2 #include <stdlib.h>
3 #include <iostream>
4 #include "nginx_queue.h"
5 #include <time.h>
6
7 using namespace std;
8
9 typedef struct ngx_cached_open_file_s
10 {
11 //其它属性省略...
12 int fd;
13 ngx_queue_t queue;
14 }ngx_cached_file_t;
15
16 typedef struct
17 {
18 //其它属性省略...
19 ngx_queue_t expire_queue;
20 //其它属性省略...
21 } ngx_open_file_cache_t;
22
23 int main(void)
24 {
25 ngx_open_file_cache_t* cache = new ngx_open_file_cache_t;
26 ngx_queue_t* q;
27 ngx_queue_init(&cache->expire_queue);
28
29 //1. 模拟文件模块,增加打开的文件到缓存中
30 for (int i = 0; i < 10; i++)
31 {
32 ngx_cached_file_t* e = new ngx_cached_file_t;
33 e->fd = i;
34 ngx_queue_insert_head(&cache->expire_queue, &e->queue);
35 }
36
37 //遍历队列
38 for (q = cache->expire_queue.next;q != ngx_queue_sentinel(&cache->expire_queue); q = q->next)
39 {
40 printf("队列中的元素:%d\n", (ngx_queue_data(q, ngx_cached_file_t, queue))->fd);
41 }
42
43 //模拟缓存的文件到期,执行出列操作
44 while (!ngx_queue_empty(&cache->expire_queue))
45 {
46 q = ngx_queue_last(&cache->expire_queue);
47 ngx_cached_file_t* cached_file = ngx_queue_data(q, ngx_cached_file_t, queue);
48 printf("出队列中的元素:%d\n", cached_file->fd);
49 ngx_queue_remove(q);
50 delete(cached_file);
51 }
52 system("pause");
53 return 0;
54 }

==================================================================================================================

最新文章

  1. Serial Port Programming on Linux(转载)
  2. Mysql 查看版本号
  3. c#文件读入与写入
  4. 算法竞赛入门经典_第二章:循环结构程序设计_上机练习_MyAnswer
  5. Sql Server 2008修改Sa密码
  6. Day5_作业
  7. php如何判断远程文件是否存在
  8. javaWeb总结——session
  9. homework-05 GoldNumberServer
  10. LoadRunner性能测试中Controller场景创建需注意的几点
  11. MyBatis-xml配置SQL文件中,传入List数组、基本类型String、int……、与自定义类型的方法
  12. 获取request header的值
  13. ASP.NET Cookie 概述
  14. [Python Study Notes]CS架构远程访问获取信息--SERVER端v2.0
  15. 剑指Offer——贪心算法
  16. phpstudy如何安装ssl证书
  17. PHP 百万级数据导出方案(多 CSV 文件压缩)
  18. bootstrapTable使用场景及方式
  19. POJ 2955 Brackets(区间DP)题解
  20. Hierarchical RNN

热门文章

  1. Debian 64位内核升级步骤
  2. win10安装MySQL5.7.31 zip版
  3. 原生sql查询返回结果集处理方法
  4. 使用javaxmail发送文字邮件
  5. 自学linux——13.Linux下mysql的安装
  6. 使用logisim搭建单周期CPU与添加指令
  7. Java基础教程——Object类
  8. sqli-labs-master less02-04
  9. LeetCode 028 Implement strStr()
  10. Toolbar+DrawerLayout+NavigationView的使用