網站首頁 編程語言 正文
前言
Nginx 作為常用的負載均衡網關. 會產生大量的日志. 但是由于 Nginx 的配置文件是一種聲明式的編程范式, 不方便描述流程控制, 因此不能通過簡單的指令實現日志的上報.
通常 Nginx 的日志上報是需要寫一個shell腳本或其他語言的腳本來定時解析 Nginx 的 log 文件, 然后進行上報.
利用 NJS 模塊, 可以實現實時的日志上報.
但是由于 NJS 模塊支持的指令的限制, 無法通過單一指令很好的實現日志上報. 通過多個指令的組合可以實現非阻塞性的實時日志上報.
該方案在 Nginx 中實現, 不依賴Node, Python 等其他進程
實現思路
Nginx 指令繁多, 以下為最近探索出的一種實現方式. 如果有更優雅的實現方法, 歡迎留言交流.
雖然擁有了強大的 Njs 模塊可以寫 JS 腳本, 但是 NJS 模塊的指令有諸多限制, 并不像 Node 一樣可以實現任意的功能.
如果要實現日志的實時上報, 需要滿足以下2個能力:
- 每個請求都可以觸發
- 后臺上報, 不阻塞當前請求的處理進程
常用的 js_set 指令雖然可以在每個請求時都觸發, 但是只支持同步的操作. 無法使用 fetch, subrequest 方法.
js_content 指令中可以使用 fetch 函數. 但只能在 location 中使用. 因此可以利用其他指令將請求轉發到 js_content 的路徑中, 在該指令中完成日志的上報.
而 http_auth_request_module 模塊的 auth_request 指令用于做請求的權限校驗, 如 jwt 校驗等. 該指令在每個請求時都會觸發, 創建一個子請求, 根據該請求的返回結果決定權限校驗的結果.
因此可以結合這兩個模塊來實現日志的上報.
實現步驟
1. 編譯 Nginx
實現該功能需要 Nginx 支持 ngx_http_js_module 和? ngx_http_auth_request_module 模塊.? 這2個模塊是默認不安裝的. 需要自己編譯實現
- NJS 模塊安裝可以參考 當JS邂逅Nginx
- http_auth_request_module 模塊只要在編譯時增加參數 --with-http_auth_request_module 即可
編譯
./configure --add-module=[NJS 模塊路徑]/NJS/nginx --with-http_auth_request_module make && make install
2. 配置文件如下
http { js_import http.js; # 引入 js 文件 server { listen 80; auth_request /proxy_report; # 該指令對于每個請求開始時都會觸發, 創建一個子請求轉發到 proxy_report 路徑上 location / { index index.html index.htm; } location /proxy_report { internal; # 限制僅接受內部請求 # 把原請求的 uri 和 method 數據保存在 header 中. 因為auth_request 請求會修改這些數據. proxy_set_header X-Original-URI $request_uri; proxy_set_header X-Original-METHOD $request_method; # 轉發到另外一個 server 上 proxy_pass http://localhost:8080/report; } } server { listen 8080; # 上報接口放在另外一個 server 中, 且該 server 中無 auth_request 指令, 避免循環觸發請求 location /report { # 通過 js_content 指令引入一個 js 處理腳本, 完成上報操作 js_content http.report; } } }
// http.js 文件 import qs from "querystring"; async function report (r) { let args = { // 從 header 中取原始的 uri 和 method 等請求數據 uri: r.headersIn['X-Original-URI'], method: r.headersIn['X-Original-METHOD'], remoteAddress: r.remoteAddress, status: r.status, headersIn: JSON.stringifry(r.headersIn), } // 發出異步請求, 不阻塞當前請求的進程, 在后臺完成上報 ngx.fetch(`http://[上報服務路徑]?${qs.stringify(args)}`, { method: 'GET', }) // 返回200的狀態碼使校驗指令成功 r.return(200) } export default { report }
總結
原文鏈接:https://juejin.cn/post/7045930355047530510
相關推薦
- 2023-04-01 pytorch常用函數之torch.randn()解讀_python
- 2022-07-21 解決win10系統網絡連接正常,但是網頁打不開的問題
- 2022-03-31 利用OpenCV實現質心跟蹤算法_python
- 2022-11-25 Docker?制作tomcat鏡像并部署項目的步驟_docker
- 2023-03-27 Android?BroadcastReceiver傳輸機制詳解_Android
- 2022-04-18 python列表推導式實現找出列表中長度大于5的名字_python
- 2022-11-29 Mybatis傳入參數類型不匹配導致的報錯:
- 2022-01-17 滑動列表數據按照A-Z首字母排列,右邊A-Z能動態定位到相應字母位置
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支