微服务架构中利用Nginx进行rewrite重写保护真实服务地址
为什么要用rewrite?
对于微服务架构,暴露给外界的一般是Zuul网关,然后利用Zuul网关进行路由,有些服务不适于Zuul网关路由,比如文件上传,如果也经过Zuul网关的***,文件就会经过多次网路传输,造成不必要的网络负担。在高并发时,可能导致网络阻塞,Zuul网关不可用。这样我们的整个系统就瘫痪了。所以,可以使用Nginx进行的rewrite进行重写地址进行跳转。有时, 我们后台的服务地址发生改变,但是为了让外界调用时不需要改变路径,也可以使用rewrite进行重写。
rewrite指令的用法
我们修改nginx配置,将以/api/upload开头的请求拦截下来,转交到真实的服务地址:
location /api/upload {
proxy_pass http://127.0.0.1:8001;
proxy_connect_timeout 600;
proxy_read_timeout 600;
}
这样的话,访问路径为:
http://127.0.0.1:8001/api/upload/image 前面多了一个 /api
我想把api给移除,
Nginx提供了rewrite指令,用于对地址进行重写,语法规则:
rewrite "用来匹配路径的正则" 重写后的路径 [指令];
案例:
server {
listen 80;
server_name api.baidu.com;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 上传路径的映射
location /api/upload {
proxy_pass http://127.0.0.1:8001;
proxy_connect_timeout 600;
proxy_read_timeout 600;
rewrite "^/api/(.*)$" /$1 break;
}
location / {
proxy_pass http://127.0.0.1:10010;
proxy_connect_timeout 600;
proxy_read_timeout 600;
}
}
-
首先,我们映射路径是/api/upload,而下面一个映射路径是 / ,根据最长路径匹配原则,/api/upload优先级更高。也就是说,凡是以/api/upload开头的路径,都会被第一个配置处理
-
proxy_pass
:反向***,这次我们***到8082端口,也就是upload-service服务 -
rewrite "^/api/(.*)$" /$1 break
,路径重写:-
"^/api/(.*)$"
:匹配路径的正则表达式,用了分组语法,把/api/
以后的所有部分当做1组 -
/$1
:重写的目标路径,这里用$1引用前面正则表达式匹配到的分组(组编号从1开始),即/api/
后面的所有。这样新的路径就是除去/api/
以外的所有,就达到了去除/api
前缀的目的 -
break
:指令,常用的有2个,分别是:last、break- last:重写路径结束后,将得到的路径重新进行一次路径匹配
- break:重写路径结束后,不再重新匹配路径。
我们这里不能选择last,否则以新的路径/upload/image来匹配,就不会被正确的匹配到8001端口了
-
修改完成,输入nginx -s reload
命令重新加载配置。
注意,如果是ajax请求,此时可能出现跨域问题,根据常用的解决跨域问题自行解决即可。