Apache日志需通过解析Remote_Addr或X-Forwarded-For字段,结合RFC 1918私有地址段(10.0.0.0/8、172.16.0.0/12、192.168.0.0/16等)及云厂商VPC网段,统计内网访问占比;Java程序可借助SubnetUtils或Guava实现CIDR匹配,并注意过滤干扰请求与统一时区。

Apache 日志本身不直接区分“内网”和“外网”,但可通过分析 Remote_Addr(或经代理后的真实客户端 IP,如 X-Forwarded-For)字段,结合已知内网 IP 段规则,统计访问来源的网络属性占比。Java 程序(如日志分析工具、Spring Boot 后端服务)可读取 Apache 的 access.log,解析 IP 并分类统计。
明确内网 IP 范围定义
根据 RFC 1918 和常用实践,典型私有地址段包括:
- 10.0.0.0/8(10.0.0.0 – 10.255.255.255)
- 172.16.0.0/12(172.16.0.0 – 172.31.255.255)
- 192.168.0.0/16(192.168.0.0 – 192.168.255.255)
- IPv6:如 fd00::/8(ULA 地址),若业务涉及 IPv6 需额外处理
注意:若服务部署在云环境(如阿里云、AWS),还需考虑云厂商的 VPC 内网网段(如阿里云 172.16–31.x.x、AWS 10.x.x.x),应按实际 VPC 配置补充。
正确获取真实客户端 IP
Apache 默认记录的是直连 TCP 连接方 IP(可能是反向代理如 Nginx、SLB 的地址)。需确保:
- 前端代理(如 Nginx)已配置
proxy_set_header X-Forwarded-For $remote_addr;,并透传原始 IP - Apache 开启
mod_remoteip模块,并配置RemoteIPHeader X-Forwarded-For和可信代理列表(RemoteIPInternalProxy) - 日志格式中使用
%{X-Forwarded-For}i或%a(启用 RemoteIP 后%a即为真实客户端 IP)
推荐在 httpd.conf 或虚拟主机中定义日志格式:
LogFormat "%a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined-realip
Java 端实现统计逻辑(示例)
使用 Java 读取日志文件(或流式消费),逐行解析并判断 IP 属性:
- 用正则或
org.apache.commons.net.util.SubnetUtils判断 IP 是否属于任一内网网段 - 累计内网计数(intranetCount)与总请求数(totalCount)
- 最终计算占比:
double intranetRatio = (double) intranetCount / totalCount;
简化判断示例(仅 IPv4):
public static boolean isIntranet(String ip) {
return ip.startsWith("10.") ||
ip.startsWith("172.16.") || ip.startsWith("172.17.") || ... ||
ip.startsWith("192.168.");
}
更健壮做法:使用 com.google.common.net.InetAddresses + SubnetUtils 做 CIDR 匹配。
注意事项与优化建议
避免常见误差:
- 未过滤健康检查请求(如
/health、/ping)、爬虫 UA、静态资源(CSS/JS/IMG)——建议按 URL 或 User-Agent 排除干扰 - 日志时区与业务时区不一致导致时间窗口统计偏差,建议统一为 UTC 或本地标准时
- 大日志文件建议用流式解析(
Files.lines()+filter/map/reduce),避免 OOM - 生产环境推荐接入 ELK(Elasticsearch + Logstash + Kibana)或 Prometheus + Grafana,用 Logstash filter 插件或 Ingest Pipeline 实现实时打标与聚合
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










