Video视频播放中断问题排查记录
问题描述:
自视频播放功能上线以来,经过初步的测试发现,视频播放一段时间后会出现中断的情况,中断的播放时长不固定(有的在三分钟左右中断,有的在十几分钟才中断),刷新后又能接着播放,但马上又中断了,出现类似提示:
问题排查:
分析可能出现的原因:
1、 网络问题。
2、 代码问题。
3、 videojs问题。
4、 视频格式问题(毕竟经过转换)。
5、 服务器问题(最容易忽略、最难排查的原因)。
针对可能出现的原因逐一排查:
1)网络问题:怎么刷新都还是有问题(有时候刷新后能接着播放),于是排除网络原因。
2)代码问题:看到错误的第一反应就是查看浏览器控制台,看是否有蛛丝马迹,果然是有错误提示,百度这个提示给出的大部分答案是浏览器不支持此视频播放,但显然不是,因为都播放了一段时间了才出现的。
那只能去看tomcat日志信息了,发现后台也有异常提示,但不是每次刷新都会提示,
开始排查后端代码,发现有一段代码使用了FileInputStream后没关闭,将此流关闭后异常确实报的没那么频繁了,可问题依然存在。
3)videojs问题:视频播放采用videojs,开始尝试用不同的浏览器测试播放功能,排查videojs版本与浏览器的兼容性问题,将原来的5.8.0版本换成7.10.2版本发现播放好像好了一点,再尝试换了几个版本效果也差不多。换火狐和IE浏览器测试,测了大概3轮都能正常播放。火狐在第4轮测试发现还是会出现自动暂停的情况,点播放后可以接着放,IE浏览器没再顾得上,说明问题还是存在的。(测试太耗时且测试的数据量不大,代表性不强)
4)格式问题:视频是经过其它部门的兄弟进行过格式转换过,怀疑可能是转换过程中视频的某项参数配置有问题,于是各种百度ffmpeg的用法,费时费力的进行各种转换测试,可结果还是不尽人意,问题还是没得到解决。
5)服务器问题:这真是一个最容易让人忽略,也是最难排查的原因,毕竟服务器运行好几年了,对它还是比较自信的,去查看tomcat的server.xml配置发现几乎没做过任何改动(除了端口号),tomcat默认的参数配置可能满足不了系统现有功能承载量。开始试着改server.xml参数配置,因为是视频播放,可能比较吃带宽,当带宽比较小的时候可能会出现超时中断的情况,于是把默认的链接超时时间由20000改成60000,测试了十几个视频后发现都能正常播放了。初步确定是tomcat服务器参数配置的问题了,开始设置不同的参数进行测试验证,从jvisualvm监控数据可以看出,线程数访问数已经远远超过了tomcat默认(200)配置的线程访问量,超过这个数量的连接将被等待甚至超时放弃,所以我们需要提高这方面的处理能力。
解决方案:
修改tomcat配置,配置如下:
<!-- Executor 配置说明 name: 共享线程池的名字,这是 Connector 为了共享线程池要引用的名字,该名字必须唯一、默认值: None namePrefix: 在JVM上,每个运行线程都可以有一个name 字符串,这一属性为线程池中每个线程的name字符串设置了一个前缀,Tomcat将把线程号追加到这一前缀的后面、默认值: catalina-exec- maxThreads: Tomcat 使用线程来处理接收的每个请求,这个值表示 Tomcat 可创建的最大的线程数,默认值是 150 minSpareThreads: 最小空闲线程数,Tomcat 启动时的初始化的线程数,表示即使没有人使用也开这么多空线程等待,默认值是 4 maxSpareThreads: 最大备用线程数,一旦创建的线程超过这个值,Tomcat 就会关闭不再需要的 socket 线程 maxIdleTime: 在Tomcat关闭一个空闲线程之前,允许空闲线程持续的时间(以毫秒为单位)默认值 60000 ms,只有当前活跃的线程数大于 minSpareThreads 的值,才会关闭空闲线程,默认值 60000 ms --> <Executor name="tomcatThreadPool" namePrefix="gy-catalina-exec-" maxThreads="500" minSpareThreads="20" maxSpareThreads="50" maxIdleTime="60000"/> <!-- Connector 配置说明 executor: 指定 executor 执行器,配置不可与 Connector 的配置重复 port: 端口号 protocol: 使用的网络协议,表示tomcat使用何种方式来接受和处理client端请求,默认值HTTP/1.1,等效于"org.apache.coyote.http11.Http11Protocol";还有熟悉的"AJP/1.3"; URIEncoding: 指定 Tomcat 容器的 URL 编码格式,语言编码格式这块倒不如其它 WEB 服务器软件配置方便,需要分别指定 connnectionTimeout: 网络连接超时,单位:毫秒,设置为 0 表示永不超时,这样设置有隐患的。通常可设置为 30000 毫秒,可根据检测实际情况,适当修改 enableLookups: 是否反查域名,以返回远程主机的主机名,取值为:true 或 false,如果设置为false,则直接返回IP地址,为了提高处理能力,应设置为 false disableUploadTimeout: 上传时是否使用超时机制 connectionUploadTimeout: 上传超时时间,毕竟文件上传可能需要消耗更多的时间,以使 Servlet 有较长的时间来完成它的执行,需要与 disableUploadTimeout 参数一起配合使用才会生效 acceptCount: 指定当所有可以使用的处理请求的线程数都被使用时,可传入连接请求的最大队列长度,超过这个数的请求将不予处理,默认为100个 keepAliveTimeout: 长连接最大保持时间(毫秒),表示在下次请求过来之前,Tomcat 保持该连接多久,默认是使用 connectionTimeout 时间,-1 为不限制超时 maxKeepAliveRequests: 表示在服务器关闭之前,该连接最大支持的请求数。超过该请求数的连接也将被关闭,1表示禁用,-1表示不限制个数,默认100个,一般设置在100~200之间 compression: 是否对响应的数据进行 GZIP 压缩,off:表示禁止压缩;on:表示允许压缩(文本将被压缩)、force:表示所有情况下都进行压缩,默认值为off,压缩数据后可以有效的减少页面的大小,一般可以减小1/3左右,节省带宽 compressionMinSize: 表示压缩响应的最小值,只有当响应报文大小大于这个值的时候才会对报文进行压缩,如果开启了压缩功能,默认值就是2048 compressableMimeType: 压缩类型,指定对哪些类型的文件进行数据压缩 redirectPort: 当用户用http请求某个资源,而该资源本身又被设置了必须要https方式访问,此时Tomcat会自动重定向到这个redirectPort设置的https端口 --> <Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" URIEncoding="UTF-8" connectionTimeout="30000" enableLookups="false" disableUploadTimeout="false" connectionUploadTimeout="150000" acceptCount="300" keepAliveTimeout="120000" maxKeepAliveRequests="150" compression="on" compressionMinSize="2048" compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain,image/gif,image/jpg,image/png" redirectPort="8443" />
配置说明:参考官方文档http://tomcat.apache.org/tomcat-8.0-doc/config/http.html