日志
在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;
}
结果展示
写入文件
在runtime/log
目录下可以看到日志的格式是log/Ym/d.log
.通过swoole
按照thinkphp5.0
风格来写logfile
.编辑server/websocket.php
的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 . ' ';
}
/*
* 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
编写脚本
需要时刻的去检测端口.可以用到linux
的crontab
去检,但是linux
的crontab
检测服务是每分钟,如需要每秒的去监听,应该换用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
# 完成~
服务平滑启动
在Mac
中swoole
不支持设置别名,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~