全面解析从多图片缓存到带宽优化-如何优化大量图片加载,降低带宽消耗,提高用户体验?

一、前言

多文件或大文件下载其实一直是一个比较头疼的问题,对于用户来说它太耗费服务器的资源和成本,尤其是在并发量比较大的应用场景下。
举个例子:假如多个用户同时使用app在线浏览车辆照片、并且每张照片都是按MB级别的数据量存储,甚至有的网站照片都是10几M、高清的那种,那么在高并发浏览照片的场景下一定会对服务器造成很大的压力,同时这段时间会占用很大的网络带宽,这就会导致你的app或其他客户端出现卡顿,带宽不够用的情况。
为啥说它耗钱,是因为如果我们的带宽不够,比如就是固定带宽10M,这种场景根本是不够用的,而公网带宽的价格也是比较昂贵的,需要很多RMB。
如果用户舍得花钱购买服务器,购买带宽那没问题,但是这里要提一点的是,如果项目的业务时间段比较聚集,峰值都在这个时间段内,那么还是建议购买带宽时不要按固定带宽购买,要按照流量计费去购买带宽,流量计费的比较适合这种突发业务量的情况。那么针对这种场景,我们的系统该如何去支撑和优化呢?一般用多大的带宽才够用?

二、带宽到底需要多大?

我们从多个优化点来聊聊这个问题:

首先,我们先来模拟一个业务场景:就从刚刚浏览车辆照片这个业务场景来说。

假设,在外网DMZ区部署了一台机器,这台机器,内外网均可访问,并满足一定的安全策略,注意的是用户访问服务器时只有这一个入口和出口,如果,在上午的9点到10点这段时间内,有300个用户同时通过app浏览车辆照片,并且每一辆车的图片为30张,图片的平均大小为1MB,那么请问,为了满足用户使用app不卡顿,请问,机房的公网带宽最低不能低于多少?

在用户的请求过程中,包括结构化数据和非结构化数据,非结构化数据就是指的车辆的图片,若结构化数据占用的带宽先忽略不计,我们来算算带宽到底应该满足多大:

带宽的单位是Mbit/s ,我们说的10M带宽,指的是每秒传输的bit数。那么我们可以通过如下公式来计算:

带宽 = 图片数*用户数*图片大小/下载时间 。所以为 30*300*1MB/1h ,

下面我来详细解释一下这个公式中的每个因素:

1. 用户数:这是指同时访问服务器的用户数量,也就是并发用户数。用户数越多,就意味着服务器需要处理更多的请求,因此需要更大的公网带宽。

2. 图片数:这是指每个用户需要下载的图片数量,也就是每个页面上的图片数。图片数越多,就意味着每个用户需要下载更多的数据,因此需要更大的公网带宽。

3. 图片大小:这是指每张图片的数据量,单位是字节(Byte),也可以用千字节(KB)或兆字节(MB)表示。图片大小越大,就意味着每张图片需要传输更多的数据,因此需要更大的公网带宽。

4. 下载时间:这是指用户下载完所有图片所需的时间,单位是秒(h)。下载时间越短,就意味着用户对下载速度的要求越高,因此需要更大的公网带宽。

通过以上公式我们计算出来 ,如果想要这300个用户1个小时将这30张图片都加载完 带宽为 9000MB/h。

为了保证用户使用app不卡顿,我们还需要考虑一些其他因素,比如网络延迟、丢包率、服务器性能等。一般来说,带宽的使用率不应超过80%,以留出一定的冗余空间。因此,我们可以将上面的结果乘以1.25,得到:

带宽=9000MB/h×1.25=11250MB/h

这就是机房的公网带宽最低不能低于的数值。换算成Mbps,就是:

带宽=11250MB/h×8=90000Mbps/h = 25Mbps/s= 25Mbit/s

但是,有个问题就是,用户不可能排着队去下载这个图片,而可能是在10s内就要求都要下完,那这样就得需要更大的带宽来支撑,即 每秒 9000Mbs/s。

按照我们刚刚计算出来的结果,我们可以发现,在理想情况下要做到不卡顿则需要 9000Mbps的带宽,这想想就离谱。

通常我们说的100Mbit的带宽,实际下载速度只有每秒12.5M,为什么呢?因为单位不一样,我们来换算一下:

1Mbit/s = 1000Kbit/s = 125KByte/s ,所以,1M带宽对应的下载速度峰值是125KB/S

1 Kbps = 1Mbit

1Mbit = 1000Mbit = 1000000bit


三、系统如何设计?


3.1. 上传时压缩

一般来说,照片拍摄出来的大小一般都为3M左右,如果直接将3M直接上传到服务器上那肯定不行,所以,在上传之前肯定要进行压缩的。

比如,可以使用cavans画布技术,使用 canvas 对象,将图片绘制到画布上,然后通过 toDataURL 方法压缩图片,可以指定图片的格式和质量。

也可以使用 FileReader 对象,将图片转换为 base64 编码,然后通过一些算法对 base64 进行压缩,比如 LZMA、LZW、Huffman 。


3.2. 图片服务器与业务服务器分离

当加载图片时,瞬时的带宽如果过大,会导致业务服务器也无法使用,不仅服务端会卡死,尤其是在单线程的前端也会出现卡死的现象。所以这时首先要在后端做出区分,图片服务器的请求不能与业务服务器放到同一台入口节点上。这样各用各的带宽即可。


3.3. 前端缓存

为了减少网络请求次数,可以使用客户端缓存技术来缓存图片,比如使用indexDB、sqlite来存储文件记录,根据文件记录将图片存储到手机或浏览的临时目录下,临时目录一般是有大小限制的,大概是200M,所以,前端缓存可以存储一段时间内经常用的图片,在某个业务节点内就会从临时目录中移除。这还要看业务需求,如果是长时间存储,这种方式就不太合适了。

前端缓存的技术是只要第一次加载完成了,其他时间都会都缓存,而不需要频繁的请求后台接口下载图片了。这种情况是一个客户端一份缓存。



3.4. 限制请求的并发数

不管是手机app 还是 浏览器、或者是小程序都会对同一资源的请求有并发限制,也就是说如果客户端一次性发送了10个请求,那么第11个请求就会失败,只有当这10个请求全部响应给客户端才算这批请求结束。这就类似后端限流了。浏览器也有限制,大概是6个并发,而微信小程序是10个并发。

这种限制的目的在于,高并发情况下,避免更多的请求占用资源,导致服务器崩溃。而浏览器或app本身帮我们做限制。



3.5. 前端图片懒加载

相比于一次性加载30张图片,虽然刚刚是分批和异步加载,但是对于客户端来说,不管用户当前在访问哪个界面,这个下载线程一直进行,直到30张图片都下载完成。这就会导致用户在访问其他页面时出现卡顿,响应变慢的情况。

为了解决这个问题,我们可以在访问加载图片的界面时,不要一次性加载所有图片,而是让用户滑动预览图片的时候下载,也即,一次性限制下载1张或2张图片,这样不仅前端没有加载大量图片的线程,同时也分摊了后端接口的资源请求峰值带宽,降低了带宽突发增长的概率。对于我们前面的应用场景来说:懒加载+图片缓存是非常好的解决方案。



3.6. CDN网络内容分发

CDN我们就把它当成一个具备高带宽的缓存服务器,相比前端缓存,它只缓存一次(前端是一个用户一个客户端)。

CDN缓存文件时,并不是每次都调用主站的下载接口下载文件,而是只有在第一次或者缓存过期的时候,才会从主站获取文件,并将其缓存到CDN的边缘节点上,以便下次有相同请求时,可以直接从缓存中返回,而不需要再回源。

通过CDN下载文件和直接通过前端下载文件,对于源站来说,占用的带宽是不一样的。通过CDN下载文件,可以减少源站的带宽消耗,因为CDN可以将大部分的请求分担到边缘节点上,而不需要每个请求都到达源站。

如果直接通过前端下载文件,会增加源站的带宽压力,因为每个请求都要从源站获取文件,如果请求量很大,可能会导致源站的拥塞或崩溃。所以,使用CDN可以大大降低带宽的使用率,并在一定程度上提高前端的访问速度。


  • 我的往期文章:

  1. SpringBoot集成Guava RateLimiter 实现限流+源码解析

  2. 一文搞懂git仓库共用的秘诀,让您优雅的管理项目。

  3. 前端多线程web worker详细教程,请保存~

  4. Mysql 索引加强版图解教程!为什么使用B+Tree的存储结构,看完这篇不懂都难。

  5. 太强了!nginx日志分析-生产环境实战!代码亲测有效

  6. springboot+redisson分布式锁+定时job实现高性能、稳定的竞拍系统

  7. 10行代码轻松实现商品分类树结构构造,让你告别复杂的循环-java8 Stream流的优雅使用

  8. 前端轮询,你还在用setInterval么?抓紧换了吧


原文始发于微信公众号(小核桃编程):全面解析从多图片缓存到带宽优化-如何优化大量图片加载,降低带宽消耗,提高用户体验?

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/216049.html

(0)
李, 若俞的头像李, 若俞

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!