0x1 需求分析
0x10 HTTP监控
RsStreamer作为P2P流媒体服务器,需要和很多并发连接的P2P播放器进行通讯,把媒体数据发送给这些P2P播放器进行播放,另外还需要和其他如认证服务器进行通讯,进行用户验证等操作.
RsStreamer在运行的过程中,很多内部状态需要及时地提供给用户,如统计有多少个用户观看了某部影片,提供某部影片流媒体服务的总带宽是多少,通过http服务的形式提供这些内部状态的监控信息,用户可以通过浏览器来直观地访问这些数据,从而了解系统运行的相关信息.
另外用户还可以通过浏览器来配置RsStreamer,如限制某个用户的带宽,对某个特定的媒体频道限制用户数目.
其他流媒体平台如helix server也提供网页形式的界面供用户查看运行状态和进行相关配置管理.
其他开源软件如nginx也有类似的功能.
0x11 数据分析
通过RsStreamer提供的http服务,把系统运行的相关信息通过RESTful接口的形式提供给数据分析系统(如elasticsearch),进行分析以后,可以对用户播放流媒体影片的行为进行数据挖掘,训练影片推荐系统,从而提供更好的用户体验.
下面先分析一下haproxy系统中监控模块是如何实现的,然后再提出RsStreamer中监控模块的设计方案.
0x2 HAProxy的实现
0x20 总体结构
haproxy中有关监控模块的总体结构图如下所示.
http service基于epoll对外提供http服务,接受浏览器的请求,建立和浏览器之间的tcp连接,根据运行状态生成对应的html格式数据,通过tcp把html数据发送给浏览器,浏览器接收到数据以后显示haproxy的运行状态.
0x21 代码流程
程序执行流程图如下
程序的执行从main函数开始,然后调用poller函数等待事件的触发.
有stats的请求到来,poller函数触发.
然后根据运行状态生成html格式数据,通过tcp发生给浏览器.
下面对这个流程图的执行过程进行进一步的分析.
0x22 相关代码模块分析
处理网络连接的主循环
该循环调用poller的poll函数,检测是否有socket事件发生,用户在浏览器中输入http://127.0.0.1:1080/stats, haproxy收到请求,run_poll_loop()检测到有client来连接,建立tcp连接,然后调用applet_run_active()来处理这些事件.
|
|
poller的poll()函数实现
1.首先扫描fd更新列表fd_updt,找到需要处理的fd,再调用epoll_ctl()来往内核来注册epoll事件.
2.然后调用epoll_wait()等待事件的发生,事件触发以后,epoll_wait()函数返回,返回值是触发的事件数目.
3.再遍历已经触发的事件,根据是要读还是写分别调用fd_may_recv()和fd_may_send().
applet_run_active()函数实现
从applet队列中找到需要执行的任务,调用相应的handler函数,对stats模块,其handler函数为http_stats_io_handler().
|
|
stats模块在applet中的注册
把stats的处理函数http_stats_io_handler注册到applet中.
请注意关键字attribute((constructor))是gcc的关键字,表明这个函数是在main()函数执行之前被调用.
|
|
生成html格式监控数据
生成html格式监控数据的调用堆栈如下.
0x23 监控相关配置
在配置文件中加入下面的内容,然后启动haproxy,这样haproxy就支持状态监控了.
0x24 浏览器运行效果如下
从图中可以看到系统运行的状态.
0x3 系统设计
参考haproxy的监控模块,设计RssStreamer的监控模块如下图所示.
http service基于st对外提供http服务,st是基于epoll来实现的, 接受浏览器的请求,建立和浏览器之间的tcp连接,state monitor负责收集系统各个模块的运行状态,html generator根据运行状态生成对应的html格式数据,通过tcp把html数据发送给浏览器,浏览器接收到数据以后显示RsStreamer的运行状态.