1、硬件環境
1.1 、網絡拓撲圖
1.2、對各個服務器的要求
2、實驗一:驗證單機mosquitto能夠支持的最大定閱端數量
2.1、Linux 進程級開啓最大文件描述符 調優
2.1.1、開啓最大文件數
系統可以開啓的最大文件描述符(可同時開啓最多的文件數),最大開啓1024,可根據需求進行調優。
2.1.2、查看系統當前可開啓最大文件描述符數
ulimit -n
[root@localhost ~]# ulimit -n
65535
2.1.3、修改最大文件描述符數
# 在limits.conf文件內添加如下行“*”標識用戶,*爲所有用戶,可改爲用戶名。
echo -ne
“
* soft nofile 65535
* hard nofile 65535
”
>>/etc/security/limits.conf
#/etc/security/limits.conf允許所有用戶打開999,999個
#<domain> <type> <item> <value>
* - nofile 999999
注:該操作在50萬併發下可使用。
2.1.4、設置登錄自動讀取限制參數
修改/etc/pam.d/login文件,在文件中添加如下行
session required /lib/security/pam_limits.so
注:這是告訴Linux在用戶完成系統登錄後,應該調用pam_limits.so模塊來設置系統對該用戶可使用的各種資源數量的最大限制(包括用戶可打開的最大文件數限制),而pam_limits.so模塊就會從/etc/security/limits.conf文件中讀取配置來設置這些限制值。修改完後保存此文件。
2.1.5、參考網址:
https://www.cnblogs.com/xiangsikai/p/9496479.html
2.2、修改mosquitto能夠支持的最大客戶端連接數
vi /etc/mosquitto/mosquitto.conf
#添加內容如下
# The maximum number of client connections to allow. This is
# a per listener setting.
# Default is -1, which means unlimited connections.
# Note that other process limits mean that unlimited connections
# are not really possible. Typically the default maximum number of
# connections possible is around 1024.
#max_connections -1
max_connections 65535
2.3、多進程測試實例 shell腳本啓動
#!/bin/bash
#python3 mqtt_sub.py 1 &
#python3 mqtt_sub.py 2 &
counter=1
loop=5000
b=0
hostip="10.10.40.242"#broker 服務端IP
while true
do
echo "counter==" $counter
b=$(( $counter % 5 ))
#sleep 1
#python3 mqtt_sub.py $counter &
topic="caoft/test/"$counter
echo $topic
#mosquitto_pub -h $hostip -t $topic -m "Hello1111 MQTT2"
mosquitto_sub -h $hostip -t $topic &
counter=$[counter+1]
if [ $counter == $loop ] ; then
break;
fi
if [ $b == 0 ] ; then
sleep 1
fi
done
2.4、結論:
①ubuntu默認安裝的mosquito 1.4.8 最大支持訂閱端的數量爲1024左右,我實際測試位1118
mosquitto -v
1592383135: mosquitto version 1.4.8 (build date Tue, 18 Jun 2019 11:59:34 -0300) starting
1592383135: Using default config.
1592383136: Opening ipv4 listen socket on port 1883.
1592383136: Error: Address already in use
ubuntu通過apt-get install 安裝Mosquittohttps://blog.csdn.net/caofengtao1314/article/details/106686329
②ubuntu默認安裝的mosquito 1.6.9 最大支持訂閱端的數量爲10000左右,我實際測試位10000,
mosquitto -v
1592382811: mosquitto version 1.6.9 starting
1592382811: Using default config.
1592382811: Opening ipv4 listen socket on port 1883.
1592382811: Error: Address already in use
ubuntu通過手動下載編譯mosquittohttps://blog.csdn.net/caofengtao1314/article/details/106686329
3、實驗二:每個客戶端定義唯一的topic,驗證發佈端發佈第一個定閱端到最後一個定閱端 時間差
3.1、多進程測試實例 shell腳本啓動
#!/bin/bash
#python3 mqtt_sub.py 1 &
#python3 mqtt_sub.py 2 &
counter=1
loop=5000
b=0
hostip="10.10.40.242"#broker 服務端IP
while true
do
echo "counter==" $counter
b=$(( $counter % 5 ))
#sleep 1
#python3 mqtt_sub.py $counter &
topic="caoft/test/"$counter
echo $topic
#mosquitto_pub -h $hostip -t $topic -m "Hello1111 MQTT2"
mosquitto_sub -h $hostip -t $topic &
counter=$[counter+1]
if [ $counter == $loop ] ; then
break;
fi
if [ $b == 0 ] ; then
sleep 1
fi
done
3.2、使用發佈端服務器MQTTBox發佈消息統計時間
發佈主題caoft/test/1
發佈主題 caoft/test/9999
訂閱端收到的消息沒有時間差
4、實驗三:使用mosquito_sub 定閱1萬個不同主題,使用mosquito_pub發佈1萬個對應的不同主題,所需要的時間消耗
4.1、訂閱端服務器start_mosquito_sub.sh
#!/bin/bash
counter=1
loop=10000
b=0
hostip="10.10.40.242"
endT=0
consume=0
startT=$[$(date +%s%N)/1000000]
while true
do
echo "counter==" $counter
b=$(( $counter % 5 ))
#sleep 1
#python3 mqtt_sub.py $counter &
topic="caoft/test/"$counter
echo $topic
#mosquitto_pub -h $hostip -t $topic -m "Hello1111 MQTT2"
mosquitto_sub -h $hostip -t $topic &
counter=$[counter+1]
if [ $counter == $loop ] ; then
break;
fi
if [ $b == 0 ] ; then
sleep 1
fi
done
endT=$[$(date +%s%N)/1000000]
consume=$[endT-startT]
echo "sub start ===" $startT "end ===" $endT "consume ==" $consume "counter==" $counter
4.2、發佈端服務器start_mosquito_pub.sh
#!/bin/bash
counter=1
loop=10000
b=0
hostip="10.10.40.242"
endT=0
consume=0
startT=$[$(date +%s%N)/1000000]
while true
do
echo "counter==" $counter
b=$(( $counter % 5 ))
#sleep 1
#python3 mqtt_sub.py $counter &
topic="caoft/test/"$counter
echo $topic
mosquitto_pub -h $hostip -t $topic -m $topic
counter=$[counter+1]
if [ $counter == $loop ] ; then
break;
fi
#if [ $b == 0 ] ; then
# sleep 1
# fi
done
mosquitto_pub -h $hostip -t $topic -m $topic
endT=$[$(date +%s%N)/1000000]
consume=$[endT-startT]
echo "start ===" $startT "end ===" $endT "consume ==" $consume "counter==" $counter
4.3、測試方法
4.3.1 首先啓動start_mosquito_sub.sh 至少需要半個小時
4.3.2 啓動start_mosquito_pub.sh的時候啓動秒錶計數等待訂閱端全部接受完數據
4.3.3 測試結果
發佈端消耗時間統計 70.142s
訂閱端消耗時間統計 71.29s
5、實驗四:使用mosquito_sub 定閱一個組主題,但是啓動1萬個定閱客戶端,使用mosquito_pub發佈1個組主題,所需要的時間消耗
5.1、訂閱端服務器start_mosquito_sub.sh
#!/bin/bash
counter=1
loop=10000
b=0
hostip="10.10.40.242"
endT=0
consume=0
startT=$[$(date +%s%N)/1000000]
while true
do
echo "counter==" $counter
b=$(( $counter % 5 ))
#sleep 1
#python3 mqtt_sub.py $counter &
topic="caoft/test/#"
echo $topic
#mosquitto_pub -h $hostip -t $topic -m "Hello1111 MQTT2"
mosquitto_sub -h $hostip -t $topic &
counter=$[counter+1]
if [ $counter == $loop ] ; then
break;
fi
if [ $b == 0 ] ; then
sleep 1
fi
done
endT=$[$(date +%s%N)/1000000]
consume=$[endT-startT]
echo "sub start ===" $startT "end ===" $endT "consume ==" $consume "counter==" $counter
5.2、發佈端服務器使用MQTTBox發佈一個組主題
MQTTBox發佈caoft/test/111
5.3、測試方法
5.3.1 首先啓動start_mosquito_sub.sh 至少需要半個小時
5.3.2 啓動MQTTBox發佈caoft/test/111 的時候啓動秒錶計數等待訂閱端全部接受完數據
5.3.3 測試結果
發佈端消耗時間統計 延遲3左右秒,訂閱端纔有響應
訂閱端消耗時間統計 7秒
6、實驗五:使用mosquito_sub 定閱一個組主題,但是啓動1萬個定閱客戶端,使用mosquito_pub發佈10個組主題,所需要的時間消耗
6.1、訂閱端服務器start_mosquito_sub.sh
#!/bin/bash
counter=1
loop=10000
b=0
hostip="10.10.40.242"
endT=0
consume=0
startT=$[$(date +%s%N)/1000000]
while true
do
echo "counter==" $counter
b=$(( $counter % 5 ))
#sleep 1
#python3 mqtt_sub.py $counter &
#topic="caoft/test/"$counter
topic="caoft/test/#"
echo $topic
#mosquitto_pub -h $hostip -t $topic -m "Hello1111 MQTT2"
mosquitto_sub -h $hostip -t $topic &
counter=$[counter+1]
if [ $counter == $loop ] ; then
break;
fi
if [ $b == 0 ] ; then
sleep 1
fi
done
endT=$[$(date +%s%N)/1000000]
consume=$[endT-startT]
echo "sub start ===" $startT "end ===" $endT "consume ==" $consume "counter==" $counter
6.2、發佈端服務器start_mosquito_pub.sh
#!/bin/bash
try_times=0
init_counter=0
loop=10000
loop_try_times=10
b=0
hostip="10.10.40.242"
endT=0
consume=0
startT=$[$(date +%s%N)/1000000]
counter=$init_counter
while true
do
while true
do
echo "counter==" $counter
b=$(( $counter % 5 ))
#sleep 1
#python3 mqtt_sub.py $counter &
topic="caoft/test/"$counter
echo $topic
mosquitto_pub -h $hostip -t $topic -m $topic
counter=$[counter+1]
if [ $counter == $loop ] ; then
break;
fi
#if [ $b == 0 ] ; then
# sleep 1
# fi
done
try_times=$[try_times+1]
counter=$init_counter
echo "counter==" $counter "try_times==" $try_times
if [ $try_times == $loop_try_times ] ; then
break;
fi
done
mosquitto_pub -h $hostip -t $topic -m $topic
endT=$[$(date +%s%N)/1000000]
consume=$[endT-startT]
echo "start ===" $startT "end ===" $endT "consume ==" $consume "counter==" $counter "try_times==" $try_times
6.3、測試方法
6.3.1 首先啓動start_mosquito_sub.sh 至少需要半個小時
6.3.2 啓動start_mosquito_pub.sh發佈caoft/test/111 的時候啓動秒錶計數等待訂閱端全部接受完數據
6.3.3 測試結果
發佈端消耗時間統計 延遲3左右秒,訂閱端纔有響應
訂閱端消耗時間統計 預計消耗至少19個小時,實際測試系統已經崩潰
7、實驗六:訂閱端使用mosquito_sub 一個不同的主題,使用python mqtt_pub 一萬個對應的訂閱端主題的信息,時間測試
7.1、訂閱端服務器start_mosquito_sub.sh
#!/bin/bash
counter=1
loop=10000
b=0
hostip="10.10.40.242"
endT=0
consume=0
startT=$[$(date +%s%N)/1000000]
while true
do
echo "counter==" $counter
b=$(( $counter % 5 ))
#sleep 1
#python3 mqtt_sub.py $counter &
topic="caoft/test/"$counter
#topic="caoft/test/#"
echo $topic
#mosquitto_pub -h $hostip -t $topic -m "Hello1111 MQTT2"
mosquitto_sub -h $hostip -t $topic &
counter=$[counter+1]
if [ $counter == $loop ] ; then
break;
fi
if [ $b == 0 ] ; then
sleep 1
fi
done
endT=$[$(date +%s%N)/1000000]
consume=$[endT-startT]
echo "sub start ===" $startT "end ===" $endT "consume ==" $consume "counter==" $counter
7.2、訂閱端服務器start_mosquito_pub.sh
# -*- coding: utf-8 -*-
import paho.mqtt.client as mqtt
import sys
import psutil
import os
import datetime
from datetime import *
MQTTHOST = "10.10.40.242"
MQTTPORT = 1883
mqttClient = mqtt.Client()
def get_head_info():
try:
raise Exception
except:
f = sys.exc_info()[2].tb_frame.f_back
return '%s, %s, %s, %s, %d' % (str(datetime.now()), f.f_code.co_filename, f.f_code.co_name, str(f.f_lineno),os.getpid())
# 連接MQTT服務器
def on_mqtt_connect():
mqttClient.connect(MQTTHOST, MQTTPORT, 60)
mqttClient.loop_start()
# publish 消息
def on_publish(topic, payload, qos):
mqttClient.publish(topic, payload, qos)
# 消息處理函數
def on_message_come(lient, userdata, msg):
print(msg.topic + " " + ":" + str(msg.payload))
# subscribe 消息
def on_subscribe():
mqttClient.subscribe("caoft/test/#", 1)
mqttClient.on_message = on_message_come # 消息到來處理函數
def main():
on_mqtt_connect()
i = 0
print(get_head_info() + " start publish")
#on_publish("caoft/test/1","caoftestt111111", 1)
while True:
topic="caoft/test/"+str(i)
on_publish(topic,topic, 1)
i += 1
if i > 10000:
break
#on_mqtt_connect()
#on_publish("caoft/test/1", "Hello Python!", 1)
print(get_head_info() + " end publish")
if __name__ == '__main__':
main()
while True:
pass
7.3、測試方法
7.3.1 首先啓動start_mosquito_sub.sh 至少需要半個小時
7.3.2 啓動start_mosquito_pub.sh發佈c的時候啓動秒錶計數等待訂閱端全部接受完數據
7.3.3 測試結果
發佈端消耗時間統計 消耗時間爲0.31秒
2020-06-18 04:33:56.975812, mqtt_sub2.py, main, 47, 1557 start publish
2020-06-18 04:33:57.284652, mqtt_sub2.py, main, 57, 1557 end publish
訂閱端消耗時間統計 55.33秒 對比 4、實驗三:使用mosquito_sub 定閱1萬個不同主題,使用mosquito_pub發佈1萬個對應的不同主題,所需要的時間消耗 71.29s 節省15秒
8、結論:
①ubuntu默認安裝的mosquito 1.4.8 最大支持訂閱端的數量爲1024左右,我實際測試位1118
ubuntu通過apt-get install 安裝Mosquittohttps://blog.csdn.net/caofengtao1314/article/details/106686329
②ubuntu默認安裝的mosquito 1.6.9 最大支持訂閱端的數量爲10000左右,我實際測試位10000,
ubuntu通過手動下載編譯mosquittohttps://blog.csdn.net/caofengtao1314/article/details/106686329
③在局域網內如果每個客戶端定義一個唯一的topic,總共啓動1萬個客戶端,通過發佈唯一的topic第一個和第1萬個topic的時間是相同的。
④對比試驗三與試驗四:對每一個客戶端發佈一個消息耗時要比對一個組發佈消息慢很多,但是訂閱端收到的消息要比發佈端發送的消息數量多 ,這是Qos=1導致的
⑤對比試驗四與實驗五:發佈10萬條組消息,沒有導致broker死機,但是訂閱端收到的消息要比發佈端發送的消息數量多 ,這是Qos=1導致的
⑥實驗六與實驗三對比 確少了MQTT的connect階段節省了15秒
⑦如果要想解決LOT設備的海量連接、海量主題、海量會話的問題,需要引入集羣
MQTT簡介之十五--Ubuntu下Mosquitto 集羣搭建