基于Redis的MessageQueue队列封装
来源:互联网 发布:淘宝图片怎么拍 编辑:程序博客网 时间:2024/06/06 12:56
Redis的链表List可以用来做链表,高并发的特性非常适合做分布式的并行消息传递。
项目地址:https://github.com/huyanping/Zebra-PHP-Framework
左进右出
1
2
$redis
->lPush(
$key
,
$value
);
$redis
->rPop(
$key
);
以下程序已在生产环境中正式使用。
基于Redis的PHP消息队列封装
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
<?php
/**
* Created by PhpStorm.
* User: huyanping
* Date: 14-8-19
* Time: 下午12:10
*
* 基于Redis的消息队列封装
*/
namespace
Zebra\MessageQueue;
class
RedisMessageQueue
implements
IMessageQueue
{
protected
$redis_server
;
protected
$server
;
protected
$port
;
/**
* @var 消息队列标志
*/
protected
$key
;
/**
* 构造队列,创建redis链接
* @param $server_config
* @param $key
* @param bool $p_connect
*/
public
function
__construct(
$server_config
=
array
(
'IP'
=>
'127.0.0.1'
,
'PORT'
=>
'6379'
),
$key
=
'redis_message_queue'
,
$p_connect
= false)
{
if
(
empty
(
$key
))
throw
new
\Exception(
'message queue key can not be empty'
);
$this
->server =
$server_config
[
'IP'
];
$this
->port =
$server_config
[
'PORT'
];
$this
->key =
$key
;
$this
->check_environment();
if
(
$p_connect
) {
$this
->pconnect();
}
else
{
$this
->connect();
}
}
/**
* 析构函数,关闭redis链接,使用长连接时,最好主动调用关闭
*/
public
function
__destruct()
{
$this
->close();
}
/**
* 短连接
*/
private
function
connect()
{
$this
->redis_server =
new
\Redis();
$this
->redis_server->connect(
$this
->server,
$this
->port);
}
/**
* 长连接
*/
public
function
pconnect()
{
$this
->redis_server =
new
\Redis();
$this
->redis_server->pconnect(
$this
->server,
$this
->port);
}
/**
* 关闭链接
*/
public
function
close()
{
$this
->redis_server->close();
}
/**
* 向队列插入一条信息
* @param $message
* @return mixed
*/
public
function
put(
$message
)
{
return
$this
->redis_server->lPush(
$this
->key,
$message
);
}
/**
* 向队列中插入一串信息
* @param $message
* @return mixed
*/
public
function
puts(){
$params
= func_get_args();
$message_array
=
array_merge
(
array
(
$this
->key),
$params
);
return
call_user_func_array(
array
(
$this
->redis_server,
'lPush'
),
$message_array
);
}
/**
* 从队列顶部获取一条记录
* @return mixed
*/
public
function
get()
{
return
$this
->redis_server->lPop(
$this
->key);
}
/**
* 选择数据库,可以用于区分不同队列
* @param $database
*/
public
function
select(
$database
)
{
$this
->redis_server->select(
$database
);
}
/**
* 获得队列状态,即目前队列中的消息数量
* @return mixed
*/
public
function
size()
{
return
$this
->redis_server->lSize(
$this
->key);
}
/**
* 获取某一位置的值,不会删除该位置的值
* @param $pos
* @return mixed
*/
public
function
view(
$pos
)
{
return
$this
->redis_server->lGet(
$this
->key,
$pos
);
}
/**
* 检查Redis扩展
* @throws Exception
*/
protected
function
check_environment()
{
if
(!\
extension_loaded
(
'redis'
)) {
throw
new
\Exception(
'Redis extension not loaded'
);
}
}
}
如果需要一次写入多个队列,可以使用如下调用方式:
1
2
3
4
<?php
$redis
=
new
RedisMessageQueue();
$redis
->puts(1, 2, 3, 4);
$redis
->puts(5, 6, 7, 8, 9);
模仿HTTPSQS输出结果的封装如下,提供了写入位置和读取位置记录的功能:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
<?php
/**
* Created by PhpStorm.
* User: huyanping
* Date: 14-9-5
* Time: 下午2:16
*
* 附加了队列状态信息的RedisMessageQueue
*/
namespace
Zebra\MessageQueue;
class
RedisMessageQueueStatus
extends
RedisMessageQueue {
protected
$record_status
;
protected
$put_position
;
protected
$get_position
;
public
function
__construct(
$server_config
=
array
(
'IP'
=>
'127.0.0.1'
,
'PORT'
=>
'6379'
),
$key
=
'redis_message_queue'
,
$p_connect
= false,
$record_status
=true
){
parent::__construct(
$server_config
,
$key
,
$p_connect
);
$this
->record_status =
$record_status
;
$this
->put_position =
$this
->key .
'_put_position'
;
$this
->get_position =
$this
->key .
'_get_position'
;
}
public
function
get(){
if
(
$queue
= parent::get()){
$incr_result
=
$this
->redis_server->incr(
$this
->get_position);
if
(!
$incr_result
)
throw
new
\Exception(
'can not mark get position,please check the redis server'
);
return
$queue
;
}
else
{
return
false;
}
}
public
function
put(
$message
){
if
(parent::put(
$message
)){
$incr_result
=
$this
->redis_server->incr(
$this
->put_position);
if
(!
$incr_result
)
throw
new
\Exception(
'can not mark put position,please check the redis server'
);
return
true;
}
else
{
return
false;
}
}
public
function
puts_status(){
$message_array
= func_get_args();
$result
= call_user_func_array(
array
(
$this
,
'puts'
),
$message_array
);
if
(
$result
){
$this
->redis_server->incrBy(
$this
->put_position,
count
(
$message_array
));
return
true;
}
return
false;
}
public
function
size(){
return
$this
->redis_server->lSize(
$this
->key);
}
public
function
status(){
$status
[
'put_position'
] = (
$put_position
=
$this
->redis_server->get(
$this
->put_position)) ?
$put_position
: 0;
$status
[
'get_position'
] = (
$get_position
=
$this
->redis_server->get(
$this
->get_position)) ?
$get_position
: 0;
$status
[
'unread_queue'
] =
$this
->size();
$status
[
'queue_name'
] =
$this
->key;
$status
[
'server'
] =
$this
->server;
$status
[
'port'
] =
$this
->port;
return
$status
;
}
public
function
status_normal(){
$status
=
$this
->status();
$message
=
'Redis Message Queue'
. PHP_EOL;
$message
.=
'-------------------'
. PHP_EOL;
$message
.=
'Message queue name:'
.
$status
[
'queue_name'
] . PHP_EOL;
$message
.=
'Put position of queue:'
.
$status
[
'put_position'
] . PHP_EOL;
$message
.=
'Get position of queue:'
.
$status
[
'get_position'
] . PHP_EOL;
$message
.=
'Number of unread queue:'
.
$status
[
'unread_queue'
] . PHP_EOL;
return
$message
;
}
public
function
status_json(){
return
\json_encode(
$this
->status());
}
}
0 0
- 基于Redis的MessageQueue队列封装
- 基于Redis的MessageQueue队列封装
- 基于Redis的MessageQueue队列封装
- 基于Redis的消息队列封装和测试
- 基于redis的消息队列
- GuozhongCrawler实现的基于redis的队列
- 基于Redis的消息队列php-resque
- 基于Redis实现的延迟队列
- 基于redis的延迟消息队列设计
- 基于redis的延迟消息队列设计
- 基于redis的延迟消息队列设计
- 基于redis的延迟消息队列设计
- 基于System V Message queue的PHP消息队列封装
- 基于spring整合activeMQ以及点对点队列的封装
- 基于redis构建消息队列
- 基于Redis实现延迟队列
- 基于 redis实现含有冻结时间的mq队列
- 基于redis+mysql+php的简单队列实现
- 是真是假?
- 彻底了解JAVA-策略模式(皇室战争是怎样炼成的)
- Javascript例题(持续更新)
- 正则表达式基本语法
- Android透明度换算
- 基于Redis的MessageQueue队列封装
- 中介者模式
- ios9新特性
- 无指针的Splay
- 字符串的截取
- Webpack:模块打包原理
- 线段树入门之入门
- 全面解析Notification
- Cannot resolve method getSupportFragmentManager();