共计 6445 个字符,预计需要花费 17 分钟才能阅读完成。
120 秒搞懂 nginx 反向代理
- 反向代理, 什么是反向代理, 那么我们肯定想知道, 什么是代理(正向代理)
-
自由的百科给我说了一堆 balabala, 不想看了. 另送一句 mmp,
- 正向代理,意思是一个位于客户端和原始服务器 (origin server) 之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端才能使用正向代理。
接下来说说我的个人理解, 所谓代理, 其实就是帮助你访问你原本访问不到的地址, 简单点说, 你想访问世界上最大的 p 站, 但是你爱国, 你访问不了, 怎么办, 没关系, 你开了个代理. 让代理去给你请求你想要的东西. 就像小时候, 金秋时节, 别人家的柿子熟了, 想吃一个, 够不到, 怎么办? 拿根棍子啊, 一棍子下去, 咚咚几声, 地下就会爬伏几坨黄黄的东西 ….. 这根棍子, 就是你开的代理, 它帮你打柿子
- 用途:
1. 访问原来无法访问的资源, 如维基百科
2. 做缓存, 减轻原站点的压力. 加快访问速度
3. 对客户端访问授权, 就是先过滤一遍, 比如用户权限, 用户是不是 vip,
4. 使用代理, 对外隐藏用户的信息, 就是你访问了 p 站, 但是 p 站不知道你访问过, 因为他认为是你的代理访问的他, 但是你觉得真的找不到你吗? 就像小时候打架, 你跟老师说你没打人, 是你手里的棍子打的人, 老师会放过你吗? 所以, 还是本本分分的做人, 不要总是干一些蝇营狗苟的勾当.
- 那么什么是反向代理呢
先给一个解释: 反向代理服务器位于用户与目标服务器之间,但是对于用户而言,反向代理服务器就相当于目标服务器,即用户直接访问反向代理服务器就可以获得目标服务器的资源。同时,用户不需要知道目标服务器的地址,也无须在用户端作任何设定。反向代理服务器通常可用来作为 Web 加速,即使用反向代理作为 Web 服务器的前置机来降低网络和服务器的负载,提高访问效率。————— 姜大庆主编;邓荣副主编.Linux 系统与网络管理:中国铁道出版社,2012.05:第 282 页
-
小虫解释
- 想起来钱钟书说过一句话, 呃. 这个时候会不会觉得小虫也会旁征博引呢.
老钱说, 假如你吃个鸡蛋觉得味道不错, 又何必认识那个下蛋的母鸡呢?
这就是反向代理的作用. 你去商店买一个鸡蛋, 但是你不会去鸡窝看看哪个母鸡下的这个蛋, 其中, 商店就是一个反向代理.
- 反向代理就是你发送一个 http 请求, 请求到达 nginx 服务器后,nginx 通过服务器配置的反向代理, 取到结果返给你, 但是具体是哪台机器取到的数据, 你不知道,
- 你不知道, 他们为何离去..... 此处奉上歌词 后会无期
- 反向代理的作用
1. 保证内网安全, 阻止 web 攻击, 比如, 你对外就暴露一个域名 比如 https://m.acurd.com, 但是你的 w … api.xxx.com wiki.xxx.com
2. 实现负载均衡, 比如 访问 host/api 通过反向代理 就会转发到 api.xxx.com 去, 访问 host/wiki 就会转发到 wiki.xxx.com
3. 就是下面我们要讲的. 利用反代实现页面缓存, 减少对服务器端 (指被代理的服务器) 的请求
nginx 反向代理和缓存实现
- 反向代理简单实现
我用 docker 启动了 4 个 nginx 服务, 具体参考使用 docker 搭建 nginx 集群, 实现负载均衡
172.17.0.2—172.17.0.5
我现在想这样, 我访问 172.17.0.3/hello 的时候, 走 172.17.0.4
- 先大概看一下两台机器
[root@localhost ~]# curl 172.17.0.3
8081
[root@localhost ~]# curl 172.17.0.3/hello.html
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.19.0</center>
</body>
</html>
[root@localhost ~]# curl 172.17.0.4
8082
[root@localhost ~]#
- 配置 8081 机器, 这里提一句, 我记得之前代理 css 的时候出现过问题, 就是有的代理走不到下面就被代理了. 所以可以把需要代理的放到前面, 防止被其他规则代理
[root@localhost ~]# cat conf1/conf.d/default.conf
server {
listen 80;
server_name localhost;
location /hello.html {
proxy_pass http://172.17.0.4;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
[root@localhost ~]#
- 重启 8081 服务器
[root@localhost ~]# docker exec -it nginx8081 bash
root@ffe603d426f2:/# service nginx restart
[....] Restarting nginx: nginx[root@localhost ~]#
- 看效果
[root@localhost ~]# curl 172.17.0.3
8081
[root@localhost ~]# curl 172.17.0.4
8082
[root@localhost ~]# curl 172.17.0.3/hello.html
hello
[root@localhost ~]# curl 172.17.0.4/hello.html
hello
[root@localhost ~]#
- 一个简单的反代做完了. 写到这里我有一个想法, 如果代理的是 /a/b/c/d/hello, 那么实际请求的应该是什么呢? 能动手不逼逼
- 修改一下 8081 的 nginx 配置文件
[root@localhost ~]# cat conf1/conf.d/default.conf
server {
listen 80;
server_name localhost;
location /hello.html {
proxy_pass http://172.17.0.4;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /a/b/c/d/hello {
proxy_pass http://172.17.0.4;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
- 重启服务器, 查看 docker 日志输出
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1a4fc8f64447 nginx "/docker-entrypoint.…" 4 hours ago Up 4 hours 0.0.0.0:8083->80/tcp nginx8083
56dcd4def721 nginx "/docker-entrypoint.…" 4 hours ago Up 4 hours 0.0.0.0:8082->80/tcp nginx8082
ffe603d426f2 nginx "/docker-entrypoint.…" 4 hours ago Up 42 minutes 0.0.0.0:8081->80/tcp nginx8081
72aacbe3c63a nginx "/docker-entrypoint.…" 4 hours ago Up 3 hours 0.0.0.0:8080->80/tcp nginx8080
2a7229a5ef30 hello-world "/hello" 7 hours ago Exited (0) 7 hours ago dreamy_hamilton
54368a05aabf hello-world "/hello" 7 hours ago Exited (0) 7 hours ago mystifying_hawking
# 查看被代理的服务器日志
[root@localhost ~]# docker logs -f 56dcd4def721
172.17.0.1 - - [02/Jul/2020:18:20:34 +0000] "GET /hello.html HTTP/1.1" 200 6 "-" "curl/7.29.0" "-"
2020/07/02 18:20:49 [error] 21#21: *32 open() "/usr/share/nginx/html/a/b/c/d/hello" failed (2: No such file or directory), client: 172.17.0.3, server: localhost, request: "GET /a/b/c/d/hello HTTP/1.0", host: "172.17.0.4"
- 说明反代的时候并不会截取你的任何请求, 而是完整的把 host 后面的东西一股脑全给转了过来
- 但是像下面这种代理, 不会全部把参数转过去的, 而是只传代理地址后面的
location /static/admin {
# return 503;
alias /opt/app/public/static/admin;
#proxy_pass http://127.0.0.1:8086/static/;
}
相信你一定可以看明白的
- 好了, 言归正传, 开始实现页面缓存, 配置 8081 的 nginx 文件
[root@localhost ~]# cat conf1/conf.d/default.conf
#缓存路径 levels=1:2 代表缓存的目录结构为 2 级目录
proxy_cache_path /usr/share/nginx/html/cache/cache levels=1:2 keys_zone=cache:20m max_size=1g;
proxy_cache_key "$host$request_uri";
server {
listen 80;
server_name localhost;
add_header X-Via $server_addr;
add_header X-Cache $upstream_cache_status;
location /hello.html {
proxy_pass http://172.17.0.4;
#反向代理缓存设置命令
proxy_cache cache;
#设置指定状态码的缓存时间 状态 200 缓存 10 分钟
proxy_cache_valid any 10m;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /a/b/c/d/hello {
proxy_pass http://172.17.0.4;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
- 重启服务器, 开启日志监听
先看一下有没有缓存文件, 是空的
[root@localhost cache]# ls
[root@localhost cache]# pwd
/root/www1/cache
[root@localhost cache]#
接下来访问第一次, 发现目录下已有缓存文件, 两级目录, 文件内容就是 hello.html 的内容,
[root@localhost cache]# curl 172.17.0.3/hello.html
hello
[root@localhost cache]# cd cache/
[root@localhost cache]# ls
2
[root@localhost cache]# cat 2/17/0568faac7d714cd625a00aebf6968172
\9þ^¥þ^7þ^~²????Q
"5efe1ea5-6"
KEY: 172.17.0.3/hello.html
HTTP/1.1 200 OK
Server: nginx/1.19.0
Date: Thu, 02 Jul 2020 19:35:32 GMT
Content-Type: text/html
Content-Length: 6
Last-Modified: Thu, 02 Jul 2020 17:51:33 GMT
Connection: close
ETag: "5efe1ea5-6"
Accept-Ranges: bytes
hello
- 访问第二次, 查看请求日志, 在请求日志中并没有第二次的请求日志, 说明 8801 直接将缓存返给了客户端, 而没有去转发 8802 服务器
- 通过 curl 查看请求头 X-Cache: HIT 命中缓存
[root@localhost cache]# curl -i 172.17.0.3/hello.html
HTTP/1.1 200 OK
Server: nginx/1.19.0
Date: Thu, 02 Jul 2020 19:41:08 GMT
Content-Type: text/html
Content-Length: 6
Connection: keep-alive
Last-Modified: Thu, 02 Jul 2020 17:51:33 GMT
ETag: "5efe1ea5-6"
X-Via: 172.17.0.3
X-Cache: HIT
Accept-Ranges: bytes
hello
- 通过 url 直接访问原地址
[root@localhost ~]# curl -i 172.17.0.3/hello.html
HTTP/1.1 200 OK
Server: nginx/1.19.0
Date: Thu, 02 Jul 2020 19:44:09 GMT
Content-Type: text/html
Content-Length: 6
Connection: keep-alive
Last-Modified: Thu, 02 Jul 2020 17:51:33 GMT
ETag: "5efe1ea5-6"
X-Via: 172.17.0.3
X-Cache: HIT
Accept-Ranges: bytes
hello
[root@localhost ~]# curl -i 172.17.0.4/hello.html
HTTP/1.1 200 OK
Server: nginx/1.19.0
Date: Thu, 02 Jul 2020 19:44:17 GMT
Content-Type: text/html
Content-Length: 10
Last-Modified: Thu, 02 Jul 2020 19:44:03 GMT
Connection: keep-alive
ETag: "5efe3903-a"
Accept-Ranges: bytes
hello8802
[root@localhost ~]#
- 说明缓存成功
结束语
- 到此, 相信小伙伴已经明白了 nginx 的反代和缓存, 顺便看一下手机, 有没有超过 5 分钟
更多文章请微信搜索公众号 < 老 A 技术联盟 > 或访问博主网站易查网