From 7431545948e7bb169bc2eed0f9c9b675476fe867 Mon Sep 17 00:00:00 2001 From: xtgxiso <124960772@qq.com> Date: Mon, 14 Nov 2016 14:17:01 +0800 Subject: [PATCH] static --- App.php | 27 ++++-- Libs/StatisticClient.php | 188 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 208 insertions(+), 7 deletions(-) create mode 100644 Libs/StatisticClient.php diff --git a/App.php b/App.php index 7ca4aad..fefb6e4 100644 --- a/App.php +++ b/App.php @@ -7,6 +7,7 @@ use Workerman\Autoloader; use Workerman\Connection\AsyncTcpConnection; use Workerman\Protocols\Http; +use WebWorker\Libs\StatisticClient; class App extends Worker { @@ -16,7 +17,7 @@ class App extends Worker * * @var string */ - const VERSION = '0.1.0'; + const VERSION = '0.1.5'; private $conn = false; private $map = array(); @@ -26,6 +27,8 @@ class App extends Worker public $onAppStart = NULL; + public $statistic = false; + public function __construct($socket_name, $context_option = array()) { parent::__construct($socket_name, $context_option); @@ -89,8 +92,10 @@ public function onClientMessage($connection,$data){ $connection->send($str); return; } - require_once __DIR__ . '/../Applications/Statistics/Clients/StatisticClient.php'; - $statistic_address = 'udp://127.0.0.1:55656'; + if ( $this->statistic ){ + require_once __DIR__ . '/Libs/StatisticClient.php'; + $statistic_address = 'udp://127.0.0.1:55656'; + } $this->conn = $connection; $url= $_SERVER["REQUEST_URI"]; $pos = stripos($url,"?"); @@ -103,7 +108,9 @@ public function onClientMessage($connection,$data){ $url_arr = explode("/",$url); $class = empty($url_arr[0]) ? "_default" : $url_arr[0]; $method = empty($url_arr[1]) ? "_default" : $url_arr[1]; - \StatisticClient::tick($class, $method); + if ( $this->statistic ){ + StatisticClient::tick($class, $method); + } $success = false; foreach($this->map as $route){ if ( $route[2] == 1){//正常路由 @@ -125,20 +132,26 @@ public function onClientMessage($connection,$data){ break; } } - \StatisticClient::report($class, $method, 1, 0, '', $statistic_address); + if ( $this->statistic ){ + StatisticClient::report($class, $method, 1, 0, '', $statistic_address); + } }catch (\Exception $e) { // Jump_exit? if ($e->getMessage() != 'jump_exit') { echo $e; } $code = $e->getCode() ? $e->getCode() : 500; - StatisticClient::report($class, $method, $success, $code, $e, $statistic_address); + if ( $this->statistic ){ + StatisticClient::report($class, $method, $success, $code, $e, $statistic_address); + } } }else{ $this->show_404($connection); $code = 404; $msg = "class $class not found"; - \StatisticClient::report($class, $method, $success, $code, $msg, $statistic_address); + if ( $this->statistic ){ + StatisticClient::report($class, $method, $success, $code, $msg, $statistic_address); + } } $this->auto_close($connection); } diff --git a/Libs/StatisticClient.php b/Libs/StatisticClient.php new file mode 100644 index 0000000..37bf538 --- /dev/null +++ b/Libs/StatisticClient.php @@ -0,0 +1,188 @@ + + * @copyright walkor + * @link http://www.workerman.net/ + * @license http://www.opensource.org/licenses/mit-license.php MIT License + */ +/** + * 统计客户端 + * @author workerman.net + */ + +namespace WebWorker\Libs; + +class StatisticClient +{ + /** + * [module=>[interface=>time_start, interface=>time_start ...], module=>[interface=>time_start ..], ... ] + * @var array + */ + protected static $timeMap = array(); + + /** + * 模块接口上报消耗时间记时 + * @param string $module + * @param string $interface + * @return void + */ + public static function tick($module = '', $interface = '') + { + return self::$timeMap[$module][$interface] = microtime(true); + } + + /** + * 上报统计数据 + * @param string $module + * @param string $interface + * @param bool $success + * @param int $code + * @param string $msg + * @param string $report_address + * @return boolean + */ + public static function report($module, $interface, $success, $code, $msg, $report_address = '') + { + $report_address = $report_address ? $report_address : 'udp://127.0.0.1:55656'; + if(isset(self::$timeMap[$module][$interface]) && self::$timeMap[$module][$interface] > 0) + { + $time_start = self::$timeMap[$module][$interface]; + self::$timeMap[$module][$interface] = 0; + } + else if(isset(self::$timeMap['']['']) && self::$timeMap[''][''] > 0) + { + $time_start = self::$timeMap['']['']; + self::$timeMap[''][''] = 0; + } + else + { + $time_start = microtime(true); + } + + $cost_time = microtime(true) - $time_start; + + $bin_data = StatisticProtocol::encode($module, $interface, $cost_time, $success, $code, $msg); + + return self::sendData($report_address, $bin_data); + } + + /** + * 发送数据给统计系统 + * @param string $address + * @param string $buffer + * @return boolean + */ + public static function sendData($address, $buffer) + { + $socket = stream_socket_client($address); + if(!$socket) + { + return false; + } + return stream_socket_sendto($socket, $buffer) == strlen($buffer); + } + +} +/** + * + * struct statisticPortocol + * { + * unsigned char module_name_len; + * unsigned char interface_name_len; + * float cost_time; + * unsigned char success; + * int code; + * unsigned short msg_len; + * unsigned int time; + * char[module_name_len] module_name; + * char[interface_name_len] interface_name; + * char[msg_len] msg; + * } + * + * @author workerman.net + */ +class StatisticProtocol +{ + /** + * 包头长度 + * @var integer + */ + const PACKAGE_FIXED_LENGTH = 17; + /** + * udp 包最大长度 + * @var integer + */ + const MAX_UDP_PACKGE_SIZE = 65507; + /** + * char类型能保存的最大数值 + * @var integer + */ + const MAX_CHAR_VALUE = 255; + /** + * usigned short 能保存的最大数值 + * @var integer + */ + const MAX_UNSIGNED_SHORT_VALUE = 65535; + /** + * 编码 + * @param string $module + * @param string $interface + * @param float $cost_time + * @param int $success + * @param int $code + * @param string $msg + * @return string + */ + public static function encode($module, $interface , $cost_time, $success, $code = 0,$msg = '') + { + // 防止模块名过长 + if(strlen($module) > self::MAX_CHAR_VALUE) + { + $module = substr($module, 0, self::MAX_CHAR_VALUE); + } + // 防止接口名过长 + if(strlen($interface) > self::MAX_CHAR_VALUE) + { + $interface = substr($interface, 0, self::MAX_CHAR_VALUE); + } + // 防止msg过长 + $module_name_length = strlen($module); + $interface_name_length = strlen($interface); + $avalible_size = self::MAX_UDP_PACKGE_SIZE - self::PACKAGE_FIXED_LENGTH - $module_name_length - $interface_name_length; + if(strlen($msg) > $avalible_size) + { + $msg = substr($msg, 0, $avalible_size); + } + // 打包 + return pack('CCfCNnN', $module_name_length, $interface_name_length, $cost_time, $success ? 1 : 0, $code, strlen($msg), time()).$module.$interface.$msg; + } + + /** + * 解包 + * @param string $bin_data + * @return array + */ + public static function decode($bin_data) + { + // 解包 + $data = unpack("Cmodule_name_len/Cinterface_name_len/fcost_time/Csuccess/Ncode/nmsg_len/Ntime", $bin_data); + $module = substr($bin_data, self::PACKAGE_FIXED_LENGTH, $data['module_name_len']); + $interface = substr($bin_data, self::PACKAGE_FIXED_LENGTH + $data['module_name_len'], $data['interface_name_len']); + $msg = substr($bin_data, self::PACKAGE_FIXED_LENGTH + $data['module_name_len'] + $data['interface_name_len']); + return array( + 'module' => $module, + 'interface' => $interface, + 'cost_time' => $data['cost_time'], + 'success' => $data['success'], + 'time' => $data['time'], + 'code' => $data['code'], + 'msg' => $msg, + ); + } +}