背景
在我的之前的文章中,我已经讨论了如何配置Nginx作为反向代理以及如何配置Nginx SSL。在本文中,我将讨论如何使用Nginx反向代理和URL重写。Nginx重写规则用于更改客户端请求的整个或部分URL。 URL重写可用于1)控制Nginx中的请求,2)通知请求资源已更改其位置等。本文涉及的所有源代码都可在gitlab上找到。请克隆该仓库并继续阅读。
场景
我有三个REST服务gateway-api
,lekana-api
和siddhi-api
。gateway-api
服务于7656
端口,它具有api/gateway
REST端点。lekana-api
服务于7654
端口,它具有api/lekana
REST端点。siddhi-api
服务于7655
端口,它具有api/siddhi
REST端点。我需要使用单个公共IP地址/域来托管这些Web服务。下图描述了将请求路由到不同Web服务的路由。bassa.com
是域名。请求到达bassa.com
路由到gateway-api
。请求到达bassa.com/lekana
路由到lekana-api
。请求到达bassa.com/siddhi
路由到siddhi-api
。
重写规则
以下是与三个REST服务端点相关的发送到Nginx的不同请求。
1. to bassa-api - http://bassa.com:80/api/bassa
2. to lekana-api - http://bassa.com:80/lekana/api/lekana
3. to siddhi-api - http://bassa.com:80/siddhi/api/siddhi
为了提供lekana和siddhi API,我需要从Nginx中重写lekana-api
和siddhi-api
的URL,如下所示。
# remove lekana part in the middle of the url
http://bassa.com:80/lekana/api/lekana -> http://lekana-api:7654/api/lekana
# remove siddhi part in the middle of the url
http://bassa.com:80/siddhi/api/siddhi -> http://lekana-api:7655/api/siddhi
Nginx配置
以下是我用于提供不同API和URL重写的bassa.com
Nginx配置文件。rewrite ^/lekana(.*)$ $1 break;
条目从URL的中间删除lekana
部分。rewrite ^/siddhi(.*)$ $1 break;
条目从URL的中间删除siddhi
部分。
server {
listen 80;
server_name bassa.com www.bassa.com;
location / {
proxy_pass http://bassa-api:7656;
}
location /lekana {
rewrite ^/lekana(.*)$ $1 break;
proxy_pass http://lekana-api:7654;
}
location /siddhi {
rewrite ^/siddhi(.*)$ $1 break;
proxy_pass http://siddhi-api:7655;
}
}
Dockerize Nginx
以下是我用于将Nginx docker化的Dockerfile
。它构建了一个带有bassa.com
配置文件的Nginx docker镜像。
FROM ubuntu:18.04
MAINTAINER Eranga Bandara (erangaeb@gmail.com)
# install nginx
RUN apt-get update -y
RUN apt-get install -y software-properties-common
RUN add-apt-repository -y ppa:nginx/stable
RUN apt-get update -y
RUN apt-get install -y nginx
# deamon mode off
RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf
RUN chown -R www-data:www-data /var/lib/nginx
# expose ports
EXPOSE 80 443
# add nginx conf
ADD config/bassa.com /etc/nginx/sites-available/bassa.com
# create symlinks
RUN ln -s /etc/nginx/sites-available/bassa.com /etc/nginx/sites-enabled/bassa
WORKDIR /etc/nginx
CMD ["nginx"]
运行服务
系统中有四个服务nginx
,bassa-api
,lekana-api
和siddhi-api
。以下是我用于运行服务的docker-compose.yaml
文件。我使用链接容器在Nginx和API服务之间进行通信。
bassa-api:
image: erangaeb/bassa-api:0.1
container_name: bassa-api
ports:
- 7656:7656
lekana-api:
image: erangaeb/lekana-api:0.1
container_name: lekana-api
ports:
- 7654:7654
siddhi-api:
image: erangaeb/siddhi-api:0.1
container_name: siddhi-api
ports:
- 7655:7655
nginx:
image: erangaeb/nginx-url-rewrite:0.1
container_name: nginx
ports:
- 80:80
- 443:443
links:
- bassa-api
- lekana-api
- siddhi-api
以下是通过docker-compose
启动和运行这些服务的方法。如果你想一次启动所有服务,则可以使用docker-compose up -d
命令。
# run services
docker-compose up -d bassa-api
docker-compose up -d lekana-api
docker-compose up -d siddhi-api
docker-compose up -d nginx
测试服务
要在本地环境中测试服务,我需要在/etc/hosts
文件中定义bassa.com
域名和我的本地机器IP。然后,请求将重定向到我的本地机器(在生产环境中,需要使用DNS服务器设置域名)。以下是我添加到/etc/hosts
文件中的条目。
# redirect bassa.com to local machine
# 192.168.1.36 is my local machine ip
192.168.1.36 www.bassa.com bassa.com
现在,我可以通过CURL
命令测试REST API。以下是不同API的请求和响应。所有请求首先进入Nginx。然后,Nginx使用URL重写将请求路由到不同的REST服务。
# bassa api
# api/bassa goes directly to root domain bassa.com
curl -X GET http://bassa.com/api/bassa
# output
bassa
# lekana api
# api/lekana goes to bassa.com/lekana
curl -X GET http://bassa.com/lekana/api/lekana
# output
lekana
# siddhi api
# api/siddhi goes to bassa.com/siddhi
curl -X GET http://bassa.com/siddhi/api/siddhi
# output
siddhi
参考
- https://gist.github.com/soheilhy/8b94347ff8336d971ad0
- https://www.keycdn.com/support/nginx-rewrite-rules
- http://blog.pixelastic.com/2013/09/27/understanding-nginx-location-blocks-rewrite-rules/
- https://medium.com/rahasak/set-up-ssl-certificates-on-nginx-c51f7dc00272
- https://medium.com/rahasak/nginx-as-reverse-proxy-with-docker-c9ead938fffd
- https://www.liquidweb.com/kb/redirecting-urls-using-nginx/
译自:https://medium.com/rahasak/nginx-reverse-proxy-with-url-rewrite-a3361a35623c
评论(0)