谷粒商城-高级-43 商城业务-域名访问负载均衡到网关

一、Nginx代理网关

网关图

上一节我们是让Nginx直接代理到我们的商品服务:192.168.10.1:10000,这样会有问题,如果商品服务做调整或者增加其他的微服务,则需要直接修改Nginx的配置文件,商品服务上线或下线我们也很难操作,这时候就需要网关来处理了,Nginx先将请求负载到网关,然后再由网关转发到 微服务。

Nginx负载均衡

Nginx官网 load balancing

官网默认的负载均衡配置:

http {
    upstream myapp1 {
        server srv1.example.com;
        server srv2.example.com;
        server srv3.example.com;
    }

    server {
        listen 80;

        location / {
            proxy_pass http://myapp1;
        }
    }
}

当访问 http://myapp1 的时候,默认会代理到上游服务器的 srvX.example.com

在上面的示例中,同一应用程序的3个实例在srv1-srv3上运行。如果未特别配置负载平衡方法,则默认为循环。所有请求都被代理到服务器组myapp1,nginx应用HTTP负载平衡来分发请求。nginx中的反向代理实现包括HTTP,HTTPS,FastCGI,uwsgi,SCGI,memcached和gRPC的负载平衡。

更改Nginx配置

修改 Nginx总的配置文件 nginx.conf

[root@localhost nginx]# cd conf
[root@localhost conf]# ls -l
total 32
drwxr-xr-x. 2 root root   47 Aug 29 19:27 conf.d
-rw-r--r--. 1 root root 1007 Aug 29 16:58 fastcgi_params
-rw-r--r--. 1 root root 2837 Aug 29 16:58 koi-utf
-rw-r--r--. 1 root root 2223 Aug 29 16:58 koi-win
-rw-r--r--. 1 root root 3957 Aug 29 16:58 mime.types
lrwxrwxrwx. 1 root root   22 Aug 29 16:58 modules -> /usr/lib/nginx/modules
-rw-r--r--. 1 root root  764 Aug 29 21:12 nginx.conf
-rw-r--r--. 1 root root  636 Aug 29 16:58 scgi_params
-rw-r--r--. 1 root root  664 Aug 29 16:58 uwsgi_params
-rw-r--r--. 1 root root 3610 Aug 29 16:58 win-utf
[root@localhost conf]# vi nginx.conf

添加上游服务器upstream配置

  #load balancing upstream configuration
    upstream gulimall{
       server 192.168.10.1:8888; # nacos gateway
    }

完整的nginx.conf文件:

[root@localhost conf]# cat nginx.conf

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;
    #load balancing upstream configuration
    upstream gulimall{
       server 192.168.10.1:8888; # nacos gateway
    }

    include /etc/nginx/conf.d/*.conf;
}

修改项目的配置文件 gulimall.conf
gulimall.conf 代理修改为:

  location / {
       #proxy_pass http://192.168.10.1:10000;
        proxy_pass http://gulimall; #use nginx.conf upstream load balancing
    }

完整的 gulimall.conf配置文件:

[root@localhost conf.d]# cat gulimall.conf
server {
    listen       80;
    server_name  gulimall.com;

    #charset koi8-r;
    #access_log  /var/log/nginx/log/host.access.log  main;

    location / {
       #proxy_pass http://192.168.10.1:10000;
        proxy_pass http://gulimall; #use nginx.conf upstream load balancing
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}

重启nginx:

更改项目网关配置

gulimall-gateway/src/main/resources/application.yml 加入商城项目的路由规则:

        - id: gulimall_host_route
          uri: lb://gulimall-product
          predicates:
            - Host=**.gulimall.com
          filters:
            - RewritePath=/api/(?<segment>.*),/renren-fast/$\{segment}

完整代码:

spring:
  cloud:
    gateway:
      routes:
        - id: product_route
          uri: lb://gulimall-product
          predicates:
            - Path=/api/product/**
          filters:
            - RewritePath=/api/(?<segment>.*),/$\{segment}

        - id: third_party_route
          uri: lb://gulimall-third-party
          predicates:
            - Path=/api/thirdparty/**
          filters:
            - RewritePath=/api/(?<segment>.*),/$\{segment}

        - id: member_route
          uri: lb://gulimall-member
          predicates:
            - Path=/api/member/**
          filters:
            - RewritePath=/api/(?<segment>.*),/$\{segment}

        - id: ware_route
          uri: lb://gulimall-ware
          predicates:
            - Path=/api/ware/**
          filters:
            - RewritePath=/api/(?<segment>.*),/$\{segment}

        - id: admin_route
          uri: lb://renren-fast
          predicates:
            - Path=/api/**
          filters:
            - RewritePath=/api/(?<segment>.*),/renren-fast/$\{segment}

        - id: gulimall_host_route
          uri: lb://gulimall-product
          predicates:
            - Host=**.gulimall.com
          filters:
            - RewritePath=/api/(?<segment>.*),/renren-fast/$\{segment}

## 前端项定义规则,都带 /api 前缀, lb 表示负载均衡到哪个注册器
## http://localhost:8888/api/captcha.jpg  需要通过注册中心网关8888端口转发到renren-fast 8080端口服务
## http://localhost:8080/renren-fast/captcha.jpg:
## filters 路径重写 /api/ -> /renren-fast/

添加完路由规则之后,然后重启网关服务,根据域名进行访问:
file

使用网关负载均衡怎么不行呢?是哪里没设置好?路由规则的host没有匹配上。

Nginx代理坑
Nginx代理给网关的时候,会丢失请求的host信息,所以在代理转发的时候,需要设置请求头:proxy_set_header Host $host

修改配置文件 /mydata/nginx/conf/conf.d/gulimall.conf

location / {
       #proxy_pass http://192.168.10.1:10000;
        proxy_set_header Host $host; # 设置请求头host
        proxy_pass http://gulimall; #use nginx.conf upstream load balancing
    }

完整的/nginx/conf/conf.d/gulimall.conf 文件:

[root@localhost conf.d]# cat gulimall.conf
server {
    listen       80;
    server_name  gulimall.com;

    #charset koi8-r;
    #access_log  /var/log/nginx/log/host.access.log  main;

    location / {
       #proxy_pass http://192.168.10.1:10000;
        proxy_set_header Host $host;
        proxy_pass http://gulimall; #use nginx.conf upstream load balancing
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}

然后重启Nginx服务,再次访问http://gulimall.com/

file

可以看到已经可以正常访问了 ^_^

二、域名映射效果总结

  • 请求接口:gulimall.com
  • 请求页面:gulimall.com

Nginx直接代理给网关,网关来进行判断

  • 如果是/api/**,转交给对应的服务器
  • 如果是 满足域名,转交给对应的服务器

另外,在配置网关路由规则时,一定要注意/api/**的要放在 页面(gulimall_host_route)请求规则的前边。

为者常成,行者常至