PHP、Tomcat获取Nginx代理后的客户端真实IP

文章目录

  • PHP、Tomcat获取Nginx代理后的客户端真实IP
    • 一、PHP获取Nginx代理后客户端真实IP
      • Nginx配置
      • PHP配置
      • 访问测试
    • 二、Tomcat获取Nginx代理后客户端真实IP
      • Nginx配置日志格式
      • Nginx配置转发IP头
      • Tomcat日志格式讲解
      • 配置Tomcat日志记录客户真实IP
    • 三、Nginx获取Nginx代理后的真实IP地址并将真实IP地址转发给Tomcat
      • 流量总入口Nginx配置如下
      • 门户入口Nginx配置如下
      • 门户应用服务器Tomcat配置如下
      • 日志查看

一、PHP获取Nginx代理后客户端真实IP

我们通过Nginx代理PHP的时候,PHP默认没有开启访问日志,这个需要我们手动开启,开启之后默认记录的客户端地址是上层代理的IP,并不是客户端真实IP地址,这个时候就需要我们自定义PHP的日志格式来实现记录客户端的真实IP地址,不再废话了,直接上配置。

Nginx配置

1.Nginx通过FastCGI模块代理PHP

vim /usr/local/nginx/conf/nginx.conflocation ~* \.php$ {root /usr/local/nginx/html;fastcgi_index   index.php;fastcgi_pass    127.0.0.1:9000;include         fastcgi_params;    #包含fastcgi_params文件fastcgi_param   SCRIPT_FILENAME    $document_root$fastcgi_script_name;}

2.修改fastcgi_params文件
在fastcgi_params文件中加入我们自定义的文本及映射的Nginx内置变量

vim /usr/local/nginx/conf/fastcgi_params
fastcgi_param  X_FORWARDED_FOR $proxy_add_x_forwarded_for;

"X-Forwarded-For"客户端请求头字段,后面附加了$remote_addr变量,中间用逗号分隔.
如果"X-Forwarded-For"字段没有出现在客户端请求头中,那么$proxy_add_x_forwarded_for变量将等于$remote_addr变量。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qNkOjtyC-1595991580539)(https://abcops.cn/wp-content/uploads/2020/07/15874572920536.jpg)]

3.重载Nginx

/usr/local/nginx/sbin/nginx -t && /usr/local/nginx/sbin/nginx -s reload

PHP配置

1.开启access.log访问日志
将www.conf文件中的access.log参数前面的注释去掉,然后指定日志打印路径(路径必须真实存在,相对路径从php家目录开始)

vim /usr/local/php/etc/php-fpm.d/www.conf
access.log = var/log/$pool.access.log

2.定义日志访问格式
同样打开www.conf文件定位到 access.format 并取消前面的注释

vim /usr/local/php/etc/php-fpm.d/www.conf
access.format = "[%R] [%{X_FORWARDED_FOR}e] [%{user}C] [%u] [%t] [%d] [%{Content-Type}o] [%{X-Powered-By}o] [%m %r%Q%q] [%s] [%f] [%{mili}d] [%{kilo}M] [%C%%]"

以上是我定义的PHP日志格式,着重讲一下 %{X_FORWARDED_FOR}e, X_FORWARDED_FOR 为我们在Nginx fastcgi_params 文件中定义的文本,这里使用 %{X_FORWARDED_FOR}e 来进行变量调用。

有关PHP日志格式说明可以参考日志格式上面的解释:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2Mm6gc99-1595991580545)(https://abcops.cn/wp-content/uploads/2020/07/15874578122750.jpg)]

3.定义完成后进行重启PHP

systemctl restart php-fpm
#然后确定php进程是否启动成功,如果启动失败,请看php启动日志
ps -ef|grep php-fpm

4.PHP日志

启动日志:/usr/local/php/var/log/php-fpm.log
访问日志:/usr/local/php/var/log/www.access.log

访问测试

重启成功后进行访问网站,然后查看PHP访问日志,以下图片可以看到,第二列为客户单的真实IP地址

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uFegt0t3-1595991580547)(https://abcops.cn/wp-content/uploads/2020/07/15874580882192.jpg)]

二、Tomcat获取Nginx代理后客户端真实IP

如果我们采用Nginx+Tomcat这种架构时,客户端请求将由Nginx转发至后端Tomcat,当有要求在Tomcat日志中也能看到客户端真实IP地址的情况下,我们就需要使用到Nginx的 proxy_set_header指令来进行协助,而且还需要修改Tomcat对于 localhost_access 的日志格式,要不然tomcat记录的访客IP全都是Nginx的, 这是因为所有的请求都是由Nginx前端服务器转发而来的。

Nginx配置日志格式

Nginx需要先获取到客户端的真实IP地址后才能将客户端真实IP地址发送到后端Tomcat,所以也需要配置Nginx的日志格式,在Nginx代理Tomcat的日志格式中最为重要的配置为 $remote_addr 来获取到真实客户端IP地址,我这里的Nginx日志格式如下:

   log_format  main  '$remote_addr" "$remote_user" "[$time_local]" "$request"'' "$status" "$body_bytes_sent" "$http_referer"'' "$http_user_agent" "$http_x_forwarded_for" "$gzip_ratio"'' "$upstream_addr" "$request_time" "$upstream_response_time" "$http_host"';

有关更多Nginx日志格式请见:https://k8sops.cn/nginx_log_module/

Nginx配置转发IP头

proxy_set_header指令可以配置到 http, server, location 三个配置段当中,我这里配置到 location 字段中。

location ^~ /crm-newm {proxy_pass  http://172.26.3.55:8086;proxy_http_version 1.1;proxy_set_header Host $host;proxy_set_header Port $proxy_port;proxy_set_header X-Real-IP $remote_addr;}

proxy_http_version指令解析:
proxy_http_version指令用于设置代理的HTTP协议版本。默认情况下,使用的是1.0版。建议将版本1.1用于keepalive连接和NTLM身份验证

Syntax: proxy_http_version 1.0 | 1.1;
Default:    proxy_http_version 1.0;
Context:    http, server, location

proxy_set_header
proxy_set_header指令用于重新定义header或将字段附加到代理服务器的请求头中。该值可以包含文本、变量、或者文本变量的组合。

**proxy_set_header Host h o s t ; ∗ ∗ H o s t 为 自 定 义 文 本 , ‘ host;** Host为自定义文本,` host;∗∗Host为自定义文本,‘host`变量为Nginx中的内置变量,用于获取当前主机名

**proxy_set_header Port p r o x y p o r t ; ∗ ∗ P o r t 为 自 定 义 文 本 , ‘ proxy_port;** Port为自定义文本,` proxyp​ort;∗∗Port为自定义文本,‘proxy_port`变量也是为Nginx中的内置变量,用于获取nginx代理的主机端口

**proxy_set_header X-Real-IP r e m o t e a d d r ; ∗ ∗ X − R e a l − I P 为 自 定 义 文 本 , ‘ remote_addr;** X-Real-IP为自定义文本,` remotea​ddr;∗∗X−Real−IP为自定义文本,‘remote_addr变量也是Nginx中的内置变量,用于获取真实客户端IP地址,与Nginx中的$remote_addr`一致

以上配置对于HTTP头部内容,这些变量是不区分大小写的

Tomcat日志格式讲解

在tomcat家目录下的 conf/server.xml 文件中,定位到 logs 字段来修改tomcat日志格式

vim conf/server.xml<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"prefix="localhost_access_log" suffix=".txt"pattern="%h %l %u %t &quot;%r&quot; %s %b" />

prefix
prefix用于指定tomcat 访问日志的前缀

suffix
suffix用于指定tomcat 访问日志的后缀

pattern
pattern用于指定tomcat 访问日志的输出格式

访问日志支持的格式如下:

    %a - 远程IP地址%A - 本地IP地址%b - 发送的字节数,不包括HTTP头,或“ - ”如果没有发送字节%B - 发送的字节数,不包括HTTP头%h - 远程主机名%H - 请求协议%l - (小写的L)- 远程逻辑从identd的用户名(总是返回' - ')%m - 请求方法%p - 本地端口%q - 查询字符串(在前面加上一个“?”如果它存在,否则是一个空字符串%r - 第一行的要求%s - 响应的HTTP状态代码%S - 用户会话ID%t - 日期和时间,在通用日志格式%u - 远程用户身份验证%U - 请求的URL路径%v - 本地服务器名(访问域名)%D - 处理请求的时间(以毫秒为单位)%T - 处理请求的时间(以秒为单位)%I -(大写的i) - 当前请求的线程名称

另外,还可以将request请求的查询参数、session会话变量值、cookie值或HTTP请求/响应头内容的变量值等内容写入到日志文件。
它仿照了apache的语法:

    %{XXX}i  xxx代表传入的头(HTTP Request)%{XXX}o  xxx代表传出​​的响应头(Http Resonse)%{XXX}c  xxx代表特定的Cookie名%{XXX}r  xxx代表ServletRequest属性名%{XXX}s  xxx代表HttpSession中的属性名

配置Tomcat日志记录客户真实IP

此配置需要修改Tomcat的日志格式来支持记录客户端的真实IP地址,默认是不可以的。
在Nginx+Tomcat架构中使用日志格式中的 %a 是获取不到真实客户端IP地址的,如果直接访问Tomcat那么 %a 可以获取到真实客户端IP地址。
如果要在Nginx+Tomcat架构中记录真实客户端IP地址需要在日志格式中添加 %{X-Real-IP}i 配置来获取,
%{X-Real-IP}i 是我们在Nginx location 配置段中指定的文本来获取 $remote_addr 变量值的,在这里将此值传送给 Tomcat。
%{Port}i 也是我们在Nginx中定义的文本来获取后端的转发端口,这里也将值转发至Tomcat。

        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"prefix="localhost_access_log" suffix=".txt"pattern="%t %{X-Real-IP}i %h:%p %A:%{Port}i %m %s %S %u %H %v %U %b %T %I" />

以上日志输出格式默认以空格做为分割的,以上格式我已经做了排版,tomcat输出访问日志如下:

  1. %t 日期和时间
  2. %{X-Real-IP}i 客户端真实IP地址
  3. %h:%p 远程IP(Nginx代理IP),远程端口(客户端访问Nginx的端口)
  4. %A:%{Port}i 本地IP地址及访问的本地端口
  5. %m HTTP请求方法
  6. %s 请求状态码
  7. %S 用户会话ID
  8. %u 远程用户身份验证
  9. %H HTTP请求协议
  10. %v 访问的域名
  11. %U 访问的URL
  12. %b 发送的字节数,不包括HTTP头,或“ – ”如果没有发送字节
  13. %T Tomcat处理请求的时间(以秒为单位)
  14. %I (大写的i)当前请求的线程名称

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z9xQhgay-1595991580554)(https://abcops.cn/wp-content/uploads/2020/07/15866750639518.jpg)]

三、Nginx获取Nginx代理后的真实IP地址并将真实IP地址转发给Tomcat

在我们线上不乏有一些企业中,在公司多套平台中的流量总入口为Nginx或者LVS,然后将总入口拿到的流量再转发给各个平台的负载均衡器,然后负载均衡器再将请求转发给真实的Web应用服务器,这种情况下,客户端请求从总入口到真实服务器共转发了两次,这时候我们需要将真实服务器以及前端的两个代理获取到真实的客户端IP地址。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IOL0UWlb-1595991580557)(https://abcops.cn/wp-content/uploads/2020/07/15866812332211.jpg)]

流量总入口Nginx配置如下

日志格式配置:

log_format  main  '$remote_addr" "$remote_user" "$time_iso8601" "$request"'' "$status" "$body_bytes_sent" "$connection" "$connection_requests" "$http_referer"'' "$http_user_agent" "$http_x_forwarded_for" "$gzip_ratio" "$request_time"'' "$upstream_addr" "$upstream_response_time" "$upstream_status" "$http_host"';
access_log  logs/access.log  main;

客户端真实IP地址转发配置

        location / {proxy_pass http://192.168.31.242;                   #转发到门户系统的Nginx代理proxy_http_version 1.1;                             #使用HTTP1.1协议proxy_set_header Host $host;                        #转发当前本地主机名称proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #通过X-Forwardel-For方式将客户端的真实IP地址转发至192.168.31.242,如果通过 $remote_addr 的方式,那么门户的Nginx将获取的地址是总流量入口的地址,并非客户端真实地址}

门户入口Nginx配置如下

日志格式设置:

    log_format  main  '$http_x_forwarded_for" "$remote_addr"  "$remote_user" "$time_iso8601" "$request"'' "$status" "$body_bytes_sent" "$connection" "$connection_requests" "$http_referer"'' "$http_user_agent" "$gzip_ratio" "$request_time"'' "$upstream_addr" "$upstream_response_time" "$upstream_status" "$http_host"';access_log  logs/access.log  main;

$http_x_forwarded_for:用来获取经过代理后的客户端真实IP地址
$remote_addr:获取客户端IP地址(这里会获取到流量总入口的Nginx IP地址)

客户端真实IP地址转发配置
门户入口Nginx拿到客户端真实IP地址后,将真实IP地址转发至后端的应用服务器

        location / {proxy_pass http://192.168.31.244:8080;      #转发到应用服务器proxy_http_version 1.1;                     #使用HTTP1.1协议proxy_set_header Host $host;                #转发当前本地主机名称proxy_set_header Port $proxy_port;          #转发被代理的端口到后端服务器proxy_set_header X-Real-IP $remote_addr;    #转发远程客户端地址到后端服务器proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;    ##通过X-Forwardel-For方式将客户端的真实IP地址转发至192.168.31.244}

门户应用服务器Tomcat配置如下

修改Tomcat日志格式

vim conf/server.xml<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"prefix="localhost_access_log" suffix=".txt"pattern="%t %{X-Forwarded-For}i %{X-Real-IP}i %h:%p %A:%{Port}i %m %s %S %u %H %v %U %b %T %I" />

%{X-Forwarded-For}i
获取门户Nginx转发过来的真实客户端IP地址

%{X-Real-IP}i
获取客户端地址(上个Nginx在 proxy_set_header 中定义的地址)

日志查看

1.总流量入口Nginx日志
重要内容为:

  1. 192.168.31.72:客户端原始IP地址 (日志变量$remote_addr获取)
  2. 192.168.31.242:80:转发地址 (日志变量$upstream_addr获取)
192.168.31.72" "-" "2020-04-12T17:13:24+08:00" "GET / HTTP/1.1" "200" "2065" "948" "1" "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.5 Safari/605.1.15" "-" "5.45" "0.390" "192.168.31.242:80" "0.389" "200" "devops.cn"
192.168.31.72" "-" "2020-04-12T17:13:25+08:00" "GET / HTTP/1.1" "200" "2065" "948" "2" "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.5 Safari/605.1.15" "-" "5.45" "0.012" "192.168.31.242:80" "0.013" "200" "devops.cn"
192.168.31.72" "-" "2020-04-12T17:13:26+08:00" "GET / HTTP/1.1" "200" "2065" "948" "3" "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.5 Safari/605.1.15" "-" "5.45" "0.007" "192.168.31.242:80" "0.007" "200" "devops.cn"

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YC0enMiZ-1595991580559)(https://abcops.cn/wp-content/uploads/2020/07/15866828175941.jpg)]

2.门户流量入口Nginx日志
重要日志内容:

  1. 192.168.31.72:客户端真实IP地址 (日志变量$http_x_forwarded_for获取,由流量入口Nginx使用X-Forwarded-For转发)
  2. 192.168.31.243:客户端原始IP地址(日志变量$remote_addr获取)
  3. 192.168.31.244:8080:转发地址 (日志变量$upstream_addr获取)
192.168.31.72" "192.168.31.243"  "-" "2020-04-12T17:13:24+08:00" "GET / HTTP/1.1" "200" "11215" "183" "1" "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.5 Safari/605.1.15" "-" "0.388" "192.168.31.244:8080" "0.388" "200" "devops.cn"
192.168.31.72" "192.168.31.243"  "-" "2020-04-12T17:13:25+08:00" "GET / HTTP/1.1" "200" "11215" "185" "1" "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.5 Safari/605.1.15" "-" "0.009" "192.168.31.244:8080" "0.009" "200" "devops.cn"
192.168.31.72" "192.168.31.243"  "-" "2020-04-12T17:13:26+08:00" "GET / HTTP/1.1" "200" "11215" "187" "1" "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.5 Safari/605.1.15" "-" "0.006" "192.168.31.244:8080" "0.006" "200" "devops.cn"

3.门户应用Tomcat日志内容

  1. 192.168.31.72, 192.168.31.243:客户端真实IP地址,因为Nginx经过了两次转发,到Tomcat时则认为在上次转发之前的IP都为真实地址 (由{X-Forwarded-For}i字段获取)
  2. 192.168.31.243 客户端原始地址 (由%{X-Real-IP}i获取,此地址是由上个Nginx转发来的)
  3. 192.168.31.242:80 客户端地址加端口 (由Tomcat日志格式 %h:%p 获取,所以认定为上个Nginx地址为客户端)
  4. 192.168.31.244:8080 本地IP地址加端口 (由Tomcat日志格式 %A 来获取本地IP,%{Port}i 由Nginx转发而来)
[12/Apr/2020:17:13:24 +0800] 192.168.31.72, 192.168.31.243 192.168.31.243 192.168.31.242:80 192.168.31.244:8080 GET 200 - - HTTP/1.1 devops.cn / 11215 0.213 http-nio-8080-exec-1
[12/Apr/2020:17:13:25 +0800] 192.168.31.72, 192.168.31.243 192.168.31.243 192.168.31.242:80 192.168.31.244:8080 GET 200 - - HTTP/1.1 devops.cn / 11215 0.007 http-nio-8080-exec-2
[12/Apr/2020:17:13:26 +0800] 192.168.31.72, 192.168.31.243 192.168.31.243 192.168.31.242:80 192.168.31.244:8080 GET 200 - - HTTP/1.1 devops.cn / 11215 0.004 http-nio-8080-exec-3

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FNHKEqND-1595991580562)(https://abcops.cn/wp-content/uploads/2020/07/15866831973974.jpg)]

.72, 192.168.31.243 192.168.31.243 192.168.31.242:80 192.168.31.244:8080 GET 200 - - HTTP/1.1 devops.cn / 11215 0.007 http-nio-8080-exec-2
[12/Apr/2020:17:13:26 +0800] 192.168.31.72, 192.168.31.243 192.168.31.243 192.168.31.242:80 192.168.31.244:8080 GET 200 - - HTTP/1.1 devops.cn / 11215 0.004 http-nio-8080-exec-3


[外链图片转存中...(img-FNHKEqND-1595991580562)]

PHP、Tomcat获取Nginx代理后的客户端真实IP相关推荐

  1. IIS 7、8启用nginx代理后日志中获取访客真实IP方法

    所需的步骤取决于您的IIS版本.此操作适用iis7之上版本. 1.下载插件F5XForwardedFor.dll:http://download.west263.net/iis7-rewrite%E6 ...

  2. nginx做负载均衡 tomcat获得客户端真实ip

    转 http://www.cnblogs.com/netsa/p/6985990.html 因项目需要做tomcat2台机器的负载均衡,配置好负载环境后,发现tomcat的日志一律是我前置nginx代 ...

  3. 程序在Nginx/k8s下如何获取客户端真实IP,带工具类

    目录 Nginx获取客户端信息 直接获取信息存在哪些问题? 如何解决这些问题? 我们整体上需要从两个方面来解决这些问题: 具体实践 配置nginx 通过Java方法获取客户端信息 Tomcat k8s ...

  4. 获取客户端真实 IP

    Tomcat + Nginx 反向代理获取客户端真实IP.域名.协议.端口 Nginx 反向代理后,Servlet 应用通过 request.getRemoteAddr() 取到的 IP 是 Ngin ...

  5. 获取客户端真实IP地址

    Java-Web获取客户端真实IP: 发生的场景:服务器端接收客户端请求的时候,一般需要进行签名验证,客户端IP限定等情况,在进行客户端IP限定的时候,需要首先获取该真实的IP. 一般分为两种情况: ...

  6. NGINX根据客户端真实ip限制/referer限制

    最近后端服务被攻击,所有接口被疯狂调用,记录一次nginx应对攻击的方案,包括黑白名单.referer限定等. 一.NGINX根据用户真实IP限源 1.nginx日志打印 在nginx.conf配置文 ...

  7. egg.js 获取客户端真实ip

    前言:在使用egg.js的时候,一般会开node服务,然后使用nginx代理我们egg.js的接口,因此产生了egg.js获取的ip地址并不是客户端真实ip,而是拿到的是nginx 的地址.故需要两点 ...

  8. 如何获取客户端真实 IP?从 Gin 的一个 Bug 说起

    1. 背景 请求 IP 作为用户的身份标识属性之一,是一种非常重要的基础数据.在很多场景下,我们会基于客户端请求 IP 去做网络安全攻击防范或访问风险控制.通常我们可以通过 HTTP 协议 Reque ...

  9. Java正确获取客户端真实IP方法整理

    转载自 干货:Java正确获取客户端真实IP方法整理 在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的.但是在通过了Apach ...

最新文章

  1. 黄聪:Microsoft Enterprise Library 5.0 系列教程(九) Policy Injection Application Block
  2. UVa 12012 - Detection of Extraterrestrial(hash)
  3. s2-045 java_S2-045漏洞初步分析
  4. SQLite数据库常用语句及MAC上的SQLite可视化工具MeasSQLlite使用
  5. MATLAB 批量改文件名称
  6. qq数据泄露_真良心,腾讯这个app竟然能查账号泄露
  7. CentOS安装Nagios网络监视工具
  8. xshell 软件的窗口一直是置顶 调整为不置顶
  9. led投屏软件_SmartDrop——LED/LCD大屏内容投屏管理软件
  10. [UE4]Cast to转换数据类型
  11. ubuntu 开启ssh
  12. python用户管理系统模块_Django的用户模块与权限系统的示例代码
  13. 使用Kotlin的Android Spinner
  14. Web前端学习 | Ajax
  15. jmail组件 java,分享Jmail发送邮件工具类
  16. Exception in thread main java.lang.NoSuchMethodException: xxx.main([Ljava.lang.String;)
  17. 免费试用微软云服务Azure(无需信用卡版)
  18. mac 启动台不显示已经安装的软件图标
  19. 【智能优化算法】蚁群算法ACO
  20. 敏捷考证?你应该知道的敏捷体系认证名单(最全整理)

热门文章

  1. Linux平台:Alexa语音服务快速入门指南
  2. ubuntu 死机原因分析
  3. 设计模式-单例模式(唯一的月亮实例附代码)
  4. ST耦合器,SC耦合器,FC耦合器,LC耦合器,MTRJ耦合器
  5. x265探索与研究(三):如何播放*.265格式的视频或解码视频流
  6. python 读取outlook邮箱邮件
  7. Pcba阻焊层选择红油蓝油绿油区别
  8. 大厂技术布道师!就这么使用责任链模式,绝对没错!
  9. 百度指数批量查询(免费放送)
  10. 铜电缆线规格型号大全