CI项目设计Redis队列

项目中需要设计一个能平衡处理多个用户请求的队列系统。通过Redis实现,当用户登录后,系统检查管理员队列和处理能力。如果管理员无法处理新请求,则从队列中移除,否则分配给用户并减少其处理能力。为解决Redis不支持循环链表的问题,采用二级结构——用户ID列表和用户详细信息映射,实现了类似循环链表的功能,虽然操作复杂性增加,但满足了存储需求。

项目开发过程中需要设计提供可平衡的处理多个用户请求的队列。

需求:

当用户登录后,查看系统中已经登录的管理员队列,然后查看后台管理员的处理能力,如果已经不能处理新的请求,则把该管理员从处理队列中删除,否则把

该管理员分配给该用户,管理员的处理能力减一,系统当前所指向的管理员+1即指向下一位可以处理问题的管理员。

分析:

最简单的设计就是维护一个循环链表的队列,可以方便的删除和修改信息,但是Redis中并不能处理这样复制的结构信息,因此只能另辟蹊径了,考虑使用

二重的结构来转换循环链表结构。先看下原来的结构:


这样的结构可以方便的处理问题,不过在redis中存储这样的结构并不能轻易的做到,于是考虑使用用户ID建立队列list,然后使用用户ID建立(key,value),当然也可以把

用户的信息建立一个以ID为KEY的list,于是经过这样的二级结构的转换,Redis就可以处理原本复杂的结构了,这里处理的时候,先检查主队列元素,然后根据以值为

Key来获取其他复杂的信息进行处理,这样设计的结构: 


这样的结构,无论删除或者添加都必须操作两个地方....以操作的复杂性换取存储的复杂性,未必设计的好,不过先用来实现功能再说吧。

Redis类: 

<?php

if (!defined('BASEPATH'))
    exit('No direct script access allowed');

class Redisdb {
    private $size ;
    private $redis ;
    private $channel_queue;
    private $current_index ;
    public function __construct() {
        $this->size = 100;
        $this->redis = new Redis();
        $this->channel_queue = 'staffs';
        $this->redis->connect('127.0.0.1', '6379');
        $this->set_index();
    }
    public function set_index($index=0){
        $this->redis->set('current_index',$index);
    }
    public function en_queue($key,$value) {     
        return  $this->redis->rpush($this->channel_queue, $key) && $this->redis->set($key,$value);;
    }
    public function is_empty(){
       return  $this->redis->lsize('admins')<=0;
    }
    public function is_full(){
        return $this->redis->lsize($this->channel_queue) >= $this->size;
    }
    public function remove($value){
        return $this->redis->lrem($this->channel_queue,$value);
    }
    public function get_list(){
        return $this->redis->lrange($this->channel_queue,0,-1);
    }
    public function delete_key($key){
        return $this->redis->delete($key);
    }
    public function get_value($key){
        return  $this->redis->get($key);
    }
  public function allocate_admin(){
	$index = $this->redis->get('current_index');
        $size  = $this->redis->lsize('admins');
	if($size ==0){
		return false;
	}
        if($index<$size){
            $key =  $this->redis->lindex('staffs',$index);
            if($this->redis->get($key)<=1){
               $this->remove($key);
               return $key;
            }else{
		$this->redis->decr($key);
		$this->redis->incr('current_index');        
		return $key ;
                
            }
             
        }else{
	    $this->redis->set('current_index',0);
            $this->allocate_admin();
        }
}

}



评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值