问题
我有2个问题一直没有想明白.
假设我做了一个项目, 开放了一些接口给用户使用. 程序源源不断的接收到请求. 然后开始处理数据.
某天. 我发现一个程序bug. 我需要修改程序. 然后需要重启.
此时会有2个问题:
- 问题1. 重启过程中, 用户的请求怎么办, 直接丢失了吗
- 问题2. 如果已经接收的请求. 程序还在处理中, 直接停服似乎不太妥当.
我能想到一个办法, 直接部署新旧2个程序. 然后使用 gateway , 前置拦截流量. 再按权重分配给2个程序.
但是有一天gateway程序也会重启. 很明显这不是一个好办法.
今天网上的一句话让我豁然开朗.
无论的你是单体应用还是微服务, 你都应该部署一个 nginx 拦在最前面.
- 我直接使用 nginx 拦在最前面. 底下无论是直连程序还是再进入业务网关. 随便你程序如何修改, 如何升级. nginx无需重启. 只需加载配置. 用户请求我可以随心所欲的控制分配.
流量分流测试
nginx最大的优点就是配置方便. 支持热更新.
nginx监听端口为8081
假设我部署2个服务分别占用端口9999和9998
按比例分配流量
nginx配置如下.
1 2 3 4 5 6 7 8 9 10 11 12
| upstream backend { server 127.0.0.1:9999 weight=90; # 程序A的地址和端口 权重 server 127.0.0.1:9998 weight=10; # 服务B的地址和端口 权重 }
server { listen 8081; server_name 127.0.0.1; location /yxhis { proxy_pass http: } }
|
执行命令重新载入配置 nginx -s reload
测试发现, 5次请求中果然有4次去了程序A, 1次去了程序B
流量全部打到程序B
修改配置
1 2 3 4 5 6 7 8 9 10 11 12 13
| upstream backend { # 直接注释程序A的端口 #server 127.0.0.1:9999 weight=90; # 程序A的地址和端口 权重 server 127.0.0.1:9998 weight=10; # 服务B的地址和端口 权重 }
server { listen 8081; server_name 127.0.0.1; location /yxhis { proxy_pass http: } }
|
执行命令重新载入配置 nginx -s reload
然后发现, 5次请求中果然全部去了程序B
简直太方便了.
nginx.conf完整的配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| worker_processes 1;
events { worker_connections 1024; }
http { include mime.types; default_type application/octet-stream; sendfile on; #tcp_nopush on;
keepalive_timeout 65;
upstream backend { server 127.0.0.1:9999 weight=90; # 旧服务的地址和端口 server 127.0.0.1:9998 weight=10; # 新服务的地址和端口 }
server { listen 8081; server_name 127.0.0.1; location /yxhis { proxy_pass http: } # 测试前端 location /# { root html; index index.html index.htm; proxy_pass http: }
} }
|
记录转发日志
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| worker_processes 1;
events { worker_connections 1024; }
http { # 记录请求和响应的出入参 log_format upstremmain escape=json '【请求】$remote_addr 【时间】[$time_local] 【转发】$upstream_addr -$request' '【入参】$request_body 【时长】$upstream_response_time';
access_log logs/access.log upstremmain;
include mime.types; default_type application/octet-stream; sendfile on; #tcp_nopush on; keepalive_timeout 65; upstream backend { server 127.0.0.1:9999 weight=50; # 旧服务的地址和端口 server 127.0.0.1:9998 weight=50; # 新服务的地址和端口 }
server { listen 8081; server_name 127.0.0.1; location /yxhis { proxy_pass http: proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-NginX-Proxy true; # 记录请求的出入参 proxy_set_body $request_body; } # 测试前端 location /# { root html; index index.html index.htm; proxy_pass http: } } }
|