公司业务访问量大,因此需要对后端emq服务器进行性能调优,在前端配置,以提高服务的健壮性。同时,由于mqtts传输方式中加解密的操作较占资源,所以需要把这部分操作让nginx服务器完成,让后端通信均为mqtt方式,减少服务器压力。
本文所有配置基于nginx-plus R17版本。
nginx的安装和简单配置参考其他网页。
- SSL Termination,翻译中文大概意思为ssl卸载(?),目的就是要在nginx端进行加解密操作。首先需要在emq的安装目录使用OpenSSL生成证书。以下为测试时使用的nginx配置文件,由于mqtt协议属于TCP/UDP协议集,因此使用stream模块。配置上游服务器188和190,监听mqtt协议的1883端口。nginx监听9993的加密协议端口,使用ssl_certificate命令指定证书路径(必须PEM格式),使用ssl_certificate_key指定私钥地址,此外,ssl_protocols和ssl_ciphers指令可用于限制连接,并仅包含SSL / TLS的强版本和密码。
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log debug;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
# TCP/UDP proxy and load balancing block
#
stream {
upstream mqtt_cluster {
server 192.168.100.188:1883;
server 192.168.100.190:1883;
}
server {
listen 9993 ssl;
proxy_pass mqtt_cluster;
ssl_certificate /etc/ssl/certs/cert.crt;
ssl_certificate_key /etc/ssl/certs/key.key;
ssl_protocols TLSv1 TLSV1.1 TLSv1.2;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
}
}
以上配置已经可以实现在nginx端进行mqtts的ssl加解密操作。测试时使用一个加密的pub端发送消息,一个加密的sub端,一个不加密的sub端接收消息。结果不论加密或不加密的sub端都可以收到消息。
- 负载均衡。是通过upstream模块来实现的,内置实现了五种负载策略,分别是轮询、最少连接、最少时间(仅nginxPlus支持)、hash和random。由于业务需求,负载均衡的同时必须保证用户进行订阅时,同一个clientID必须始终是同一台服务器进行处理,除非该服务器宕机不可用,即要保证会话持久性。所以使用hash算法配置负载均衡。使用的配置文件在上文的基础上添加了一行hash 192.168.100.187 consistent;,即从187这个ip发送的mqtt消息始终有同一个上游服务器处理,但这种方式并不符合业务需求,因为无法在配置文件中写出所有客户的IP。因此需要通过mqtt客户端的唯一标识clientID来做hash算法,但由于时间关系没有深入研究,在此记录github项目连接以便空闲的时候继续。
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log debug;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
# TCP/UDP proxy and load balancing block
#
stream {
upstream mqtt_cluster {
hash 192.168.100.187 consistent;
server 192.168.100.188:1883;
server 192.168.100.190:1883;
}
server {
listen 9993 ssl;
proxy_pass mqtt_cluster;
ssl_certificate /etc/ssl/certs/cert.crt;
ssl_certificate_key /etc/ssl/certs/key.key;
ssl_protocols TLSv1 TLSV1.1 TLSv1.2;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
}
}