当前位置:首页 > PHP教程 > php高级应用 > 列表

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

发布:smiling 来源: PHP粉丝网  添加日期:2014-08-27 14:16:53 浏览: 评论:0 

关于什么是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的连接也会自动断开,而不是保持连接状态.

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

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

  1.  
  2. $s = new SphinxClient(); 
  3. //开源代码phpfensi.com 
  4. var_dump($s); 
  5. $s->setServer('192.168.1.108','9312'); 
  6. //$s->open(); 
  7. var_dump($s->query('abxxxx')); 
  8. var_dump($s->query('abxxxx')); 

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

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

  1. 611 fcntl64(3, F_SETFL, O_RDONLY|O_NONBLOCK) = 0 
  2. 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) 
  3. 613 select(4, NULL, [3], NULL, {60, 0})     = 1 (out [3], left {59, 999996}) 
  4. 614 fcntl64(3, F_SETFL, O_RDONLY)           = 0 
  5. 615 send(3, "1", 4, MSG_NOSIGNAL)    = 4 
  6. 616 recv(3, "1", 4, 0)               = 4 
  7. 617 send(3, "1312241", 16, MSG_NOSIGNAL) = 16 
  8. 618 send(3, "246abxx"..., 140, MSG_NOSIGNAL) = 140 
  9. 619 recv(3, "131`", 8, 0)       = 8 
  10. 620 recv(3, "25title4text2"..., 96, 0) = 96 
  11. 621 close(3)     
  12. 。。。。。。。。。。。。。。。。。。。 
  13. 。。。。。。。。。。。。。。。。。。。 
  14. 756 socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3 
  15. 757 fcntl64(3, F_SETFL, O_RDONLY|O_NONBLOCK) = 0 
  16. 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) 
  17. 759 select(4, NULL, [3], NULL, {60, 0})     = 1 (out [3], left {59, 999997}) 
  18. 760 fcntl64(3, F_SETFL, O_RDONLY)           = 0 
  19. 761 send(3, "1", 4, MSG_NOSIGNAL)    = 4 
  20. 762 recv(3, "1", 4, 0)               = 4 
  21. 763 send(3, "1312241", 16, MSG_NOSIGNAL) = 16 
  22. 764 send(3, "246abxx"..., 140, MSG_NOSIGNAL) = 140 
  23. 765 recv(3, "131`", 8, 0)       = 8 
  24. 766 recv(3, "25title4text2"..., 96, 0) = 96 
  25. 767 close(3)                                = 0 
  26. 768 write(1, "array(9) {n", 11array(9) { 

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

  1. 611 fcntl64(3, F_SETFL, O_RDONLY|O_NONBLOCK) = 0 
  2. 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) 
  3. 613 select(4, NULL, [3], NULL, {60, 0})     = 1 (out [3], left {59, 999996}) 
  4. 614 fcntl64(3, F_SETFL, O_RDONLY)           = 0 
  5. 615 send(3, "1", 4, MSG_NOSIGNAL)    = 4 
  6. 616 recv(3, "1", 4, 0)               = 4 
  7. 617 send(3, "441", 12, MSG_NOSIGNAL) = 12 
  8. 618 select(4, [3], NULL, [3], {0, 0})       = 0 (Timeout) 
  9. 619 send(3, "1312241", 16, MSG_NOSIGNAL) = 16 
  10. 620 send(3, "246abxx"..., 140, MSG_NOSIGNAL) = 140 
  11. 621 recv(3, "131`", 8, 0)       = 8 
  12. 622 recv(3, "25title4text2"..., 96, 0) = 96 
  13. 623 write(1, "array(9) {n", 11array(9) { 
  14. 624 )    = 11 

Tags: Sphinx长连接 PHP长连接

分享到: