walkor 11 éve
szülő
commit
65cf4664bf

+ 7 - 12
applications/Demo/Bootstrap/BusinessWorker.php

@@ -110,31 +110,27 @@ class BusinessWorker extends Man\Core\SocketWorker
         $session_str_copy = $pack->ext_data;
         $cmd = $pack->header['cmd'];
         
-        StatisticClient::tick();
-        $module = __CLASS__;
         $interface = isset(self::$interfaceMap[$cmd]) ? self::$interfaceMap[$cmd] : $cmd;
-        $success = 1;
-        $code = 0;
-        $msg = '';
+        StatisticClient::tick(__CLASS__, $interface);
         try{
             switch($cmd)
             {
                 case GatewayProtocol::CMD_ON_GATEWAY_CONNECTION:
-                    call_user_func_array(array('Event', 'onGatewayConnect'), array(Context::$client_id));
+                    Event::onGatewayConnect(Context::$client_id);
                     break;
                 case GatewayProtocol::CMD_ON_MESSAGE:
-                    call_user_func_array(array('Event', 'onMessage'), array(Context::$client_id, $pack->body));
+                    Event::onMessage(Context::$client_id, $pack->body);
                     break;
                 case GatewayProtocol::CMD_ON_CLOSE:
-                    call_user_func_array(array('Event', 'onClose'), array(Context::$client_id));
+                    Event::onClose(Context::$client_id);
                     break;
             }
+            StatisticClient::report(__CLASS__, $interface, 1, 0, '');
         }
         catch(\Exception $e)
         {
-            $success = 0;
-            $code = $e->getCode() > 0 ? $e->getCode() : 500;
-            $msg = 'uid:'.Context::$client_id."\tclient_ip:".Context::$client_ip."\n".$e->__toString();
+            $msg = 'client_id:'.Context::$client_id."\tclient_ip:".Context::$client_ip."\n".$e->__toString();
+            StatisticClient::report(__CLASS__, $interface, 0, $e->getCode() > 0 ? $e->getCode() : 201, $msg);
         }
         
         $session_str_now = $_SESSION !== null ? Context::sessionEncode($_SESSION) : '';
@@ -144,7 +140,6 @@ class BusinessWorker extends Man\Core\SocketWorker
         }
         
         Context::clear();
-        StatisticClient::report($module, $interface, $success, $code, $msg);
     }
     
     /**

+ 199 - 70
applications/Demo/Bootstrap/Gateway.php

@@ -114,13 +114,8 @@ class Gateway extends Man\Core\SocketWorker
      */
     public function dealInput($recv_buffer)
     {
-        // 只要客户端有回应就是没掉线
-        if(!empty($this->pingInfo[$this->connClientMap[$this->currentDealFd]]))
-        {
-            $this->pingInfo[$this->connClientMap[$this->currentDealFd]] = 0;
-        }
         // 处理粘包
-        return call_user_func_array(array('Event', 'onGatewayMessage'), array($recv_buffer));
+        return Event::onGatewayMessage($recv_buffer);
     }
     
     /**
@@ -129,22 +124,20 @@ class Gateway extends Man\Core\SocketWorker
      */
     public function dealProcess($recv_buffer)
     {
+        // 客户端发来任何一个完整的包都视为回应了服务端发的心跳
+        if(!empty($this->pingInfo[$this->connClientMap[$this->currentDealFd]]))
+        {
+            $this->pingInfo[$this->connClientMap[$this->currentDealFd]] = 0;
+        }
+        
         // 统计打点
-        StatisticClient::tick();
-        $module = __CLASS__;
-        $success = 1;
-        $code = 0;
-        $msg = '';
-        $interface = 'CMD_ON_MESSAGE';
+        StatisticClient::tick(__CLASS__, 'CMD_ON_MESSAGE');
         // 触发ON_MESSAGE
-        $ret =$this->sendToWorker(GatewayProtocol::CMD_ON_MESSAGE, $this->currentDealFd, $recv_buffer);
-        if($ret === false)
+        if(false === $this->sendToWorker(GatewayProtocol::CMD_ON_MESSAGE, $this->currentDealFd, $recv_buffer))
         {
-            $success = 0;
-            $msg = 'sendToWorker(CMD_ON_MESSAGE, '.$this->currentDealFd.', strlen($recv_buffer) = '.strlen($recv_buffer).') fail ';
-            $code = 102;
+            return StatisticClient::report(__CLASS__, 'CMD_ON_MESSAGE', 0, 132, __CLASS__.'::dealProcess()->sendToWorker() fail');
         }
-        StatisticClient::report($module, $interface, $success, $code, $msg);
+        StatisticClient::report(__CLASS__, 'CMD_ON_MESSAGE', 1, 0, '');
     }
     
     /**
@@ -162,6 +155,12 @@ class Gateway extends Man\Core\SocketWorker
         $start_port = Man\Core\Lib\Config::get($this->workerName.'.lan_port_start');
         // 计算本进程监听的ip端口
         $this->lanPort = $start_port - posix_getppid() + posix_getpid();
+        // 如果端口不在合法范围
+        if($this->lanPort<0 || $this->lanPort >=65535)
+        {
+            $this->lanPort = rand($start_port, 65535);
+        }
+        // 如果
         $this->lanIp = Man\Core\Lib\Config::get($this->workerName.'.lan_ip');
         if(!$this->lanIp)
         {
@@ -186,7 +185,11 @@ class Gateway extends Man\Core\SocketWorker
         }
         
         // 注册套接字
-        $this->registerAddress($this->lanIp.':'.$this->lanPort);
+        if(!$this->registerAddress($this->lanIp.':'.$this->lanPort))
+        {
+            $this->notice('registerAddress fail and exit');
+            $this->stop();
+        }
         
         // 添加读udp/tcp事件
         $this->event->add($this->innerMainSocketUdp,  Man\Core\Events\BaseEvent::EV_READ, array($this, 'recvInnerUdp'));
@@ -210,11 +213,11 @@ class Gateway extends Man\Core\SocketWorker
             $this->pingData = $ping_data_or_path;
         }
         
-        // 不返回心跳回应的限定值
+        // 不返回心跳回应(客户端发来的任何数据都算是回应)的限定值
         $this->pingNotResponseLimit = (int)\Man\Core\Lib\Config::get($this->workerName.'.ping_not_response_limit');
         
         // 设置定时任务,发送心跳
-        if($this->pingInterval > 0 && $this->pingData)
+        if($this->pingInterval > 0)
         {
             \Man\Core\Lib\Task::init($this->event);
             \Man\Core\Lib\Task::add($this->pingInterval, array($this, 'ping'));
@@ -262,11 +265,9 @@ class Gateway extends Man\Core\SocketWorker
         $this->clientConnMap[$global_client_id] = $fd;
         $this->connClientMap[$fd] = $global_client_id;
         $address = array('local_ip'=>$this->lanIp, 'local_port'=>$this->lanPort, 'socket_id'=>$fd);
+        
         // 保存客户端内部通讯地址
-        if(!Store::instance('gateway')->set($global_client_id, $address))
-        {
-            $this->notice("Store::instance('gateway')->set($global_client_id, ".json_encode($address).") fail");
-        }
+        $this->storeClientAddress($global_client_id, $address);
         
         // 客户端保存 ip:port
         $address= $this->getRemoteAddress($fd);
@@ -284,7 +285,16 @@ class Gateway extends Man\Core\SocketWorker
         // 触发GatewayOnConnection事件
         if(method_exists('Event','onGatewayConnect'))
         {
-            $this->sendToWorker(GatewayProtocol::CMD_ON_GATEWAY_CONNECTION, $fd);
+            // 统计打点
+            StatisticClient::tick(__CLASS__, 'CMD_ON_GATEWAY_CONNECTION');
+            if(false === $this->sendToWorker(GatewayProtocol::CMD_ON_GATEWAY_CONNECTION, $fd))
+            {
+                StatisticClient::report(__CLASS__, 'CMD_ON_GATEWAY_CONNECTION', 0, 131, __CLASS__.'::accept()->sendToWorker() fail');
+            }
+            else
+            {
+                StatisticClient::report(__CLASS__, 'CMD_ON_GATEWAY_CONNECTION', 1, 0, '');
+            }
         }
         
         return $new_connection;
@@ -296,17 +306,49 @@ class Gateway extends Man\Core\SocketWorker
      */
     protected function registerAddress($address)
     {
-        // 这里使用了信号量只能实现单机互斥,分布式互斥需要借助于memcache incr 或者其他分布式存储
+        // 统计打点
+        StatisticClient::tick(__CLASS__, 'registerAddress');
+        // 这里使用了信号量只能实现单机互斥,分布式互斥需要借助于memcached incr cas 或者其他分布式存储
         \Man\Core\Lib\Mutex::get();
+        // key
         $key = 'GLOBAL_GATEWAY_ADDRESS';
-        $addresses_list = Store::instance('gateway')->get($key);
+        // 获取实例
+        try 
+        {
+            $store = Store::instance('gateway');
+        }
+        catch(\Exception $msg)
+        {
+            StatisticClient::report(__CLASS__, 'registerAddress', 0, 107, $msg);
+            \Man\Core\Lib\Mutex::release();
+            return false;
+        }
+        // 获取数据
+        $addresses_list = $store->get($key);
         if(empty($addresses_list))
         {
             $addresses_list = array();
         }
+        // 添加数据
         $addresses_list[$address] = $address;
-        Store::instance('gateway')->set($key, $addresses_list);
+        // 存储
+        if(!$store->set($key, $addresses_list))
+        {
+            // 存储失败
+            \Man\Core\Lib\Mutex::release();
+            $msg = "注册gateway通信地址出错";
+            if(get_class($store) == 'Memcached')
+            {
+                $msg .= " 原因:".$store->getResultMessage();
+            }
+            $this->notice($msg);
+            StatisticClient::report(__CLASS__, 'registerAddress', 0, 107, new \Exception($msg));
+            return false;
+        }
+        // 存储成功
         \Man\Core\Lib\Mutex::release();
+        StatisticClient::report(__CLASS__, 'registerAddress', 1, 0, '');
+        return true;
     }
     
     /**
@@ -315,17 +357,47 @@ class Gateway extends Man\Core\SocketWorker
      */
     protected function unregisterAddress($address)
     {
-        // 这里使用了信号量只能实现单机互斥,分布式互斥需要借助于memcache incr 或者其他分布式存储
+        // 统计打点
+        StatisticClient::tick(__CLASS__, 'unregisterAddress');
+        // 这里使用了信号量只能实现单机互斥,分布式互斥需要借助于memcached incr cas或者其他分布式存储
         \Man\Core\Lib\Mutex::get();
+        // key
         $key = 'GLOBAL_GATEWAY_ADDRESS';
-        $addresses_list = Store::instance('gateway')->get($key);
+        // 获取存储实例
+        try 
+        {
+            $store = Store::instance('gateway');
+        }
+        catch (\Exception $msg)
+        {
+            StatisticClient::report(__CLASS__, 'unregisterAddress', 0, 108, $msg);
+            \Man\Core\Lib\Mutex::release();
+            return false;
+        }
+        // 获取数据
+        $addresses_list = $store->get($key);
         if(empty($addresses_list))
         {
             $addresses_list = array();
         }
+        // 去掉要删除的数据
         unset($addresses_list[$address]);
-        Store::instance('gateway')->set($key, $addresses_list);
+        // 保存数据
+        if(!$store->set($key, $addresses_list))
+        {
+            \Man\Core\Lib\Mutex::release();
+            $msg = "删除gateway通信地址出错";
+            if(get_class($store) == 'Memcached')
+            {
+                $msg .= " 原因:".$store->getResultMessage();
+            }
+            $this->notice($msg);
+            StatisticClient::report(__CLASS__, 'unregisterAddress', 0, 108, new \Exception($msg));
+            return;
+        }
+        // 存储成功
         \Man\Core\Lib\Mutex::release();
+        StatisticClient::report(__CLASS__, 'unregisterAddress', 1, 0, '');
     }
     
     /**
@@ -411,11 +483,12 @@ class Gateway extends Man\Core\SocketWorker
             if(!empty($this->recvBuffers[$fd]['buf']))
             {
                 $this->statusInfo['send_fail']++;
-                $this->notice("INNER_CLIENT_CLOSE\nCLIENT_IP:".$this->getRemoteIp()."\nBUFFER:[".bin2hex($this->recvBuffers[$fd]['buf'])."]\n");
             }
     
             // 关闭链接
             $this->closeInnerClient($fd);
+            $this->notice("CLIENT:".$this->getRemoteIp()." CLOSE INNER_CONNECTION\n");
+            
             if($this->workerStatus == self::STATUS_SHUTDOWN)
             {
                 $this->stop();
@@ -429,16 +502,8 @@ class Gateway extends Man\Core\SocketWorker
         // 包接收完毕
         if(0 === $remain_len)
         {
-            // 执行处理
-            try{
-                // 内部通讯业务处理
-                $this->innerDealProcess($this->recvBuffers[$fd]['buf']);
-            }
-            catch(\Exception $e)
-            {
-                $this->notice('CODE:' . $e->getCode() . ' MESSAGE:' . $e->getMessage()."\n".$e->getTraceAsString()."\nCLIENT_IP:".$this->getRemoteIp()."\nBUFFER:[".var_export($this->recvBuffers[$fd]['buf'],true)."]\n");
-                $this->statusInfo['throw_exception'] ++;
-            }
+            // 内部通讯业务处理
+            $this->innerDealProcess($this->recvBuffers[$fd]['buf']);
             $this->recvBuffers[$fd] = array('buf'=>'', 'remain_len'=>GatewayProtocol::HEAD_LEN);
         }
         // 出错
@@ -446,7 +511,7 @@ class Gateway extends Man\Core\SocketWorker
         {
             // 出错
             $this->statusInfo['packet_err']++;
-            $this->notice("INNER_PACKET_ERROR\nCLIENT_IP:".$this->getRemoteIp()."\nBUFFER:[".var_export($this->recvBuffers[$fd]['buf'],true)."]\n");
+            $this->notice("INNER_PACKET_ERROR and CLOSE_INNER_CONNECTION\nCLIENT_IP:".$this->getRemoteIp()."\nBUFFER:[".bin2hex($this->recvBuffers[$fd]['buf'])."]\n");
             $this->closeInnerClient($fd);
         }
         else
@@ -472,19 +537,18 @@ class Gateway extends Man\Core\SocketWorker
     {
         $pack = new GatewayProtocol($recv_buffer);
         $cmd = $pack->header['cmd'];
-        StatisticClient::tick();
-        $module = __CLASS__;
         $interface = isset(self::$interfaceMap[$cmd]) ? self::$interfaceMap[$cmd] : $cmd;
-        $success = 1;
-        $code = 0;
-        $msg = '';
+        StatisticClient::tick(__CLASS__, $interface);
         try
         {
             switch($cmd)
             {
                 // 向某客户端发送数据
                 case GatewayProtocol::CMD_SEND_TO_ONE:
-                    $this->sendToSocketId($pack->header['socket_id'], $pack->body);
+                    if(false === $this->sendToSocketId($pack->header['socket_id'], $pack->body))
+                    {
+                        throw new \Exception('发送数据到客户端失败,可能是该客户端的发送缓冲区已满,或者客户端已经下线', 121);
+                    }
                     break;
                 // 踢掉客户端
                 case GatewayProtocol::CMD_KICK:
@@ -528,16 +592,15 @@ class Gateway extends Man\Core\SocketWorker
                 default :
                     $err_msg = "gateway inner pack err cmd=$cmd";
                     $this->notice($err_msg);
-                    throw new \Exception($err_msg, 501);
+                    throw new \Exception($err_msg, 110);
             }
         }
-        catch(\Exception $e)
+        catch(\Exception $msg)
         {
-            $success = 0;
-            $code = $e->getCode() > 0 ? $e->getCode() : 500; 
-            $msg = $e->__toString();
+            StatisticClient::report(__CLASS__, $interface, 0, $msg->getCode() > 0 ? $msg->getCode() : 111, $msg);
+            return;
         }
-        StatisticClient::report($module, $interface, $success, $code, $msg);
+        StatisticClient::report(__CLASS__, $interface, 1, 0, '');
     }
     
     /**
@@ -587,7 +650,7 @@ class Gateway extends Man\Core\SocketWorker
     {
         if(!isset($this->connections[$socket_id]))
         {
-            return false;
+            return null;
         }
         $this->currentDealFd = $socket_id;
         return $this->sendToClient($bin_data);
@@ -599,16 +662,14 @@ class Gateway extends Man\Core\SocketWorker
      */
     protected function closeClient($fd)
     {
-        StatisticClient::tick();
         if($client_id = $this->getClientIdByFd($fd))
         {
             $this->sendToWorker(GatewayProtocol::CMD_ON_CLOSE, $fd);
-            Store::instance('gateway')->delete($client_id);
+            $this->deleteClientAddress($client_id);
             unset($this->clientConnMap[$client_id]);
         }
         unset($this->connClientMap[$fd], $this->connSessionMap[$fd], $this->connRemoteAddressMap[$fd]);
         parent::closeClient($fd);
-        StatisticClient::report(__CLASS__, 'CMD_ON_CLOSE', 1, 0, '');
     }
     
     /**
@@ -650,12 +711,22 @@ class Gateway extends Man\Core\SocketWorker
     {
         if($this->currentDealFd = array_rand($this->workerConnections))
         {
-            return $this->sendToClient($bin_data);
+             if(false === $this->sendToClient($bin_data))
+             {
+                 $msg = "sendBufferToWorker fail. May be the send buffer are overflow";
+                 $this->notice($msg);
+                 StatisticClient::report(__CLASS__, 'sendBufferToWorker', 0, 101, new \Exception($msg));
+                 return false;
+             }
         }
         else
         {
-            $this->notice("sendBufferToWorker fail \$this->workerConnections=".var_export($this->workerConnections,true));
+            $msg = "sendBufferToWorker fail. the Connections between Gateway and BusinessWorker are not ready";
+            $this->notice($msg);
+            StatisticClient::report(__CLASS__, 'sendBufferToWorker', 0, 102, new \Exception($msg));
+            return false;
         }
+        StatisticClient::report(__CLASS__, 'sendBufferToWorker', 1, 0, '');
     }
     
     /**
@@ -664,7 +735,7 @@ class Gateway extends Man\Core\SocketWorker
      */
     protected function notice($str, $display=true)
     {
-        $str = 'Worker['.get_class($this).']:'."$str ip:".$this->getRemoteIp();
+        $str = 'Worker['.get_class($this).']:'."$str";
         Man\Core\Lib\Log::add($str);
         if($display && Man\Core\Lib\Config::get('workerman.debug') == 1)
         {
@@ -673,7 +744,7 @@ class Gateway extends Man\Core\SocketWorker
     }
     
     /**
-     * 进程停止时,清除一些数据
+     * 进程停止时,清除一些数据,忽略错误
      * @see Man\Core.SocketWorker::onStop()
      */
     public function onStop()
@@ -690,22 +761,76 @@ class Gateway extends Man\Core\SocketWorker
      */
     protected function createGlobalClientId()
     {
+        StatisticClient::tick(__CLASS__, 'createGlobalClientId');
         $global_socket_key = 'GLOBAL_SOCKET_ID_KEY';
-        $global_client_id = Store::instance('gateway')->increment($global_socket_key);
+        $store = Store::instance('gateway');
+        $global_client_id = $store->increment($global_socket_key);
         if(!$global_client_id || $global_client_id > 2147483646)
         {
-            Store::instance('gateway')->set($global_socket_key, 1);
+            $store->set($global_socket_key, 0);
+            $global_client_id = $store->increment($global_socket_key);
         }
-        else 
+        
+        if(!$global_client_id)
         {
+            $msg = "生成全局client_id出错";
+            if(get_class($store) == 'Memcached')
+            {
+                $msg .= " 原因:".$store->getResultMessage(); 
+            }
+            $this->notice($msg);
+            StatisticClient::report(__CLASS__, 'createGlobalClientId', 0, 104, new \Exception($msg));
             return $global_client_id;
         }
-        return Store::instance('gateway')->increment($global_socket_key);
+        StatisticClient::report(__CLASS__, 'createGlobalClientId', 1, 0, '');
+        return $global_client_id;
+    }
+    
+    /**
+     * 保存客户端内部通讯地址
+     * @param int $global_client_id
+     * @param string $address
+     */
+    protected function storeClientAddress($global_client_id, $address)
+    {
+        StatisticClient::tick(__CLASS__, 'storeClientAddress');
+        if(!Store::instance('gateway')->set($global_client_id, $address))
+        {
+            $msg = "保存客户端通讯地址出错";
+            if(get_class(Store::instance('gateway')) == 'Memcached')
+            {
+                $msg .= " 原因:".Store::instance('gateway')->getResultMessage();
+            }
+            $this->notice($msg);
+            return StatisticClient::report(__CLASS__, 'storeClientAddress', 0, 105, new \Exception($msg));
+        }
+        StatisticClient::report(__CLASS__, 'storeClientAddress', 1, 0, '');
+    }
+    
+    /**
+     * 删除客户端内部通讯地址
+     * @param int $global_client_id
+     * @param string $address
+     */
+    protected function deleteClientAddress($global_client_id)
+    {
+        StatisticClient::tick(__CLASS__, 'deleteClientAddress');
+        if(!Store::instance('gateway')->delete($global_client_id))
+        {
+            $msg = "删除客户端通讯地址出错";
+            if(get_class(Store::instance('gateway')) == 'Memcached')
+            {
+                $msg .= " 原因:".Store::instance('gateway')->getResultMessage();
+            }
+            $this->notice($msg);
+            return StatisticClient::report(__CLASS__, 'deleteClientAddress', 0, 106, new \Exception($msg));
+        }
+        StatisticClient::report(__CLASS__, 'deleteClientAddress', 1, 0, '');
     }
     
     /**
      * 向客户端发送心跳数据
-     * 并把没回应心跳的客户端踢掉
+     * 并把规定时间内没回应(客户端发来的任何数据都算是回应)的客户端踢掉
      */
     public function ping()
     {
@@ -727,7 +852,11 @@ class Gateway extends Man\Core\SocketWorker
         // 向所有链接发送心跳数据
         foreach($this->clientConnMap as $client_id=>$conn)
         {
-            $this->sendToSocketId($conn, $this->pingData);
+            // 如果没设置ping的数据,则不发送心跳给客户端,但是要求客户端在规定的时间内(ping_interval*ping_not_response_limit)有请求发来,不然会断开
+            if($this->pingData)
+            {
+                $this->sendToSocketId($conn, $this->pingData);
+            }
             if(isset($this->pingInfo[$client_id]))
             {
                 $this->pingInfo[$client_id]++;

+ 1 - 2
applications/Demo/Lib/Gateway.php

@@ -277,8 +277,7 @@ class Gateway
            $connections = self::$businessWorker->getGatewayConnections();
            if(!isset($connections[$address]))
            {
-               $e = new \Exception("sendToGateway($address, $buffer) fail \$connections:".var_export($connections, true));
-               return false;
+               throw new \Exception("sendToGateway($address, \$buffer) fail \$connections:".var_export($connections, true));
            }
            return self::$businessWorker->sendToClient($buffer, $connections[$address]);
        }

+ 9 - 1
applications/Demo/Lib/StoreDriver/File.php

@@ -30,7 +30,7 @@ class File
     public function __construct($config_name)
     {
         $this->dataFile = \Config\Store::$storePath . "/$config_name.store.cache.php";
-        if(!is_dir(\Config\Store::$storePath) && !mkdir(\Config\Store::$storePath, 0777, true))
+        if(!is_dir(\Config\Store::$storePath) && !@mkdir(\Config\Store::$storePath, 0777, true))
         {
             // 可能目录已经被其它进程创建
             clearstatcache();
@@ -122,6 +122,14 @@ class File
     }
     
     /**
+     * 清零销毁存储数据
+     */
+    public function destroy()
+    {
+        @unlink($this->dataFile);
+    }
+    
+    /**
      * 写入磁盘
      * @return number
      */

+ 7 - 7
applications/Statistics/Modules/main.php

@@ -244,19 +244,19 @@ function formatSt($str, $date, &$code_map)
         $data[$time_line] = array(
                 'time'          => date('Y-m-d H:i:s', $time_line),
                 'total_count'   => $item['suc_count']+$item['fail_count'],
-                'total_avg_time'=> $item['suc_count']+$item['fail_count'] == 0 ? 0 : round(($item['suc_cost_time']+$item['fail_cost_time'])/($item['suc_count']+$item['fail_count']), 4),
+                'total_avg_time'=> $item['suc_count']+$item['fail_count'] == 0 ? 0 : round(($item['suc_cost_time']+$item['fail_cost_time'])/($item['suc_count']+$item['fail_count']), 6),
                 'suc_count'     => $item['suc_count'],
-                'suc_avg_time'  => $item['suc_count'] == 0 ? $item['suc_count'] : round($item['suc_cost_time']/$item['suc_count'], 4),
+                'suc_avg_time'  => $item['suc_count'] == 0 ? $item['suc_count'] : round($item['suc_cost_time']/$item['suc_count'], 6),
                 'fail_count'    => $item['fail_count'],
-                'fail_avg_time' => $item['fail_count'] == 0 ? 0 : round($item['fail_cost_time']/$item['fail_count'], 4),
+                'fail_avg_time' => $item['fail_count'] == 0 ? 0 : round($item['fail_cost_time']/$item['fail_count'], 6),
                 'precent'       => $item['suc_count']+$item['fail_count'] == 0 ? 0 : round(($item['suc_count']*100/($item['suc_count']+$item['fail_count'])), 4),
         );
     }
     $time_point =  strtotime($date);
     for($i=0;$i<288;$i++)
     {
-    $data[$time_point] = isset($data[$time_point]) ? $data[$time_point] :
-    array(
+        $data[$time_point] = isset($data[$time_point]) ? $data[$time_point] :
+        array(
             'time' => date('Y-m-d H:i:s', $time_point),
             'total_count'   => 0,
             'total_avg_time'=> 0,
@@ -265,8 +265,8 @@ function formatSt($str, $date, &$code_map)
             'fail_count'    => 0,
             'fail_avg_time' => 0,
             'precent'       => 100,
-            );
-            $time_point +=300;
+        );
+        $time_point +=300;
     }
     ksort($data);
     return $data;

+ 1 - 1
workerman/Core/AbstractWorker.php

@@ -260,7 +260,7 @@ abstract class AbstractWorker
     {
         $str = 'Worker['.get_class($this).']:'.$str;
         Lib\Log::add($str);
-        if($display && Lib\Config::get('workerman.debug') == 1)
+        if($display && Lib\Config::get('workerman.debug') == 1 && @posix_ttyname(STDOUT))
         {
             echo $str."\n";
         }

+ 3 - 3
workerman/Core/Master.php

@@ -33,7 +33,7 @@ class Master
      * 版本
      * @var string
      */
-    const VERSION = '2.1.3';
+    const VERSION = '2.1.4';
     
     /**
      * 服务名
@@ -916,10 +916,10 @@ class Master
      */
     public static function notice($msg, $display = false)
     {
-        Lib\Log::add("Server:".$msg);
+        Lib\Log::add("Server:".trim($msg));
         if($display)
         {
-            if(self::$serviceStatus == self::STATUS_STARTING)
+            if(self::$serviceStatus == self::STATUS_STARTING && @posix_ttyname(STDOUT))
             {
                 echo($msg."\n");
             }

+ 6 - 6
workerman/Core/SocketWorker.php

@@ -398,7 +398,7 @@ abstract class SocketWorker extends AbstractWorker
             // 出错
             $this->statusInfo['packet_err']++;
             $this->sendToClient('packet_err:'.$this->recvBuffers[$fd]['buf']);
-            $this->notice("PACKET_ERROR\nCLIENT_IP:".$this->getRemoteIp()."\nBUFFER:[".var_export($this->recvBuffers[$fd]['buf'],true)."]\n");
+            $this->notice("PACKET_ERROR\nCLIENT_IP:".$this->getRemoteIp()."\nBUFFER:[".bin2hex($this->recvBuffers[$fd]['buf'])."]\n");
             $this->closeClient($fd);
         }
         // 包接收完毕
@@ -413,7 +413,7 @@ abstract class SocketWorker extends AbstractWorker
             }
             catch(\Exception $e)
             {
-                $this->notice('CODE:' . $e->getCode() . ' MESSAGE:' . $e->getMessage()."\n".$e->getTraceAsString()."\nCLIENT_IP:".$this->getRemoteIp()."\nBUFFER:[".var_export($this->recvBuffers[$fd]['buf'],true)."]\n");
+                $this->notice('CODE:' . $e->getCode() . ' MESSAGE:' . $e->getMessage()."\n".$e->getTraceAsString()."\nCLIENT_IP:".$this->getRemoteIp()."\nBUFFER:[".bin2hex($this->recvBuffers[$fd]['buf'])."]\n");
                 $this->statusInfo['throw_exception'] ++;
             }
             
@@ -437,7 +437,7 @@ abstract class SocketWorker extends AbstractWorker
             // 判断是否大于接收缓冲区最大值限制
             if(strlen($this->recvBuffers[$fd]['buf']) + $remain_len > $this->maxRecvBufferSize)
             {
-                $this->notice('client_ip:'.$this->getRemoteIp().' strlen(recvBuffers['.$this->currentDealFd.'])='.strlen($this->recvBuffers[$fd]['buf']).'+' . $remain_len . '>' . $this->maxRecvBufferSize.' and close connection');
+                $this->notice('client_ip:'.$this->getRemoteIp().' send a packet which length greater than conf.max_recv_buffer_size:' . $this->maxRecvBufferSize.' .May be an attack so close connection');
                 $this->closeClient($fd);
             }
             else
@@ -567,10 +567,10 @@ abstract class SocketWorker extends AbstractWorker
             {
                 // 获得将要发送的buffer的长度
                 $total_send_buffer_len = strlen($this->sendBuffers[$this->currentDealFd]) + strlen($buffer_to_send);
-                // 如果大于最大限制值则丢弃这
+                // 如果大于最大限制值则丢弃这
                 if($total_send_buffer_len > $this->maxSendBufferSize)
                 {
-                    $this->notice('client_ip:'.$this->getRemoteIp().' strlen(sendBuffer['.$this->currentDealFd.'])='.$total_send_buffer_len.'>' . $this->maxSendBufferSize.' and droped');
+                    $this->notice('sendToClient fail. The send buffer\'s length of client_ip:'.$this->getRemoteIp().' is '.$total_send_buffer_len.' greater than conf.d.max_send_buffer_size:' . $this->maxSendBufferSize.', so discard the packet');
                     return false;
                 }
                 // 将数据放入发送缓冲区中,等待发送
@@ -596,7 +596,7 @@ abstract class SocketWorker extends AbstractWorker
             
             if(!isset($this->connections[$this->currentDealFd]))
             {
-                $debug_str = new \Exception('sendToClient fail $this->connections['.var_export($this->currentDealFd, true).'] is null');
+                $debug_str = new \Exception('sendToClient fail. Connections of '. $this->currentDealFd.' does not exist');
                 $this->notice((string)$debug_str);
                 return false;
             }

+ 0 - 2
workerman/conf/conf.d/BusinessWorker.conf

@@ -8,7 +8,5 @@ start_workers = 5
 user = root
 ;请求到来时预读长度,这里固定29
 preread_length = 29
-;设置最大请求数,超过这个请求数后会安全重启该进程(主要是避免因业务代码不规范导致的内存泄露)
-max_requests=10000
 ;必须是长链接
 persistent_connection = 1

+ 1 - 1
workerman/conf/conf.d/Monitor.conf

@@ -1,5 +1,5 @@
 ;==该worker的说明==
-;①监听2000端口,并提供telnet远程控制功能
+;①监听2009端口,并提供telnet远程控制功能
 ;②监控worker进程退出次数及状态,有异常时告警(告警发送邮件或者短信需要自己实现)
 ;③监控master进程是否异常退出
 ;④监控每个worker进程内存是否大于设定值,大于设定值则安全重启对应进程