C日志模块 + 时间模块
1. ngx日志
功能:
- 格式化
增加 %V 等格式 - 前缀
时间 + pid + level - level 控制是否输出
- 输出流控制
日志文件 + stderr
逻辑流程
判断level
加前缀
加格式化数据
输出流控制
时间模块
ngx的设计
1. 缓存时间信息
若每次读取时间都调用系统C库函数,则 不仅效率低,而且 可能 非 Async-Signal-Safe ,
所以 ngx 采用 在确保安全的情况下 调用 获得时间的函数,并将其 缓存下来,已供任意时间 读取。
为了 方便多种场景使用, ngx 不仅缓存 time(NULL) 的值(ngx_time_t),还将其进行格式转换为 人可读的 字符串,根据格式缓存在对应的 变量中。
48 static ngx_time_t cached_time[NGX_TIME_SLOTS];
49 static u_char cached_err_log_time[NGX_TIME_SLOTS]
50 [sizeof("1970/09/28 12:00:00")];
51 static u_char cached_http_time[NGX_TIME_SLOTS]
52 [sizeof("Mon, 28 Sep 1970 06:00:00 GMT")] ;
53 static u_char cached_http_log_time[NGX_TIME_SLOTS]
54 [sizeof("28/Sep/1970:12:00:00 +0600")];
55 static u_char cached_http_log_iso8601[NGX_TIME_SLOTS]
56 [sizeof("1970-09-28T12:00:00+06:00")];
57 static u_char cached_syslog_time[NGX_TIME_SLOTS]
58 [sizeof("Sep 28 12:00:00")];
2. 写上锁,读不用锁
由于写全局变量,所以需要上锁,
ngx使用 一个变量,判断是否为 1 ,实现锁
309 #define ngx_trylock(lock) (*(lock) == 0 && ngx_atomic_cmp_set(lock, 0, 1))
310 #define ngx_unlock(lock) *(lock) = 0
由于写时间次数少,读时间次数多,所以 读时间不上锁。
3. 读不用锁,导致多个缓存片段
由于读时时间时,可能另一个线程同时写时间,会导致冲突,
所以ngx设置了 64个缓存,
24 #define NGX_TIME_SLOTS 64
48 static ngx_time_t cached_time[NGX_TIME_SLOTS];
当写时间需要修改缓存时,写下一个缓存,因此避免 读写冲突
101 tp = &cached_time[slot];
102
103 if (tp->sec == sec) {
104 tp->msec = msec;
105 ngx_unlock(&ngx_time_lock);
106 return;
107 }
108
109 if (slot == NGX_TIME_SLOTS - 1) {
110 slot = 0;
111 } else {
112 slot++;
113 }
115 tp = &cached_time[slot];
116
117 tp->sec = sec;
118 tp->msec = msec;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?