📢 什么是Nginx 负载均衡
Nginx 负载均衡 是使用 Nginx 来分发进入的流量,确保多个后端服务器(通常称为"上游服务器"或"后端")公平地共享负载,以便每个服务器都不会过载。它旨在优化资源使用,最大化吞吐量,最小化响应时间,并确保没有一个后端服务器过于繁忙。
以下是 Nginx 负载均衡的关键概念和特点:
🌟 核心概念
-
上游 (Upstream): 上游是一组后端服务器,它们共同处理来自 Nginx 的请求。这些服务器可以是 web 服务器、应用服务器或其他类型的服务器。
-
服务器 (Server): 在 Nginx 上下文中,服务器指的是一个特定的监听 IP 地址和端口的实体。每个服务器可以路由流量到一个或多个上游。
-
位置 (Location): 在 HTTP 上下文中,位置用于定义如何响应请求的某些部分。每个位置都可以定义其负载均衡器的行为。
🌟 负载均衡方法
Nginx 支持多种负载均衡策略,包括:
-
轮询 (Round Robin): 默认的负载均衡方法。每个请求按顺序分配到不同的后端服务器。
-
加权轮询 (Weighted Round Robin): 每个后端服务器都分配一个权重。服务器与较高权重收到比服务器与较低权重更多的请求。
-
最少连接 (Least Connections): 新请求将转发到当前活动连接数最少的服务器。
-
IP 哈希 (IP Hash): 使用客户端 IP 地址的哈希结果确定应该向哪个服务器转发请求。这可以确保来自特定客户端的请求总是转发到同一台后端服务器,从而实现会话的粘性。
-
通用哈希 (Generic Hash): 使用一种更灵活的哈希方法,可以基于文本、变量等进行哈希。
🌟 其他特点
-
健康检查: Nginx 可以定期检查后端服务器的健康状况,并在检测到故障时自动从旋转中删除它们。
-
SSL/TLS 终止: Nginx 可以为后端服务器终止 SSL/TLS 连接,从而减轻后端服务器的负担。
-
持久连接: Nginx 支持与后端服务器的持久连接,从而减少握手的开销。
-
动态服务器: 使用 Nginx Plus,你可以动态地在上游组中添加、删除或修改服务器,无需重新加载配置。
🌟 使用场景
Nginx 负载均衡在各种情境中都非常有用,例如:
- 当单个服务器无法处理所有流量时。
- 在高可用性配置中,以确保在一个服务器出现故障时,流量可以转移到另一个服务器。
- 当需要对多个版本的应用进行 A/B 测试时。
🖧 Nginx 模块概览
在 Nginx 中,有两个主要的模块分别处理不同层次的网络请求:http
模块和 stream
模块。以下是对这两个模块的详细介绍:
🌐 http
模块
-
层次 📶:
http
模块主要处理应用层的请求,特别是 HTTP 和 HTTPS 请求。
-
功能 🔧:
- ✅ 提供 HTTP 服务:包括静态内容服务、动态内容代理以及负载均衡。
- ✅ HTTP 特性:支持各种 HTTP 特定的功能,如重定向、重写、缓存、压缩、安全性头部、Cookie 管理等。
- ✅ 请求头识别:可以识别 HTTP 请求头,从而做出基于请求头的决策。
- ✅ 安全通信:支持 SSL/TLS。
- ✅ 代理与负载均衡:支持各种 HTTP/HTTPS 代理和负载均衡策略。
🌍 stream
模块
-
层次 📶:
stream
模块主要处理传输层的请求,例如 TCP 和 UDP 请求。
-
功能 🔧:
- ✅ 四层转发:提供四层的 TCP/UDP 转发和负载均衡。
- ✅ 透明处理:由于它在四层工作,所以它对传输的数据是透明的,不会解析应用层协议。
- ✅ 路由决策:可以基于 IP 地址和端口进行路由决策。
- ✅ 安全通信:支持 SSL/TLS,适用于 SSL 加密的 TCP 通信。
- ✅ 非 HTTP 负载均衡:用于非 HTTP 协议的负载均衡,如 MySQL、SSH、SMTP 等。
🔄 stream
是否可以取代 http
?
-
🤔 在某些应用场景中,
stream
模块可以替代http
模块,特别是当您只需要基于 IP 和端口进行路由决策时。 -
❌ 但是,
stream
模块不能完全替代http
模块。这是因为http
模块提供了许多 HTTP/HTTPS 请求的高级功能,这些功能在stream
模块中不可用。 -
🌟 总结:
stream
和http
模块都有其独特的用途。选择使用哪个模块取决于您的具体需求。在处理常见的 web 服务器和代理任务时,http
模块是首选。而对于四层负载均衡和代理需求,stream
模块是理想的选择。
🚀 Nginx 负载均衡算法
当你的网站流量增加时,一个服务器可能不足以处理所有请求。在这种情况下,你可以设置多个应用服务器,并使用 Nginx作为负载均衡器,根据特定的算法(如轮询、最少连接等)将请求分发到各个服务器。
算法 | 对故障服务器的处理 | 服务器恢复后的行为 |
---|---|---|
轮询(Round Robin) | 继续发送请求到故障服务器,可能导致失败或超时 | 恢复后重新开始分发请求 |
权重(Weighted RR) | 停止发送请求到故障服务器,直到恢复正常 | 恢复后重新开始分发请求,根据权重可能有不同的比例 |
最小连接(Least Conn) | 继续发送请求到故障服务器,可能导致失败或超时 | 恢复后重新开始分发请求,基于当前连接数选择服务器 |
IP哈希(IP Hash) | 继续将请求发送到故障服务器 | 恢复后继续将来自相同IP地址的请求发送到相同服务器 |
📌 热备
(Hot Standby)
当您有一个备份服务器可用时,您可以配置 Nginx 以只在主服务器失败时使用它。
http {
upstream myapp0 {
server www.example.com;
server bad.example.com down;
server bak.example.com backup;
}
server {
listen 80; # 侦听 80 端口
server_name www.example.com; # 服务器域名
location / {
proxy_pass http://myapp0; # 转发请求到上面定义的 upstream
}
}
}
📝 注释: 在这里,只有当 myapp01.example.com
失败时,myapp02.example.com
才会开始接收请求。
1. 初始请求:
当一个请求到达 Nginx 并被定向至 myapp0
后端组,首先会尝试转发请求至 www.example.com
。这是因为它是 upstream
配置块中的第一个 server
指令。
2. 跳过标记为 down
的服务器:
Nginx 会跳过 bad.example.com
,因为它后面的 down
指令标记这个服务器为不可用。
3. 使用备份服务器:
如果 www.example.com
无法处理请求(例如,它宕机或超时),Nginx 会考虑转发请求至 bak.example.com
。这是由于它后面的 backup
指令,它被指定为备份服务器,只在其他非备份服务器不可用时才会被考虑。
总结:
默认地,请求会被转发至 www.example.com
。只有当 www.example.com
无法处理请求时,才会考虑备份服务器 bak.example.com
。而 bad.example.com
由于标记为 down
,所以永远不会接收到请求。
📌 轮询
(Round Robin)
流程:
- 客户端发起请求到 Nginx。
- Nginx 根据轮询策略将请求转发到下一个服务器。
- 后端服务器处理请求并返回响应到 Nginx。
- Nginx 将响应返回给客户端。
http {
upstream myapp1 {
# 使用轮询算法
server srv1.example.com; # 第一个服务器
server srv2.example.com; # 第二个服务器
server srv3.example.com; # 第三个服务器
}
server {
listen 80; # 侦听 80 端口
server_name www.example.com; # 服务器域名
location / {
proxy_pass http://myapp1; # 转发请求到上面定义的 upstream
}
}
}
📌 最少连接
(Least Connections)
流程:
- 客户端发起请求到 Nginx。
- Nginx 检查所有后端服务器,选择当前有最少活动连接的服务器。
- 将请求转发到该服务器。
- 服务器处理请求并返回响应到 Nginx。
- Nginx 将响应返回给客户端。
http {
upstream myapp2 {
least_conn; # 使用最少连接算法
server srv1.example.com; # 第一个服务器
server srv2.example.com weight=3; # 第二个服务器,权重为 3
}
server {
listen 80; # 侦听 80 端口
server_name www.example.com; # 服务器域名
location / {
proxy_pass http://myapp2; # 转发请求到上面定义的 upstream
}
}
}
📌 IP 哈希
(IP Hash)
http {
upstream myapp3 {
ip_hash; # 使用 IP 哈希算法
server srv1.example.com; # 第一个服务器
server srv2.example.com; # 第二个服务器
}
server {
listen 80; # 侦听 80 端口
server_name www.example.com; # 服务器域名
location / {
proxy_pass http://myapp3; # 转发请求到上面定义的 upstream
}
}
}
🌐 IP哈希(IP Hash)负载均衡工作原理:
-
🚀 客户端发起请求到Nginx。
-
📡 Nginx获取客户端的IP地址。
-
🔢 Nginx使用客户端IP地址计算哈希值。这个哈希值通常是一个非负整数。
-
🎯 哈希值与后端服务器的数量进行取模运算(求余数),以确定应该将请求路由到哪个后端服务器。
- 🖥️ 假设你有两台后端服务器,分别为
srv1.example.com
和srv2.example.com
。 - 🧮 如果哈希值是奇数,那么
(哈希值 % 2)
结果为1,请求将路由到srv2.example.com
。 - 🧮 如果哈希值是偶数,那么
(哈希值 % 2)
结果为0,请求将路由到srv1.example.com
。
- 🖥️ 假设你有两台后端服务器,分别为
-
🔄 请求被转发到选中的后端服务器,然后由该服务器处理。
-
📝 这个过程确保了相同客户端IP地址的请求将始终被路由到相同的后端服务器,从而维护了会话状态。不同的客户端IP地址将产生不同的哈希值,这会分散负载并确保请求被均匀地分配给后端服务器。
-
⚠️ 需要注意的是,IP哈希算法有一些限制,例如,如果后端服务器的数量变化,哈希值可能导致不均匀的分配。因此,在使用IP哈希算法时,通常需要考虑后端服务器的动态性。如果服务器数量经常变化,可能需要其他负载均衡算法来更好地适应变化。
📌 加权负载均衡
(Weighted Load Balancing)
可以为每个后端服务器分配一个权重,权重高的服务器将处理更多的请求。
http {
upstream myapp4 {
server myapp41.example.com;
server myapp42.example.com weight=3;
server myapp43.example.com weight=2;
}
server {
listen 80; # 侦听 80 端口
server_name www.example.com; # 服务器域名
location / {
proxy_pass http://myapp4; # 转发请求到上面定义的 upstream
}
}
}
下面是基于你提供的Nginx配置示例的加权负载均衡的运行流程的一个简要说明:
-
客户端发出请求:客户端向Nginx服务器发送请求。
-
Nginx接收请求:Nginx服务器接收到客户端的请求。
-
负载均衡器处理请求:请求到达负载均衡器,负载均衡器的任务是决定将请求分发给哪个后端服务器。
-
权重分配:负载均衡器根据配置中的权重分配决定将请求分发给哪个后端服务器。根据上面的配置示例,如果有10个请求到达负载均衡器,分发可能如下:
myapp41.example.com
:处理1个请求。myapp42.example.com
:处理3个请求。myapp43.example.com
:处理2个请求。
-
请求转发:负载均衡器将请求转发给相应的后端服务器。例如,如果请求被分配给
myapp01.example.com
,则请求将被发送到myapp01.example.com
服务器上。 -
后端服务器处理请求:被选中的后端服务器接收到请求并处理它,然后生成响应。
-
响应返回:后端服务器生成的响应被发送回负载均衡器。
-
负载均衡器返回响应:负载均衡器接收到来自后端服务器的响应,并将其发送回客户端。
-
客户端接收响应:客户端最终接收到来自Nginx服务器的响应,响应的内容是由后端服务器处理生成的。
📌 proxy_next_upstream
指令
当使用 Nginx 进行反向代理和负载均衡时,proxy_next_upstream
指令非常有用。以下是一个完整的 Nginx 示例配置,包括了 proxy_next_upstream
的使用以及一些其他相关配置项的说明:
error 建立连接 / 发送请求 / 接收响应时出错(缺省值之一);
timeout 建立连接 / 发送请求 / 接收响应时超时(缺省值之一);
invalid_header 上游返回空白或无效响应;
http_500 上游返回 500 Internal Server Error;
http_501 上游返回 501 Not Implemented;
http_502 上游返回 502 Bad Gateway;
http_503 上游返回 503 Service Unavailable;
http_504 上游返回 504 Gateway Timeout;
http_404 上游返回 404 Not Found;
http_429 上游返回 429 Too Many Requests;
non_idempotent 解除对非幂等请求 (POST, LOCK, PATCH) 的封印,小心造成重复提交;
off 不得转给下一台服务器。
🌐 Nginx配置示例
http {
upstream myapp5 {
server myapp51.example.com;
server myapp52.example.com;
server myapp53.example.com;
}
server {
listen 80;
server_name mywebsite.com;
location / {
proxy_pass http://myapp5;
# 使用 proxy_next_upstream 指令定义故障转移策略
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
# 设置最大失败次数和超时时间
proxy_max_temp_file_size 0;
proxy_connect_timeout 5;
proxy_send_timeout 5;
proxy_read_timeout 5;
proxy_buffering off;
}
}
}
解释和说明:
-
在
upstream
块中定义了一个名为myapp5
的后端服务器组,其中包含了三个后端服务器。这是要负载均衡的服务器池。 -
在
server
块中,我们定义了一个虚拟主机,监听端口 80,该虚拟主机用于处理来自mywebsite.com
的请求。 -
在
location /
块中,我们配置了反向代理,将请求代理到名为myapp5
的后端服务器组。这是一个基本的反向代理配置。 -
🔄
proxy_next_upstream
指令定义了故障转移策略。根据这个配置,当发生以下情况之一时,Nginx 将尝试使用下一个可用的后端服务器:通信错误 (error)、连接或读取超时 (timeout)、后端服务器返回 HTTP 500、502、503 或 504 错误。 -
我们还设置了一些与代理相关的超时和缓冲参数,以确保在发生问题时有适当的超时和缓冲控制。这些设置可以根据实际需求进行调整。
总之,上述配置演示了如何在 Nginx 中使用 proxy_next_upstream
指令来定义故障转移策略。当一个请求到达时,Nginx 将尝试将其转发到 myapp5
中的服务器,并根据 proxy_next_upstream
指令定义的错误情况来决定是否尝试下一个服务器,从而实现负载均衡和故障转移的目标。
📊 Nginx TCP 和 UDP 负载平衡
🔍 关于 Nginx 的 TCP 和 UDP 负载均衡介绍
Nginx,作为一个高性能的 web 服务器和反向代理服务器,不仅仅局限于处理 HTTP 请求。从版本 1.9.0 开始,它还拓展了其功能,以支持四层的 TCP 和 UDP 负载均衡。
📘 核心模块的引入
- 📌
ngx_stream_core_module
模块:- 从 Nginx 1.9.0 版本开始,Nginx 引入了这个核心模块。
- 这个模块标志着 Nginx 进入了四层负载均衡的领域。
- 它使 Nginx 能够在更低的网络层面进行数据包的转发和负载均衡。
🌐 TCP 和 UDP 的支持
-
📌 TCP 转发和负载均衡:
- 该模块不仅支持 TCP 数据包的转发,还为其提供了负载均衡功能。
- 用户可以根据需要配置多个后端服务器,并基于不同的策略进行负载均衡。
-
📌 UDP 转发:
- 与 TCP 负载均衡类似,该模块也支持 UDP 数据包的转发。
- 它还同样支持
upstream
配置,为 UDP 流量提供负载均衡。
-
🚫 注意:
- 当使用 Nginx 进行 UDP 转发时,请求包会被转发到指定的目标服务器。
- 然而,返回的 UDP 包是由目标机器直接发送到客户端的,而不会再次经过 Nginx。
- 这意味着如果目标机器的 IP 被屏蔽或无法访问,客户端将无法接收到返回的 UDP 包。这并不是由 Nginx 引起的问题,而是 UDP 通信的固有特性。
🛠️ 手动编译并安装Nginx
- 下载 1.9版本 以上的 nginx:
wget http://nginx.org/download/nginx-1.20.2.tar.gz
- 安装依赖包:
yum install -y gcc glibc gcc-c++ prce-devel openssl-devel pcre-devel
useradd -s /sbin/nologin nginx -M
- 解压并编译:
tar xf nginx-1.20.2.tar.gz && cd nginx-1.20.2
- 手动编译并安装:
./configure \
--prefix=/usr/local/nginx-1.20.2 \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_stub_status_module \
--with-stream
- 检查配置文件:
/usr/local/nginx/sbin/nginx -t
💼 使用Nginx实现 TCP 反向代理
在处理HTTP请求的同时,Nginx还能够有效地处理TCP请求,为用户提供了一个功能强大的四层转发和负载均衡解决方案。
🧰 核心工具: stream
模块
- 📌 四层网络处理:
- Nginx 的
stream
模块专门处理四层的网络请求,即TCP和UDP请求。 - 它是Nginx TCP和UDP转发及负载均衡功能的核心。
- Nginx 的
📋 配置与使用
-
📜 日志格式:
- 使用
stream
模块,管理员可以定义自己的日志格式,捕获有关传入和传出流量的详细信息。
- 使用
-
📜 Upstream 配置:
upstream
配置允许用户定义后端服务器群组。- 用户可以基于不同的策略(如权重、IP哈希等)进行负载均衡。
-
📜 服务器监听设置:
- 使用
server
块,管理员可以定义监听的端口和相关的转发规则。 - 这确保了来自客户端的请求被正确地转发到后端服务器。
- 使用
-
📜 示例配置:
user nginx;
worker_processes 1;
events {
worker_connections 1024;
}
stream {
# 全局配置
preread_timeout 120s;
proxy_connect_timeout 120s;
proxy_protocol_timeout 120s;
resolver_timeout 120s;
proxy_timeout 120s;
tcp_nodelay on;
# 设置日志格式
log_format proxy '$remote_addr [$time_local] '
'$protocol $status $bytes_sent $bytes_received '
'$session_time "$upstream_addr" "$upstream_bytes_sent"'
'"$upstream_bytes_received" "$upstream_connect_time"';
access_log /var/log/nginx/stream.access.log proxy;
error_log /var/log/nginx/stream.error.log error;
upstream app_pg {
hash $remote_addr consistent;
server 192.168.100.60:5432;
server 192.168.100.61:5432;
server 192.168.100.62:5432;
}
server {
# 不指定协议默认是TCP协议
listen 127.0.0.1:5432 so_keepalive=on;
proxy_pass app_pg;
}
server{
listen *:3306 so_keepalive=30m::10;
proxy_connect_timeout 10s;
proxy_timeout 20s;
proxy_buffer_size 512k;
proxy_pass 192.168.100.60:8000;
}
}
-
日志格式: 这里定义了一个
proxy
日志格式,用于捕获有关传入和传出流量的详细信息。 -
Upstream 配置:
upstream
定义了后端服务器群组app_pg
。这个群组中有三个后端服务器,分别运行在192.168.100.60
,192.168.100.61
, 和192.168.100.62
上的5432
端口。 -
服务器监听设置: 定义了两个
server
块。- 第一个
server
块监听127.0.0.1
的5432
端口,并将流量代理到app_pg
upstream。 - 第二个
server
块监听所有接口的3306
端口,并将流量代理到192.168.100.60:8000
。
- 第一个
当然,让我为您提供一个关于如何使用 Nginx 实现 SSH 转发的详细示例,并进行解释。
🔑 Nginx实现 SSH 转发
SSH (安全外壳协议) 是一个加密的网络协议,用于在不安全的网络上安全地执行远程登录和其他网络服务。有时,出于安全或其他原因,我们可能需要将 SSH 服务的默认端口从 22 更改为其他端口。Nginx 的 stream
模块允许我们轻松地做到这一点,同时为 SSH 服务提供负载均衡。
🧰 核心工具: stream
模块
- 📌 四层网络处理:
- Nginx 的
stream
模块专门处理四层的网络请求。 - 它是 Nginx 的四层转发和负载均衡功能的核心。
- Nginx 的
📋 配置与使用
通过这个配置,Nginx 将作为一个 SSH 反向代理,将来自 2222
端口的流量转发到后端服务器的 22
端口。这样,您可以为 SSH 服务提供额外的安全性,同时保持后端 SSH 服务在其默认端口运行。
user nginx;
worker_processes 1;
events {
worker_connections 1024;
}
stream {
upstream ssh {
hash $remote_addr consistent;
server 192.168.1.42:22 weight=5;
}
server {
listen 2222;
proxy_pass ssh;
}
}
-
Upstream 配置:
upstream
定义了一个名为ssh
的后端服务器群组。这个群组中有一个后端服务器,运行在192.168.1.42
上的22
端口,并分配了一个权重为 5 的权值。 -
服务器监听设置: 定义了一个
server
块,该块监听所有接口的2222
端口,并将流量代理到ssh
upstream。
🌐 Nginx 实现 UDP 转发
Nginx 不仅可以处理 HTTP 和 TCP 请求,还可以处理 UDP 请求。从 Nginx 1.9.3 版本开始,其 stream
模块已支持 UDP 转发,这为 DNS 和其他基于 UDP 的服务提供了一个强大的代理和负载均衡解决方案。
🧰 核心工具: stream
模块
- 📌 四层网络处理:
- Nginx 的
stream
模块专门处理四层的网络请求。 - 它是 Nginx 的四层转发和负载均衡功能的核心。
- Nginx 的
📋 配置与使用
通过这个配置,Nginx 将作为一个 UDP 反向代理,特别是为 DNS 请求。这样,您可以为 DNS 服务提供负载均衡,同时保持后端 DNS 服务在其默认端口运行。
user nginx;
worker_processes 1;
events {
worker_connections 1024;
}
stream {
# 全局配置
proxy_timeout 120s;
tcp_nodelay on;
# 设置日志格式
log_format proxy '$remote_addr [$time_local] '
'$protocol $status $bytes_sent $bytes_received '
'$session_time "$upstream_addr" '
'"$upstream_bytes_sent" "$upstream_bytes_received" "$upstream_connect_time"';
access_log /var/log/nginx/stream.access.log proxy;
error_log /var/log/nginx/stream.error.log error;
# 配置dns负载均衡
upstream dns_upstreams {
server 1.1.1.1:53 weight=1;
server 1.0.0.1:53 weight=1; # weight负载均衡权重
server 8.8.8.8:53 weight=1 backup; # backup标记为备用服务器
}
server{
listen 53 udp;
proxy_responses 1; # UDP协议专用;期望后端返回给客户端数据包的数量
proxy_timeout 20s; # 超时时间
proxy_pass dns_upstreams;
}
}
-
日志格式: 这里定义了一个
proxy
日志格式,用于捕获有关传入和传出 UDP 流量的详细信息。 -
Upstream 配置:
upstream
定义了一个名为dns_upstreams
的后端服务器群组。这个群组中有三个 DNS 服务器,可为客户端提供域名解析服务。 -
服务器监听设置: 定义了一个
server
块,该块监听所有接口的53
端口(DNS 的默认端口),并将流量代理到dns_upstreams
upstream。
🔄 协议转换: HTTP 到 TCP 或 UDP
在微服务的环境中,可能存在一些服务不使用常规的 HTTP/HTTPS 协议,而是使用其他基于 TCP 或 UDP 的协议。在这种情况下,Nginx 可以作为一个桥梁,将 HTTP 请求转换为 TCP 或 UDP 请求。
🎯 为什么需要协议转换?
-
多样性的微服务 🌐:
- 在复杂的微服务架构中,不是所有的服务都使用 HTTP。例如,一个服务可能是一个旧的数据库,只支持特定的 TCP 协议,或者一个实时消息服务使用 UDP 协议。
-
统一入口点 🚪:
- 有一个统一的入口点(如 HTTP API 网关)能够简化客户端的交互。客户端只需要知道如何与 API 网关交互,而不需要了解背后的服务如何工作或它们使用哪种协议。
🛠️ 如何使用 Nginx 进行协议转换?
-
HTTP 代理 🌐:
- 客户端首先发出 HTTP 请求到 Nginx。
-
转换逻辑 🔀:
- Nginx 使用
stream
模块将 HTTP 请求转换为 TCP 或 UDP 请求。这可能涉及读取 HTTP 请求的一部分内容,然后创建一个新的非 HTTP 请求。
- Nginx 使用
-
与微服务通信 🔄:
- Nginx 将转换后的请求发送到后端微服务,并等待响应。
-
回到 HTTP 🌐:
- 一旦微服务响应,Nginx 再次将其转换回 HTTP 响应并发送回客户端。
🌟 示例应用场景
1️⃣ 数据库代理 🗄️:
场景描述:
客户端希望通过 HTTP API 查询一个只支持特定 TCP 协议的数据库。
实现过程:
http {
server {
listen 80;
location /api/query {
# 使用 ngx_http_js_module 或其他模块来处理 HTTP 请求,
# 转换为数据库可以理解的 TCP 格式
# 这里仅为示例,实际转换逻辑可能需要自定义脚本或模块
js_content my_custom_js_handler;
proxy_pass http://localhost:9000; # 假设转换后的请求被转发到一个本地代理,该代理再与数据库通信
}
}
}
stream {
server {
listen 9000;
proxy_pass database-server-ip:database-port; # 将请求转发到真实的数据库服务器
}
}
-
客户端发起请求: 客户端向 Nginx 发起一个 HTTP GET 请求,例如:
http://nginx-proxy/api/query?sql=SELECT * FROM users
. -
Nginx 接收请求: Nginx 使用
http
模块接收请求,并解析请求中的查询参数。 -
转换请求: Nginx 使用内部逻辑(可能是一个脚本或程序)将 HTTP 请求转换为数据库可以理解的 TCP 协议格式。
-
与数据库通信: Nginx 使用
stream
模块将转换后的 TCP 请求发送到数据库。 -
收到数据库响应: 一旦数据库处理请求并返回结果,Nginx 接收这些结果。
-
将结果转换为 HTTP 响应: Nginx 将数据库的 TCP 响应转换回 HTTP 格式,并将其发送回客户端。
2️⃣ 实时消息 ✉️:
场景描述:
客户端希望通过 HTTP API 发送一个实时消息,而该消息服务使用 UDP 协议。
实现过程:
http {
server {
listen 80;
location /api/send-message {
# 使用 ngx_http_js_module 或其他模块来处理 HTTP 请求,
# 转换为消息服务可以理解的 UDP 格式
# 这里仅为示例,实际转换逻辑可能需要自定义脚本或模块
js_content my_custom_js_udp_handler;
proxy_pass http://localhost:9100; # 假设转换后的请求被转发到一个本地代理,该代理再与消息服务通信
}
}
}
stream {
server {
listen 9100 udp;
proxy_pass message-service-ip:message-service-udp-port; # 将 UDP 数据包转发到真实的消息服务
}
}
-
客户端发起请求: 客户端向 Nginx 发起一个 HTTP POST 请求,例如:
http://nginx-proxy/api/send-message
,并在请求体中包含消息内容。 -
Nginx 接收请求: Nginx 使用
http
模块接收请求,并解析请求体中的消息内容。 -
转换请求: Nginx 使用内部逻辑(可能是一个脚本或程序)将 HTTP 请求转换为消息服务可以理解的 UDP 数据包格式。
-
发送 UDP 数据包: Nginx 使用
stream
模块将转换后的 UDP 数据包发送到实时消息服务。 -
收到消息服务响应: 消息服务处理数据包并发送一个确认回来。
-
将响应转换为 HTTP 响应: Nginx 将消息服务的 UDP 响应转换为 HTTP 格式,并通知客户端消息已成功发送。