好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

浅析关于PHP中Sphinx长连接问题 - php高级应用

浅析关于PHP中Sphinx长连接问题

关于什么是Sphinx这里我不不介绍了大家可百度查一下,下面我来介绍的是关于PHP中Sphinx长连接问题解析,希望些文章对各位朋友有帮助.

SphinxClient::open

(PECL sphinx >= 1.0.3)

SphinxClient::open — 建立到搜索服务端的持久连接

说明: public bool SphinxClient::open(void)

建立到搜索服务端的持久连接.

参数:此函数没有参数.

返回值:成功时返回 TRUE,或者在失败时返回 FALSE.

今日在做PHP系统代码优化时,对sphinx的长连接做了一些分析发现php的sphinx api并不是我们想象中的那样会在php-fpm的fastcgi状态下一直与sphinx的searchd进程保持长连接,sphinx的api接口中open()方法仅仅提供了在一次会话请求中保证多个sphinx调用在单个php进程中是共用一个sphinx tcp连接通道,当php解释运行完,与sphinx的连接也会自动断开,而不是保持连接状态.

> So it seems that the definition of  'persistent connection'  in Sphinx is different from  > persistent MySql connections when using a PhP API : the persistence is only across  > multiple calls *in the same php request execution*  and  not persistence within the client  > process i.e. across multiple php requests. 

我们可以做一个这样的实验来证明我的观点,给php增加sphinx.so扩展,然后写如下测试代码:

  $s  =  new  SphinxClient();  //开源代码phpfensi测试数据   var_dump( $s );  $s ->setServer( '192.168.1.108' , '9312' );  //$s->open();   var_dump( $s ->query( 'abxxxx' ));  var_dump( $s ->query( 'abxxxx' )); 

注意这里$s->open()先屏蔽,然后我们在cli状态下利用strace命令跟踪执行此php脚本,收集系统调用信息会发现.

在系统调用中出现了两次connect到192.168.1.108的请求,也就是说在没调用open方法的时候,在同一个php运行时中会导致两次对sphinx产生的tcp请求.

611 fcntl64(3, F_SETFL, O_RDONLY|O_NONBLOCK) = 0  612 connect(3, {sa_family=AF_INET, sin_port=htons(9312), sin_addr=inet_addr( "192.168.1.108" )}, 16) = -1 EINPROGRESS (Operation now in progress)  613 select(4, NULL, [3], NULL, {60, 0})     = 1 (out [3], left {59, 999996})  614 fcntl64(3, F_SETFL, O_RDONLY)           = 0  615 send(3,  "1" , 4, MSG_NOSIGNAL)    = 4  616 recv(3,  "1" , 4, 0)               = 4  617 send(3,  "1312241" , 16, MSG_NOSIGNAL) = 16  618 send(3,  "246abxx" ..., 140, MSG_NOSIGNAL) = 140  619 recv(3,  "131`" , 8, 0)       = 8  620 recv(3,  "25title4text2" ..., 96, 0) = 96  621 close(3)      。。。。。。。。。。。。。。。。。。。  。。。。。。。。。。。。。。。。。。。  756 socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3  757 fcntl64(3, F_SETFL, O_RDONLY|O_NONBLOCK) = 0  758 connect(3, {sa_family=AF_INET, sin_port=htons(9312), sin_addr=inet_addr( "192.168.1.108" )}, 16) = -1 EINPROGRESS (Operation now in progress)  759 select(4, NULL, [3], NULL, {60, 0})     = 1 (out [3], left {59, 999997})  760 fcntl64(3, F_SETFL, O_RDONLY)           = 0  761 send(3,  "1" , 4, MSG_NOSIGNAL)    = 4  762 recv(3,  "1" , 4, 0)               = 4  763 send(3,  "1312241" , 16, MSG_NOSIGNAL) = 16  764 send(3,  "246abxx" ..., 140, MSG_NOSIGNAL) = 140  765 recv(3,  "131`" , 8, 0)       = 8  766 recv(3,  "25title4text2" ..., 96, 0) = 96  767 close(3)                                = 0  768 write(1,  "array(9) {n" , 11array(9) { 

然后我们取消open调用的注释,继续strace,会发现这时候依然是连续调用两次query方法,但在第一次query调用后api不会立即close掉tcp连接,而是继续给到第二次query调用使用.

611 fcntl64(3, F_SETFL, O_RDONLY|O_NONBLOCK) = 0  612 connect(3, {sa_family=AF_INET, sin_port=htons(9312), sin_addr=inet_addr( "192.168.1.108" )}, 16) = -1 EINPROGRESS (Operation now in progress)  613 select(4, NULL, [3], NULL, {60, 0})     = 1 (out [3], left {59, 999996})  614 fcntl64(3, F_SETFL, O_RDONLY)           = 0  615 send(3,  "1" , 4, MSG_NOSIGNAL)    = 4  616 recv(3,  "1" , 4, 0)               = 4  617 send(3,  "441" , 12, MSG_NOSIGNAL) = 12  618 select(4, [3], NULL, [3], {0, 0})       = 0 (Timeout)  619 send(3,  "1312241" , 16, MSG_NOSIGNAL) = 16  620 send(3,  "246abxx" ..., 140, MSG_NOSIGNAL) = 140  621 recv(3,  "131`" , 8, 0)       = 8  622 recv(3,  "25title4text2" ..., 96, 0) = 96  623 write(1,  "array(9) {n" , 11array(9) {  624 )    = 11 

查看更多关于浅析关于PHP中Sphinx长连接问题 - php高级应用的详细内容...

  阅读:45次