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