使用emqx提供的docker镜像进行布署后,通常会考虑通过nginx代理具体的服务。
如:EMQX Dashboard, 容器访问地址为:127.0.0.1:18083
可以在nginx.conf
中增加对EMQX Dashboard的代理,以实现通过自定义端口、域名的访问需求。
示例如下:
server {
listen <target>;
server_name <domain>
location / {
proxy_pass http://127.0.0.1:18083/;
proxy_set_header Host $host;
...
}
}
EMQX 提供的服务中包含 REST API,Dashboard中本身也使用了REST API。
如: Dashboard - 问题分析 - 主题监控 - 主题详情 对应的REST API地址为:
http://127.0.0.1:18083/api/v5/mqtt/topic_metrics/{topic}
根据 api-doc 对 GET: /mqtt/topic_metrics/{topic} 接口描述:
Topic string. Notice: Topic string in url path must be encoded
需要对Topic编码,以解决Topic也是使用 “/” 实现多层级对url造成的冲突。
类似需要使用topic做为参数的接口还有如:
- DELETE: /mqtt/topic_metrics/{topic}
- GET: /topics/{topic}
测试中直接调用EMQX提供地址并根据要求对topic进行编码,并不会导致问题,但是如需通过nginx代理,就存在url被nginx自行decode,再传递给容器导致请求错误的可能性。
示例问题如下, 当:
topic=testtopic/1
编码后对应请求url:
http://192.168.0.9:8080/api/v5/mqtt/topic_metrics/testtopic%2F1
nginx在接收到请求后,会将 testtopic%2F1
进行decode并传递:
http://127.0.0.1:18083/api/v5/mqtt/topic_metrics/testtopic/1
但rest api实际并没有对应 /api/v5/mqtt/topic_metrics/testtopic/1 的资源,导致 响应错误。
这是由于nginx.conf → location → proxy_pass 支持多种匹配配置:
proxy_pass http://127.0.0.1:18083/;
proxy_pass http://127.0.0.1:18083;
proxy_pass http://127.0.0.1:18083$1;
通过测试,当配置为 proxy_pass http://127.0.0.1:18083/
时,nginx会自动进行UrlDecode,导致上述问题发生。
因此,解决这个问题也比较简单,只需将proxy_pass http://127.0.0.1:18083/
修改为:proxy_pass http://127.0.0.1:18083;
,nginx重新加载配置,再次请求接口测试,响应恢复正常。