如前述,我们项目中目前还在Win32平台,切换到了Nginx架构的RTMP服务器。当然也是长时间不规范的直接双击运行的,虽说Nginx的架构保证进程活着问题不大,但是无法应对突然的停电,停电之后无人去操作启动,造成了无人觉察的故障,这也是一个极大的风险。
技术选型
当然我们的目标是把nginx做成一个服务,不像Linux下那么方便。基本上就两种方法,自己写一个监控服务,另外一种就是使用第三方工具做成系统服务,这其中第三方服务基本不太会监控Nginx的死活,只会保证系统开机自启Nginx(当然也有直接放到启动菜单或者注册表中的办法,我们暂还是用比较规范的方法)。
自己开发的话有一定工作量,况且Nginx的稳定性问题不大,因此不太有必要自研。网络上比较流行的方法是采用Windows Service Wrapper工具(WinSW)进行包装,也有很多其他软件,不过这个软件相对简单易用,而且普遍反映相对其他软件功能没有问题。
此开源项目的地址是:https://github.com/kohsuke/winsw
2.0之后的版本提供了.net 2.0和.net 4.0两个版本的下载,根据实际情况下载。
WinSW配置
WinSW的使用相对比较简单,基本步骤如下
首先建议将下载的exe改名,比如我们给Nginx包装的服务,那改名为
nginx-service.exe
。然后创建同名的xml配置文件,如
nginx-service.xml
,比如Nginx可配置如下
<service>
<id>nginx</id>
<name>Nginx Media Service</name>
<description>Nginx Based Media Streaming Server</description>
<executable>nginx.exe</executable>
<logpath>./logs</logpath>
<logmode>roll</logmode>
<stopexecutable>nginx.exe</stopexecutable>
<stopargument>-s</stopargument>
<stopargument>stop</stopargument>
</service>XML文件的详细配置教程见官方文档 xmlConfigFile.md
安装,使用管理员权限的CMD,输入安装命令
nginx-service.exe install
启动,在CMD输入启动命令,或者在系统services.msc图形界面启动
nginx-service.exe start
其中,该命令可使用 start | stop | install | uninstall 等,对应启动、停止、安装、卸载等
Nginx日志清理
不说Linux下很方便的清理方式,只谈Windows。如果你仔细观察,会发现Nginx生成的日志文件不会自动分割,比如按时间或者按大小,这样长此以往,文件会非常大。观察现网的日志已经五百多兆了,急需清理,通过 /stat 统计页面查看,长期都有五六十个推流端在推流,当然总推流时长不会很长。
大部分网上的办法都是重启Nginx服务,我觉得不可接收,有些更好的方案是转移文件,然后reload。
我们来试试reload的效果,修改配置文件中比如日志的名称,然后nginx -s reload
,你会发现没有权限!为什么没有权限,通过任务管理器可以看到Nginx的权限是SYSTEM,可以想到系统服务都是SYSTEM权限的,想操作还得用这个权限,正常情况下我们是不能获取到SYSTEM权限,根据网上办法也不靠谱,但是既然WInSW搞出来了SYSTEM权限, 类似的,我们再制作个NginxReloadService,就执行reload操作即可解决权限,简单暴力,那么再探究下日志问题。
如前,然后再测试,基本OK,如果你运气好点,你会发现更严重的问题,Nignx的进程有三个,而且通过 /stat 查不到正在进行的推流统计,当然也没办法播放了。应该是Nginx在reload的时候,Nginx重新创建了一个新的worker进程来提供服务并采用了新配置,老的worker进程在现有服务完成后会退出,为了验证,停止了推流,这个进程很快关闭。
这么看来,reload方式的主要问题是不实时,在rtmp这种长连接的情况下不太可用。重启大法好啊,难道就只剩这一个办法了么。
完美的方案
观察和思考良久,发现网上比较好的博客在介绍Linux下日志分割的时候,并不是重启进程啥的,用的是信号SIGUSR1,也就是让Nignx重新打开日志文件。这给了我们启示,说明Nginx是支持受命令控制重新打开日志文件的,当然Windows下是没有这个信号的,仔细查阅下发现这个信号其实等同与nginx -s reopen
,对就是reopen这个一直被忽略的命令。再来试试效果,手动Move文件之后,然后reopen,文件生成了,进程PID根本就没变,看来reopen是个完美的方案。
结合前述问题,最终通过WinSW再封装一个reopen的操作的服务(可以保证SYSTEM权限),剩下的就是定时任务了(注意运行账户改为SYSTEM),基本上完美解决日志分割问题,并且没有特别的副作用。
Nginx Logrote Service 配置样例
|
Nginx Logrote Service 批处理文件样例
@ECHO OFF |
PS:网上的方法真是误人子弟啊,一个高质量的博客显得是多么重要!