二十五 网关Nginx负载模型配置

通过模拟多个 HTTP 服务配置到 Nginx 做负载均衡,以学习 API 网关负载的配置和使用。

设计

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

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

这里先介绍基于 Nginx 如何构建出一套负载均衡的网络请求模型,方便理解这样一个过程。

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

25-设计-1

wg 是一个固定开头的地址,转换后面紧跟着所访问的具体方法。在前面章节中已经实现过 uri 映射到具体的 RPC 上。所以当我们通过在浏览器进行 HTTP 访问接口接口 http://localhost:8090/wg/activity/sayHi 时,则会访问的到对应的 api 协议转换通信服务上,完成对应的 RPC 调用和结果封装。

那么现在我们需要的是根据一个 URL 地址所访问路径的差异,访问到不同的 api 协议转换通信服务上,这样就可以完成一个负载调用的过程了。

25-设计-2

那么本章节我们就先对 Nginx 配置操作处理负载,同时本章先不用把所有的 API 网关应用都启动起来。

往往我们要处理一个小问题时,先不要引入过多的条件项来干扰结果。所以我们先通过 Socket 工具模拟网关的方式进行处理。

实现

Nginx 负载部署

首次部署

1
2
docker pull nginx
docker run --name Nginx -d -p 8090:80 nginx
  • Nginx 的名称可以自己起
  • 8090 是映射的端口,Docker 容器配置的是 80 端口。访问时候可以: http://localhost:8090

25-实现-1

拷贝配置

首次部署 Nginx 后,其实我们还不好操作配置文件。也就是 Nginx 的配置文件,因为只有拿到配置文件我们才能自己管理它。

那么这里我们需要使用命令把配置文件拷贝到我们本地,之后重启 Nginx 服务。在拷贝文件之后启动 Nginx 之前,记得要删掉之前的 Nginx 服务。你可以使用 docker rm 命令,也可以在 Docker Desktop 的可视化界面中操作。

25-实现-2

1
docker container cp Nginx:/etc/nginx/nginx.conf /Users/ray/Source/api-gateway/api-gateway-center/doc/data/nginx

此外还需要一个 html 内容放到本地;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<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>

重新启动

1
docker run --name Nginx -d -v /Users/ray/Source/api-gateway/api-gateway-center/doc/data/html:/usr/share/nginx/html -v /Users/ray/Source/api-gateway/api-gateway-center/doc/data/nginx/nginx.conf:/etc/nginx/nginx.conf -p 8090:80 nginx

这次启动就要把配置文件所在的本地路径给配置上了,后面修改自己本地的配置文件后重新启动即可。

Nginx 负载配置

Socket Debugger 模拟 HTTP 服务

配置三个 HTTP 服务端以及对应的访问路径和响应信息

Api101

25-实现-3

Api102

25-实现-4

Api201

25-实现-5

配置完成后,可以尝试访问地址:http://10.17.69.148:9001/ 查看请求结果

25-实现-6

Nginx 配置负载调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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 10.17.69.148:9001;
server 10.17.69.148:9002;
}

# 设定负载均衡的服务器列表
upstream api02 {
server 10.17.69.148:9003;
}

# HTTP服务器
server {
# 监听80端口,用于HTTP协议
listen 80;

# 定义使用IP/域名访问
server_name 10.17.69.148;

# 首页
index index.html;

# 反向代理的路径(upstream绑定),location 后面设置映射的路径
location / {
proxy_pass http://10.17.69.148:9001;
}

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

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

重点在 server 中 location 的配置,分别调度用到 api01、api02,另外在 upstream api01 中通过连接数进行负载。在 Nginx 中还有 IP 哈希负载。

可参考 Nginx 配置文档:nginx-tutorial

测试

访问 Nginx 接口:http://10.17.69.148:8090/api01/ 以及 http://10.17.69.148:8090/api02/

25-测试

通过不同的地址访问以及刷新可以看到我们的服务被负载轮训请求了。说明 Nginx 已经配置完成。