diff --git a/src/Network/Connection/ConnectionManager.php b/src/Network/Connection/ConnectionManager.php index 60316f70..ab33edf2 100644 --- a/src/Network/Connection/ConnectionManager.php +++ b/src/Network/Connection/ConnectionManager.php @@ -12,6 +12,8 @@ use Zan\Framework\Network\Connection\Exception\ConnectTimeoutException; use Zan\Framework\Network\Connection\Exception\GetConnectionTimeoutFromPool; use Zan\Framework\Network\Server\Timer\Timer; +use Zan\Framework\Sdk\Monitor\Constant; +use Zan\Framework\Sdk\Monitor\Hawk; use Zan\Framework\Utilities\DesignPattern\Singleton; class ConnectionManager @@ -114,6 +116,39 @@ public function monitor() sys_echo("pool_ex info [type=$poolKey, all=$all, free=$free]"); }; }); + + $config = Config::get('hawk'); + if (!$config['run']) { + return; + } + $time = $config['time']; + Timer::tick($time, [$this, 'monitorTick']); + } + + public function monitorTick() + { + $hawk = Hawk::getInstance(); + + foreach (self::$poolMap as $poolKey => $pool) { + $activeNums = $pool->getActiveConnection()->length(); + $freeNums = $pool->getFreeConnection()->length(); + + $hawk->add(Constant::BIZ_CONNECTION_POOL, + [ + 'free' => $freeNums, + 'active' => $activeNums, + ], [ + 'pool_name' => $poolKey, + ] + ); + } + + foreach (self::$poolExMap as $poolKey => $pool) { + $hawk->add(Constant::BIZ_CONNECTION_POOL, $pool->getStatInfo(), [ + 'pool_name' => $poolKey, + ] + ); + } } public function setServer($server) diff --git a/src/Network/Http/Server.php b/src/Network/Http/Server.php index 5c9ee509..9c20f444 100644 --- a/src/Network/Http/Server.php +++ b/src/Network/Http/Server.php @@ -12,6 +12,7 @@ use Zan\Framework\Network\Server\ServerStart\InitLogConfig; use Zan\Framework\Network\Server\WorkerStart\InitializeConnectionPool; use Zan\Framework\Network\Server\WorkerStart\InitializeErrorHandler; +use Zan\Framework\Network\Server\WorkerStart\InitializeHawkMonitor; use Zan\Framework\Network\Server\WorkerStart\InitializeWorkerMonitor; use Zan\Framework\Network\Server\WorkerStart\InitializeServerDiscovery; use Zan\Framework\Network\Http\ServerStart\InitializeUrlConfig; @@ -42,6 +43,7 @@ class Server extends ServerBase protected $workerStartItems = [ InitializeErrorHandler::class, InitializeWorkerMonitor::class, + InitializeHawkMonitor::class, InitializeConnectionPool::class, InitializeServerDiscovery::class, ]; diff --git a/src/Network/Server/Monitor/Worker.php b/src/Network/Server/Monitor/Worker.php index e33efda8..f108ed6a 100644 --- a/src/Network/Server/Monitor/Worker.php +++ b/src/Network/Server/Monitor/Worker.php @@ -3,9 +3,14 @@ namespace Zan\Framework\Network\Server\Monitor; +use Zan\Framework\Foundation\Core\Config; +use Zan\Framework\Foundation\Coroutine\Task; +use Zan\Framework\Sdk\Monitor\Constant; +use Zan\Framework\Sdk\Monitor\Hawk; use Zan\Framework\Utilities\DesignPattern\Singleton; use Zan\Framework\Network\Http\Server; use Zan\Framework\Network\Server\Timer\Timer; +use Zan\Framework\Utilities\Types\Time; class Worker @@ -51,6 +56,8 @@ public function init($server,$config){ $this->restart(); $this->checkStart(); + //add by chiyou + $this->hawk(); } public function restart() @@ -138,8 +145,23 @@ public function close() $this->server->swooleServer->exit(); } - public function reactionReceive() - { + public function hawk(){ + $run = Config::get('hawk.run'); + if (!$run) { + return; + } + $time = Config::get('hawk.time'); + Timer::tick($time, [$this,'callHawk']); + } + + public function callHawk() { + $hawk = Hawk::getInstance(); + $memory = memory_get_usage(); + $hawk->add(Constant::BIZ_WORKER_MEMORY, + ['used' => $memory]); + } + + public function reactionReceive(){ //触发限流 if ($this->reactionNum > $this->maxConcurrency) { return false; diff --git a/src/Network/Tcp/RequestHandler.php b/src/Network/Tcp/RequestHandler.php index 8566ff5d..910756a9 100644 --- a/src/Network/Tcp/RequestHandler.php +++ b/src/Network/Tcp/RequestHandler.php @@ -13,6 +13,8 @@ use Zan\Framework\Network\Server\Middleware\MiddlewareManager; use Zan\Framework\Network\Server\Monitor\Worker; use Zan\Framework\Network\Server\Timer\Timer; +use Zan\Framework\Sdk\Log\Log; +use Zan\Framework\Sdk\Monitor\Hawk; use Zan\Framework\Sdk\Trace\Tracer; use Zan\Framework\Utilities\DesignPattern\Context; use Zan\Framework\Utilities\Types\Time; @@ -151,6 +153,7 @@ public function handleRequestFinish() public function handleTimeout() { $this->task->setStatus(Signal::TASK_KILLED); + $this->reportHawk(); $ex = $this->logTimeout(); $coroutine = static::handleException($this->middleWareManager, $this->response, $ex); Task::execute($coroutine, $this->context); @@ -212,6 +215,21 @@ private function getRequestTimeoutJobId() { return spl_object_hash($this) . '_handle_timeout'; } + + private function reportHawk() + { + $hawk = Hawk::getInstance(); + $hawk->addTotalFailureTime(Hawk::SERVER, + $this->request->getServiceName(), + $this->request->getMethodName(), + $this->request->getRemoteIp(), + microtime(true) - $this->request->getStartTime()); + $hawk->addTotalFailureCount(Hawk::SERVER, + $this->request->getServiceName(), + $this->request->getMethodName(), + $this->request->getRemoteIp()); + } + private function logErr(\Exception $e) { $key = Config::get('log.zan_framework'); diff --git a/src/Network/Tcp/RequestTask.php b/src/Network/Tcp/RequestTask.php index f3e029d7..4a757da2 100644 --- a/src/Network/Tcp/RequestTask.php +++ b/src/Network/Tcp/RequestTask.php @@ -9,6 +9,7 @@ use Zan\Framework\Network\Exception\GenericInvokeException; use Zan\Framework\Network\Server\Middleware\MiddlewareManager; use Zan\Framework\Sdk\Log\Log; +use Zan\Framework\Sdk\Monitor\Hawk; use Zan\Framework\Sdk\Trace\Constant; use Zan\Framework\Sdk\Trace\Tracer; use Zan\Framework\Utilities\DesignPattern\Context; @@ -48,8 +49,33 @@ public function run() $this->handleRequestException($e); } } + private function handleRequestException($e) { + $hawk = Hawk::getInstance(); + if ($e instanceof TApplicationException) { + $hawk->addTotalFailureTime(Hawk::SERVER, + $this->request->getServiceName(), + $this->request->getMethodName(), + $this->request->getRemoteIp(), + microtime(true) - $this->request->getStartTime()); + $hawk->addTotalFailureCount(Hawk::SERVER, + $this->request->getServiceName(), + $this->request->getMethodName(), + $this->request->getRemoteIp()); + $this->logErr($e); + } else { + $hawk->addTotalSuccessTime(Hawk::SERVER, + $this->request->getServiceName(), + $this->request->getMethodName(), + $this->request->getRemoteIp(), + microtime(true) - $this->request->getStartTime()); + $hawk->addTotalSuccessCount(Hawk::SERVER, + $this->request->getServiceName(), + $this->request->getMethodName(), + $this->request->getRemoteIp()); + } + $coroutine = RequestHandler::handleException($this->middleWareManager, $this->response, $e); Task::execute($coroutine, $this->context); @@ -75,6 +101,17 @@ private function doRun() $result = (yield $dispatcher->dispatch($this->request, $this->context)); $this->output($result); + $hawk = Hawk::getInstance(); + $hawk->addTotalSuccessTime(Hawk::SERVER, + $this->request->getServiceName(), + $this->request->getMethodName(), + $this->request->getRemoteIp(), + microtime(true) - $this->request->getStartTime()); + $hawk->addTotalSuccessCount(Hawk::SERVER, + $this->request->getServiceName(), + $this->request->getMethodName(), + $this->request->getRemoteIp()); + $this->context->getEvent()->fire($this->context->get('request_end_event_name')); } diff --git a/src/Network/Tcp/Server.php b/src/Network/Tcp/Server.php index b88c47f8..4fb08f39 100644 --- a/src/Network/Tcp/Server.php +++ b/src/Network/Tcp/Server.php @@ -5,6 +5,7 @@ use Zan\Framework\Network\Server\Monitor\Worker; use Zan\Framework\Network\Server\WorkerStart\InitializeErrorHandler; use Zan\Framework\Network\Server\WorkerStart\InitializeEtcdTTLRefreshing; +use Zan\Framework\Network\Server\WorkerStart\InitializeHawkMonitor; use Zan\Framework\Network\ServerManager\ServerDiscoveryInitiator; use Zan\Framework\Network\ServerManager\ServerStore; use Zan\Framework\Network\Server\WorkerStart\InitializeServerDiscovery; @@ -39,6 +40,7 @@ class Server extends ServerBase InitializeEtcdTTLRefreshing::class, InitializeConnectionPool::class, InitializeServerDiscovery::class, + InitializeHawkMonitor::class, ]; public function setSwooleEvent() diff --git a/src/Nova/Network/Client.php b/src/Nova/Network/Client.php index a465afa8..63ed1fa6 100644 --- a/src/Nova/Network/Client.php +++ b/src/Nova/Network/Client.php @@ -14,6 +14,7 @@ use Zan\Framework\Network\Connection\Driver\NovaClient; use Zan\Framework\Network\Server\Timer\Timer; use Zan\Framework\Sdk\Log\Log; +use Zan\Framework\Sdk\Monitor\Hawk; use Zan\Framework\Network\Tcp\RpcContext; use Zan\Framework\Sdk\Trace\Constant; use Zan\Framework\Sdk\Trace\DebuggerTrace; @@ -123,6 +124,7 @@ public function recv($data) } /* @var $packer Packer */ $packer = $context->getPacker(); + $hawk = Hawk::getInstance(); $serverIp = long2ip($remoteIP) . ':' . $remotePort; if ($serviceName == $context->getReqServiceName() @@ -140,28 +142,35 @@ public function recv($data) if (null !== $trace) { if ($e instanceof TApplicationException) { //只有系统异常上报异常信息 + $hawk->addTotalFailureTime(Hawk::CLIENT, $serviceName, $methodName, $serverIp, microtime(true) - $context->getStartTime()); + $hawk->addTotalFailureCount(Hawk::CLIENT, $serviceName, $methodName, $serverIp); $trace->commit($e->getTraceAsString()); } else { + $hawk->addTotalSuccessTime(Hawk::CLIENT, $serviceName, $methodName, $serverIp, microtime(true) - $context->getStartTime()); + $hawk->addTotalSuccessCount(Hawk::CLIENT, $serviceName, $methodName, $serverIp); $trace->commit(Constant::SUCCESS); } } if ($debuggerTrace instanceof DebuggerTrace) { $debuggerTrace->commit("error", $e); } + call_user_func($cb, null, $e); return; } else { + $hawk->addTotalSuccessTime(Hawk::CLIENT, $serviceName, $methodName, $serverIp, microtime(true) - $context->getStartTime()); + $hawk->addTotalSuccessCount(Hawk::CLIENT, $serviceName, $methodName, $serverIp); $ret = isset($response[$packer->successKey]) ? $response[$packer->successKey] : null; if (null !== $trace) { $trace->commit(Constant::SUCCESS); - } + } if ($debuggerTrace instanceof DebuggerTrace) { $debuggerTrace->commit("info", $ret); } - call_user_func($cb, $ret); - return; + call_user_func($cb, $ret); + return; } } } else { @@ -213,6 +222,7 @@ public function call($method, $inputArguments, $outputStruct, $exceptionStruct) $localIp = ip2long($sockInfo['host']); $localPort = $sockInfo['port']; $sendBuffer = null; + $hawk = Hawk::getInstance(); $serverIp = $localIp . ':' . $localPort; /** @var Trace $trace */ @@ -261,6 +271,8 @@ public function call($method, $inputArguments, $outputStruct, $exceptionStruct) $this->_conn->setLastUsedTime(); $sent = $this->_sock->send($sendBuffer); if (false === $sent) { + $hawk->addTotalFailureTime(Hawk::CLIENT, $this->_serviceName, $method, $serverIp, microtime(true) - $context->getStartTime()); + $hawk->addTotalFailureCount(Hawk::CLIENT, $this->_serviceName, $method, $serverIp); $exception = new NetworkException(socket_strerror($this->_sock->errCode), $this->_sock->errCode); goto handle_exception; } @@ -277,6 +289,8 @@ public function call($method, $inputArguments, $outputStruct, $exceptionStruct) yield $this; return; } else { + $hawk->addTotalFailureTime(Hawk::CLIENT, $this->_serviceName, $method, $serverIp, microtime(true) - $context->getStartTime()); + $hawk->addTotalFailureCount(Hawk::CLIENT, $this->_serviceName, $method, $serverIp); $exception = new ProtocolException('nova.encoding.failed'); goto handle_exception; } diff --git a/src/Nova/Service/NovaConfig.php b/src/Nova/Service/NovaConfig.php index 962b79db..482162a7 100644 --- a/src/Nova/Service/NovaConfig.php +++ b/src/Nova/Service/NovaConfig.php @@ -5,13 +5,14 @@ use Kdt\Iron\Nova\Exception\FrameworkException; use Kdt\Iron\Nova\Foundation\Traits\InstanceManager; +use Zan\Framework\Foundation\Application; use Zan\Framework\Foundation\Core\Path; class NovaConfig { use InstanceManager; - private static $genericInvokePath = "vendor/zanphp/zan/src/Nova/Generic/gen-php"; + private $genericInvokePath; private static $genericInvokeBaseNamespace = "Com\\Youzan\\Nova\\"; @@ -21,6 +22,23 @@ class NovaConfig private $etcdNamespaces = []; + public function __construct() + { + $app = Application::getInstance(); + $base = $app->getBasePath(); + + $f1 = "vendor/nova-service/generic/sdk/gen-php"; + $f2 = "vendor/zanphp/zan/src/Nova/Generic/gen-php"; + + if (is_dir("$base/$f1")) { + $this->genericInvokePath = $f1; + } else if (is_dir("$base/$f2")) { + $this->genericInvokePath = $f2; + } else { + throw new \InvalidArgumentException("missing nova generic invoke package"); + } + } + public function setConfig(array $config) { self::validatorConfig($config); @@ -53,7 +71,7 @@ public function setConfig(array $config) $config[] = [ "appName" => $app, "domain" => $domain, - "path" => Path::getRootPath() . self::$genericInvokePath . "/", + "path" => Path::getRootPath() . $this->genericInvokePath . "/", "namespace" => self::$genericInvokeBaseNamespace, "protocol" => Registry::PROTO_NOVA, ]; diff --git a/src/Sdk/Trace/Trace.php b/src/Sdk/Trace/Trace.php index f9b35c47..ae4622dc 100644 --- a/src/Sdk/Trace/Trace.php +++ b/src/Sdk/Trace/Trace.php @@ -1,14 +1,10 @@