nginx使用

nginx使用


Nginx(发音为 “engine-x”)是一个高性能、轻量级的HTTP和反向代理服务器,同时也支持IMAP/POP3/SMTP协议。它被广泛应用于各种Web服务场景中,以下是Nginx的主要功能:

一、重写和路由

提供灵活的URL重写和路由功能,允许根据正则表达式或者其他条件进行URL转换和内部跳转。

   server {
       location /old-path {
           rewrite ^/old-path/(.*)$ /new-path/$1 permanent;  # URL永久重写
       }
   }

   server {
       location / {
           if ($request_uri ~ ^/api/v1(.*)$) {
               proxy_pass http://api-backend/$1;  # 路由特定路径到后端API服务器
           }
       }
   }

1、location必须以/开头吗?

在Nginx的location指令中,路径确实必须以斜杠 / 开头,除非使用的是正则表达式匹配(如 location ~ pattern { … })。对于前缀匹配和等值匹配(即 location /path { … } 和 location = /path { … }),路径都必须以斜杠开头。

2、location匹配规则

#错误,必须以/开头或使用正则表达式匹配
location api {
   ……
}

#nginx会自上而下扫描全部location,找到最佳匹配才执行
#例如:http://localhost/api会匹配到location /api/ {}而不是location /api {}
location /api {
	#http://localhost/flh/api/ 匹配不到“/”代表从uri的根开始匹配,http://localhost/flh/api/的uri是“/flh/api/”
	#http://localhost/apiflh   能匹配到
	#http://localhost/api/flh  能匹配到
   ……
}
location /api/ {
	#http://localhost/flh/api/ 匹配不到“/”代表从uri的根开始匹配,http://localhost/flh/api/的uri是“/flh/api/”
	#http://localhost/apiflh   匹配不到
	#http://localhost/api/flh  能匹配到
	#建议使用本格式
   ……
}

3、rewrite和proxy_pass的区别

rewrite 和 proxy_pass 是 Nginx 中用于处理请求的两个不同指令,它们有着不同的功能和作用:

rewrite:

  • 功能:rewrite 指令用于在 Nginx 内部重写 URI(统一资源标识符),它可以在服务器或 location 块中使用。

  • 用法:通过正则表达式匹配当前请求的 URI,并将其替换为新的 URI。这可以用来改变请求路径,比如重定向、清理 URL 等。

  • 示例:

       server {
           location /old-path {
               rewrite ^/old-path/(.*)$ /new-path/$1 permanent;  # URL永久重写
           }
       }
    

    上述规则会将所有以 /old-path 开始的请求重写为 /new-path 加上原来路径剩余部分。

proxy_pass:

  • 功能:proxy_pass 指令用于将客户端的请求转发到一个上游服务器,即实现反向代理的功能。当Nginx接收到请求时,它不会自己处理请求,而是将请求转发给后端服务如Tomcat、Node.js应用或其他HTTP服务器等。

  • 用法:配置 proxy_pass 指令时,通常会指定一个代理服务器的地址和端口,也可以包含一个URI路径,该路径会被附加到代理服务器地址之后。

  • 示例:

         location /api {
             proxy_pass http://backend-server:8080/api;
             # 其他相关的代理设置,如header传递等
         }
    

    这样,所有对 /api 的请求都会被转发到 http://backend-server:8080/api 处理。

总结起来,rewrite 更像是在本地处理请求并修改其路径,而 proxy_pass 则是将请求整体转交给其他服务器去处理。在动静分离的场景下,rewrite 可能用于调整静态资源路径,而 proxy_pass 则负责将动态请求转发至后端应用服务器。两者常配合使用,共同实现复杂的路由策略。

4、rewrite中关键字last、break、permanent、redirect的区别

  • last(不加关键字,行为类似last)
    1. 当rewrite指令使用了last修饰符时,当前的重写规则执行完毕后,Nginx会立即停止在当前location块内的所有后续规则的处理。
    2. 然后,Nginx会根据已重写后的URL重新匹配新的location块,并开始执行新匹配到的location块中的配置指令。
    3. 如果没有找到新的location块匹配,则通常会执行该server或默认server的配置。
  • break
    1. 当rewrite指令使用了break修饰符时,当前的重写规则执行完毕后,Nginx将终止当前rewrite循环,即不再继续尝试匹配当前location块内剩余的rewrite规则。
    2. 但与last不同的是,break并不会导致重新匹配新的location块,而是继续执行当前location块内的非rewrite指令(如proxy_pass、access_log等)。
  • permanent
    1. 执行重写:当请求的URI与带有permanent修饰符的rewrite指令规则相匹配时,Nginx会按照规则重写URI,并记录下新的URI。
    2. 发送重定向响应:不同于last和break,permanent修饰符会立即向客户端发送一个HTTP状态码为301的响应头,指示客户端未来应使用新的URI进行访问。此响应头包含已重写后的URI作为Location字段的值。
    3. 停止处理:当permanent生效时,Nginx不会继续执行当前location块内的其他任何rewrite规则,也不会执行像proxy_pass、try_files等后续指令。它会立即终止对该请求的进一步处理,并返回重定向响应给客户端。
  • redirect
    1. 发送HTTP 302临时重定向响应,同时终止对当前请求的进一步处理。
  • redirect和permanent的区别
    1. 都会导致浏览器地址栏变更为新URL。
    2. 302临时重定向在一段时间内,搜索引擎可能会同时索引旧URL和新URL,但最终会将权重转移到新URL上。301永久重定向搜索引擎会索引新URL。

5、proxy_pass匹配规则

#假设有4个nginx配置如下,现有一个请求http://localhost:80/api/flh,请问转发后的地址分别是什么?

server {
    listen 80;
    location /api/ {
		proxy_pass http://192.168.1.100:8080;
		#http://192.168.1.100:8080/api/flh
    }
}
server {
    listen 80;
    location /api/ {
		proxy_pass http://192.168.1.100:8080/;
		#http://192.168.1.100:8080/flh
    }
}
server {
    listen 80;
    location /api/ {
		proxy_pass http://192.168.1.100:8080/test;
		#原请求http://localhost:80/api/flh
		#转发后http://192.168.1.100:8080/testflh
    }
}
server {
    listen 80;
    location /api/ {
		proxy_pass http://192.168.1.100:8080/test/;
		#http://192.168.1.100:8080/test/flh
    }
}

6、nginx配置路径使用/还是\

  • 在URL路径和Web服务器配置(如Nginx)中,斜杠 / 是作为路径分隔符使用的,并且始终是统一的,无论使用的是哪种操作系统。
  • 在Windows系统下,本地文件路径通常使用反斜杠 \ 作为路径分隔符,例如:C:\Users\username\Desktop\file.txt。但在编程语言中直接写入字符串时,由于\在大多数编程语言中具有转义字符的含义,所以通常会采用双反斜杠 \ 或者单个正斜杠 / 来表示路径,现代Windows系统通常也接受正斜杠 / 作为路径分隔符。
  • 在类Unix系统下,包括Linux和macOS,本地文件路径使用正斜杠 / 作为路径分隔符,例如:/home/username/Desktop/file.txt。
  • 由于Nginx会自动处理路径中的反斜杠,所以即使在Windows系统中也可以直接使用正斜杠/。例如:root c:/web/content;

二、反向代理

Nginx最常用于设置反向代理,它可以接受客户端请求,并根据配置规则将这些请求透明地转发给后端的一组服务器。通过这种方式,可以实现负载均衡,隐藏真实的服务器IP地址,以及提供统一入口点等功能。

实现

   server {
    listen 80;

    # 这个location块匹配所有的根路径(/)请求
    location / {
        # proxy_pass指令用于指定将请求转发到的目标地址,可以是IP:port形式或者域名形式
        # 例如:proxy_pass http://192.168.1.100:8080/;
        proxy_pass http://ip:port/;

        # 设置代理时传递给后端服务器的Host头部信息,保持与原始请求一致
        proxy_set_header Host $host;

        # 设置X-Real-IP头部信息,将客户端的真实IP地址传递给后端服务器
        proxy_set_header X-Real-IP $remote_addr;
        
        # 可能还需要添加其他有用的头部信息,例如:
        # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

1、配置代理时必须配置proxy_set_header吗?

proxy_set_header在Nginx反向代理配置中并非必须的,但是通常情况下建议设置这些头部信息以确保正确处理请求和响应。

  • proxy_set_header Host $host;

    这个设置通常是必要的,因为许多Web应用程序依赖于Host头来确定请求的目的地(例如,在负载均衡或虚拟主机场景中)。将$host传递给后端服务器有助于保持原始请求中的主机名信息不变,这对于某些服务器来说是至关重要的。

  • proxy_set_header X-Real-IP $remote_addr;

    这个设置用于将客户端的真实IP地址传递给后端服务器。因为在反向代理的情况下,后端服务器接收到的请求源IP将是代理服务器的IP而非客户端的真实IP。如果您的后端应用需要根据客户端真实IP进行访问控制、日志记录等操作,那么这个设置就是必需的。

  • 其他如X-Forwarded-For等头部信息也常被用于记录客户端IP链路以及识别经过了哪些代理服务器

总之,是否配置proxy_set_header取决于您的具体需求和后端服务如何处理这些头部信息。但在实际部署中,为了保证前后端交互的正常进行,通常建议按需配置这些头部字段。

2、是否可以配置多个监听端口?

Nginx可以配置多个监听端口以处理来自不同端口的请求。每个监听端口可以对应不同的服务或配置规则。以下是一个配置多个监听端口的示例:

# 在http块内配置多个server块来监听不同的端口

http {
    # 第一个server块,监听80端口
    server {
        listen 80;

        # 配置默认站点根目录
        root /var/www/html/default;
        
        # 其他location和设置...
    }

    # 第二个server块,监听8080端口
    server {
        listen 8080;

        # 配置特定站点的根目录
        root /var/www/html/secondary;

        # 可能会有不同的location规则和其他配置...
    }

    # 更多server块,监听其他端口
    server {
        listen 443 ssl;  # 同时监听443端口并启用SSL加密
        server_name example.com;

        # SSL证书配置
        ssl_certificate /path/to/cert.pem;
        ssl_certificate_key /path/to/key.pem;

        # 此服务器的特定配置
        ...
    }
}

3、正向代理和反向代理的区别

正向代理(Forward Proxy)

  • 角色:站在客户端一侧,作为客户端访问外部网络的“中介”。
  • 工作方式:客户端配置代理服务器地址后,通过它去访问目标网站。目标网站看到的请求来源是代理服务器而非直接来自客户端。
  • 应用场景:企业内部网络过滤、隐藏客户端真实IP、突破地域限制等。

反向代理(Reverse Proxy)

  • 角色:站在服务端一侧,对外界而言,它是服务的“门面”或“入口”。
  • 工作方式:客户端无需知道后端服务器的具体信息,直接向反向代理服务器发送请求。反向代理根据规则将请求转发给内部网络中的实际服务器处理,并返回结果给客户端。
  • 应用场景:负载均衡(分发请求到多台服务器)、安全防护(隐藏内部服务器信息和提供统一的安全策略)、缓存加速(减少对后端服务器的压力)、内容过滤与重写等。

三、负载均衡

作为反向代理的一部分,Nginx可以根据多种策略(例如轮询、权重分配、最少连接数等)在多个后端服务器之间分发流量,从而实现高可用性和性能优化。

负载均衡策略

  1. 轮询(Round Robin):
    默认策略,将请求均匀地分配给后端服务器列表中的每一台服务器。

    http {
        upstream backend {
            server server1_ip:port;
            server server2_ip:port;
            # 可以添加更多服务器...
        }
    
        server {
            listen 80;
    
            location / {
                proxy_pass http://backend;
                # 其他必要的代理设置...
            }
        }
    }
    
  2. 加权轮询(Weighted Round Robin):
    每个服务器可以被分配一个权重值,权重高的服务器将得到更多的请求。

    
    http {
        upstream backend {
            server server1_ip:port weight=3;  # 该服务器权重为3
            server server2_ip:port weight=1;  # 该服务器权重为1
        }
    
        server {
            listen 80;
    
            location / {
                proxy_pass http://backend;
                # 其他必要的代理设置...
            }
        }
    }
    
  3. 最少连接数(Least Connections):
    将新的请求发送到当前活跃连接数最少的后端服务器上。

    
    http {
        upstream backend {
            least_conn;
            server server1_ip:port;
            server server2_ip:port;
        }
    
        server {
            listen 80;
    
            location / {
                proxy_pass http://backend;
                # 其他必要的代理设置...
            }
        }
    }
    
  4. IP哈希(ip_hash):
    根据客户端IP地址的散列结果来决定请求转发到哪个后端服务器,实现会话持久化。

    
    http {
        upstream backend {
            ip_hash;
            server server1_ip:port;
            server server2_ip:port;
        }
    
        server {
            listen 80;
    
            location / {
                proxy_pass http://backend;
                # 其他必要的代理设置...
            }
        }
    }
    
  5. 基于HTTP头或cookie的会话粘滞(sticky session):
    通过设置特定的HTTP头部或者使用cookie来维持用户会话与特定后端服务器之间的关联。

    首先,你需要安装 nginx-sticky-module-ng 模块。然后在配置文件中加入如下内容:

    
    http {
        upstream backend {
            server server1_ip:port;
            server server2_ip:port;
            # 可添加更多服务器...
        }
    
        server {
            listen 80;
    
            location / {
                sticky cookie srv_id expires=1h domain=.yourdomain.com;
                proxy_pass http://backend;
                # 其他必要的代理设置...
            }
        }
    }
    

    这个配置会在客户端设置一个名为 srv_id 的cookie,根据该cookie的值将请求转发到同一台后端服务器上。

  6. Fair(第三方模块提供):
    根据后端服务器的响应时间动态调整权重,将请求分发给响应时间最短的服务器,需要安装nginx-upstream-fair模块。由于实际应用中可能存在兼容性和稳定性问题,请谨慎考虑是否采用此方法,并查阅相关文档进行配置。

nginx可以应付什么量级的负载均衡?

Nginx作为一款高性能的HTTP和反向代理服务器,其负载均衡能力可以应付非常高量级的流量。具体能应对多少量级取决于多个因素:

  1. 硬件资源:服务器的CPU、内存、网络带宽等硬件配置直接影响Nginx处理请求的能力。
  2. 配置优化:合理配置Nginx的工作模式、连接数限制、缓存策略、SSL会话复用等参数,可以显著提升性能。
  3. 并发连接数:Nginx通过高效的事件驱动模型(如epoll或kqueue)能够支持高并发连接,理论上可以达到数十万甚至上百万级别的并发连接数。
  4. 后端集群规模:通过增加更多的后端服务器并配合合理的负载均衡策略,Nginx可以将流量分散到多台机器上,实现水平扩展以应对大规模访问。
  5. 负载均衡策略:不同的负载均衡策略对系统性能的影响也不同,比如轮询、最少连接数、权重分配等,正确选择和配置合适的策略有助于提高整体系统的承载能力。
  6. 健康检查与故障恢复:有效的健康检查机制能够确保只有健康的后端服务器参与到服务中,降低因单点故障导致的整体性能下降。

在实际生产环境中,Nginx被广泛应用于大型网站、云计算平台和其他需要高可用性及大流量处理的场景,支撑TB级别甚至PB级别的数据流量。然而,具体的承受能力需要根据实际情况进行测试和调整,并随着技术更新和硬件升级而不断提升。

四、动静分离

Nginx能够很好地处理静态内容(如HTML、CSS、JavaScript文件、图片等),并将其与动态内容请求分开。静态资源直接由Nginx服务器响应,动态请求则转发到应用服务器(如PHP-FPM或Java应用服务器)。

http {
    server {
        listen 80;
        
        # 静态文件处理1
        location /static/ {
            root /var/www/static; # 设置静态文件目录
            expires 30d; # 设置浏览器缓存过期时间,可选
            try_files $uri $uri/ =404; # 当请求的资源不存在时返回404错误
        }
         # 静态资源处理2 - 将请求映射到服务器的特定目录下
        location /static/ {  # 对以'/static/'开头的URL请求进行匹配
            alias /var/www/static/;  # 'alias'指令指定实际存储静态文件的服务器绝对路径
            expires 1d;  # 设置浏览器缓存过期时间为1天,有助于减少带宽和服务器负载
        }

        # 动态请求转发到后端服务器
        location /api/ {
            proxy_pass http://localhost:8080/api; # 转发至本地8080端口的后端服务
            proxy_set_header Host $host; # 传递主机头信息
            proxy_set_header X-Real-IP $remote_addr; # 传递客户端真实IP地址
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 传递经过代理的客户端IP地址
        }

        # 如果希望将所有非静态资源的请求都视为动态请求
        #(location满足最佳匹配原则,当用户请求 /static/image.jpg时,会匹配到location /static/ {})
        location / {
            proxy_pass http://localhost:8080; # 将其他所有非静态资源请求转发至后端服务
            # 同样可以设置相关的proxy_set_header以传递客户端信息
        }
    }
}

alias和root的区别

在Nginx实现动静分离时,root和alias都可以用来指定静态文件的路径。它们的主要区别在于处理请求URI的方式不同。
root指令:定义一个基本目录,然后将请求URI附加到这个基本目录后面来定位资源。例如:

location /static/ {
       root /var/www;
   }

当用户请求 /static/image.jpg 时,Nginx会查找 /var/www/static/image.jpg。

alias指令:用于映射URL到特定的目录,它会替换匹配的location部分而不是附加到基础路径上。例如:

location /static/ {
       alias /var/www/static-files/;
   }

当用户请求 /static/image.jpg 时,Nginx会查找 /var/www/static-files/image.jpg,而不是 /var/www/static-files/static/image.jpg。

在实际应用中,选择root还是alias取决于你的需求和目录结构。对于动静分离,通常情况下两者都可用于静态资源服务,但当需要精确控制请求URI映射到文件系统路径而不进行额外拼接时,使用alias更为合适。不过,在多数简单场景下,root指令已经足够满足需求,并且其用法更直观易理解

五、缓存加速

Nginx提供了强大的缓存功能,能够缓存来自后端服务器的静态内容,减少对后端服务器的压力,同时加快对频繁访问内容的响应速度。

在Nginx中,可以通过配置FastCGI缓存或HTTP缓存来实现对动态或静态内容的缓存加速。这里分别给出两个示例:

1、使用HTTP缓存(适用于静态内容)


http {
    proxy_cache_path /var/cache/nginx/static_cache levels=1:2 keys_zone=my_http_cache:10m inactive=1d;

    server {
        listen 80;
        
        location /static/ {
            alias /var/www/example.com/static/;
            
            # HTTP缓存配置
            expires 1d; # 设置资源过期时间为一天
            add_header Cache-Control public; # 允许所有中间代理缓存
            proxy_cache my_http_cache; # 使用上面定义的缓存区域
            proxy_cache_bypass $http_pragma; # 如果请求包含Pragma:no-cache,则绕过缓存
            proxy_cache_revalidate on; # 在缓存有效期内尝试验证缓存是否仍然有效
            proxy_cache_min_uses 1; # 在至少被使用一次后才开始缓存
            proxy_cache_lock on; # 当多个请求同时到达时,只有第一个请求会获取新数据,其他请求等待并使用同一个缓存版本
            add_header X-Cache-Status $upstream_cache_status; # 添加缓存状态头

            # 其他静态文件处理相关配置
        }
    }
}

2、使用FastCGI缓存(适用于PHP等动态内容)

http {
    proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_fastcgi_cache:10m inactive=60m;

    server {
        listen 80;
        
        location ~ \.php$ {
            root /var/www/example.com;
            fastcgi_pass unix:/run/php/php7.4-fpm.sock;
            include fastcgi_params;
            
            # FastCGI缓存配置
            proxy_cache my_fastcgi_cache; # 使用上面定义的缓存区域
            proxy_cache_key "$scheme$request_method$host$request_uri"; # 缓存键生成规则
            proxy_cache_valid 200 302 60m; # 对于200和302响应码,缓存60分钟
            proxy_cache_methods GET HEAD; # 只缓存GET和HEAD请求
            add_header X-Cache-Status $upstream_cache_status; # 添加缓存状态头

            # 其他FastCGI相关配置
        }
    }
}

六、SSL终止(即HTTPS解密)

Nginx可作为HTTPS请求的前端处理器,处理SSL/TLS加密解密,减轻后端服务器的加密计算负担,并且支持证书管理、SSL会话缓存等功能。

   http {
    # 定义服务器监听HTTPS端口并启用SSL模块
    server {
        listen 443 ssl;
        server_name yourdomain.com; # 替换为你的域名

        # SSL证书文件路径设置
        ssl_certificate /path/to/your/server.crt; # 服务器证书文件
        ssl_certificate_key /path/to/your/server.key; # 私钥文件

        # SSL相关配置选项,可根据需要调整
        ssl_protocols TLSv1.2 TLSv1.3; # 支持的TLS协议版本
        ssl_ciphers HIGH:!aNULL:!MD5; # 安全加密套件列表
        ssl_prefer_server_ciphers on; # 优先使用服务器指定的加密套件
        ssl_session_cache shared:SSL:10m; # SSL会话缓存大小和类型
        ssl_session_timeout 1d; # SSL会话超时时间

        # 解密客户端请求后,将HTTP请求转发至后端服务器
        location / {
            proxy_pass http://backend-server:8080; # 替换为你的后端服务器地址与端口
            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_set_header X-Forwarded-Proto https; # 传递原始协议信息给后端
        }
    }
}

在这个示例中,Nginx监听443端口以接收HTTPS请求,并通过提供的服务器证书和私钥对客户端的SSL连接进行终止。然后,它将解密后的HTTP请求代理到后端服务器上。后端服务器无需处理SSL/TLS握手过程,只需处理普通的HTTP请求即可。
请确保替换上述配置中的yourdomain.com、/path/to/your/server.crt 和 /path/to/your/server.key 为你实际的域名和证书文件路径。同时,根据你的后端服务配置,正确设置 proxy_pass 指令指向的实际地址。

七、虚拟主机

支持多站点管理,基于域名或者IP来区分不同的网站,一个Nginx实例可以配置多个虚拟主机。

   server {
       listen 80;
       server_name example1.com;

       root /var/www/example1;
       index index.html;

       location / {
           try_files $uri $uri/ =404;
       }
   }

   server {
       listen 80;
       server_name example2.com;

       root /var/www/example2;
       index index.html;

       location / {
           try_files $uri $uri/ =404;
       }
   }

当请求的域名是example1.com或www.example1.com时,请求将被第一个server块处理;

当请求的域名是example2.com或www.example2.com时,请求将被第二个server块处理;

如果没有任何server_name匹配请求的域名,那么Nginx将使用第一个server块作为默认匹配项。

八、限速和保护

可以配置速率限制,防止DDoS攻击和其他恶意活动;同时支持基本认证、IP黑名单、白名单等多种安全措施。

   limit_req_zone $binary_remote_addr zone=req_limit:10m rate=1r/s;  # 定义速率限制区域

   server {
       location / {
           limit_req zone=req_limit burst=5 nodelay;  # 每秒不超过1个请求,突发允许5个
       }
   }

   server {
       auth_basic "Restricted Area";
       auth_basic_user_file /etc/nginx/.htpasswd;  # 基本身份验证

       location / {
           # ...
       }
   }

九、健康检查

Nginx可以定期检查后端服务器的健康状况,并自动从负载均衡池中移除不健康的服务器。

   upstream backend {
       server backend1.example.com;
       server backend2.example.com;

       keepalive 64;
       check interval=3000 rise=2 fall=5 timeout=1000;  # Nginx Plus支持健康检查
   }

十、实际解决问题示例

1、转发页面请求(A平台调用B的页面)

请求流程:

  1. A平台发起请求http://ip1:port1/rhm3/hismzzj.htm
  2. nginx重定向并把浏览器地址栏更新为http://ip1:port1/rhm-configure/page/his/mzzj,然后nginx把请求转发到B地址http://ip2:port2/rhm-configure/page/his/mzzj
  3. B返回html页面,页面中引入需要的js,css;(此处html引入js、css等资源使用的是相对路径)
  4. js中请求rhm5的页面作为子页面嵌入B返回的页面中
  #必须使用重定向并加上permanent强制把浏览器地址栏地址改变为http://ip1:port1/rhm-configure/page/his/mzzj
  location /hismzzj.htm {
        rewrite ^/hismzzj.htm$ /rhm-configure/page/his/mzzj permanent;
  }
  
  #然后走 /rhm-configure代理转发到http://ip2:port2/rhm-configure/page/his/mzzj;
  #此时B返回html页面中引入js的写法是<script src="../../js/jquery-3.6.1.js"></script>
  #html的位置http://ip1:port1/rhm-configure/his/mzzj.html,则获取js的地址是http://ip:port/rhm-configure/js/jquery-3.6.1.js正好命中位置
  location /rhm-configure {
	    proxy_pass  http://ip2:port2/rhm-configure;	       
  }
  
  #如果只是用proxy_pass完成转发,此时浏览器地址还是http://ip1:port1/rhm3/hismzzj.htm
  #请求js的地址是http://ip1:port1/js/jquery-3.6.1.js,路径错误,此处js只是举例用,还有其它类似路径的请求
  location /rhm3/hismzzj.htm {
	    proxy_pass  http://ip2:port2/rhm-configure/page/his/mzzj;	       
  }
  
  #js中请求rhm5的页面作为子页面嵌入B返回的页面中,请求http://ip1:port1/rhm5代理到http://ip2:port2/rhm5
  location /rhm5 {
        proxy_pass http://ip2:port2;
  }

2、根据自定义请求头的值转发到不同服务器的接口

#写法1   
server {
        listen       80;
        server_name  localhost;

		#下载数据转发代理
		location /piduhongguang/downloaddata {
			set $flag 0;
        	#if语句不支持“||” “&&”
			if ($http_m_type = 'UPDATE_ORGANIZATION') {
				set $flag 1;
			}
			if ($http_m_type = 'UPDATE_PERSONNEL') {
				set $flag 1;
			}
			if ($http_m_type = 'PHS_RECORD') {
				set $flag 1;
			}
            #把代理分成转发和重定向两部分实现是因为,在if语句中proxy_pass后不允许配置uri
			if ($flag = 0) {
				#没有匹配到,跳转到A
				rewrite ^/(.*)$ /fmd/user/downLoadInfoPtSanLian break;
				proxy_pass http://ip1:port1;
			}
			if ($flag = 1) {
				#匹配到,跳转到B
				rewrite ^/(.*)$ /rhmful/api/v2/pidu/basedata/syncData break;
				proxy_pass http://ip2:port2;
			}
        }
   }

#写法2 
server {
        listen       80;
        server_name  localhost;

		#下载数据转发代理
		location /piduhongguang/downloaddata {
        	//默认A地址
			set $target_url 'http://ip1:port1/fmd/user/downLoadInfoPtSanLian';
        	#匹配到,跳转到B
            #if语句不支持“||” “&&”
			if ($http_m_type = 'UPDATE_ORGANIZATION') {
				set $target_url 'http://ip2:port2/rhmful/api/v2/pidu/basedata/syncData';
			}
			if ($http_m_type = 'UPDATE_PERSONNEL') {
				set $target_url 'http://ip2:port2/rhmful/api/v2/pidu/basedata/syncData';
			}
			if ($http_m_type = 'PHS_RECORD') {
				set $target_url 'http://ip2:port2/rhmful/api/v2/pidu/basedata/syncData';
			}
        	#proxy_pass后使用自定义变量时,$target_url不可使用localhost(用127.0.0.1代替),很多默认处理会失效
            proxy_pass $target_url;
        }
   }

当客户端发起一个到localhost/piduhongguang/downloaddata的HTTP请求时:

  1. 首先设置变量$flag为0。

  2. 检查请求头中的$http_m_type字段,如果它的值等于 ‘UPDATE_ORGANIZATION’、‘UPDATE_PERSONNEL’ 或 PHS_RECORD’ 中的任何一个,则将 $flag 设置为 1。

  3. 根据 $flag 的值来决定如何处理请求:

    • 如果 $flag 为 0,表示请求头中没有匹配到预设的类型之一,此时通过 rewrite 规则将请求重定向至 /fmd/user/downLoadInfoPtSanLian 路径,并使用 break 结束当前重写阶段。然后通过 proxy_pass 将修改后的请求代理到本地8090端口的服务上。http://ip1:port1/fmd/user/downLoadInfoPtSanLian
    • 如果 f l a g 为 1 ,意味着请求头中的 flag 为 1,意味着请求头中的 flag1,意味着请求头中的http_m_type匹配到了预设类型,这时同样通过 rewrite 规则将请求重定向至 /rhmful/api/v2/pidu/basedata/syncData 路径,并用 break 结束重写阶段。最后依然通过 proxy_pass 将请求转发给本地8090端口的同一个服务。http://http://ip2:8port2/rhmful/api/v2/pidu/basedata/syncData

    总结:这个配置根据HTTP请求头中的特定字段值($http_m_type)来决定请求应被转发至后端服务的哪个具体接口,实现了基于请求内容动态路由的功能。

优化

在Nginx中,处理rewrite和proxy_pass的方式是基于事件循环而非逐行执行。if语句和rewrite指令的使用存在一定的限制和复杂性。nginx官方文档强烈建议避免在if语句中使用proxy_pass,并且尽量减少对if语句的依赖,因为它们可能会导致意想不到的结果和性能问题。
为了解决这个问题,可以考虑采用其他方法,例如使用变量结合单个rewrite规则和一个统一的proxy_pass:

http {
    #map只能写在http中不能写在server或location中
    map $http_m_type $target_path {
        UPDATE_ORGANIZATION  'http://ip1:port1/rhmful/api/v2/pidu/basedata/syncData';
        UPDATE_PERSONNEL     'http://ip1:port1/rhmful/api/v2/pidu/basedata/syncData';
        PHS_RECORD           'http://ip1:port1/rhmful/api/v2/pidu/basedata/syncData';
        default              'http://ip2:port2/fmd/user/downLoadInfoPtSanLian';
    }

    server {
        listen       80;
        server_name  localhost;

        location /piduhongguang/downloaddata {
            proxy_pass $target_path;
        }
    }
}
  • 29
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值