程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> 淺析關於PHP中Sphinx長連接問題

淺析關於PHP中Sphinx長連接問題

編輯:關於PHP編程

關於什麼是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的連接也會自動斷開,而不是保持連接狀態。

這篇帖子也佐證了樓主的這個想法:http://sphinxsearch.com/forum/view.html?id=7200


> 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擴展,然後寫如下測試代碼:


<!--?php<br /-->
$s = new SphinxClient();

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

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved