SWOOLE 从入门到放弃之写个小框架(十七)

这次要搞定Log类,经过分析得出原因,每产生一次日志就直接写入,I/O高了。。。。swoole_async_writefile异步写入方法很牛X,也没法保证硬盘能扛得住。。改变思路,让日志每隔一段时间写入一次,减少I/O,在写入之前,先把它写到变量里,说白了就是放内存里。这个时间间隔就用要用swoole_timer_tick 间隔时钟定时器。

按照我的这个思路,先优化Log类吧。代码如下,

<?php
/**
 * 日志
 */
namespace Piz;
class Log
{
    /**
     * 实例
     * @var object
     */
    private static $instance ;
    /**
     * 配置参数
     * @var array
     */
    private static $config = [] ;

    private static $logs = [] ;

    private function __construct ()
    {
    }

    public static function get_instance(){
        if(is_null (self::$instance)){
            self::$config = Config::get_instance ()->get('app.log');
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * write 方法别名
     * @param       $type
     * @param array ...$logs
     */
    public function logs($type,...$logs){
        $this->write ($type,...$logs);
    }
    /**
     * 写入日志
     * @param       $type
     * @param array ...$msg
     */
    public function write($type,...$logs){
        $type = strtoupper ($type);
        $msg = "{$type} \t ".date("Y-m-d h:i:s")." \t ".join (" \t ",$logs);
        if( !in_array($type,self::$config['level'])) return false;
        if(self::$config['echo']){
            echo $msg,PHP_EOL;
        }
        self::$logs[$type][]=$msg ;
    }
    /**
     * swoole异步写入日志信息
     * @param mixed  $msg   调试信息
     * @param string $type  信息类型
     * @return bool
     */
    public function save(){
        if (empty(self::$logs)) return false;
        foreach(self::$logs as $type => $logs){
            $dir_path = LOG_PATH.date('Ymd').DIRECTORY_SEPARATOR;
            !is_dir($dir_path) && mkdir($dir_path,0777);
            $filename  = date("h").'.'.$type.'.log';
            $content = NULL ;
            foreach($logs as $log){
                $content .=$log.PHP_EOL;
            }
            swoole_async_writefile($dir_path.$filename , $content, NULL, FILE_APPEND);
        }
        self::$logs = [] ;
        return true;
    }
}

然后,修改Server.php,在onWorkerStart方法里增加一个定时器,让它每隔3秒就写一次

        //每3秒执行一次
        swoole_timer_tick(3000,function ($time_id){
            Log::get_instance ()->save();
        });

AB压测一下。看下效果

 ab -c 100 -n 10000 http://127.0.0.1:9501/
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests

Server Software:        swoole-http-server
Server Hostname:        127.0.0.1
Server Port:            9501

Document Path:          /
Document Length:        46 bytes

Concurrency Level:      100
Time taken for tests:   0.768 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      1940000 bytes
HTML transferred:       460000 bytes
Requests per second:    13027.50 [#/sec] (mean)
Time per request:       7.676 [ms] (mean)
Time per request:       0.077 [ms] (mean, across all concurrent requests)
Transfer rate:          2468.10 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    3   0.5      3       6
Processing:     1    4   2.3      4      31
Waiting:        0    3   2.2      3      31
Total:          3    8   2.4      7      35

Percentage of the requests served within a certain time (ms)
  50%      7
  66%      8
  75%      8
  80%      8
  90%      8
  95%      9
  98%     12
  99%     15
 100%     35 (longest request)

我擦,我突然觉得我立的FLAG是不是底了,还没怎么优化它就13K了?很慌。。。

又一想,想加的功能还没加完呢,估计加完了就歇菜了。。

小伙伴门,代码传到码去了。。。https://gitee.com/pizzzz/piz

下一篇,搞个铁钩。。。钩搭一下

点赞