Nginx提示未知指令'match'的原因及配置问题解决方法
问题描述
配置Nginx作为MQTT反向代理并添加健康检查后,重载时出现报错:
nginx: [emerg] unknown directive "match" in /etc/nginx/nginx.conf:171
已配置include modules/*.conf,询问是否缺失组件及解决配置问题的方法。
配置内容
log_format mqtt '$remote_addr [$time_local] $protocol $status $bytes_received ' '$bytes_sent $upstream_addr'; upstream hive_mq { server 192.168.11.200:1883; #node1 server 127.0.0.1:1883; #node2 zone tcp_mem 64k; } match mqtt_conn { # Send CONNECT packet with client ID "nginx health check" send \x10\x20\x00\x06\x4d\x51\x49\x73\x64\x70\x03\x02\x00\x3c\x00\x12\x6e\x67\x69\x6e\x78\x20\x68\x65\x61\x6c\x74\x68\x20\x63\x68\x65\x63\x6b; expect \x20\x02\x00\x00; # Entire payload of CONNACK packet } server { listen 8081; proxy_pass hive_mq; proxy_connect_timeout 1s; health_check match=mqtt_conn; access_log /var/log/nginx/mqtt_access.log mqtt; error_log /var/log/nginx/mqtt_error.log; # Health check notifications }
报错详情
nginx.service - The nginx HTTP and reverse proxy server Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled) Drop-In: /usr/lib/systemd/system/nginx.service.d └─php-fpm.conf Active: failed (Result: exit-code) since Fri 2022-12-02 03:20:49 UTC; 2s ago Process: 51793 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS) Process: 51821 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=1/FAILURE) Process: 51819 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS) Main PID: 51794 (code=killed, signal=KILL) Dec 02 03:20:49 localhost systemd[1]: Starting The nginx HTTP and reverse proxy server... Dec 02 03:20:49 localhost nginx[51821]: nginx: [emerg] unknown directive "match" in /etc/nginx/nginx.conf:171 Dec 02 03:20:49 localhost nginx[51821]: nginx: configuration file /etc/nginx/nginx.conf test failed Dec 02 03:20:49 localhost systemd[1]: nginx.service: Control process exited, code=exited status=1 Dec 02 03:20:49 localhost systemd[1]: nginx.service: Failed with result 'exit-code'. Dec 02 03:20:49 localhost systemd[1]: Failed to start The nginx HTTP and reverse proxy server.
解决方案
核心原因
- 功能依赖Nginx Plus:
match和TCP类型的health_check是Nginx Plus专属指令,开源版Nginx默认不支持。 - 配置块位置错误:MQTT是TCP协议,相关反向代理和健康检查必须放在
stream块中,而非http块(http块仅处理HTTP请求),即使是Nginx Plus,放在http块中也会报错。
分场景解决
场景1:使用Nginx Plus
- 确认已加载
ngx_stream_module和ngx_stream_healthcheck_module,检查modules/*.conf中是否有对应加载指令。 - 将所有MQTT相关配置移至
stream块内,修正后的配置示例:
stream { log_format mqtt '$remote_addr [$time_local] $protocol $status $bytes_received ' '$bytes_sent $upstream_addr'; upstream hive_mq { server 192.168.11.200:1883; #node1 server 127.0.0.1:1883; #node2 zone tcp_mem 64k; } match mqtt_conn { # Send CONNECT packet with client ID "nginx health check" send \x10\x20\x00\x06\x4d\x51\x49\x73\x64\x70\x03\x02\x00\x3c\x00\x12\x6e\x67\x69\x6e\x78\x20\x68\x65\x61\x6c\x74\x68\x20\x63\x68\x65\x63\x6b; expect \x20\x02\x00\x00; # Entire payload of CONNACK packet } server { listen 8081; proxy_pass hive_mq; proxy_connect_timeout 1s; health_check match=mqtt_conn; access_log /var/log/nginx/mqtt_access.log mqtt; error_log /var/log/nginx/mqtt_error.log; # Health check notifications } }
- 测试配置:
nginx -t,无报错后重载Nginx:systemctl reload nginx
场景2:使用开源版Nginx
方案A:添加第三方健康检查模块
使用nginx_upstream_check_module(淘宝开源的TCP健康检查模块),需重新编译Nginx:
- 下载模块源码。
- 重新编译Nginx:
./configure --add-module=/path/to/nginx_upstream_check_module && make && make install - 修改配置示例:
stream { upstream hive_mq { server 192.168.11.200:1883; server 127.0.0.1:1883; check interval=3000 rise=2 fall=5 timeout=1000 type=tcp; check_send "\x10\x20\x00\x06\x4d\x51\x49\x73\x64\x70\x03\x02\x00\x3c\x00\x12\x6e\x67\x69\x6e\x78\x20\x68\x65\x61\x6c\x74\x68\x20\x63\x68\x65\x63\x6b"; check_expect "\x20\x02\x00\x00"; } server { listen 8081; proxy_pass hive_mq; proxy_connect_timeout 1s; } }
方案B:使用外部监控工具
用Keepalived、Prometheus+Alertmanager等工具独立监控MQTT后端可用性,通过脚本动态调整Nginx upstream节点:后端不可用时移除节点,恢复后重新添加。
内容的提问来源于stack exchange,提问作者puncheung tong
相关产品推荐
相关产品推荐

