欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

关于redis中的发布与订阅以及shell脚本与php之间的相互传值

 redis的发布订阅是一个很方便的消息队列功能,用过rabbmitmq或者beanstalk的话就对这不陌生了。消息队列就是一边往队列里写东西,每次写入消息后另一方立马就感知到了消息并且去处理消息。比起beanstalk目前我觉得redis的消息队列缺少了一个任务放回策略。不过对于消息队列一般的功能也够用了。

    消息队列的发布方php代码:


$redis = new Redis();
$redis->connect('192.168.162.19', 6379);
$redis->auth('data');
$channel = 'English';
$message = 'new word';
#向频道发送消息,返回接收到此信息的订阅者数量
$clients = $redis->publish($channel, $message);

    也可以直接在redis命令行下操作:返回的0和1表示有几个终端接收到了消息。



192.168.162.19:6379> publish English 13
(integer) 0
192.168.162.19:6379> publish English 13q
(integer) 1

    接收到的PHP代码:



#设置socket连接不超时
ini_set('default_socket_timeout', -1);   
$redis = new Redis();
#此处连接redis时不要输入超时时间,如果配置了超时时间为某个时间值,则会出现redis read error错误并停止消除队列监听。
$redis->connect('192.168.162.19', 6379);
$redis->auth('data');

#设置客户端监听redisu订阅频道,如有消息执行回调函数callback_function
$result=$redis->subscribe(array('English'), 'callback_function');
function callback_function($instance, $channelName, $message)
{
    print_r($instance);
    echo $channelName. $message;
    #$instance->unsubscribe(array('English'));
    #exit(88);
}
exit('99');

命令行下执行上面的php接收方代码,则发布发发布一条消息后,接收方就会打印出$instance,$channelName和$message的内容。这里需要注意的是。
1,$instance虽然是redis连接资源,但它不能使用redis的get,set之类的方法,只能使用subscribe,psubscribe,unsubscribe,punsubscribe四个命令。故如果要在callback_function中再调用redis拿数据的话,需要重新调用redis连接或其它方式。
2,在回调方法中调用unsubscribe取消订阅消息并不能停止客户端的php脚本,此时只是不接收消息,但是在linux服务器上的php脚本依然是阻塞状态。
3,psubscribe和punsubscribe与不带p的命令的区别就是带p的命令可以执行preg模式匹配。其它一样。
4,正因为2的原因,如果在执行一次订阅处理操作后要退出订阅并只能在php程序中执行exit(我未发现其它办法)。


因为我在开发的一个程序是用shell脚本执行php进行sphinx数据同步的整套程序,执行过程中shell和php需要相互交互传递数据。
shell调用php传递参数的方式之前也有文章:http://www.04007.cn/article/381.html
shell调用php之后如果要获取php的执行结果,也有两种方法:
1,php中直接执行shell命令设置变量或者通过第三方比如redis、比如文件缓存得来交互数据。不过这个有些麻烦。
2,如果shell中只需要得到php执行的一个结果,比如成功与否,则完全可以在php执行结束时输出状态码。然后shell中使用$?来取得这个状态码。
第2个方法在这个文章里有涉及:http://www.04007.cn/article/449.html

    php中使用exit函数输出状态码,但是需要注意:exit的参数status如果是一个字符串,在退出之前该函数会打印status,如果status是一个 integer,该值会作为退出状态码,并且不会被打印输出。退出状态码应该在范围0至254,不应使用被PHP保留的退出状态码255。状态码0用于成功中止程序。


void exit ([ string $status ] )
void exit ( int $status )
#以下这两行的执行意义完全不同。
exit('99')
exit(99)

另外:连接redis时使用pconnect和connet的区别,有篇文章写得不错:
1. 当使用pconnect时,连接会被重用,连接的生命周期是fpm进程的生命周期,而非一次php的执行。 
2.如果代码中使用pconnect,close的作用仅是使当前php不能再进行redis请求,但无法真正关闭redis长连接,连接在后续请求中仍然会被重用,直至fpm进程生命周期结束。


本文地址:http://www.04007.cn/article/453.html 未经许可,不得转载.

来自 http://www.04007.cn/article/453.html

普通分类: