一、场景
现有如下的的应用需求:
1.利用域名代理多个端口的应用
2.利用二级目录代理多个端口的应用
3.利用二级目录代理多个IP服务器的应用
4.利用域名代理多个服务器的应用
5.利用端口代理多个服务器应用
二、场景实现
1.利用域名代理多个端口的应用
这个实现比较简单,基本上是一些基础的配置,在我应用中,我利用docker搭建了两个应用,一个nextcloud,一个是jupyter,其中一个运行在8088端口,一个运行在8888端口。现在的利用场景一的技术进行实现,nginx的配置文件如下:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name jupyter.test.com ;
access_log /var/log/nginx/host.access.log main;
location / {
proxy_pass http://127.0.0.1:8888/;
proxy_redirect / /;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
server {
listen 80;
server_name nextcloud.test.com;
access_log /var/log/nginx/nextcloud.log main;
location / {
proxy_pass http://127.0.0.1:8088/;
proxy_redirect / /;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
简单的解释如下:
首先建立两个server,
- 其监听的端口都是80
- 其服务器名称分别是不同的域名,这是区分两个server的关键
- 然后是服务器日志,这里可以定义其他日志,如错误日志等
location /
一个关键,就是到根目录时如何进行操作,简单的解释如下 :
proxy_pass http://127.0.0.1:8088/;
表示所有到根目录的请求由代理到8088端口
proxy_redirect / /;
表示所有重定向定向到根据目录下,这里有一个问题,就是此处是给同一个站的重定向设置的,如果是不同站点的重定向,该如何处理,以后再研究。
此处的域名都是一个本地的域名,无法进行网络的访问,但在本地还是运行的挺好的。其在进行应用区分的时候,是以请求的主机名字段来区分的,如果是请求到80端口的主机名为nextcloud.test.com,则由server_name为nextcloud.test.com的主机进行处理。另一个同理。
利用二级目录代理多个端口的应用
这个基本的思路是有,但在实现上还是有些问题的。简单的配置文件如下:
server {
listen 80;
server_name localhost;
#access_log /var/log/nginx/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
#if ( $cookie_jupyter = 'test' ){
# rewrite ^/(.*)$ /jupyter/$1 last;
#}
#if ( $http_referer ~* "jupyter" ){
# rewrite ^/(.*)$ /jupyter/$1 last;
#}
#if ( $cookie_nextcloud = 1 ){
# rewrite ^/(.*)$ /nextcloud/$1 last;
#}
#if ( $http_referer ~* ^.*/nextcloud/.*$ ){
# rewrite ^/(.*)$ /nextcoud/$1 last;
#}
rewrite ^/(.*)$ /jupyter/$1;
}
location /jupyter/ {
proxy_pass http://127.0.0.1:8888/;
proxy_redirect / /jupyter/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
if ($http_cookie !~* "jupyter=test") {
add_header Set-Cookie jupyter=test;
}
}
location /nextcloud/ {
proxy_pass http://127.0.0.1:8088/;
proxy_redirect / /nextcloud/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
if ($http_cookie !~* "nextcloud=1") {
add_header Set-Cookie nextcloud=1;
}
}
面临的一个困难:
在请求过程中,由于所有的请求都是向服务器IP的80端口发出的,这时,浏览器会认为这是同一个站点。同时,页面中的相对路径,请求到根目录下时,必然会发生404错误。
解决方法思路如下:
1.利用referer进行区分
- 基本思路:
根据请求头中的referer字段,来区分是请求那个目录下文件的,将请求到根目录下的url进行重写(rewrite),然后进行请求。
2.存在问题:
根据 referer 字段进行区分,有时有些请求不一定带referer字段,带了也不一定含有指定的目录
2.利用cookie进行解决
- 基本思路:
在nginx响应的时候,写入cookie,利用cookie进行区分。
- 存在问题:
同一个请求的IP,浏览器会认为是同一个站点,将所有的cookie全部保存,有时会解析错误。比如:我先访问 jupyter,然后访问nextcloud,jupyter的cookie还保存着,
而我在访问nextcloud的时候,如果是jupyter的cookie的规则在前面,会先将所有的url重写为/jupyter/
,此时,也会出现错误。目前尚不知该如何解决。
3.利用二级目录代理多个IP服务器的应用
未进行具体的实现,但在实现的服务器建立,利用upstream的ip_hash来进行流的引导,从而实现多个目录代理的实现。
upstream server1{
ip_hash;
server 192.168.1.1:80;
}
upstream server2{
ip_hash;
server 192.168.1.2:80;
}
upstream server3{
ip_hash;
server 192.168.1.3:80;
}
server {
listen 80;
server_name localhost;
location /app1/ {
proxy_pass http://server1/;
}
server {
listen 80;
server_name localhost;
location /app2/ {
proxy_pass http://server2/;
}
server {
listen 80;
server_name localhost;
location /app3/ {
proxy_pass http://server3/;
}
4.利用域名代理多个服务器的应用
在端口的基础上,将不同端口改为不同的服务应用即可
server {
listen 80;
server_name www.exp1.com;
location / {
proxy_pass http://192.168.1.1/
}
server {
listen 80;
server_name www.exp2.com;
location / {
proxy_pass http://192.168.1.2/
}
server {
listen 80;
server_name www.exp3.com;
location / {
proxy_pass http://192.168.1.3/
}
5.利用端口代理多个服务器应用
在nginx 端开启多个端口,直接将端口代理到相应的服务器即可
server {
listen 8081;
server_name localhost;
location / {
proxy_pass http://192.168.1.1/
}
server {
listen 8082;
server_name localhost;
location / {
proxy_pass http://192.168.1.2/
}
server {
listen 8083;
server_name localhost;
location / {
proxy_pass http://192.168.1.3/
}