创建一个用于记录和传递链路信息的Nginx模块,该模块在我们的直播分发模块之后启动。每台机器的链路信息存储于link_module的ctx中的units,units是一个动态数组,元素的类型为unit,记录链路中每一个session的信息。
当前需求中需要打印的链路信息为节点内链路和节点间链路,故我们在每台机器上存储链路的思路为上游节点的节点间链路信息+本节点的节点内链路信息。
链路信息的更新:
我们在每一层都记录相应的链路信息,根据流数据的来源不同,更新本机链路信息的方式也不同。如果数据来自CDN以外,在执行publish信令的过程中,将链路信息存入到相应模块的ctx。
如果数据来自cdn内部,通过amf meta data(内部定义的)的回调函数或是解析响应头(http)来执行链路数据的更新和存储。
具体如下:
1.ctx的初始化:
publisher调用链:初始化为自己(仅限外部推流,并记录客户端推流ip),然后notify all player。
player调用链:使用自己 + publisher的链路信息初始化(如果没有publish_ctx,仅初始化自己,并将客户端推流ip置空)
2.ctx的更新:
publisher链路信息更新:
接收到18信息或是响应头的时候,更新链路信息(上层信息+自己 ), 并notify all player。
player链路信息的更新主要依赖于publisher的通知:
2.1、pulbish join的时候,遍历live stream下players,更新链路信息
2.2、publiser 接收消息(amf或header)更新的时候,遍历live stream下players,更新更新链路信息
3.player发送amf和响应头:
3.1.响应头只会在flv连接建立后发送一次,之后flv链路信息的更新也是依赖于自定义的amf数据包。
3.2.amf包通过write调用链发送链路信息(具体是否发送还需要经过check校验:比如说链路信息无需送给客户,或是配置未开启链路传递)
3.3发送链路的内容会经过过滤重新生成,上游节点的内部链路将会被剔除,同时检测客户端推流ip是否为空,如果为空,表示回源失败,使用特殊ip:0.0.0.0来填充客户端推流ip。
链路信息的打印(链路日志的打印功能默认关闭):
1、publisher 打印截止到当前session的节点间数据,只有session类型为client_publish和relay_pull才会打印。
达到以下几个条件之一时触发日志打印:
①连接刚开始时,打印第一条日志
如果是cdn外部的客户端推流,在link_module的publish调用中初始化ctx时打印
如果是内部的回源或是转推,在上游的link_module的play调用链中初始化ctx后会将链路信息通知下游,下游在收到amf或是响应头的时候,会打印日志
②连接过程中,达到日志打印周期(支持可配,默认为600s)
在log_module的publish调用中启动timer,周期打印
③连接过程中,收到metadata里有链路信息
下游收到amf时,更新本机的链路信息,并打印日志。
④连接结束时,打印最后一条日志
连接结束时,log模块在disconnect时统一删除timer,并打一条日志
2、player 在monitor日志中打印当前节点内的全部链路数据,只有session类型为 client play 才会打印,在var_get_data中实现。