在壓力測試環(huán)境中,發(fā)現(xiàn) Gateway::sendToUid($uid,$msg); 執(zhí)行時間有些可怕,最多的超過6秒了。
機器環(huán)境:Gateway和Worker分離。
測試代碼:
.....
$t1 = microtime(true);
Gateway::sendToUid('teacher_827181', $msgstr);
$t2 = microtime(true);
echo "\n\n發(fā)老師耗時" . round($t2-$t1,3) . "秒\n\n";
.....
請問此問題該如何解決?
首先壓測時要根據(jù)手冊優(yōu)化后linux內(nèi)核,并安裝event擴展,否則系統(tǒng)通訊性能會有很大影響。
Gateway::sendToUid 和 Gateway::sendToClient不同,Gateway::sendToUid是向所有g(shù)ateway進(jìn)程發(fā)送一條發(fā)送指令,Gateway::sendToClient是向?qū)?yīng)的那一個client_id發(fā)送指令。Gateway::sendToUid性能要比Gateway::sendToClient差很多。但是在GatewayWorker中環(huán)境里Gateway::sendToUid 接口都是異步非阻塞的,系統(tǒng)負(fù)載正常的情況下不會耗時這么長時間。
另外看下是不是用了GatewayClient,如果是GatewayClient,通訊過程是阻塞的,而且要與register連接,然后與所有g(shù)ateway連接通訊,耗時要長一些,但是這個是GatewayClient的問題,不是GatewayWorker問題。
最后并不是任何壓力程序都能運行飛快,當(dāng)系統(tǒng)因壓測負(fù)載很高時,可能平時不耗時的操作都非常慢,原因很簡單,系統(tǒng)處理不過來了,當(dāng)有復(fù)雜業(yè)務(wù)或者業(yè)務(wù)本身性能很差時會更明顯。
另外請問,如果我給100個uid發(fā)消息的話,
我把100個uid寫入數(shù)組后傳入Gateway::sendToUid發(fā)送,
請問這種是請求100次gateway還是請求1次gateway?
謝謝walkor大哥的指導(dǎo)。
請問GatewayClient如何查看?我用的是這個方法,請問是GatewayClient嗎?
public static function sendToUid($uid, $message)
{
$gateway_data = GatewayProtocol::$empty;
$gateway_data['cmd'] = GatewayProtocol::CMD_SEND_TO_UID;
$gateway_data['body'] = $message;
if (!is_array($uid)) {
$uid = array($uid);
}
$gateway_data['ext_data'] = json_encode($uid);
self::sendToAllGateway($gateway_data);
我看了一下 Lib\Gateway.php 的代碼,在 sendToAllGateway() 這里,【如果有businessWorker實例,說明運行在workerman環(huán)境中,通過businessWorker中的長連接發(fā)送數(shù)據(jù)】這個分支,代碼很簡單,而且都是異步操作,我覺得就算系統(tǒng)性能再差,也不至于拖到 6 秒之久。(如果是因為系統(tǒng)未優(yōu)化,那也應(yīng)該是在連接環(huán)節(jié)出問題,不會因此在發(fā)送環(huán)節(jié)卡?。?/p>
但如果走的是【運行在其它環(huán)境中,通過注冊中心得到gateway地址】這一支的話,里面涉及到跟 register 通信,那個是同步通信,就比較說得通了。
檢查一下你的 BusinessWorker 啟動代碼,是不是改寫了 onWorkerStart。如果原配的 onWorkerStart 沒有執(zhí)行到的話,就會誤導(dǎo)到【運行在其它環(huán)境中……】這個分支。
GatewayWorker 文檔說 onWorkerStart 可以定制(http://m.wtbis.cn/gatewaydoc/gateway-worker-development/business-worker.html),我估計這是個誤導(dǎo),正確的做法似乎應(yīng)該是定義 Events::onWorkerStart 才對。