业务流程

在前面的章节中我们已经打通了,网关所有模块的连通,如下图

但是这里有一个问题,我么每次进行访问的,之前测试使用的是7397端口,而我们在之前的章节说过,我们的网关算力和RPC服务是有分组的,每组又有多个,而算力服务根据RPC服务分类,会有多组,每组也会有多个,所有的算力节点api-gateway-core在分布式场景下

  • 一是同时启动不可能全部都绑定7397端口,因此端口就会有多个,而我们本地http要想让用户无感,就必须不让用户知道端口的变化,用户也只需要访问一个端口地址,就像之前测试的localhost:8090/sayhi这种,能变的只有/sayhi这种访问路径,那么就需要一个统一的映射,根据访问前缀映射到不同的算力节点进行网关服务

  • 二是每个分组有多个算力实例,这些示例要分担压力,那就设计到负载均衡

API 网关是用于支撑分布式 RPC 接口协议转换提供 HTTP 调用的一套服务,那么 API 网关系统就需要可横向扩展来满足系统的吞吐量诉求。所以这里需要让 API 网关来支持分布式架构部署,提供负载均衡的能力。

那么在这方面有一套非常成熟的模式就是基于 Nginx 以及 LVS、F5 相关的配置构建出负载均衡服务。在这里同样我们的 API 网关也可以被这样的方式进行处理,来满足部署需求。

首先我们知道,API网关是根据 HTTP 协议请求的地址转换为对应映射泛化调用的 RPC 框架。这部分请求地址被配置到数据库中。如图

wg 是一个固定开头的地址,转换后面紧跟着所访问的具体方法。在前面章节中已经实现过 uri 映射到具体的 RPC 上。所以当我们通过在浏览器进行 HTTP 访问接口接口 http://localhost:8090/wg/activity/sayHi 时,则会访问的到对应的 api 协议转换通信服务上,完成对应的 RPC 调用和结果封装。现在实际场景下我们有多个分组,每个分组有多个算力节点,那么现在我们需要的是根据一个 URL 地址所访问路径的差异,访问到不同的 api 协议转换通信服务上(api-gateway-core),这样就可以完成一个负载调用的过程了。如图

因此本章节我们就将使用 Nginx 配置操作处理负载,同时本章先不用把所有的 API 网关应用都启动起来。但是本章节不会先把所有的 API 网关应用都启动起来,我们先对nginx进行配置,使其可以达到根据不同的访问路径进行映射不同的服务上,同时进行负载均衡的实验,配置好后,后续只需要添加对应的服务映射即可。

业务实现

本章结构如下

首先我们需要先定义好对应的nginx配置,如下nginx.conf。(服务端在本地电脑不在docker中)。这部分看不懂配置可以学习 Nginx 配置文档

 ​
 user  nginx;
 worker_processes  auto;
 ​
 error_log  /var/log/nginx/error.log notice;
 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;
 ​
     #include /etc/nginx/conf.d/*.conf;
 ​
     # 设定负载均衡的服务器列表
     upstream api01 {
 ​
         least_conn;
 ​
         server host.docker.internal:9001;
         server host.docker.internal:9002;
     }
 ​
     # 设定负载均衡的服务器列表
     upstream api02 {
         server host.docker.internal:9003;
     }
 ​
     # HTTP服务器
     server {
         # 监听80端口,用于HTTP协议
         listen  80;
 ​
         # 定义使用IP/域名访问
         server_name localhost;
 ​
         # 首页
         index index.html;
 ​
         # 反向代理的路径(upstream绑定),location 后面设置映射的路径
         location / {
             proxy_pass http://host.docker.internal:9001;
         }
 ​
         location /api01/ {
             proxy_pass http://api01;
         }
 ​
          location /api02/ {
             proxy_pass http://api02;
         }
     }
 }
 ​

这里由于我们本地的环境是windows下安装docker desktop,然后docker安装nginx的,而访问是在本地浏览器测试访问的,因此在server的IP地址配置上有所不同,如果是在服务器上,只需要修改为对应服务器IP即可。这里有如下区分(都是在本地测试,不对外提供访问)

  • 若服务端(后端)在docker中,那么配置有server_name localhost;proxy_pass http://api-gateway-engine:7397; # 用容器服务名

  • 若服务端在宿主机中,不在docker中(如IDEA),那么配置有server_name localhost;proxy_pass http://host.docker.internal:7397; # 用宿主机特殊域名

然后其index的文件如下index.html

 <html>
 <head>
     <title>Welcome to nginx!</title>
     <style>
         html { color-scheme: light dark; }
         body { width: 35em; margin: 0 auto;
             font-family: Tahoma, Verdana, Arial, sans-serif; }
     </style>
 </head>
 <body>
 <h1>Welcome to nginx!</h1>
 <p>If you see this page, the nginx web server is successfully installed and
     working. Further configuration is required.</p>
 ​
 <p>For online documentation and support please refer to
     <a href="http://nginx.org/">nginx.org</a>.<br/>
     Commercial support is available at
     <a href="http://nginx.com/">nginx.com</a>.</p>
 ​
 <p><em>Thank you for using nginx.</em></p>
 </body>
 </html>
 ​
 ​

最后nginx对应的docker-compose.yml配置如下docker-compose-environment.yml

   #nginx
   nginx: # 新增的 Nginx 服务
     image: nginx
     container_name: Nginx
     restart: always
     ports:
       - "8090:80"
     volumes:
       # 静态资源目录映射
       - ./nginx/html:/usr/share/nginx/html
       # Nginx 配置文件映射
       - ./nginx/conf/nginx.conf:/etc/nginx/nginx.conf
     networks:
       - api-gateway

测试

本次测试是为了检验配置环境能否进行对应的根据不同的访问路径进行映射不同的服务,并进行负载均衡。

  • 测试环境windows下用网络调试助手 NetAssist 3.8.2进行模拟环境测试,如果是MAC则用Socket Debugger。本机为windows环境

首先我们根据nginx的配置用网络调试助手 NetAssist 3.8.2构造3个服务端,如下图

  • 先是api01对应的两个服务实例,监听9001,9002端口

  • 然后是api02对应的服务实例,监听9003端口

  • 最后是构造构造 HTTP 响应,分别在api01,api02的服务端的发送窗口下,输入响应,后续收到请求点击发送即可

 HTTP/1.1 200 OK
 Content-Type: text/plain
 Content-Length: 19
 ​
 hello api01/api02 9001/9002/9003
 ​

最后我们在浏览器分别进行访问,观察三个服务端的接收请求界面

我们先测试http://localhost:8090/api01/,这一次是负载到了9001端口的服务上,点击发送

我们再刷新一下http://localhost:8090/api01/,这一次负载到了9002端口的服务上,点击发送

最后我么测试下http://localhost:8090/api02/,这一次是负载到了9003端口的服务上,点击发送

其中Portainer观测nginx日志如下图

测试成功

参考资料