本文目錄一覽:
thrift server timed out超時
寫於2020-01-13
一、故障描述
時間是2017年的某天:
有個服務,Python+Thrift做的Server;
對應庫及版本:Cython==0.23.5,thriftpy==0.3.7。
相關配置: 服務超時時間3s
線上使用Supervisor管理進程。
一直跑著沒問題,有天運維同學提問題,該服務日誌出現大量time out(那時候Kibana還沒搭起來,日誌只能在伺服器上看)。日誌如下:
二、排查過程
猜測:
驗證:
三、溝通問題
四、收穫
Thrift server比較和使用
Thrift提供了多種伺服器實現。
TSimplerServer在while循環中每次接受一個連接,處理連接請求,直到客戶端關閉了連接,它才會去接受一個新的連接。由於它只在一個單獨的線程中以阻塞I/O的方式完成這些工作,所以它只能服務一個客戶端連接,其他所有客戶端在被伺服器端接受之前都只能等待。其使用方法如下:
TNonblockingServer 使用非阻塞的 I/O 解決了TSimpleServer一個客戶端阻塞其他所有客戶端的問題。它使用了java.nio.channels.Selector,通過調用select(),它使得你阻塞在多個連接上,而不是阻塞在單一的連接上。當一或多個連接準備好被接受/讀/寫時,select()調用便會返回。TNonblockingServer處理這些連接的時候,要麼接受它,要麼從它那讀數據,要麼把數據寫到它那裡,然後再次調用select()來等待下一個可用的連接。通用這種方式,server可同時服務多個客戶端,而不會出現一個客戶端把其他客戶端全部「餓死」的情況。
使用方法:
ThreadedSelectorServer允許你用多個線程來處理網路 I/O。它維護了兩個線程池,一個用來處理網路 I/O,另一個用來進行請求的處理。使用方法:
TThreadPoolServer有一個專用的線程用來接受連接旦接受了一個連接,它就會被放入ThreadPoolExecutor中的一個 worker 線程里處理。worker 線程被綁定到特定的客戶端連接上,直到它關閉。一旦連接關閉,該worker線程就又回到了線程池中。你可以配置線程池的最小、最大線程數,默認值分別是5(最小)和Integer.MAX_VALUE(最大)。使用方法:
如何設置php thrift 超時時間
最近需要用到Thrift介面,
是Facebook開發的apache開源項目,公司要用,研究了一下
所以寫了個PHP調用Thrift的方法事例
以下是代碼,以免以後別人再走彎路
我是在Yii框架中實現的,和原生代碼應該是一樣的
官方下載包里也有PHP調用Thrift的例子
?php
/**
* @author fzxa
* @create 2012/05/22
Thrift推薦職位相關介面
註:詳細說明文檔在 \protected\components\thrift\推薦系統API.docx
@desc 說明Thrift介面數據格式:
EntityType介面數據格式
enum EntityType {
POSITION = 0,
RESUME = 1
}
EntityInfo介面數據格式
struct EntityInfo {
1: EntityType type,
2: string id, // 實體id
3: double rank, // rank值
4: string address, // 工作地點
5: i32 salary, // 薪水
6: string industry, // 行業類別
7: string profession, // 職業類別
8: i32 workingage, // 工作年限
9: i32 degree, // 學歷
10: string time, // 過期時間或更新時間
11: mapstring,string descriptions, // 文字描述,其中key為欄位名,value為欄位內容
12: mapstring,i32 tags, // 技能標籤
}
ResultInfo介面數據格式
struct ResultInfo {
1: EntityType type,
2: string id, // 實體id
3: i32 score, // 推薦分數,取值範圍:[0, 100]
}
*/
$GLOBALS[‘THRIFT_ROOT’] = $_SERVER[‘DOCUMENT_ROOT’].’/p/protected/components/thrift’;
require_once( $GLOBALS[‘THRIFT_ROOT’] . ‘/Thrift.php’ );
require_once( $GLOBALS[‘THRIFT_ROOT’] . ‘/transport/TSocket.php’ );
require_once( $GLOBALS[‘THRIFT_ROOT’] . ‘/transport/TBufferedTransport.php’ );
require_once( $GLOBALS[‘THRIFT_ROOT’] . ‘/protocol/TBinaryProtocol.php’ );
//生成的文件 RecommendService.php
require_once( $GLOBALS[‘THRIFT_ROOT’] . ‘/RecommendService.php’ );
//ini_set(‘display_errors’, E_ALL);
class ThriftInterface
{
private static $thriftHost = ‘*.*.*.*’; //Thrift介面伺服器IP
private static $thriftPort = 8080; //Thrift埠
/**
* 建立Thrift連接
* @return boolean
*/
private static function client(){
$socket = new TSocket(self::$thriftHost, self::$thriftPort);
$socket-setSendTimeout(10000);
$socket-setRecvTimeout(20000);
$transport = new TBufferedTransport($socket);
$protocol = new TBinaryProtocol($transport);
$client = new RecommendServiceClient($protocol);
$transport-open();
$socket-setDebug(TRUE);
return $client;
}
/**
* 獲取職位推薦列表ById
*
* @param Number $type 0:代表職位,1:代表簡歷
* @param Number $id 實體ID
* @param Array 推薦結果列表
* @example: $Recommend = ThriftInterface::getRecommendedResultById(‘1′,’1982’);
*/
public static function getRecommendedResultById($type,$id){
$client = self::client();
$ResultById = $client-getRecommendedResultById($type, $id);
return $ResultById;
}
/**
* 獲取推薦列表ByEntity
* @param EntityInfo $entity 職位或簡歷實體信息
*/
public static function getRecommendedResultByEntity($entity){
$client = self::client();
$EntityInfo = new EntityInfo();
$EntityInfo-type = (string)$entity[‘type’];
$EntityInfo-id = (string)$entity[‘id’];
$EntityInfo-rank = (float)$entity[‘rank’];
$EntityInfo-address = (string)$entity[‘address’];
$EntityInfo-salary = (int)$entity[‘salary’];
$EntityInfo-industry = (string)$entity[‘industry’];
$EntityInfo-profession = (string)$entity[‘profession’];
$EntityInfo-workingage = (int)$entity[‘workingage’];
$EntityInfo-degree = (int)$entity[‘degree’];
$EntityInfo-time = (string)$entity[‘time’];
$EntityInfo-descriptions = (array)$entity[‘descriptions’];
$EntityInfo-tags = (array)$entity[‘tags’];
$ResultByEntity = $client-getRecommendedResultByEntity($EntityInfo);
return $ResultByEntity;
}
/**
* 計算任一簡歷與職位的匹配分數ById
*
* @param Number $type1 0:代表職位,1:代表簡歷
* @param Number $id1 實體ID
* @param Number $type2 0:代表職位,1:代表簡歷
* @param Number $id2 實體ID
* @example Number
*/
public static function getRecommendedScoreById($type1, $id1, $type2, $id2){
$client = self::client();
$ScoreById = $client-getRecommendedScoreById($type1, $id1, $type2, $id2);
return $ScoreById;
}
/**
* 計算任一簡歷與職位的匹配分數ByEntity
*
* @param EntityInfo $entity 實體的所有信息
* @param EntityType $type2
* @param string $id2 實體ID2
* @return i32 簡歷與職位的推薦分數,取值範圍:[0, 100]
*/
public static function getRecommendedScoreByEntity($entity, $type2, $id2){
$client = self::client();
$EntityInfo = new EntityInfo();
$EntityInfo-type = (string)$entity[‘type’];
$EntityInfo-id = (string)$entity[‘id’];
$EntityInfo-rank = (float)$entity[‘rank’];
$EntityInfo-address = (string)$entity[‘address’];
$EntityInfo-salary = (int)$entity[‘salary’];
$EntityInfo-industry = (string)$entity[‘industry’];
$EntityInfo-profession = (string)$entity[‘profession’];
$EntityInfo-workingage = (int)$entity[‘workingage’];
$EntityInfo-degree = (int)$entity[‘degree’];
$EntityInfo-time = (string)$entity[‘time’];
$EntityInfo-descriptions = (array)$entity[‘descriptions’];
$EntityInfo-tags = (array)$entity[‘tags’];
$ResultInfo = new ResultInfo();
$ResultInfo-type = (string)$type2[‘type’];
$ResultInfo-id = (string)$type2[‘id’];
$ResultInfo-score = (int)$type2[‘score’];
$ScoreByEntity = $client-getRecommendedScoreByEntity($EntityInfo, $type2, $id2);
return $ScoreByEntity;
}
}
轉載
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/194776.html