nginx 反向代理的典型应用场景及方案

一、场景

现有如下的的应用需求:

1.利用域名代理多个端口的应用

nginx 反向代理的典型应用场景及方案_第1张图片

2.利用二级目录代理多个端口的应用

nginx 反向代理的典型应用场景及方案_第2张图片

3.利用二级目录代理多个IP服务器的应用

nginx 反向代理的典型应用场景及方案_第3张图片

4.利用域名代理多个服务器的应用

nginx 反向代理的典型应用场景及方案_第4张图片

5.利用端口代理多个服务器应用

nginx 反向代理的典型应用场景及方案_第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,

  1. 其监听的端口都是80
  2. 其服务器名称分别是不同的域名,这是区分两个server的关键
  3. 然后是服务器日志,这里可以定义其他日志,如错误日志等
  4. 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进行区分

  1. 基本思路:

根据请求头中的referer字段,来区分是请求那个目录下文件的,将请求到根目录下的url进行重写(rewrite),然后进行请求。

2.存在问题:

根据 referer 字段进行区分,有时有些请求不一定带referer字段,带了也不一定含有指定的目录

2.利用cookie进行解决

  1. 基本思路:

在nginx响应的时候,写入cookie,利用cookie进行区分。

  1. 存在问题:

同一个请求的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/
    }

你可能感兴趣的:(技术分享,学习笔记,nginx,运维,服务器)