通过memcached实现领号排队功能及python队列实例

前言:

前段时间写的那个域用户平台,要做大量的新功能运维测试,据说要抄IT组,让那帮人到搞,跑一下 ! 尼玛,这可吓坏了我了。 因为平台要和windows做大量的交互,那边powershell又很不给力,改成多线程版本后,出现莫名的问题,很让人闹心。现在的状态是,client给server端可以同时推送两片信息,要是多的话,powershell实在处理不了,我只能放到queue队列里面了。


现在很多的堵塞都是在windows那边,我这边因为用的是tornado,对于用户访问是无压力的,但是windows那边不能同时运行多了,不然会提示bug。。

ad的信息我暂时还没有批量的同步过来,所以只能单点搞了 ~

   一直在想咋才能不出丑。所以做了好多的限制,比如短信接口的token机制,用户更新接口的次数的限制。 现在唯一的节点就是和win那边的交互。别等到了周一的时候,一帮人把 获取手机号码、修改密码、更新用户信息的接口给点爆了。

   突然想到12306那个渣渣,可以用排队呀。。。 这样的话,最少能看起来很高端的样子。


095147584.jpg


我的前端实现 ~

用户点击的时候,我会从后端的api查看队列中的数目,以及有谁排在我的前面 ~

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
         $( "#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();
                             }
                         }
                     });
         });
});



后端的实现~

不用redis做队列的原因是,python调用队列的时候总是莫名的关闭,卸载安装了好多遍。。。怪事 ~  和powershell多线程一样都很怪~

安装配置memcached环境,简单点直接yum ~

需要编译安装的朋友,用下面的脚本~

1
2
3
4
5
6
7
8
9
10
11
12
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


100923886.jpg

启动memcached 命令是:  /usr/local/memcached/bin/memcached -d -m 100 -c 1000 -u root -p 11211


1
2
3
4
5
6
7
8
9
10
-d 选项是启动一个守护进程
-m 是分配给Memcache使用的内存数量,单位是MB,默认64MB
-M  return  error on memory exhausted (rather than removing items)
-u 是运行Memcache的用户,如果当前为root 的话,需要使用此参数指定用户
-l 是监听的服务器IP地址,默认为所有网卡
-p 是设置Memcache的TCP监听的端口,最好是 1024 以上的端口
-c 选项是最大运行的并发连接数,默认是 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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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作为数据库缓存的方法如下:
  key=derive_key(obj)
  obj=mc. get (key)
  if  not obj:
  obj=backend_api. get (…)
  mc. set (obj)
  #现在可以操作obj


构造函数

delete(key,time=0)

删除某个键。time的单位是秒,确保特定时间内的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)

添加一个键值对,内部调用_set()方法。

replace(key,val,time=0,min_compress_len=0)

替换值,内部调用_set()方法。

set(key,val,time=0,min_compress_len=0)

无条件的设置键值对。time设置超时,单位是秒。min_compress_len用于设置zlib压缩。内部调用_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本身没有的实现的,但是高手还是多呀,有个高手开源了一个memcached队列的python实现方案。


RedQueue参考了github开源项目starling(ruby写的), twitter曾经使用伊做队列服务,后来改成了用scala写的scaling(kestrol) . Redqueue用python的高性能框架tornado写成。支持memcache协议, 也就是说伪装成一个memcache server,由于许多语言都有了memcache库,也就有了应用redqueue的土壤。 
redqueue是可以持久化的,使用日志文件记录所有的操作,当系统重启的时候,可以恢复没有处理的未超时任务重新处理。 这样对于server端的容错性有好处。更进一步的是,redqueue具有客户端容错性,客户通过get命令从队列中得到一个任务,使用delete删除这个任务,如果没有delete而因某种原因退出了,则该任务会被server重新塞入队列等待处理。

101232965.jpg


关于redqueue的python应用小demo ~

1
2
3
4
5
6
7
8
9
10
11
12
13
# 引入memcache模块
import  memcache
#初始化客户端
mc = memcache.Client([ '127.0.0.1:12345' ])  # 假设redqueue server守候在localhost的 12345 端口
# 发布一个项目到key myqueue中, 值为 "Hello world"
mc. set ( "xiaorui" "good" )
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
# 消费者从queue server中取出一个任务, 并打印
print mc. get ( "xiaorui" )  # 应该是 good
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
# 删除一个任务,必须做,否则server会认为客户端异常发生了,而重新队列处理该任务
# 什么时候客户端确认该任务已经确保执行了,就可以 delete 掉。在这之间,任务不会被其他客户端执行。
mc. delete ( "xiaorui" )

105833308.jpg

这个是作者给的过程:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
== 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  is  not None:
    >>>     mc. delete ( 'abc' )


现在队列有了,我给大家说下,我那边是咋实现排队的~

当用户访问页面下一步的时候,我会判断队列,要是他前面有人在进行,我会给他重定向到最初的页面。当别人搞完了,他才可以的。

但是这样的话,还有个问题,那就是要是有5个人同时进了队列里面了,我给他们已经排序了,要是老大和老二,他不在进行了,老三的话,咋办。。。  这时候就需要配置队列里面的值和kv的一个值做时间的生效。  也就是说  老大和老二要是在指定的时间内没有完成的话,我会把他们踢出去,这样老三就成老大了。



 本文转自 rfyiamcool 51CTO博客,原文链接:http://blog.51cto.com/rfyiamcool/1330636,如需转载请自行联系原作者





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值