UCMQ是一款支持簡單HTTP協議的輕量級消息隊列服務,基本特性以下: linux
l 支持HTTP協議的GET/POST方法,支持長鏈接(keep-alive); git
l 請求響應很是快速,入隊列、出隊列速度超過10000次/秒; github
l 每一個UCMQ實例支持多隊列,隊列經過操做接口自動建立; json
l 單個隊列支持的最大消息數量(未取出的)能夠不限制,默認限制在1百萬之內; 安全
l 能夠在不中止服務的狀況下便捷地修改單個隊列的屬性; bash
l 能夠實時查看隊列屬性(入隊列數量、出隊列數量、未讀消息數量、消息積壓數量)。 運維
項目的最初原型來自於HTTPSQS(http://blog.s135.com/httpsqs/),UCMQ的主要修改以下: curl
l 數據存儲棄用TC,改用日誌型文件方式存儲。積壓數據量不受限於內存,性能更高,大量的數據積壓也不會致使性能波動,隊列數據能夠獨立搬遷。 性能
l 增長了多個運維接口和功能接口。 測試
l 徹底支持標準HTTP協議,同時兼容原有HTTPSQS協議。
項目 |
需求 |
說明 |
編譯器 |
g++ |
在4.1.2上測試經過 |
libevent版本 |
2.0.10以上stable版本 |
|
從libevent的官方主頁上下載相應的源碼包進行安裝,下面以2.0.21版本爲例:
$ wget https://github.com/downloads/libevent/libevent/libevent-2.0.21-stable.tar.gz
$ ./configure --prefix=$HOME/local/libevent
$ make clean && make && make install
從github下載UCMQ官方最新版本,下載指令以下:
$ git clone git://github.com/ucopensource/ucmq.git
基本目錄結構以下:
$ tree -d
|-- test
|-- conf
|-- client #客戶端的代碼
`-- source #服務端的代碼
配置腳本(configure)能夠附加額外的參數,經常使用的參數有以下:
參數 |
說明 |
示例 |
--with-libevent |
從DIR目錄下查找libevent庫 |
--with-libevent=$HOME/local/ |
--prefix |
安裝的根目錄 |
--prefix=$HOME/local/ucmq |
--with-arch=ARCH |
編譯的目標系統 |
--with-arch=i686 |
編譯和安裝:
$ ./configure --with-libevent=$HOME/local/libevent --prefix=$HOME/local/ucmq
$ make clean && make && make install
[server]
http_listen_addr=127.0.0.1 //監聽地址
http_listen_port=1818 //監聽端口
allow_exec_ip=0 //容許執行運維指令的ip,0爲不限制
binlog_file_path=../binlog //binlog目錄(暫未實現主從)
output_log_path=../log //日誌目錄
output_log_level=INFO //日誌記錄級別
keep_alive=300 //長鏈接有效時間(單位:秒)
conf_file=../conf/ucmq.ini //配置文件路徑
pid_file=/tmp/ucmq_eth0_1818.pid //進程保護文件
res_store_space=4 //預留磁盤空間(單位:GB)
[rtag]
sync_interval=10 //數據文件內存映射持久化操做間隔(寫操做次數)
sync_time_interval=100 //間隔n秒後持久化rtag和DB的信息,會調用fsync。
[queue]
def_max_queue=1000000 //隊列容許積壓消息量,設置爲0則不限制
#延時只能設置更大
def_delay=0 //隊列延時時間
#如下內容自從啓動後不容許修改
[db]
data_file_path=../data //data文件存放路徑
#文件大小不容許超過64,必須是系統頁大小的倍數
db_file_max_size=64 //容許的data文件的最大限制(單位:MB)
$ ./ucmq -h
---------------------------------------------------------------------------
HTTP Simple Message Queue Service - ucmq v2.0.1 (May 21 2013 11:19:54)
-c config file path
-d run as a daemon
-v, --version print version and exit
-h, --help print this help and exit
Note1: Use command "killall ucmq" and "kill `cat /tmp/ucmq.pid`" to stop ucmq.
Note2: Please don't use the command "pkill -9 ucmq" and "kill -9 PID of ucmq" !
----------------------------------------------------------------------------
$ ./ucmq –c ../conf/ucmq.ini –d
要使ucmq正常退出,除了kill進程號以外,還能夠在使用如下命令:
$ curl "http://<mq_ip>:<mq_port>/exec?cmd=kill"
協議中全部參數均大小寫敏感。服務端返回的內容中以「UCMQ_HTTP」開頭的返回內容被稱爲「返回標識」,該標識描述了HTTP請求的服務返回狀態(返回標識尾部有隱藏的「\r\n」)。若是隊列還未建立,可經過執行某些操做(put/maxqueue/delay)建立新的隊列。
PS:若是在linux終端(如bash)中使用curl操做下述命令,請務必注意在url先後加上括號,以免「&」字符被轉義。
把消息寫入隊列有兩種方式:HTTP GET和HTTP POST,若是但願傳遞大於2k字節或者非文本數據,建議使用HTTP POST方式。
入隊列HTTP GET方式,格式以下:
http://<mq_ip>:<mq_port>/?name=<queue_name>&opt=put&data=<data_string>&ver=2
使用curl方式執行POST方法,如:
$ curl -d "<data>" "http://<mq_ip>:<mq_port>/?name=<queue_name>&opt=put&ver=2"
UCMQ_HTTP_OK
參數說明:
描述 |
是否容許爲空 |
約束 |
備註 |
|
queue_name |
隊列名稱 |
不能爲空 |
隊列名由「字母」,「數字」及「下劃線」構成;「下劃線」不能出如今開頭或結尾。隊列名稱不超過32字節 |
若是該隊列不存在則自動建立 |
opt |
操做標識 |
不能爲空 |
須要絕對匹配,大小寫敏感 |
|
data |
被寫入消息 |
不能爲空 |
消息內容不能爲空 |
如消息記錄長度超過服務端數據文件大小,將返回失敗。(見服務端參數:db_file_max_size) |
ver |
接口版本標識 |
可爲空 |
數字 |
本文檔均以ver=2爲樣例,加入此標識則使用標準的http協議 |
HTTP返回值以下:
結果 |
HTTP Code |
HTTP Reason |
返回內容 |
描述 |
成功 |
200 |
OK |
UCMQ_HTTP_OK |
寫隊列成功 |
失敗 |
400 |
Bad Request |
UCMQ_HTTP_ERR_BAD_REQ |
請求非法 |
200 |
OK |
UCMQ_HTTP_ERR_INV_NAME |
隊列名非法 |
|
UCMQ_HTTP_ERR_INV_DATA |
消息非法 (例如:消息長度爲空或大於數據文件大小) |
|||
UCMQ_HTTP_ERR_WLOCK |
隊列寫鎖 |
|||
UCMQ_HTTP_ERR_QUE_FULL |
隊列已滿 (超過本隊列消息數上線) |
|||
UCMQ_HTTP_ERR_NO_STORAGE |
服務端存儲空間不足 |
|||
UCMQ_HTTP_ERR_PUT_ERR |
寫隊列失敗 |
|||
UCMQ_HTTP_ERR_UNKNOWN_OPT |
未知操做 |
|||
UCMQ_HTTP_ERR_QUE_ADD_ERR |
隊列數量以超出服務端限制,沒法建立。 |
讀取消息隊列,格式以下:
http://<mq_ip>:<mq_port>/?name=<queue_name>&opt=get&ver=2
HTTP返回值以下:
結果 |
HTTP Code |
HTTP Reason |
返回內容 |
描述 |
成功 |
200 |
OK |
UCMQ_HTTP_OK加具體內容 |
讀隊列成功 |
失敗 |
400 |
Bad Request |
UCMQ_HTTP_ERR_BAD_REQ |
請求非法 |
200 |
OK |
UCMQ_HTTP_ERR_INV_NAME |
隊列名非法 |
|
UCMQ_HTTP_ERR_QUE_NO_EXIST |
隊列不存在 |
|||
UCMQ_HTTP_ERR_QUE_EMPTY |
消息已取空 |
|||
UCMQ_HTTP_ERR_GET_ERR |
讀隊列失敗 |
|||
UCMQ_HTTP_ERR_UNKNOWN_OPT |
未知操做 |
查看某隊列狀態,格式以下:
http://<mq_ip>:<mq_port>/?name=<queue_name>&opt=status&ver=2
HTTP返回值以下:
結果 |
HTTP Code |
HTTP Reason |
返回內容 |
描述 |
成功 |
200 |
OK |
具體內容 |
獲取隊列消息成功 |
失敗 |
400 |
Bad Request |
UCMQ_HTTP_ERR_BAD_REQ |
請求非法 |
200 |
OK |
UCMQ_HTTP_ERR_INV_NAME |
隊列名非法 |
|
UCMQ_HTTP_ERR_QUE_NO_EXIST |
隊列不存在 |
|||
UCMQ_HTTP_ERR_UNKNOWN_OPT |
未知操做 |
輸出結果如:
HTTP Simple Message Queue Service v2.0.1 (May 24 2013 11:15:50)
Queue Name: 001
Put the number of queue : 1
Get the number of queue : 0
Unread the number of queue : 1
Maximum number of queue: 1000000
Delay time of queue: 0
Queue write lock cut-OFF time: 0
其中的含義以下:
字段 |
含義 |
Queue Name |
當前隊列名 |
Put the number of queue |
已寫消息記錄數 |
Get the number of queue |
已讀消息記錄數 |
Unread the number of queue |
未讀消息數 |
Maximum items of queue |
存儲消息數限制 |
Delay times of queue |
該隊列消息延時時間 |
Queue write lock cut-OFF time |
隊列寫入鎖截止時間,0表示無寫鎖 |
爲了便於程序對該數據的處理,所以提供了json方式的返回:
http://<mq_ip>:<mq_port>/?name=<queue_name>&opt=status_json&ver=2
輸出結果如:
{「name」:」<queue_name>」,」put_num」:2,」get_num」:1,」unread」:1,」maxqueue」:1000000,」delay」:0,」wlock」:0}
另外,若是對一個徹底沒有使用過的隊列名獲取狀態,Put the number of queue、Get the number of queue、Unread the number of queue、Delay times of queue、Queue write lock cut-OFF time爲0。
設置某個隊列存儲消息記錄數最大限制,可使用如下命令:
http://<mq_ip>:<mq_port>/?name=<queue_name>&opt=maxqueue&num=<size>&ver=2
參數說明:
參數名 |
描述 |
是否爲空 |
約束 |
備註 |
num |
消息記錄數 |
不能爲空 |
整數 |
若是設置爲「0」(不建議),則不限制隊列大小。有可能致使磁盤寫滿。 |
HTTP返回值以下:
結果 |
HTTP Code |
HTTP Reason |
返回內容 |
描述 |
成功 |
200 |
OK |
UCMQ_HTTP_OK |
設置隊列最大消息上限成功 |
失敗 |
400 |
Bad Request |
UCMQ_HTTP_ERR_BAD_REQ |
請求非法 |
200 |
OK |
UCMQ_HTTP_ERR_INV_NAME |
隊列名非法 |
|
UCMQ_HTTP_ERR_QUE_ADD_ERR |
隊列數量以超出服務端限制,沒法建立。 |
|||
UCMQ_HTTP_ERR_INV_NUM |
錯誤的取值 (超出合法取值範圍,合法取值不大於:1000000000條消息) |
|||
UCMQ_HTTP_ERR_MAXQUE_ERR |
設置隊列最大消息數失敗 |
|||
UCMQ_HTTP_ERR_UNKNOWN_OPT |
未知操做 |
隊列被設置延時隊列後,該消息需在寫入後等候「time」秒鐘後才能被讀取。設置隊列延時可使用如下命令:
http://<mq_ip>:<mq_port>/?name=<queue_name>&opt=delay&num=<time>&ver=2
參數說明:
參數名 |
描述 |
是否爲空 |
約束 |
備註 |
num |
隊列延時時間 |
不能爲空 |
整數 |
隊列延時由當前設置決定,設置爲「0」時即時解除全部消息的延時 |
HTTP返回值以下:
結果 |
HTTP Code |
HTTP Reason |
返回內容 |
描述 |
成功 |
200 |
OK |
UCMQ_HTTP_OK |
設置延時隊列成功 |
失敗 |
400 |
Bad Request |
UCMQ_HTTP_ERR_BAD_REQ |
請求非法 |
200 |
OK |
UCMQ_HTTP_ERR_INV_NAME |
隊列名非法 |
|
UCMQ_HTTP_ERR_QUE_ADD_ERR |
隊列數量以超出服務端限制,沒法建立。 |
|||
UCMQ_HTTP_ERR_INV_NUM |
錯誤的取值 (超出合法取值範圍) |
|||
UCMQ_HTTP_ERR_DELAY_ERR |
設置延時隊列失敗 |
|||
UCMQ_HTTP_ERR_UNKNOWN_OPT |
未知操做 |
隊列寫鎖(又稱:設置隊列只讀)此接口常被用於運維,目的是讓隊列鎖定寫入,只提供對外的消息讀取。設置某個隊列寫鎖可使用如下命令:
http://<mq_ip>:<mq_port>/?name=<queue_name>&opt=wlock&num=<time>&ver=2
參數說明:
參數名 |
描述 |
是否爲空 |
約束 |
備註 |
num |
隊列寫入鎖時間 |
可爲空 |
整數 |
爲空:永久寫鎖(只讀) 爲0:釋放寫鎖 爲n:寫鎖時間(單位:秒) |
HTTP返回值以下:
結果 |
HTTP Code |
HTTP Reason |
返回內容 |
描述 |
成功 |
200 |
OK |
UCMQ_HTTP_OK |
設置隊列寫鎖成功 |
失敗 |
400 |
Bad Request |
UCMQ_HTTP_ERR_BAD_REQ |
請求非法 |
200 |
OK |
UCMQ_HTTP_ERR_INV_NAME |
隊列名非法 |
|
UCMQ_HTTP_ERR_QUE_NO_EXIST |
隊列不存在 |
|||
UCMQ_HTTP_ERR_INV_NUM |
錯誤的取值 (超出合法取值範圍) |
|||
設置隊列寫鎖失敗 |
||||
UCMQ_HTTP_ERR_UNKNOWN_OPT |
未知操做 |
本接口將爲全部隊列設置持久化間隔時間。此接口是爲了保證數據持久化,設置後數據將會定時fsync到磁盤中。過於頻繁的此類操做將較的影響服務端性能。同步間隔依數據安全性需求而定。經過如下命令能夠修改同步時間間隔:
http://<mq_ip>:<mq_port>/?opt=synctime&num=<value>&ver=2
參數說明:
參數名 |
描述 |
是否爲空 |
約束 |
備註 |
num |
間隔時間 |
不能爲空 |
整數 |
num爲時間間隔的值,當設置目標值爲「0」時不一樣步。默認值在配置文件中設置。單位爲:「秒」。 |
HTTP返回值以下:
結果 |
HTTP Code |
HTTP Reason |
返回內容 |
描述 |
成功 |
200 |
OK |
UCMQ_HTTP_OK |
設置同步間隔時間成功 |
失敗 |
400 |
Bad Request |
UCMQ_HTTP_ERR_BAD_REQ |
請求非法 |
200 |
OK |
UCMQ_HTTP_ERR_INV_NUM |
錯誤的取值 (超出合法取值範圍) |
|
UCMQ_HTTP_ERR_SYNC_TIEM_ERR |
設置同步間隔時間失敗 |
|||
UCMQ_HTTP_ERR_UNKNOWN_OPT |
未知操做 |
重置隊列指的是把一條隊列所有恢復到初始狀態:
http://<mq_ip>:<mq_port>/?name=<queue_name>&opt=reset&ver=2
HTTP返回值以下:
結果 |
HTTP Code |
HTTP Reason |
返回內容 |
描述 |
成功 |
200 |
OK |
UCMQ_HTTP_OK |
重置隊列成功 |
失敗 |
400 |
Bad Request |
UCMQ_HTTP_ERR_BAD_REQ |
請求非法 |
200 |
OK |
UCMQ_HTTP_ERR_INV_NAME |
隊列名非法 |
|
UCMQ_HTTP_ERR_QUE_NO_EXIST |
隊列不存在 |
|||
UCMQ_HTTP_ERR_RESET_ERR |
重置隊列失敗 |
|||
UCMQ_HTTP_ERR_UNKNOWN_OPT |
未知操做 |
刪除隊列把一條隊列的數據所有清除,包括其歷史紀錄和磁盤上的數據。命令以下:
http://<mq_ip>:<mq_port>/?name=<queue_name>&opt=remove&ver=2
HTTP返回值以下:
結果 |
HTTP Code |
HTTP Reason |
返回內容 |
描述 |
成功 |
200 |
OK |
UCMQ_HTTP_OK |
刪除隊列成功 |
失敗 |
400 |
Bad Request |
UCMQ_HTTP_ERR_BAD_REQ |
請求非法 |
200 |
OK |
UCMQ_HTTP_ERR_INV_NAME |
隊列名非法 |
|
UCMQ_HTTP_ERR_QUE_NO_EXIST |
隊列不存在 |
|||
UCMQ_HTTP_ERR_REMOVE_ERR |
刪除隊列失敗 |
|||
UCMQ_HTTP_ERR_UNKNOWN_OPT |
未知操做 |
運維接口能夠經過配置文件的allow_exec_ip(若是配置文件設置爲「0」則全部ip可執行,若是設置指導ip則只有此ip可操做)容許的ip對UCMQ作操做。基本功能以下表:
操做 |
命令 |
備註 |
關閉服務 |
http:// <mq_ip>:<mq_port>/exec?cmd=kill |
關閉實例 |
重載配置 |
http:// <mq_ip>:<mq_port>/exec?cmd=reload |
配置重載 |
獲取proc/pid/file |
http:// <mq_ip>:<mq_port>/exec?cmd=get&file=stat |
獲取進程信息 |
獲取全部隊列信息 |
http:// <mq_ip>:<mq_port>/stat?type |
全部隊列監控 |
內存使用狀況 |
http:// <mq_ip>:<mq_port>/stat?type=mem |
內存使用狀況 |
隊列最後一分鐘運行狀況 |
http:// <mq_ip>:<mq_port>/stat?type=info |
一分鐘內實例狀況 |
cpu資源消耗狀況 |
cpu使用狀況 |
若是以上協議都不能匹配,服務端會根據不一樣狀況給出相應的錯誤返回,如:
結果 |
HTTP Code |
HTTP Reason |
返回內容 |
描述 |
語法解析失敗 |
400 |
Bad Request |
UCMQ_HTTP_ERR_BAD_REQ |
請求非法,使用HTTP GET方法時,需將上傳的消息作uri encode。 |
未知操做 |
200 |
OK |
UCMQ_HTTP_ERR_UNKNOWN_OPT |
隊列操做不可知 |
非法隊列名 |
200 |
OK |
UCMQ_HTTP_ERR_INV_NAME |
非法隊列名,隊列名爲空或超長 |
隊列不存在 |
200 |
OK |
UCMQ_HTTP_ERR_QUE_NO_EXIST |
隊列還沒有建立 |
沒法建立隊列 |
200 |
OK |
UCMQ_HTTP_ERR_QUE_ADD_ERR |
隊列數量以超出服務端限制,沒法建立。 |