基于请求头分发适用于多个集群场景;也适应进行服务灰度发布的场景。

1、基于host分发

适用于一个公司有多个网站,一个网站设置为一个集群
  1. #nginx分发器设置
  2. http {
  3. upstream web1 { # 名为web1的反向代理群组
  4. server server1;
  5. }
  6. upstream web2 { # 名为web2的反向代理群组
  7. server server2;
  8. }
  9. server { # web1虚拟主机
  10. listen 80;
  11. server_name www.web1.com; # 基于域名分发必须有域名
  12. location / {
  13. proxy_pass http://web1;
  14. }
  15. }
  16. server { # web2虚拟主机
  17. listen 80;
  18. server_name www.web2.com; # 基于域名分发必须有域名
  19. location / {
  20. proxy_pass http://web2;
  21. }
  22. }
  23. }

2、基于开发语言分发

适用于混合开发的网站,某些大型网站既有php也有jsp
  1. # 分发器上nginx配置
  2. http {
  3. upstream php {
  4. server server1;
  5. }
  6. upstream asp {
  7. server server2;
  8. }
  9. upstream html {
  10. server server2;
  11. }
  12. server {
  13. location ~* \.php$ { # 以php结尾的
  14. proxy_pass http://php;
  15. }
  16. location ~* \.asp$ { # 以asp结尾的
  17. proxy_pass http://asp;
  18. }
  19. location ~* \.html$ { # 以html结尾的
  20. proxy_pass http://html;
  21. }
  22. }
  23. }

3、基于浏览器分发

常应用于PC端和移动端区分或浏览器适配
  1. upstream curl {
  2. server server1;
  3. }
  4. upstream firefox {
  5. server server2;
  6. }
  7. upstream other {
  8. server server3;
  9. }
  10. server {
  11. listen 80;
  12. server_name www.web1.com;
  13. location / {
  14. proxy_pass http://other;
  15. if ( $http_user_agent ~* curl ) {
  16. proxy_pass http://curl;
  17. }
  18. if ( $http_user_agent ~* firefox ) {
  19. proxy_pass http://firefox;
  20. }
  21. }
  22. }

4、基于源IP分

通过ngx_http_geo_module模块,根据客户端ip访问到不同的server
  1. upstream bj.server {
  2. server server1; # web01
  3. }
  4. upstream sh.server {
  5. server server2; # web02
  6. }
  7. upstream default.server {
  8. server server3; # web03
  9. }
  10. geo $geo { # IP库
  11. default default;
  12. server1 bj; # 北京
  13. server2 sh; # 上海
  14. }
  15. server {
  16. listen 80;
  17. server_name www.web1.com;
  18. location / {
  19. proxy_pass http://$geo.server$request_uri;
  20. }
  21. }

5、根据http header转发到不同的服务

根据请求 Header 转发不同后端服务server。
  1. http {
  2. map $http_custom_header $backend_name {
  3. default backend1;
  4. "version2.0" backend2;
  5. }
  6. upstream backend1 {
  7. server backend1.example.com;
  8. }
  9. upstream backend2 {
  10. server backend2.example.com;
  11. }
  12. server {
  13. listen 80;
  14. location / {
  15. proxy_pass http://$backend_name;
  16. proxy_set_header Host $host;
  17. proxy_set_header X-Real-IP $remote_addr;
  18. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  19. proxy_set_header X-Forwarded-Proto $scheme;
  20. }
  21. }
  22. }
在这个配置中,<font style="color:rgb(30, 107, 184);">$http_custom_header</font> 是一个变量,代表HTTP请求header中的自定义字段。map 指令根据这个变量的值来设置一个变量 <font style="color:rgb(30, 107, 184);">$backend_name</font>。如果请求header中的自定义字段值为 <font style="color:rgb(30, 107, 184);">"version2.0"</font>,则会将请求转发到 backend2.example.com;否则,会转发到 backend1.example.com。

也可以如下配置

  1. map $http_accept $version {
  2. default "";
  3. "application/vnd.demo.v2.0+json" "v2.0";
  4. }
  5. upstream backend1 {
  6. server backend1.example.com;
  7. }
  8. upstream backend2 {
  9. server backend2.example.com;
  10. }
  11. server {
  12. listen 80;
  13. server_name olive.com;
  14. charset utf-8;
  15. autoindex off;
  16. location / {
  17. proxy_set_header Host $host;
  18. proxy_set_header X-Real-IP $remote_addr;
  19. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  20. proxy_set_header X-Forwarded-Proto $scheme;
  21. proxy_set_header X-Forwarded-Port $server_port;
  22. proxy_set_header X-Forwarded-Ssl on;
  23. if ($version="v2.0"){
  24. proxy_pass http://backend2;
  25. break;
  26. }
  27. proxy_pass http://backend1;
  28. }
  29. }
在这个配置中,<font style="color:rgb(30, 107, 184);">$http_accept</font> 是一个变量,代表HTTP请求header中的<font style="color:rgb(30, 107, 184);">http_accept</font>字段。map 指令根据这个变量的值来设置一个变量 <font style="color:rgb(30, 107, 184);">$version</font>。如果请求header中的自定义字段值为 <font style="color:rgb(30, 107, 184);">"application/vnd.demo.v2.0+json"</font>,则<font style="color:rgb(30, 107, 184);">$version</font>的值为<font style="color:rgb(30, 107, 184);">v2.0</font>;否则<font style="color:rgb(30, 107, 184);">$version</font>的值为空字符串。然后<font style="color:rgb(30, 107, 184);">if</font>条件判断根据<font style="color:rgb(30, 107, 184);">$version</font>的值进行转发。