IM系统如何提高用户发送、浏览图片和音视频消息的体验呢?一是保证图片、音视频消息发送得又快又稳,二是保证用户浏览播放图片、音视频消息时流畅不卡顿。
算法
针对不一样的主流运营商提供不一样的上传接入点 IP,而后经过运营商 DNS 解析,让用户能经过本运营商的上传接入点来快速上传图片和视频;后端的图片上传存储服务也能够部署在多线机房,这样上传服务也能快速地把文件流提交给存储层,从而避免从接入点到存储服务的跨网开销,也能解决其余运营商的用户下载图片时须要跨网的问题。后端
对于拥有多机房的公司,也能够只把上传存储服务部署在单线机房,而后再经过专线解决多个单线机房之间的访问。缓存
把多媒体消息上传通道和普通消息收发通道独立开。安全
发送图片、视频这样的多媒体消息时,先经过独立通道上传文件流,上传完成后会返回文件的惟一标识 ID,而后再把这个惟一标识 ID 做为消息的引用,经过普通消息收发通道进行发送。性能优化
对于语音这样的消息,经过普通消息收发的长连通道来分片上传语音流,更方便经过长连来下推给接收方,避免用户在播放语音时须要从远程临时下载文件,使用流畅度会更好。服务器
不用多说,咱们都知道 CDN 的做用是让资源离用户更近。并发
CDN 加速主要采起“拉模式”的策略。客户端上传的图片、音视频发布到多个分布在各地的 CDN 节点的服务器上,当有用户须要访问这些图片和音视频时,可以经过 DNS 负载均衡技术,根据用户来源就近访问 CDN 节点中缓存的图片和音视频消息,若是 CDN 节点中没有须要的资源,会先从源站同步到当前节点上,再返回给用户。负载均衡
在上面提到:若是 CDN 节点中没有须要的资源,会先从源站同步到当前节点上,再返回给用户。但若是是超高热度的大型聊天室,可能用户就近访问的节点没有须要的资源,则高并发的请求都被回源到源站,会对源站的带宽和存储带来很大的压力。高并发
针对这个问题,能够采用“预热”的方式,来提早强制 CDN 节点回源并获取最新文件,减轻源站的压力,提升资源的访问效率。性能
图片
好比服务器对图片生成几种常见的低分辨率缩略图,用户点开时,根据终端的分辨率按需下载,“查看原图”时再去加载大图,这样能够提高加载速度。
将上传的图片转为 WebP 或渐进式 JPEG 格式。
前者能够在保持相同质量的前提下,比一样的 PNG 或 JPEG 图片小 30% 左右,但在 iOS 系统上的支持性不太好,须要必定的开发成本;
后者可以在加载图像时提供低分辨率的“预览”,节省数据流量,提高图像加载速度,加载体验更好,但渐进式 JPEG 编码比传统基线 JPEG 的编码速度慢了 60%,须要权衡性能和成本的平衡。
视频
在播放器下载完视频的格式信息、关键帧等信息后,播放器就能够开始播放,同时结合 HTTP 协议自带支持的 Range 头按需分片获取后续的视频流,从而来实现边下边播和拖动快进。
边下边播须要服务端支持 Range 分片获取。
对视频流进行“部分提早加载”,也就是所谓的“秒开”,能够提高用户的体验。
预加载能够按时间或者大小来限制。好比,咱们能够设定预加载 3s 的视频流,或者设定预加载 512KB 的视频流。
主流的视频格式采用 H.264 编码,H.265 是 2013 年新制定的视频编码标准。一样的画质和一样的码率,H.265 比 H.264 占用的存储空间要少 50%,但编码复杂度远高于 H.264(10 倍左右)。
所以在实现时,只选取部分热点视频来进行 H.265 编码,下降转码开销的同时来尽可能提高 H.265 视频的覆盖度。
借助即时消息自身的“长链接”通道,将音频流、图片或视频的缩略图推送下去,这样就不会由于须要临时从服务端获取而出现卡顿了,减小加载耗时,提高用户体验。
用户经过上传服务,把视频上传到服务端;服务端进行视频的 HLS 切片并针对切完的 TS 文件流进行加密,同时把密钥存储到密钥服务中。
当有用户请求该视频时,CDN 节点从源站回源加密的视频文件,播放器先经过下载的 M3U8 索引文件获取到“密钥地址”。
客户端缓存的认证 Token 拼接到该“密钥地址”后面,再经过该地址请求鉴权服务,鉴权服务检查携带的认证 Token 是否有权限访问该视频文件。
若是权限没问题,会从密钥存储服务中将该视频的密钥文件返回给播放器,这时播放器就能自动解密播放了。
HLS 仅支持视频的加解密操做,不支持图片等其余格式的资源。针对其余格式的资源,能够采用“时间戳防盗链”的方案。
Token防盗链经过对时间有关的字符串进行签名,将时间,签名信息经过必定的方式传递给CDN节点服务器做为判断依据,CDN 节点则会根据 URL 的加密形式,取出对应的过时时间,和当前服务器时间进行比较,确认请求是否过时,过时的话,则直接拒绝;若是时间未过时,CDN 节点将根据约定的签名算法和密文,计算后的值和 URL 中的原始加密串进行比较;经过以后,请求会被认为是合法的。不合法的请求能够采起禁止访问或其余操做。