前段時間寫的那個域用戶平臺,要做大量的新功能運維測試,據(jù)說要抄 IT 組,讓那幫人到搞,跑一下! 尼瑪,這可嚇壞了我了。 因為平臺要和 windows 做大量的交互,那邊 powershell 又很不給力,改成多線程版本后,出現(xiàn)莫名的問題,很讓人鬧心?,F(xiàn)在的狀態(tài)是,client 給 server 端可以同時推送兩片信息,要是多的話,powershell 實在處理不了,我只能放到 queue 隊列里面了。
現(xiàn)在很多的堵塞都是在 windows 那邊,我這邊因為用的是 tornado,對于用戶訪問是無壓力的,但是 windows 那邊不能同時運行多了,不然會提示 bug。。。
ad 的信息我暫時還沒有批量的同步過來,所以只能單點搞了 ~
一直在想咋才能不出丑。所以做了好多的限制,比如短信接口的 token 機制,用戶更新接口的次數(shù)的限制。 現(xiàn)在唯一的節(jié)點就是和 win 那邊的交互。別等到了周一的時候,一幫人把 獲取手機號碼、修改密碼、更新用戶信息的接口給點爆了。
突然想到 12306 那個渣渣,可以用排隊呀。。。 這樣的話,最少能看起來很高端的樣子。
http://wiki.jikexueyuan.com/project/python-actual-combat/images/36.jpg" alt="pic" />
我的前端實現(xiàn) ~
用戶點擊的時候,我會從后端的 api 查看隊列中的數(shù)目,以及有誰排在我的前面 ~
$("#dialog").hide();
$("#mailname").focus();
$("#service").click(function(){
$.ajax({
type: "POST",
url: "/queue",
data : $("#form_service").serialize(),
dataType: "html",
timeout:5000,
error: function(){
alert('nima,超時了');
},
success: function(data,status){
if( data=="ok"){
<!-- alert (data+status+"成功了");-->
var a=$("input[name=mailname]").val();
window.location.href="/mailpost?mailname="+a; }
else{
$('#myModal').modal();
}
}
});
});
});
后端的實現(xiàn)~
不用 redis 做隊列的原因是,python 調(diào)用隊列的時候總是莫名的關閉,卸載安裝了好多遍。。。怪事 ~ 和 powershell 多線程一樣都很怪~
安裝配置 memcached 環(huán)境,簡單點直接 yum ~
需要編譯安裝的朋友,用下面的腳本~
wget https://github.com/downloads/libevent/libevent/libevent-2.0.21-stable.tar.gz
tar xzf libevent-2.0.21-stable.tar.gz
cd libevent-2.0.21-stable
./configure
make
make install
wget http://memcached.googlecode.com/files/memcached-1.4.15.tar.gz
tar vxzf memcached-1.4.15.tar.gz
cd memcached-1.4.15
./configure --prefix=/usr/local/webserver/memcached
make
make install
http://wiki.jikexueyuan.com/project/python-actual-combat/images/37.jpg" alt="pic" />
啟動 memcached 命令是: /usr/local/memcached/bin/memcached -d -m 100 -c 1000 -u root -p 11211
-d 選項是啟動一個守護進程
-m 是分配給 Memcache 使用的內(nèi)存數(shù)量,單位是 MB,默認 64 MB
-M return error on memory exhausted (rather than removing items)
-u 是運行 Memcache 的用戶,如果當前為 root 的話,需要使用此參數(shù)指定用戶
-l 是監(jiān)聽的服務器 IP 地址,默認為所有網(wǎng)卡
-p 是設置 Memcache 的 TCP 監(jiān)聽的端口,最好是 1024 以上的端口
-c 選項是最大運行的并發(fā)連接數(shù),默認是 1024
-P 是設置保存 Memcache 的 pid 文件
-f chunk size growth factor (default: 1.25)
-I Override the size of each slab page. Adjusts max item size(1.4.2 版本新增)
有朋友可能沒有接觸過 memcached,也有沒有用 python 操作 memcached 的。 我在這里就簡單操作下,讓大家瞅瞅哈~
python 操作 memcached 需要安裝 python-memcached 模塊
pip install python-memcached
import memcache
mc=memcache.Client(['127.0.0.1:11211'],debug=0)
mc.set(“xiaorui.cc”,”fengyun”)
value=mc.get(“xiaorui.cc”)
mc.set(“another_key”,3)
mc.delete(“another_key)
mc.set(“key”,”1″) #用于自動增量/減量的必須是字符串
mc.incr(“key”)
mc.decr(“key”)
標準的使用 memcache 作為數(shù)據(jù)庫緩存的方法如下:
key=derive_key(obj)
obj=mc.get(key)
if not obj:
obj=backend_api.get(…)
mc.set(obj)
#現(xiàn)在可以操作 obj
構造函數(shù)
delete(key,time=0)
刪除某個鍵。time 的單位是秒,確保特定時間內(nèi)的 set/update 操作會失敗。返回 1 成功,0 失敗。
incr(key,delta=1)
給自增量變量加上 delta,默認為 1。
decr(key,delta=1)
給自減量變量減去 delta,默認為 1。
add(key,val,time=0,min_compress_len=0)
添加一個鍵值對,內(nèi)部調(diào)用 _set() 方法。
replace(key,val,time=0,min_compress_len=0)
替換值,內(nèi)部調(diào)用_set() 方法。
set(key,val,time=0,min_compress_len=0)
無條件的設置鍵值對。time 設置超時,單位是秒。min_compress_len 用于設置 zlib 壓縮。內(nèi)部調(diào)用_set() 方法。
set_multi(mapping,time=0,key_prefix=”,min_compress_len=0)
設置多個鍵值對。
get(key)
獲取值。出錯則返回 None。
get_multi(keys,key_prefix=”)
獲取多個鍵的值,返回字典。keys 為健明列表。key_prefix 是鍵名前綴,可以最終構成 key_prefix+key 的完整鍵名。與 set_multi 中一樣。
Memcached 本身沒有的實現(xiàn)的,但是高手還是多呀,有個高手開源了一個 memcached 隊列的 python 實現(xiàn)方案。
RedQueue 參考了 github 開源項目 starling(ruby 寫的), twitter 曾經(jīng)使用伊做隊列服務,后來改成了用 scala 寫的 scaling(kestrol) . Redqueue 用 python 的高性能框架 tornado 寫成。支持 memcache 協(xié)議, 也就是說偽裝成一個 memcache server,由于許多語言都有了 memcache 庫,也就有了應用 redqueue 的土壤。
redqueue 是可以持久化的,使用日志文件記錄所有的操作,當系統(tǒng)重啟的時候,可以恢復沒有處理的未超時任務重新處理。 這樣對于 server 端的容錯性有好處。更進一步的是,redqueue 具有客戶端容錯性,客戶通過 get 命令從隊列中得到一個任務,使用 delete 刪除這個任務,如果沒有 delete 而因某種原因退出了,則該任務會被 server 重新塞入隊列等待處理。
http://wiki.jikexueyuan.com/project/python-actual-combat/images/38.jpg" alt="pic" />
關于 redqueue 的 python 應用小 demo ~
# 引入 memcache 模塊
import memcache
#初始化客戶端
mc = memcache.Client(['127.0.0.1:12345']) # 假設 redqueue server 守候在 localhost 的 12345 端口
# 發(fā)布一個項目到 key myqueue 中, 值為"Hello world"
mc.set("xiaorui", "good")
# 消費者從 queue server 中取出一個任務, 并打印
print mc.get("xiaorui") # 應該是 good
# 刪除一個任務,必須做,否則 server 會認為客戶端異常發(fā)生了,而重新隊列處理該任務
# 什么時候客戶端確認該任務已經(jīng)確保執(zhí)行了,就可以 delete 掉。在這之間,任務不會被其他客戶端執(zhí)行。
mc.delete("xiaorui")
http://wiki.jikexueyuan.com/project/python-actual-combat/images/39.jpg" alt="pic" />
這個是作者給的過程:
== Install and Run
Install tornado and (optional) python-memcached for client testing
Get the source from
git@github.com:superisaac/redqueue.git
Install
% python setup.py install
Make the log dir
% mkdir -p log
Run the server
% redqueue_server.py
For more options please run
% redqueue_server.py --help
== Reserve/delete mode
Reserve/delete mode is currently the sole mode, once an item is fetched, a delete request must be send later to mark the item is used, or else the item will be recycled back later.
>>> mc.set('abc', '123')
>>> v = mc.get('abc')
>>> if v is not None:
>>> mc.delete('abc')
現(xiàn)在隊列有了,我給大家說下,我那邊是咋實現(xiàn)排隊的~
當用戶訪問頁面下一步的時候,我會判斷隊列,要是他前面有人在進行,我會給他重定向到最初的頁面。當別人搞完了,他才可以的。
但是這樣的話,還有個問題,那就是要是有 5 個人同時進了隊列里面了,我給他們已經(jīng)排序了,要是老大和老二,他不在進行了,老三的話,咋辦。。。 這時候就需要配置隊列里面的值和 kv 的一個值做時間的生效。 也就是說 老大和老二要是在指定的時間內(nèi)沒有完成的話,我會把他們踢出去,這樣老三就成老大了。
本文出自 “峰云,就她了?!?博客,謝絕轉(zhuǎn)載!