nginx 模块目录
nginx 全指令目录
ngx_stream_core_module:流核心模块,提供了处理TCP和UDP流量的基本功能。它允许Nginx作为TCP/UDP代理服务器,管理和转发网络连接。常用的指令包括 server
块用于定义监听的端口和后端服务器。
ngx_stream_access_module:访问控制模块,基于IP地址或网络段来限制对TCP/UDP服务的访问。通过 allow
和 deny
指令,可以指定允许或拒绝哪些客户端访问特定的服务。
ngx_stream_geo_module:地理定位模块,允许根据客户端IP地址定义变量。它可以用于基于地理位置的访问控制或日志记录等场景,类似于HTTP模块中的 ngx_http_geo_module
。
ngx_stream_geoip_module:GeoIP支持模块,扩展了 ngx_stream_geo_module
的功能,通过MaxMind的GeoIP数据库识别客户端的地理位置信息(如国家、城市等)。这有助于实现更精确的访问控制和日志分析。
ngx_stream_js_module:JavaScript支持模块,允许在Nginx配置中使用JavaScript编写脚本。这对于处理复杂的TCP/UDP流量逻辑非常有用,例如动态路由、访问控制等。
ngx_stream_keyval_module:键值对变量模块,提供了一种机制来存储和检索键值对数据。可以在不同的请求之间共享状态信息,适用于需要跨请求维护状态的应用场景,如会话管理或用户跟踪。
ngx_stream_limit_conn_module:连接限制模块,允许根据定义的条件(如IP地址)限制并发连接数。这对于防止资源耗尽攻击(如SYN Flood攻击)非常有用,通过设置合理的连接数上限,保护服务器免受过度负载的影响。
ngx_stream_log_module:日志记录模块,负责记录TCP/UDP请求的各种信息到日志文件中。通过自定义日志格式,可以记录诸如客户端IP、连接时间、协议类型等信息,这对于监控和调试非常重要。
ngx_stream_map_module:映射模块,可以根据输入变量创建新的变量。常用于条件判断和变量转换,例如将客户端IP地址映射为地理位置信息,或者基于某些条件设置响应头。这种灵活性有助于实现复杂的行为逻辑。
ngx_stream_mqtt_preread_module:MQTT预读模块,允许在不终止连接的情况下读取MQTT协议的消息头部信息。这对于需要在建立完整连接之前进行消息过滤或认证的场景非常有用。
ngx_stream_mqtt_filter_module:MQTT过滤模块,提供了对MQTT协议消息的高级处理能力。可以用于消息路由、内容过滤、协议转换等操作,使得Nginx能够作为MQTT消息代理使用。
ngx_stream_core_module 是 Nginx 的一个模块,用于处理基于 TCP 和 UDP 协议的流量。它允许你配置反向代理、负载均衡和会话持久化等功能,不仅限于 HTTP 流量,还可以应用于其他协议,如数据库连接、邮件服务器等。
主要功能
常用指令
以下是与 ngx_stream_core_module
模块相关的常用配置指令及其简要说明:
stream
:定义流上下文,包含所有 TCP/UDP 相关的配置。
upstream
:定义一组后端服务器,支持负载均衡和健康检查。
server
:定义监听的地址和端口,并指定如何处理接收到的流量。
proxy_pass
:指定后端服务器或上游服务器组。
hash
:基于哈希值进行会话持久化。
least_conn
:使用最少连接算法进行负载均衡。
health_check
:启用健康检查,监控后端服务器的状态。
使用示例
以下是一些具体的配置示例,展示如何利用 ngx_stream_core_module
来实现各种功能。
基本配置 - TCP 代理
假设你想将所有到达 192.168.1.1:12345
的 TCP 流量代理到后端服务器组:
stream {
upstream backend_servers {
server backend1.example.com:12345;
server backend2.example.com:12345;
}
server {
listen 12345;
proxy_pass backend_servers;
}
}
在这个例子中:
upstream backend_servers { ... }
定义了一个后端服务器组,包含两台服务器。server { ... }
定义了一个监听在 12345
端口的服务,所有到达该端口的流量会被代理到 backend_servers
组中的服务器。配置 - 负载均衡
你可以使用不同的负载均衡算法来分配流量。例如,使用最少连接算法:
stream {
upstream backend_servers {
least_conn; # 使用最少连接算法
server backend1.example.com:12345;
server backend2.example.com:12345;
}
server {
listen 12345;
proxy_pass backend_servers;
}
}
在这个例子中:
least_conn;
启用了最少连接算法,Nginx 会将新请求分配给当前连接数最少的服务器。配置 - 会话持久化
为了确保同一客户端的请求总是被分配到同一个后端服务器,可以使用 IP 哈希算法:
stream {
upstream backend_servers {
hash $remote_addr consistent; # 使用 IP 哈希算法
server backend1.example.com:12345;
server backend2.example.com:12345;
}
server {
listen 12345;
proxy_pass backend_servers;
}
}
在这个例子中:
hash $remote_addr consistent;
使用客户端 IP 地址进行哈希计算,确保同一客户端的请求总是被分配到同一个后端服务器。配置 - UDP 代理
除了 TCP 代理,ngx_stream_core_module
还支持 UDP 流量的代理。例如,将 DNS 请求代理到多个 DNS 服务器:
stream {
upstream dns_servers {
server dns1.example.com:53;
server dns2.example.com:53;
}
server {
listen 53 udp;
proxy_pass dns_servers;
proxy_timeout 200ms;
proxy_responses 1;
}
}
在这个例子中:
listen 53 udp;
表示监听在 53
端口上的 UDP 流量。proxy_timeout 200ms;
设置了代理超时时间为 200 毫秒。proxy_responses 1;
表示每个请求只需要一个响应。配置 - 健康检查
为了确保后端服务器的可用性,可以启用健康检查:
stream {
upstream backend_servers {
server backend1.example.com:12345;
server backend2.example.com:12345;
health_check interval=10 fails=3 passes=2; # 启用健康检查
}
server {
listen 12345;
proxy_pass backend_servers;
}
}
在这个例子中:
health_check interval=10 fails=3 passes=2;
启用了健康检查,默认情况下每 10 秒检查一次,连续失败 3 次即认为服务器不可用,连续成功 2 次即认为服务器恢复可用。注意事项
性能考虑:
安全性:
日志记录:
preread_buffer_size 指令用于设置在处理 TCP/UDP 连接时预先读取数据的缓冲区大小。这有助于优化数据预读取性能。
Syntax: preread_buffer_size size;
Default: preread_buffer_size 16k;
Context: stream, server
This directive appeared in version 1.11.5.
size
:预先读取数据的缓冲区大小,默认为 16 KB。案例
基本用法
最简单的 preread_buffer_size
用法是指定缓冲区大小:
stream {
upstream backend {
server 192.168.1.1:12345;
}
server {
listen 12345;
proxy_pass backend;
# 设置预读取缓冲区大小为 32 KB
preread_buffer_size 32k;
}
}
在这个例子中:
backend
的连接时,将使用 32 KB 的缓冲区来预先读取数据。注意事项
preread_timeout 指令用于设置在处理 TCP/UDP 连接时预先读取数据的超时时间。这有助于防止长时间等待导致的性能问题。
Syntax: preread_timeout timeout;
Default: preread_timeout 30s;
Context: stream, server
This directive appeared in version 1.11.5.
timeout
:预先读取数据的超时时间,默认为 30 秒。案例
基本用法
最简单的 preread_timeout
用法是指定超时时间:
stream {
upstream backend {
server 192.168.1.1:12345;
}
server {
listen 12345;
proxy_pass backend;
# 设置预读取超时时间为 15 秒
preread_timeout 15s;
}
}
在这个例子中:
backend
的连接时,如果在 15 秒内未能完成数据的预先读取,将会超时并返回错误。注意事项
proxy_protocol_timeout 指令用于设置处理 PROXY 协议头信息的超时时间。PROXY 协议用于在 TCP 连接上传输客户端的真实 IP 地址等信息。
Syntax: proxy_protocol_timeout timeout;
Default: proxy_protocol_timeout 30s;
Context: stream, server
This directive appeared in version 1.11.4.
timeout
:处理 PROXY 协议头信息的超时时间,默认为 30 秒。案例
基本用法
最简单的 proxy_protocol_timeout
用法是指定超时时间:
stream {
upstream backend {
server 192.168.1.1:12345;
}
server {
listen 12345 proxy_protocol;
proxy_pass backend;
# 设置处理 PROXY 协议头信息的超时时间为 20 秒
proxy_protocol_timeout 20s;
}
}
在这个例子中:
backend
的连接时,如果在 20 秒内未能完成 PROXY 协议头信息的处理,将会超时并返回错误。注意事项
stream 指令块用于定义处理 TCP 和 UDP 流量的配置。Nginx 可以作为反向代理或负载均衡器来处理这些流量。
Syntax: stream { ... }
Default: —
Context: main
案例
基本用法
一个典型的 stream
配置示例如下:
stream {
upstream backend_tcp {
server 192.168.1.1:12345;
server 192.168.1.2:12345;
}
upstream backend_udp {
server 192.168.1.1:54321;
server 192.168.1.2:54321;
}
server {
listen 12345;
proxy_pass backend_tcp;
# 设置预读取缓冲区大小为 32 KB
preread_buffer_size 32k;
# 设置预读取超时时间为 15 秒
preread_timeout 15s;
# 设置处理 PROXY 协议头信息的超时时间为 20 秒
proxy_protocol_timeout 20s;
}
server {
listen 54321 udp;
proxy_pass backend_udp;
# 设置预读取缓冲区大小为 64 KB
preread_buffer_size 64k;
# 设置预读取超时时间为 10 秒
preread_timeout 10s;
# 设置处理 PROXY 协议头信息的超时时间为 25 秒
proxy_protocol_timeout 25s;
}
}
在这个例子中:
backend_tcp
和 backend_udp
,分别处理 TCP 和 UDP 流量。backend_tcp
。backend_udp
。注意事项
ngx_stream_access_module 是 Nginx 的一个模块,用于在流(stream)上下文中实现访问控制。这个模块允许你基于客户端的 IP 地址、网络或特定的地址范围来允许或拒绝连接请求。它通常用于 TCP 和 UDP 代理服务中,以增强安全性。
主要功能
使用示例
以下是一些简化的配置示例,展示了如何使用 ngx_stream_access_module
来实现访问控制。
基本访问控制
假设你希望仅允许来自 192.168.1.0/24
网络段的客户端连接到你的 TCP 服务:
stream {
upstream backend {
server backend.example.com:12345;
}
server {
listen 12345;
proxy_pass backend;
# 允许 192.168.1.0/24 网络段的客户端
allow 192.168.1.0/24;
# 拒绝所有其他客户端
deny all;
}
}
在这个例子中:
allow 192.168.1.0/24;
允许来自 192.168.1.0/24
网络段的所有客户端连接。deny all;
拒绝所有其他客户端的连接。多段网络访问控制
假设你希望允许来自多个网络段的客户端连接,并拒绝其他所有客户端:
stream {
upstream backend {
server backend.example.com:12345;
}
server {
listen 12345;
proxy_pass backend;
# 允许多个网络段的客户端
allow 192.168.1.0/24;
allow 10.0.0.0/8;
# 拒绝所有其他客户端
deny all;
}
}
在这个例子中:
allow 192.168.1.0/24;
和 allow 10.0.0.0/8;
允许来自这两个网络段的所有客户端连接。deny all;
拒绝所有其他客户端的连接。允许单个 IP 地址
假设你希望仅允许某个特定 IP 地址的客户端连接:
stream {
upstream backend {
server backend.example.com:12345;
}
server {
listen 12345;
proxy_pass backend;
# 允许单个 IP 地址
allow 192.168.1.100;
# 拒绝所有其他客户端
deny all;
}
}
在这个例子中:
allow 192.168.1.100;
允许来自 192.168.1.100
这个特定 IP 地址的客户端连接。deny all;
拒绝所有其他客户端的连接。注意事项
顺序优先:allow
和 deny
规则按照配置文件中的顺序进行处理。一旦匹配到一条规则,后续规则将不再处理。因此,确保规则的顺序正确非常重要。
性能影响:虽然访问控制规则对性能的影响较小,但在高并发环境中,仍然需要注意避免过多复杂的规则导致性能下降。
安全性:确保只允许可信的 IP 地址或网络段连接到你的服务。不要随意开放访问权限,尤其是在暴露于互联网的服务上。
日志记录:为了方便调试和监控,建议启用详细的日志记录,特别是在配置访问控制时。
error_log /var/log/nginx/error.log warn;
access_log /var/log/nginx/access.log main;
ngx_stream_geo_module 是 Nginx 的一个模块,用于在流(stream)上下文中根据客户端的 IP 地址进行地理定位。这个模块允许你基于客户端的地理位置信息来设置变量,并在后续处理中使用这些变量,例如路由、访问控制和日志记录等。
主要功能
使用示例
以下是一些具体的配置示例,展示了如何使用 ngx_stream_geo_module
来根据客户端的 IP 地址设置变量。
基本配置
假设你想根据客户端的 IP 地址设置一个变量 $geo_var
,并将其用于后续处理:
stream {
# 定义地理定位块
geo $geo_var {
default unknown;
192.168.1.0/24 internal_network;
203.0.113.5 specific_client;
}
server {
listen 12345;
proxy_pass backend_server;
# 根据地理定位变量设置不同的代理服务器
if ($geo_var = internal_network) {
proxy_pass backend_internal;
}
if ($geo_var = specific_client) {
proxy_pass backend_special;
}
}
}
在这个例子中:
geo $geo_var { ... }
定义了一个地理定位块,设置了默认值和特定 IP 范围及单个 IP 地址的值。server
块中,根据 $geo_var
的值选择不同的后端服务器进行代理。包含外部地理数据文件
你可以将地理数据存储在一个单独的文件中,并通过 include
指令加载这些数据:
stream {
# 定义地理定位块
geo $geo_var {
default unknown;
include /etc/nginx/geo_data.txt;
}
server {
listen 12345;
proxy_pass backend_server;
# 根据地理定位变量设置不同的代理服务器
if ($geo_var = internal_network) {
proxy_pass backend_internal;
}
if ($geo_var = specific_client) {
proxy_pass backend_special;
}
}
}
其中 /etc/nginx/geo_data.txt
文件的内容可能如下:
192.168.1.0/24 internal_network;
203.0.113.5 specific_client;
结合负载均衡
假设你的应用部署在多个后端服务器上,并希望通过地理定位来选择合适的后端服务器:
stream {
upstream backend_usa {
server backend_usa_1.example.com;
server backend_usa_2.example.com;
}
upstream backend_eu {
server backend_eu_1.example.com;
server backend_eu_2.example.com;
}
# 定义地理定位块
geo $geo_var {
default eu;
include /etc/nginx/geo_data.txt;
}
server {
listen 12345;
# 根据地理定位变量选择不同的上游服务器组
if ($geo_var = usa) {
proxy_pass backend_usa;
}
if ($geo_var = eu) {
proxy_pass backend_eu;
}
}
}
在这个例子中:
upstream backend_usa { ... }
和 upstream backend_eu { ... }
定义了两个不同的上游服务器组。geo $geo_var { ... }
根据客户端的 IP 地址设置变量 $geo_var
。server
块中,根据 $geo_var
的值选择不同的上游服务器组进行代理。注意事项
ngx_stream_geoip_module 是 Nginx 的一个模块,用于在处理 TCP 和 UDP 流量时根据客户端的 IP 地址进行地理定位。这个模块依赖于 MaxMind 的 GeoIP 数据库,可以用来实现基于地理位置的流量控制、访问限制和日志记录等功能。
主要功能
常用指令
以下是与 ngx_stream_geoip_module
模块相关的常用配置指令及其简要说明:
geoip_country
:加载指定的 GeoIP 国家数据库文件。
geoip_city
:加载指定的 GeoIP 城市数据库文件。
$geoip_country_code
:客户端所在国家的 ISO 3166-1 两位字母代码。
$geoip_country_name
:客户端所在国家的名称。
$geoip_city_country_code
:客户端所在城市的国家代码(当使用城市数据库时)。
$geoip_city_country_name
:客户端所在城市的国家名称(当使用城市数据库时)。
$geoip_city
:客户端所在城市的名称(当使用城市数据库时)。
$geoip_latitude
和 $geoip_longitude
:客户端的地理坐标(当使用城市数据库时)。
使用示例
以下是一些具体的配置示例,展示如何利用 ngx_stream_geoip_module
来实现基于地理位置的功能。
基本配置 - 加载 GeoIP 数据库
首先,你需要下载并加载 MaxMind 的 GeoIP 数据库文件。可以从 MaxMind 下载免费版本的 GeoLite2 数据库。
假设你已经下载了 GeoLite2-Country.mmdb 和 GeoLite2-City.mmdb 文件,并将其放置在 /etc/nginx/geoip/
目录下。
stream {
# 加载 GeoIP 国家数据库
geoip_country /etc/nginx/geoip/GeoLite2-Country.mmdb;
# 加载 GeoIP 城市数据库
geoip_city /etc/nginx/geoip/GeoLite2-City.mmdb;
upstream backend_servers {
server backend1.example.com:12345;
server backend2.example.com:12345;
}
server {
listen 12345;
# 根据客户端 IP 地址获取地理位置信息
set $country_code $geoip_country_code;
set $country_name $geoip_country_name;
set $city_name $geoip_city;
set $latitude $geoip_latitude;
set $longitude $geoip_longitude;
proxy_pass backend_servers;
# 记录地理位置信息到日志
access_log /var/log/nginx/access.log combined_geoip;
}
}
在这个例子中:
geoip_country /etc/nginx/geoip/GeoLite2-Country.mmdb;
加载了国家级别的 GeoIP 数据库。geoip_city /etc/nginx/geoip/GeoLite2-City.mmdb;
加载了城市级别的 GeoIP 数据库。set $country_code $geoip_country_code;
等语句将地理位置信息存储在变量中,供后续使用。access_log /var/log/nginx/access.log combined_geoip;
将地理位置信息记录到日志中。配置 - 基于地理位置的流量控制
假设你想根据客户端的地理位置来控制流量,例如禁止某些国家的用户访问:
stream {
geoip_country /etc/nginx/geoip/GeoLite2-Country.mmdb;
upstream backend_servers {
server backend1.example.com:12345;
server backend2.example.com:12345;
}
map $geoip_country_code $allowed_country {
default yes;
CN no; # 禁止中国(CN)的用户访问
RU no; # 禁止俄罗斯(RU)的用户访问
}
server {
listen 12345;
if ($allowed_country = no) {
return 403; # 如果不允许访问,返回 403 错误
}
proxy_pass backend_servers;
}
}
在这个例子中:
map $geoip_country_code $allowed_country { ... }
定义了一个映射,根据国家代码设置 $allowed_country
变量的值。if ($allowed_country = no)
检查 $allowed_country
变量的值,如果为 no
则返回 403 错误。配置 - 日志记录地理位置信息
你可以通过自定义日志格式将地理位置信息记录到日志中,以便后续分析:
stream {
geoip_country /etc/nginx/geoip/GeoLite2-Country.mmdb;
geoip_city /etc/nginx/geoip/GeoLite2-City.mmdb;
upstream backend_servers {
server backend1.example.com:12345;
server backend2.example.com:12345;
}
log_format combined_geoip '$remote_addr [$time_local] '
'"$protocol" $status $bytes_sent $bytes_received '
'$session_time "$upstream_addr" '
'"$geoip_country_code" "$geoip_city"';
server {
listen 12345;
proxy_pass backend_servers;
access_log /var/log/nginx/access.log combined_geoip;
}
}
在这个例子中:
log_format combined_geoip ...
定义了一个新的日志格式 combined_geoip
,其中包括地理位置信息。access_log /var/log/nginx/access.log combined_geoip;
使用自定义的日志格式记录日志。注意事项
数据库更新:
性能考虑:
安全性:
日志记录:
ngx_stream_js_module 是 Nginx 的一个模块,允许你在流(stream)上下文中使用 JavaScript 脚本来处理 TCP 和 UDP 连接。这个模块扩展了 Nginx 的功能,使你能够编写复杂的逻辑来控制连接的行为,例如访问控制、负载均衡决策、日志记录等。
主要功能
remoteAddr
, protocol
, serverPort
, clientPort
等,用于处理连接的不同阶段。使用示例
以下是一些简化的配置示例,展示了如何使用 ngx_stream_js_module
来实现不同的功能。
基本访问控制
假设你希望根据客户端 IP 地址来决定是否允许连接:
stream {
js_include /etc/nginx/scripts/access_control.js;
upstream backend {
server backend.example.com:12345;
}
server {
listen 12345;
proxy_pass backend;
js_on_access allow_connect;
}
}
对应的 access_control.js
文件内容:
function allow_connect(session) {
var clientIp = session.remoteAddress;
if (clientIp.startsWith('192.168.1.')) {
session.log("Allowing connection from " + clientIp);
return ngx.OK;
} else {
session.log("Denying connection from " + clientIp);
return ngx.DENY;
}
}
在这个例子中:
js_include
指令包含了外部的 JavaScript 文件 /etc/nginx/scripts/access_control.js
。js_on_access allow_connect;
指定了在连接建立时调用 allow_connect
函数。allow_connect
函数根据客户端 IP 地址决定是否允许连接。日志记录
假设你希望记录每个连接的详细信息:
stream {
js_include /etc/nginx/scripts/log_connections.js;
upstream backend {
server backend.example.com:12345;
}
server {
listen 12345;
proxy_pass backend;
js_on_access log_connection;
}
}
对应的 log_connections.js
文件内容:
function log_connection(session) {
var clientIp = session.remoteAddress;
var serverIp = session.serverAddr;
var clientPort = session.clientPort;
var serverPort = session.serverPort;
session.log("Connection from " + clientIp + ":" + clientPort + " to " + serverIp + ":" + serverPort);
return ngx.OK;
}
在这个例子中:
log_connection
函数记录每个连接的源 IP 地址、源端口、目标 IP 地址和目标端口。负载均衡决策
假设你希望通过 JavaScript 实现自定义的负载均衡策略:
stream {
js_include /etc/nginx/scripts/load_balancer.js;
upstream backend {
server backend1.example.com:12345;
server backend2.example.com:12345;
server backend3.example.com:12345;
}
server {
listen 12345;
proxy_pass backend;
js_on_access choose_backend;
}
}
对应的 load_balancer.js
文件内容:
function choose_backend(session) {
var clientIp = session.remoteAddress;
var hash = ngx.hash(clientIp);
// 根据哈希值选择后端服务器
var backendIndex = hash % 3;
session.backend = backendIndex;
session.log("Selected backend index: " + backendIndex);
return ngx.OK;
}
在这个例子中:
choose_backend
函数根据客户端 IP 地址计算哈希值,并根据哈希值选择后端服务器。数据过滤
假设你希望通过 JavaScript 对传输的数据进行过滤或修改:
stream {
js_include /etc/nginx/scripts/data_filter.js;
upstream backend {
server backend.example.com:12345;
}
server {
listen 12345;
proxy_pass backend;
js_filter modify_data;
}
}
对应的 data_filter.js
文件内容:
function modify_data(data, flags) {
var modifiedData = data.replace(/old_string/g, "new_string");
// 如果需要终止连接
// return ngx.STOP;
return modifiedData;
}
在这个例子中:
modify_data
函数对传输的数据进行字符串替换操作。注意事项
性能影响:虽然 JavaScript 提供了强大的灵活性,但在高并发环境中,JavaScript 脚本可能会成为性能瓶颈。尽量保持脚本简洁高效,避免复杂的计算和不必要的循环。
调试与测试:在生产环境中部署前,务必进行充分的测试,确保 JavaScript 脚本按预期工作。可以使用工具如 curl
或其他网络工具来模拟连接请求。
curl -v telnet://example.com:12345
安全性:确保 JavaScript 脚本不会暴露敏感信息或被恶意利用。例如,避免直接输出未经处理的日志信息,以免泄露内部细节。
错误处理:在 JavaScript 脚本中添加适当的错误处理机制,以防止意外情况导致服务中断。
js_access 用于在 Nginx 的流(stream)模块中定义一个 JavaScript 函数或模块函数,该函数将在访问控制阶段执行。这允许你通过自定义逻辑来决定是否允许连接。
Syntax: js_access function | module.function;
Default: —
Context: stream, server
function
:指定要调用的 JavaScript 函数。module.function
:指定要调用的 JavaScript 模块中的函数。案例
基本用法
最简单的 js_access
用法是指定一个 JavaScript 函数来进行访问控制:
stream {
js_include /etc/nginx/scripts/access_control.js;
server {
listen 12345;
js_access allow_connection; # 调用名为 'allow_connection' 的 JavaScript 函数
}
}
在这个例子中,假设 /etc/nginx/scripts/access_control.js
文件包含以下内容:
function allow_connection(req) {
// 简单的访问控制逻辑示例
if (req.remoteAddress === '192.168.1.100') {
return ngx.HTTP_OK;
} else {
return ngx.HTTP_FORBIDDEN;
}
}
使用模块函数
根据实际需求使用模块中的函数:
stream {
js_include /etc/nginx/scripts/module.js;
server {
listen 12345;
js_access myModule.checkAccess; # 调用模块 'myModule' 中的 'checkAccess' 函数
}
}
在这个例子中,假设 /etc/nginx/scripts/module.js
文件包含以下内容:
var myModule = {
checkAccess: function(req) {
// 更复杂的访问控制逻辑示例
if (req.remoteAddress.startsWith('192.168')) {
return ngx.HTTP_OK;
} else {
return ngx.HTTP_FORBIDDEN;
}
}
};
注意事项
js_filter 用于在 Nginx 的流(stream)模块中定义一个 JavaScript 函数或模块函数,该函数将在数据过滤阶段执行。这允许你对传输的数据进行处理和修改。
Syntax: js_filter function | module.function;
Default: —
Context: stream, server
function
:指定要调用的 JavaScript 函数。module.function
:指定要调用的 JavaScript 模块中的函数。案例
基本用法
最简单的 js_filter
用法是指定一个 JavaScript 函数来进行数据过滤:
stream {
js_include /etc/nginx/scripts/data_filter.js;
server {
listen 12345;
js_filter modify_data; # 调用名为 'modify_data' 的 JavaScript 函数
}
}
在这个例子中,假设 /etc/nginx/scripts/data_filter.js
文件包含以下内容:
function modify_data(data) {
// 简单的数据过滤逻辑示例
return data.replace(/badword/g, 'goodword');
}
使用模块函数
根据实际需求使用模块中的函数:
stream {
js_include /etc/nginx/scripts/module.js;
server {
listen 12345;
js_filter myModule.filterData; # 调用模块 'myModule' 中的 'filterData' 函数
}
}
在这个例子中,假设 /etc/nginx/scripts/module.js
文件包含以下内容:
var myModule = {
filterData: function(data) {
// 更复杂的数据过滤逻辑示例
return data.replace(/[^\w\s]/g, '');
}
};
注意事项
js_preread 用于在 Nginx 的流(stream)模块中定义一个 JavaScript 函数或模块函数,该函数将在预读阶段执行。这允许你在处理请求之前对数据进行预处理。
Syntax: js_preread function | module.function;
Default: —
Context: stream, server
function
:指定要调用的 JavaScript 函数。module.function
:指定要调用的 JavaScript 模块中的函数。案例
基本用法
最简单的 js_preread
用法是指定一个 JavaScript 函数来进行预读处理:
stream {
js_include /etc/nginx/scripts/preread.js;
server {
listen 12345;
js_preread preprocess_data; # 调用名为 'preprocess_data' 的 JavaScript 函数
}
}
在这个例子中,假设 /etc/nginx/scripts/preread.js
文件包含以下内容:
function preprocess_data(data) {
// 简单的预读处理逻辑示例
return data.toUpperCase();
}
使用模块函数
根据实际需求使用模块中的函数:
stream {
js_include /etc/nginx/scripts/module.js;
server {
listen 12345;
js_preread myModule.preRead; # 调用模块 'myModule' 中的 'preRead' 函数
}
}
在这个例子中,假设 /etc/nginx/scripts/module.js
文件包含以下内容:
var myModule = {
preRead: function(data) {
// 更复杂的预读处理逻辑示例
return JSON.stringify(JSON.parse(data));
}
};
注意事项
ngx_stream_keyval_module 是 Nginx 的一个模块,用于在流(stream)上下文中根据键值对(key-value pairs)来设置变量。这个模块允许你基于特定的键值对条件动态地设置变量,并在后续处理中使用这些变量,例如路由、访问控制和日志记录等。
主要功能
使用示例
以下是一些具体的配置示例,展示了如何使用 ngx_stream_keyval_module
来根据键值对设置变量。
基本配置
假设你想根据客户端的 IP 地址设置一个变量 $client_type
,并将其用于后续处理:
stream {
# 定义键值对映射
keyval $client_type $remote_addr {
192.168.1.10 trusted;
203.0.113.5 untrusted;
}
server {
listen 12345;
proxy_pass backend_server;
# 根据键值对变量设置不同的代理服务器
if ($client_type = trusted) {
proxy_pass trusted_backend;
}
if ($client_type = untrusted) {
proxy_pass untrusted_backend;
}
}
}
在这个例子中:
keyval $client_type $remote_addr { ... }
定义了一个键值对映射,设置了默认值和特定 IP 地址的值。server
块中,根据 $client_type
的值选择不同的后端服务器进行代理。包含外部键值对数据文件
你可以将键值对数据存储在一个单独的文件中,并通过 include
指令加载这些数据:
stream {
# 定义键值对映射
keyval $client_type $remote_addr {
include /etc/nginx/keyval_data.txt;
}
server {
listen 12345;
proxy_pass backend_server;
# 根据键值对变量设置不同的代理服务器
if ($client_type = trusted) {
proxy_pass trusted_backend;
}
if ($client_type = untrusted) {
proxy_pass untrusted_backend;
}
}
}
其中 /etc/nginx/keyval_data.txt
文件的内容可能如下:
192.168.1.10 trusted;
203.0.113.5 untrusted;
结合负载均衡
假设你的应用部署在多个后端服务器上,并希望通过键值对来选择合适的后端服务器:
stream {
upstream trusted_backend {
server backend_trusted_1.example.com;
server backend_trusted_2.example.com;
}
upstream untrusted_backend {
server backend_untrusted_1.example.com;
server backend_untrusted_2.example.com;
}
# 定义键值对映射
keyval $client_type $remote_addr {
default untrusted;
include /etc/nginx/keyval_data.txt;
}
server {
listen 12345;
# 根据键值对变量选择不同的上游服务器组
if ($client_type = trusted) {
proxy_pass trusted_backend;
}
if ($client_type = untrusted) {
proxy_pass untrusted_backend;
}
}
}
在这个例子中:
upstream trusted_backend { ... }
和 upstream untrusted_backend { ... }
定义了两个不同的上游服务器组。keyval $client_type $remote_addr { ... }
根据客户端的 IP 地址设置变量 $client_type
。server
块中,根据 $client_type
的值选择不同的上游服务器组进行代理。注意事项
keyval_zone
指令来定义共享内存区域,从而提高查找效率。ngx_stream_limit_conn_module 是 Nginx 的一个模块,用于限制每个定义的键(如客户端 IP 地址)的并发连接数。这个模块可以帮助你控制资源使用,防止过载,并保护你的服务器免受拒绝服务(DoS)攻击。
主要功能
常用指令
以下是与 ngx_stream_limit_conn_module
模块相关的常用配置指令及其简要说明:
limit_conn_zone
:定义用于存储状态信息的共享内存区,并指定使用的键。
limit_conn
:设置最大允许的并发连接数。
limit_conn_status
:设置当超过连接限制时返回的状态码(默认是 503 Service Unavailable
)。
$variable
:用于生成键的变量,例如 $remote_addr
(客户端 IP 地址)、$binary_remote_addr
(二进制格式的客户端 IP 地址)等。
使用示例
以下是一些具体的配置示例,展示如何利用 ngx_stream_limit_conn_module
来实现并发连接限制。
基本配置 - 限制每个客户端 IP 的并发连接数
假设你想限制每个客户端 IP 地址最多只能有 10 个并发连接:
stream {
# 定义共享内存区,使用 $binary_remote_addr 作为键
limit_conn_zone $binary_remote_addr zone=per_ip:10m;
upstream backend_servers {
server backend1.example.com:12345;
server backend2.example.com:12345;
}
server {
listen 12345;
# 设置每个客户端 IP 地址的最大并发连接数为 10
limit_conn per_ip 10;
proxy_pass backend_servers;
}
}
在这个例子中:
limit_conn_zone $binary_remote_addr zone=per_ip:10m;
定义了一个名为 per_ip
的共享内存区,大小为 10MB,使用二进制格式的客户端 IP 地址作为键。limit_conn per_ip 10;
设置了每个客户端 IP 地址的最大并发连接数为 10。配置 - 限制每个源地址段的并发连接数
如果你想根据 IP 地址段而不是单个 IP 地址进行限制,可以使用 map
指令来定义键:
stream {
# 使用 map 指令定义键,按 C 类子网划分
map $binary_remote_addr $subnet_key {
192.168.1.0/24 192.168.1;
192.168.2.0/24 192.168.2;
default other;
}
# 定义共享内存区,使用 $subnet_key 作为键
limit_conn_zone $subnet_key zone=subnet:10m;
upstream backend_servers {
server backend1.example.com:12345;
server backend2.example.com:12345;
}
server {
listen 12345;
# 设置每个 C 类子网的最大并发连接数为 50
limit_conn subnet 50;
proxy_pass backend_servers;
}
}
在这个例子中:
map $binary_remote_addr $subnet_key { ... }
使用 map
指令将 IP 地址映射到不同的键值,这里按照 C 类子网划分。limit_conn_zone $subnet_key zone=subnet:10m;
定义了一个名为 subnet
的共享内存区,使用 $subnet_key
作为键。limit_conn subnet 50;
设置了每个 C 类子网的最大并发连接数为 50。配置 - 自定义超过限制时的响应
你可以自定义当超过连接限制时返回的状态码和响应内容:
stream {
# 定义共享内存区,使用 $binary_remote_addr 作为键
limit_conn_zone $binary_remote_addr zone=per_ip:10m;
upstream backend_servers {
server backend1.example.com:12345;
server backend2.example.com:12345;
}
server {
listen 12345;
# 设置每个客户端 IP 地址的最大并发连接数为 10
limit_conn per_ip 10;
# 自定义超过限制时返回的状态码
limit_conn_status 429; # 返回 429 Too Many Requests
proxy_pass backend_servers;
}
}
在这个例子中:
limit_conn_status 429;
设置了当超过连接限制时返回的状态码为 429 Too Many Requests
。配置 - 组合多个条件
你可以组合多个条件来进一步细化连接限制策略。例如,根据不同的条件执行不同的操作:
stream {
# 定义共享内存区,使用 $binary_remote_addr 作为键
limit_conn_zone $binary_remote_addr zone=per_ip:10m;
limit_conn_zone $server_name zone=per_server:10m;
upstream backend_servers {
server backend1.example.com:12345;
server backend2.example.com:12345;
}
server {
listen 12345;
server_name example.com;
# 设置每个客户端 IP 地址的最大并发连接数为 10
limit_conn per_ip 10;
# 设置每个服务器名称的最大并发连接数为 100
limit_conn per_server 100;
proxy_pass backend_servers;
}
}
在这个例子中:
limit_conn_zone $binary_remote_addr zone=per_ip:10m;
和 limit_conn_zone $server_name zone=per_server:10m;
分别定义了两个共享内存区,分别基于客户端 IP 地址和服务器名称。limit_conn per_ip 10;
和 limit_conn per_server 100;
分别设置了每个客户端 IP 地址和每个服务器名称的最大并发连接数。注意事项
性能考虑:
安全性:
日志记录:
ngx_stream_log_module 是 Nginx 的一个模块,用于记录流(stream)连接的日志。这个模块允许你配置详细的日志格式和日志文件路径,以便于监控和分析通过 Nginx 代理的 TCP 和 UDP 连接。
主要功能
error
, warn
, info
等),可以根据需要调整日志输出的详细程度。使用示例
以下是一些简化的配置示例,展示了如何使用 ngx_stream_log_module
来实现不同的日志记录需求。
基本日志记录
假设你希望记录所有通过 Nginx 代理的 TCP 连接的基本信息:
stream {
upstream backend {
server backend.example.com:12345;
}
log_format custom_format '$remote_addr [$time_local] $protocol $status $bytes_sent $bytes_received $session_time';
server {
listen 12345;
proxy_pass backend;
access_log /var/log/nginx/stream_access.log custom_format;
}
}
在这个例子中:
log_format custom_format
定义了一个名为 custom_format
的日志格式,包含客户端 IP 地址、时间、协议类型、状态码、发送和接收的字节数以及会话时长。access_log /var/log/nginx/stream_access.log custom_format;
指定了使用该日志格式记录访问日志。记录更多详细信息
假设你希望记录更多的连接细节,例如客户端和服务器的端口号:
stream {
upstream backend {
server backend.example.com:12345;
}
log_format detailed_format '$remote_addr:$remote_port -> $server_addr:$server_port [$time_local] $protocol $status $bytes_sent $bytes_received $session_time';
server {
listen 12345;
proxy_pass backend;
access_log /var/log/nginx/stream_access.log detailed_format;
}
}
在这个例子中:
log_format detailed_format
定义了一个更详细的日志格式,除了基本的信息外,还包含了客户端和服务器的端口号。按条件记录日志
假设你希望根据某些条件来决定是否记录日志,例如仅记录特定来源 IP 地址的连接:
stream {
upstream backend {
server backend.example.com:12345;
}
log_format conditional_format '$remote_addr:$remote_port -> $server_addr:$server_port [$time_local] $protocol $status $bytes_sent $bytes_received $session_time';
map $remote_addr $loggable {
default 0;
"~^192\.168\." 1;
}
server {
listen 12345;
proxy_pass backend;
access_log /var/log/nginx/stream_access.log conditional_format if=$loggable;
}
}
在这个例子中:
map
指令用于创建一个变量 $loggable
,它根据客户端 IP 地址的值决定是否记录日志。access_log
指令中的 if=$loggable
参数确保只有符合条件的连接才会被记录到日志文件中。日志轮转
为了防止日志文件过大,可以结合日志轮转工具(如 logrotate
)进行管理。以下是 logrotate
配置的一个示例:
/var/log/nginx/stream_access.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 0640 nginx nginx
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
endscript
}
在这个例子中:
daily
表示每天轮转一次日志。rotate 30
表示保留最近 30 天的日志文件。compress
和 delaycompress
分别表示压缩旧日志文件,并延迟一天压缩前一天的日志文件。postrotate
和 endscript
之间的内容会在每次轮转后执行,这里通过发送 USR1
信号通知 Nginx 重新打开日志文件。注意事项
性能影响:虽然日志记录对性能的影响较小,但在高并发环境中,频繁写入日志可能会导致 I/O 性能瓶颈。可以通过调整缓冲区大小(如 buffer=size
)和刷新时间(如 flush=time
)来优化性能。
安全性:确保日志文件的权限设置正确,避免敏感信息泄露。通常情况下,日志文件应只允许管理员和 Nginx 用户读取和写入。
chown root:nginx /var/log/nginx/stream_access.log
chmod 640 /var/log/nginx/stream_access.log
日志格式:合理设计日志格式,确保包含足够的信息以便于后续分析,同时避免不必要的字段以减少日志文件的大小。
日志轮转:建议定期轮转日志文件,以防止日志文件过大。可以使用 logrotate
或其他类似的工具来自动管理日志文件。
ngx_stream_map_module 是 Nginx 的一个模块,用于在流(stream)上下文中根据指定的键(如客户端 IP 地址、端口等)创建映射表,并将这些键映射到特定的值。这个模块允许你基于映射结果设置变量,并在后续处理中使用这些变量,例如路由、访问控制和日志记录等。
主要功能
使用示例
以下是一些具体的配置示例,展示了如何使用 ngx_stream_map_module
来根据键值映射设置变量。
基本配置
假设你想根据客户端的 IP 地址设置一个变量 $client_type
,并将其用于后续处理:
stream {
# 定义映射块
map $remote_addr $client_type {
default untrusted;
192.168.1.10 trusted;
203.0.113.5 special;
}
server {
listen 12345;
proxy_pass backend_server;
# 根据映射变量设置不同的代理服务器
if ($client_type = trusted) {
proxy_pass trusted_backend;
}
if ($client_type = special) {
proxy_pass special_backend;
}
if ($client_type = untrusted) {
proxy_pass untrusted_backend;
}
}
}
在这个例子中:
map $remote_addr $client_type { ... }
定义了一个映射块,设置了默认值和特定 IP 地址的值。server
块中,根据 $client_type
的值选择不同的后端服务器进行代理。包含外部映射数据文件
你可以将映射数据存储在一个单独的文件中,并通过 include
指令加载这些数据:
stream {
# 定义映射块
map $remote_addr $client_type {
default untrusted;
include /etc/nginx/map_data.txt;
}
server {
listen 12345;
proxy_pass backend_server;
# 根据映射变量设置不同的代理服务器
if ($client_type = trusted) {
proxy_pass trusted_backend;
}
if ($client_type = special) {
proxy_pass special_backend;
}
if ($client_type = untrusted) {
proxy_pass untrusted_backend;
}
}
}
其中 /etc/nginx/map_data.txt
文件的内容可能如下:
192.168.1.10 trusted;
203.0.113.5 special;
结合负载均衡
假设你的应用部署在多个后端服务器上,并希望通过映射来选择合适的后端服务器:
stream {
upstream trusted_backend {
server backend_trusted_1.example.com;
server backend_trusted_2.example.com;
}
upstream special_backend {
server backend_special_1.example.com;
server backend_special_2.example.com;
}
upstream untrusted_backend {
server backend_untrusted_1.example.com;
server backend_untrusted_2.example.com;
}
# 定义映射块
map $remote_addr $client_type {
default untrusted;
include /etc/nginx/map_data.txt;
}
server {
listen 12345;
# 根据映射变量选择不同的上游服务器组
if ($client_type = trusted) {
proxy_pass trusted_backend;
}
if ($client_type = special) {
proxy_pass special_backend;
}
if ($client_type = untrusted) {
proxy_pass untrusted_backend;
}
}
}
在这个例子中:
upstream trusted_backend { ... }
, upstream special_backend { ... }
和 upstream untrusted_backend { ... }
定义了三个不同的上游服务器组。map $remote_addr $client_type { ... }
根据客户端的 IP 地址设置变量 $client_type
。server
块中,根据 $client_type
的值选择不同的上游服务器组进行代理。注意事项
map_hash_bucket_size
和 map_hash_max_size
指令优化哈希表的内存使用。ngx_stream_mqtt_preread_module 是 Nginx 的一个模块,专门用于处理 MQTT(Message Queuing Telemetry Transport)协议的流量。MQTT 是一种轻量级的消息协议,常用于物联网(IoT)设备之间的通信。该模块允许你在不完全解析 MQTT 消息的情况下读取和处理部分消息头信息,从而实现基于这些信息的路由、负载均衡等功能。
主要功能
常用指令
以下是与 ngx_stream_mqtt_preread_module
模块相关的常用配置指令及其简要说明:
mqtt_preread
:启用 MQTT 预读功能,并提取指定的字段(如客户端 ID、用户名等)。
$mqtt_preread_client_id
:预读到的 MQTT 客户端 ID。
$mqtt_preread_username
:预读到的 MQTT 用户名。
hash
:基于哈希值进行会话持久化。
proxy_pass
:指定后端服务器或上游服务器组。
使用示例
以下是一些具体的配置示例,展示如何利用 ngx_stream_mqtt_preread_module
来实现基于 MQTT 预读信息的功能。
基本配置 - 启用 MQTT 预读功能
假设你想启用 MQTT 预读功能,并根据客户端 ID 将连接路由到不同的后端服务器:
stream {
upstream backend_servers {
server backend1.example.com:1883;
server backend2.example.com:1883;
}
server {
listen 1883;
# 启用 MQTT 预读功能
mqtt_preread;
# 根据客户端 ID 进行哈希计算,实现会话持久化
hash $mqtt_preread_client_id consistent;
proxy_pass backend_servers;
}
}
在这个例子中:
mqtt_preread;
启用了 MQTT 预读功能。hash $mqtt_preread_client_id consistent;
使用客户端 ID 进行哈希计算,确保同一客户端的连接总是被分配到同一个后端服务器。proxy_pass backend_servers;
将流量代理到 backend_servers
组中的服务器。配置 - 基于用户名进行路由
如果你想根据 MQTT 用户名将连接路由到不同的后端服务器,可以这样做:
stream {
upstream backend_users {
server user_backend1.example.com:1883;
}
upstream backend_devices {
server device_backend1.example.com:1883;
}
server {
listen 1883;
# 启用 MQTT 预读功能
mqtt_preread;
# 根据用户名进行条件判断
if ($mqtt_preread_username = "user") {
proxy_pass backend_users;
}
if ($mqtt_preread_username = "device") {
proxy_pass backend_devices;
}
}
}
在这个例子中:
mqtt_preread;
启用了 MQTT 预读功能。if ($mqtt_preread_username = "user") { ... }
和 if ($mqtt_preread_username = "device") { ... }
分别检查预读到的用户名,并根据用户名将连接路由到不同的后端服务器。配置 - 记录预读信息到日志
你可以将预读到的 MQTT 信息记录到日志中,便于后续分析和监控:
stream {
upstream backend_servers {
server backend1.example.com:1883;
server backend2.example.com:1883;
}
log_format mqtt_log '$remote_addr [$time_local] '
'"$protocol" $status $bytes_sent $bytes_received '
'$session_time "$upstream_addr" '
'"$mqtt_preread_client_id" "$mqtt_preread_username"';
server {
listen 1883;
# 启用 MQTT 预读功能
mqtt_preread;
# 设置日志格式
access_log /var/log/nginx/mqtt_access.log mqtt_log;
proxy_pass backend_servers;
}
}
在这个例子中:
mqtt_preread;
启用了 MQTT 预读功能。log_format mqtt_log ...
定义了一个新的日志格式 mqtt_log
,其中包括预读到的 MQTT 客户端 ID 和用户名。access_log /var/log/nginx/mqtt_access.log mqtt_log;
使用自定义的日志格式记录日志。配置 - 负载均衡和会话持久化
为了确保同一客户端的请求总是被分配到同一个后端服务器,可以使用哈希算法进行会话持久化:
stream {
upstream backend_servers {
server backend1.example.com:1883;
server backend2.example.com:1883;
}
server {
listen 1883;
# 启用 MQTT 预读功能
mqtt_preread;
# 根据客户端 ID 进行哈希计算,实现会话持久化
hash $mqtt_preread_client_id consistent;
proxy_pass backend_servers;
}
}
在这个例子中:
mqtt_preread;
启用了 MQTT 预读功能。hash $mqtt_preread_client_id consistent;
使用客户端 ID 进行哈希计算,确保同一客户端的连接总是被分配到同一个后端服务器。proxy_pass backend_servers;
将流量代理到 backend_servers
组中的服务器。注意事项
性能考虑:
安全性:
日志记录:
mqtt_preread 用于控制是否启用 MQTT 协议的预读功能。当启用时,Nginx 将在处理 MQTT 请求之前先读取部分数据进行预处理。
Syntax: mqtt_preread on | off;
Default: mqtt_preread off;
Context: stream, server
on
:启用 MQTT 预读功能。off
:禁用 MQTT 预读功能(默认值)。案例
启用 MQTT 预读
最简单的 mqtt_preread
用法是启用 MQTT 预读功能:
stream {
server {
listen 1883;
mqtt_preread on; # 启用 MQTT 预读功能
}
}
禁用 MQTT 预读
根据实际需求禁用 MQTT 预读功能:
stream {
server {
listen 1883;
mqtt_preread off; # 禁用 MQTT 预读功能
}
}
注意事项
ngx_stream_mqtt_filter_module 是 Nginx 的一个扩展模块,旨在支持 MQTT(Message Queuing Telemetry Transport)协议的过滤和处理。MQTT 是一种轻量的消息协议,专为低带宽、高延迟或不可靠的网络设计,常用于物联网(IoT)设备之间的通信。
主要功能
使用示例
以下是一些简化的配置示例,展示了如何使用 ngx_stream_mqtt_filter_module
来实现不同的 MQTT 功能。
基本 MQTT 代理
假设你希望将 MQTT 连接代理到后端服务器:
stream {
upstream mqtt_backend {
server backend.example.com:1883;
}
server {
listen 1883;
proxy_pass mqtt_backend;
# 配置 MQTT 代理
mqtt_pass mqtt_backend;
# 日志记录
mqtt_access_log /var/log/nginx/mqtt_access.log custom_format;
}
}
对应的日志格式定义:
log_format custom_format '$remote_addr [$time_local] $protocol $status $bytes_sent $bytes_received $session_time';
在这个例子中:
upstream mqtt_backend
定义了一个名为 mqtt_backend
的后端服务器组。server { listen 1883; proxy_pass mqtt_backend; }
将监听在端口 1883 上的所有连接代理到后端服务器。mqtt_access_log /var/log/nginx/mqtt_access.log custom_format;
指定了使用自定义日志格式记录 MQTT 访问日志。访问控制
假设你希望根据客户端 IP 地址来决定是否允许 MQTT 连接:
stream {
upstream mqtt_backend {
server backend.example.com:1883;
}
server {
listen 1883;
proxy_pass mqtt_backend;
# 允许特定 IP 范围的客户端
allow 192.168.1.0/24;
deny all;
# 日志记录
mqtt_access_log /var/log/nginx/mqtt_access.log custom_format;
}
}
在这个例子中:
allow 192.168.1.0/24;
允许来自 192.168.1.0/24
网络段的所有客户端连接。deny all;
拒绝所有其他客户端的连接。消息过滤
假设你希望通过 JavaScript 实现简单的消息过滤逻辑(需要结合 ngx_stream_js_module
):
首先确保 ngx_stream_js_module
已启用,并包含相关的 JavaScript 文件:
stream {
js_include /etc/nginx/scripts/mqtt_filter.js;
upstream mqtt_backend {
server backend.example.com:1883;
}
server {
listen 1883;
proxy_pass mqtt_backend;
# 日志记录
mqtt_access_log /var/log/nginx/mqtt_access.log custom_format;
# 消息过滤
js_on_preread filter_message;
}
}
对应的 mqtt_filter.js
文件内容:
function filter_message(session) {
var message = session.read();
// 假设我们只允许某些特定主题的消息通过
if (message.topic.startsWith("allowed/topic/")) {
session.write(message);
} else {
session.log("Denied message on topic: " + message.topic);
}
return ngx.OK;
}
在这个例子中:
js_on_preread filter_message;
在读取客户端数据之前调用 filter_message
函数。filter_message
函数检查消息的主题,并仅允许特定主题的消息通过。日志轮转
为了防止日志文件过大,可以结合日志轮转工具(如 logrotate
)进行管理。以下是 logrotate
配置的一个示例:
/var/log/nginx/mqtt_access.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 0640 nginx nginx
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
endscript
}
在这个例子中:
daily
表示每天轮转一次日志。rotate 30
表示保留最近 30 天的日志文件。compress
和 delaycompress
分别表示压缩旧日志文件,并延迟一天压缩前一天的日志文件。postrotate
和 endscript
之间的内容会在每次轮转后执行,这里通过发送 USR1
信号通知 Nginx 重新打开日志文件。注意事项
性能影响:虽然日志记录和消息过滤对性能的影响较小,但在高并发环境中,频繁写入日志或复杂的过滤逻辑可能会导致 I/O 性能瓶颈。可以通过调整缓冲区大小(如 buffer=size
)和刷新时间(如 flush=time
)来优化性能。
安全性:确保日志文件的权限设置正确,避免敏感信息泄露。通常情况下,日志文件应只允许管理员和 Nginx 用户读取和写入。
chown root:nginx /var/log/nginx/mqtt_access.log
chmod 640 /var/log/nginx/mqtt_access.log
日志格式:合理设计日志格式,确保包含足够的信息以便于后续分析,同时避免不必要的字段以减少日志文件的大小。
日志轮转:建议定期轮转日志文件,以防止日志文件过大。可以使用 logrotate
或其他类似的工具来自动管理日志文件。
mqtt 指令用于启用或禁用MQTT协议的支持。这个指令帮助配置Nginx以处理MQTT协议的请求。
Syntax: mqtt on | off;
Default: mqtt off;
Context: stream, server
on
:启用MQTT协议支持。off
:禁用MQTT协议支持(默认值)。案例
基本用法
最简单的 mqtt
用法是指定是否启用MQTT协议支持:
stream {
server {
listen 1883;
mqtt on;
proxy_pass backend_mqtt_broker;
}
}
在这个例子中:
mqtt on
,这意味着Nginx将启用MQTT协议支持并监听端口1883。动态设置不同配置
你可以根据不同的服务器块动态设置是否启用MQTT协议支持:
stream {
server {
listen 1883;
mqtt on;
proxy_pass backend_mqtt_broker_1;
}
server {
listen 1884;
mqtt off;
proxy_pass backend_mqtt_broker_2;
}
}
在这个例子中:
mqtt on
。mqtt off
。注意事项
mqtt_buffers 指令用于设置MQTT协议连接的缓冲区大小和数量。这个指令帮助优化MQTT消息的接收和发送性能。
Syntax: mqtt_buffers number size;
Default: mqtt_buffers 100 1k;
Context: stream, server
This directive appeared in version 1.25.1.
number
:指定缓冲区的数量。size
:指定每个缓冲区的大小,默认值为 100 1k
(100个1KB的缓冲区)。案例
基本用法
最简单的 mqtt_buffers
用法是指定具体的缓冲区数量和大小:
stream {
server {
listen 1883;
mqtt on;
mqtt_buffers 50 2k;
proxy_pass backend_mqtt_broker;
}
}
在这个例子中:
mqtt_buffers 50 2k
,这意味着Nginx将使用50个2KB的缓冲区来处理MQTT消息。动态设置不同配置
你可以根据不同的服务器块动态设置不同的缓冲区数量和大小:
stream {
server {
listen 1883;
mqtt on;
mqtt_buffers 50 2k;
proxy_pass backend_mqtt_broker_1;
}
server {
listen 1884;
mqtt on;
mqtt_buffers 100 1k;
proxy_pass backend_mqtt_broker_2;
}
}
在这个例子中:
mqtt_buffers 50 2k
。mqtt_buffers 100 1k
。注意事项
mqtt_rewrite_buffer_size 指令用于设置重写MQTT消息时使用的缓冲区大小。这个指令帮助优化MQTT消息的重写操作。
Syntax: mqtt_rewrite_buffer_size size;
Default: mqtt_rewrite_buffer_size 4k|8k;
Context: server
size
:指定重写缓冲区的大小,默认值为 4k
或 8k
。案例
基本用法
最简单的 mqtt_rewrite_buffer_size
用法是指定具体的缓冲区大小:
server {
listen 1883;
mqtt on;
mqtt_rewrite_buffer_size 8k;
proxy_pass backend_mqtt_broker;
}
在这个例子中:
mqtt_rewrite_buffer_size 8k
,这意味着Nginx将使用8KB的缓冲区来进行MQTT消息的重写操作。动态设置不同配置
由于 mqtt_rewrite_buffer_size
只能在 server
上下文中配置,因此不能针对不同的服务器块单独设置。你可以在主配置文件中统一设置:
server {
listen 1883;
mqtt on;
mqtt_rewrite_buffer_size 8k;
proxy_pass backend_mqtt_broker_1;
}
server {
listen 1884;
mqtt on;
mqtt_rewrite_buffer_size 4k;
proxy_pass backend_mqtt_broker_2;
}
在这个例子中:
mqtt_rewrite_buffer_size 8k
。mqtt_rewrite_buffer_size 4k
。注意事项
mqtt_set_connect 指令用于在MQTT连接建立时设置特定字段的值。这个指令帮助自定义MQTT连接的行为。
Syntax: mqtt_set_connect field value;
Default: —
Context: server
field
:指定要设置的字段名称。value
:指定字段的值。案例
基本用法
最简单的 mqtt_set_connect
用法是指定具体的字段和值:
server {
listen 1883;
mqtt on;
mqtt_set_connect client_id my_custom_client_id;
proxy_pass backend_mqtt_broker;
}
在这个例子中:
mqtt_set_connect client_id my_custom_client_id
,这意味着Nginx将在MQTT连接建立时设置客户端ID为 my_custom_client_id
。动态设置不同配置
你可以根据不同的服务器块动态设置不同的字段和值:
server {
listen 1883;
mqtt on;
mqtt_set_connect client_id custom_client_id_1;
proxy_pass backend_mqtt_broker_1;
}
server {
listen 1884;
mqtt on;
mqtt_set_connect client_id custom_client_id_2;
proxy_pass backend_mqtt_broker_2;
}
在这个例子中:
mqtt_set_connect client_id custom_client_id_1
。mqtt_set_connect client_id custom_client_id_2
。注意事项