⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 网络 「网络」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注微信公众号:【芋道源码】有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言都将得到认真回复。甚至不知道如何读源码也可以请教噢。
  4. 新的源码解析文章实时收到通知。每周更新一篇左右。
  5. 认真的源码交流微信群。

Nginx 的 access.log 里藏着网站的所有秘密——谁在访问、从哪来、看了什么、停留多久。但大多数人的做法是 tail -f access.log 然后肉眼扫描,或者写几行 awk 脚本凑合着看。说实话,这跟用算盘分析大数据没啥区别。

你可能会说:上 ELK 啊。但就为了分析个 Nginx 日志,搞一套 ES + Logstash + Kibana?杀鸡用牛刀,光运维成本就劝退了。

NginxPulse 就是那把”刚好够用的瑞士军刀”。 轻量级 Nginx 访问日志分析面板,实时统计、PV 过滤、IP 归属地解析、可视化报表,一个 Docker 命令就能跑起来,不需要任何外部依赖。

GitHub 地址:https://github.com/likaia/nginxpulse

技术选型:为什么是 Go + SQLite?

层级 技术选型 选型理由
后端 Go 1.23.x · Gin · Logrus 编译成单二进制,交叉编译方便,部署零依赖
数据 SQLite (modernc.org/sqlite) 不需要额外装数据库,嵌入式存储,读多写少的日志场景完美适配
IP 归属地 ip2region(本地库)+ ip-api.com(远程批量) 本地查询兜底,断网也能用
前端 Vue 3 · Vite · TypeScript · PrimeVue · ECharts/Chart.js 现代前端技术栈,图表交互体验好
容器 Docker / Docker Compose 一键部署,前后端打成单镜像

这套技术选型很克制。 没有用 MySQL/PostgreSQL 这类”正经”数据库,没有上 Redis 缓存,没有搞微服务架构——一个 Go 二进制 + 一个 SQLite 文件,整个应用的内存占用可能还不到 ES 的一个索引碎片。

对于个人博客、中小站点的日志分析来说,这才是正确的”量级”。

IP 归属地查询:五层降级策略,设计得很讲究

IP 归属地解析是日志分析的核心功能之一。很多开源工具要么只支持本地库(数据老旧),要么只调远程 API(慢且有限额)。NginxPulse 搞了一套五层逐级降级策略,值得学习:

请求 IP → ① 快速过滤 → ② 内存缓存 → ③ 远程批量查询 → ④ 本地 ip2region → ⑤ IPv6 特殊处理

① 快速过滤(零成本)
127.0.0.1、192.168.x.x、空值这类地址直接返回”本地/内网”,一次远程查询都不浪费。别笑——很多工具真的会把 127.0.0.1 发到远程 API 去查。

② 内存缓存(最多 50,000 条)
大部分站点的访客 IP 是高度重复的。5 万条缓存基本能覆盖中小站点一天的独立 IP,命中率极高。

③ 远程批量查询
调 ip-api.com/batch 接口,单批最多 100 个 IP,超时 1.2 秒。批量接口比逐个查效率高 10 倍以上,而且 ip-api 的免费额度(每分钟 45 次)按”请求次数”算不是按”IP 数量”算,一次请求查 100 个 IP 只算 1 次。

④ 本地兜底
远程挂了或返回”未知”?没关系,ip2region 本地数据库兜底。断网照样能用,虽然准确度略低,但总比返回空白强。

⑤ IPv6 特殊处理
ip2region 只支持 IPv4,IPv6 只能走远程。远程也查不到就老实返回”未知”。

部署提示:ip2region.xdb 内嵌在二进制中,首次启动自动解压到 ./var/nginxpulse_data/ip2region.xdb,加载向量索引提升查询性能。记得放行 ip-api.com 的出站访问,否则远程查询层直接废掉。

Docker 部署:真的只要一行

整个项目打成单镜像(前端 Nginx + 后端服务),不用分别部署前后端,不用配反向代理。

方式一:拉取远程镜像(推荐)

docker run -d --name nginxpulse \
-p 8088:8088 \
-p 8089:8089 \
-e WEBSITES='[{"name":"主站","logPath":"/share/log/nginx/access.log","domains":["kaisir.cn","www.kaisir.cn"]}]' \
-v ./nginx_data/logs/all/access.log:/share/log/nginx/access.log:ro \
-v "$(pwd)/var/nginxpulse_data:/app/var/nginxpulse_data" \
magiccoders/nginxpulse:latest

方式二:本地构建

docker build -t nginxpulse:local .

docker run -d --name nginxpulse \
-p 8088:8088 \
-p 8089:8089 \
-e WEBSITES='[{"name":"主站","logPath":"/share/log/nginx/access.log","domains":["kaisir.cn","www.kaisir.cn"]}]' \
-v ./nginx_data/logs/all/access.log:/share/log/nginx/access.log:ro \
-v "$(pwd)/var/nginxpulse_data:/app/var/nginxpulse_data" \
nginxpulse:local

跑起来后访问 8088 端口就能看到面板。唯一需要改的就是 WEBSITES 环境变量里的日志路径和域名。 多站点?数组里多加几个 JSON 对象就行。

适合谁用: 个人博客、中小站点、不想上 ELK 又想看日志统计的团队。大流量站点(日均百万 PV 以上)建议还是上正经的日志系统。

文章目录
  1. 1. 技术选型:为什么是 Go + SQLite?
  2. 2. IP 归属地查询:五层降级策略,设计得很讲究
  3. 3. Docker 部署:真的只要一行