日志

  在server/websocket.php添加

public function onRequest($request, $response)
{
    ...
    
    $_FILES = [];
    if (isset($request->files)) {
        foreach ($request->files as $key => $val) {
            $_FILES[$key] = $val;
        }
    }
    // 写在设置全局变量后面  
    /*记录日志*/
    $this->writeLog();
    
    ...
}

/*记录日志*/
public function writeLog()
{
    $data = array_merge(['data' => date('Y-m-d H:i:s')], $_GET, $_POST, $_SERVER);
    $logs = '';
    foreach ($data as $key => $val) {
        $logs .= $key . ':' . $val . ' ';
    }
    echo $logs;  
}

  结果展示

2019-06-25T11:42:47.png

写入文件

  在runtime/log目录下可以看到日志的格式是log/Ym/d.log.通过swoole按照thinkphp5.0风格来写logfile.编辑server/websocket.phpwriteLog().

/*记录日志*/
public function writeLog()
{
    $data = array_merge(['data' => date('Y-m-d H:i:s')], $_GET, $_POST, $_SERVER);
    $logs = '';
    foreach ($data as $key => $val) {
        $logs .= $key . ':' . $val . ' ';
    }
    /*
     * swoole_async_writefile
     * 异步文件写日志
     * 日志文件路径 日记内容 回调函数  追加的形式
     * APP_Path就是我们的application目录
     * tmd 没这个方法了。要想用要么使用协程自己替换。要么下载async-ext扩展https://github.com/swoole/ext-async
     * */
    go(function () use ($logs) {
        /*判断目录存在不存在*/
        $dir = APP_PATH . '../runtime/log/' . date('Ym') . '/';
        if (!is_dir($dir)) {
            mkdir($dir, 0777, true);
        }
            $this->exeWriteLog($dir . date('d') . '_success.log', $logs);
        });
}

/*执行写入日志*/
public function exeWriteLog($filename, $content)
{
    /*
     * 如果文件不存在,则创建文件,相当于fopen()函数行为。
     * 如果文件存在,默认将清空文件内的内容,可设置 flags 参数值为 FILE_APPEND。
     * */
    file_put_contents($filename, PHP_EOL . $content, FILE_APPEND);
}

多次请求的问题

  thinkphp中请求一个页面他会走两次请求,tmd让人很头疼.之前做个视频网站也是因为走个图片的地址.因为没有然后报错~.他请求两次也是很费资源的!解决,修改server/websocket.php

/*request 回调*/
public function onRequest($request, $response)
{
    // 顶部添加,如果没有问题可以不用加这段~
    if($request->server['request_uri'] == '/xxx'){
        // 返回404 并结束。如果不用end() 会报500。这个请求就协程自己的吧
        $response->status(404);
        $response->end();
        return ;
    }
    ...
}

服务监控

Linux下查看端口

  启动服务的时候都是到服务目录下执行php xxx.php. 如果我们不对服务做监控,他突然挂掉了,而我们并不知道.所以我们更好的管理服务以及定位到问题的所在.需要写个脚本来监控服务~

# 启动服务
php server/websocket.php
# 查看进程
netstat -anp | grep 950
tcp        0      0 0.0.0.0:9503            0.0.0.0:*               LISTEN      127358/php
tcp        0      0 0.0.0.0:9504            0.0.0.0:*               LISTEN      127358/php
tcp        0      0 0.0.0.0:9505            0.0.0.0:*               LISTEN      127358/php
# 这里因为我做了聊天室和图文直播,分别用了9503,9604.所以启动服务后有3个进程.

-- 简单的返回值
netstat -anp | grep 9503 | grep LISTEN | wc -l
# 服务启动时返回
1
# 服务为启动返回
0

编写脚本

  需要时刻的去检测端口.可以用到linuxcrontab去检,但是linuxcrontab检测服务是每分钟,如需要每秒的去监听,应该换用swoole的毫秒级定时器.先写一个简单的脚本server/script/montitor/server.php.

class Server
{
    const POST = 9503;
    
    public function port()
    {
        $shell = 'netstat -anp  | grep ' . self::POST . '| grep LISTEN | wc -l';
        $result = shell_exec($shell);
        if($result != 1){
            /*发送报警 短信或者邮件*/
            echo date('Y-m-d H:i:s') . 'error' .PHP_EOL;
        }else{
            echo date('Y-m-d H:i:s') . 'success' .PHP_EOL;
        }
    }
}

\swoole_timer_tick(2000,function($timer_id){
    (new Server())->port();
    echo 'timer_start' . PHP_EOL;
});

  启动脚本,关闭服务,启动服务测试.

# 启动脚本监听
php server/script/montitor/server.php
# 返回
2019-06-25 13:55:02error
timer_start
2019-06-25 13:55:04success
timer_start
2019-06-25 13:55:06success
timer_start
2019-06-25 13:55:08success
timer_start
2019-06-25 13:55:10error
timer_start
2019-06-25 13:55:12error
timer_start

后台执行

  通过php xxx.php去执行的,这样是不行的.应该让脚本在后台无间断的去执行吧.在linux中有个强大的后台执行命令nohup [程序名] & ,符号&是指后台运行,不加就是直接执行.

# 查看php执行文件路径
find /usr/local/php/ -name php
# 返回php执行文件路径
/usr/local/php/bin/php
# 查看脚本所在路径
pwd
# 返回
/data/wwwroot/liveTelecast/server/script/montitor
cd /data/wwwroot/liveTelecast/server/script/montitor
# 创建日志文件
mkdir log
cd log
touch 2.txt
# 后台PHP执行脚本,输入到日志文件
nohup /usr/local/php/bin/php /data/wwwroot/liveTelecast/server/script/montitor/server.php > /data/wwwroot/liveTelecast/server/script/montitor/log/2.txt &
# 返回pid.如果想关闭,执行kill -9 返回的pid就好.
[1] 130473
[root@localhost montitor]# nohup: 忽略输入重定向错误到标准输出端

# 查看pid的进程
ps -ef | grep 130473
# 返回
root     130473 127391  0 10:24 pts/1    00:00:00 /usr/local/php/bin/php /data/wwwroot/liveTelecast/server/script/montitor/server.php
root     130543 127391  0 10:24 pts/1    00:00:00 grep --color=auto 130473
# 查看日志文件
cat 2.txt
# 返回
2019-06-25 14:25:18success
timer_start
2019-06-25 14:25:20success
timer_start
2019-06-25 14:25:22error
timer_start
2019-06-25 14:25:24error
timer_start
# 完成~

服务平滑启动

  在Macswoole不支持设置别名,swoole有三个信号源.sigterm停止服务,sigusr1重启worker进程,sigusr2全部重启taskwork进程.

设置别名

  在server/websocket.php中添加

public function __construct()
{
    ...
    /*平滑重启*/
    $this->websocket->on('start',[$this,'onStart']);
    ...
}

/*
 * 平滑重启服务
 * 
 * */
public function onStart($server)
{
    /*给个进程名称 给祝进程起别名*/
    swoole_set_process_name('live_game');
}

  重启服务,查看结果

netstat -anp | grep 9503
# 返回
tcp        0      0 0.0.0.0:9503            0.0.0.0:*               LISTEN      19563/live_game
# 获取进程pid
pidof live_game
# 返回pid
19563

平滑启动

touch server/.reload.sh
# 添加
echo 'loading...'
pid=`pidof live_game`
echo $pid
kill -USR1 $pid
echo "loading success"
# 保存执行
./server/.reload.sh
-bash: ./server/.reload.sh: 权限不够
# 添加可执行权限
chmod +x server/.reload.sh
# 开启服务后,再另一个终端测试
sh server/.reload.sh
# 输出
loading...
22978
loading success
# 服务端终端显示
[root@localhost liveTelecast]# php server/websocket.php
[2019-06-25 12:21:10 $22979.0]    INFO    Server is reloading all workers now
[2019-06-25 12:22:03 $22979.0]    INFO    Server is reloading all workers now
# ok~
Last modification:February 18th, 2020 at 10:20 pm