鍍金池/ 教程/ Python/ 通過 memcached 實現(xiàn)領號排隊功能及 python 隊列實例
通過 memcached 實現(xiàn)領號排隊功能及 python 隊列實例
利用 pypy 提高 python 腳本的執(zhí)行速度及測試性能
Python FAQ3-python 中 的原始(raw)字符串
Mongodb 千萬級數(shù)據(jù)在 python 下的綜合壓力測試及應用探討
Parallel Python 實現(xiàn)程序的并行多 cpu 多核利用【pp 模塊】
python simplejson 模塊淺談
服務端 socket 開發(fā)之多線程和 gevent 框架并發(fā)測試[python 語言]
python Howto 之 logging 模塊
python 之 MySQLdb 庫的使用
關于 python 調(diào)用 zabbix api 接口的自動化實例 [結合 saltstack]
python 之利用 PIL 庫實現(xiàn)頁面的圖片驗證碼及縮略圖
Python 通過 amqp 消息隊列協(xié)議中的 Qpid 實現(xiàn)數(shù)據(jù)通信
python 中用 string.maketrans 和 translate 巧妙替換字符串
python linecache 模塊讀取文件用法詳解
Python 批量更新 nginx 配置文件
python 計算文件的行數(shù)和讀取某一行內(nèi)容的實現(xiàn)方法
python+Django 實現(xiàn) Nagios 自動化添加監(jiān)控項目
多套方案來提高 python web 框架的并發(fā)處理能力
python 寫報警程序中的聲音實現(xiàn) winsound
python 調(diào)用 zabbix 的 api 接口添加主機、查詢組、主機、模板
對 Python-memcache 分布式散列和調(diào)用的實現(xiàn)
使用 python 構建基于 hadoop 的 mapreduce 日志分析平臺
一個腳本講述 python 語言的基礎規(guī)范,適合初學者
Python 編寫的 socket 服務器和客戶端
如何將 Mac OS X10.9 下的 Python2.7 升級到最新的 Python3.3
python 監(jiān)控文件或目錄變化
報警監(jiān)控平臺擴展功能 url 回調(diào)的設計及應用 [python 語言]
Python 處理 cassandra 升級后的回滾腳本
python 實現(xiàn) select 和 epoll 模型 socket 網(wǎng)絡編程
關于 B+tree (附 python 模擬代碼)
通過 python 和 websocket 構建實時通信系統(tǒng)[擴展 saltstack 監(jiān)控]

通過 memcached 實現(xiàn)領號排隊功能及 python 隊列實例

前言:

前段時間寫的那個域用戶平臺,要做大量的新功能運維測試,據(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)載!