关于什么是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();
-
- var_dump($s);
- $s->setServer('192.168.1.108','9312');
-
- 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
|