【高并发专题】-高并发下前后端常用解决方案总结(全套)

鲁迅说过:如果你也想戴上高级Java程序员这顶高帽子,那么高并发相关解决方案你必须深入骨髓.


高并发场景下,主要解决几个问题:

①请求的响应时间变长,如何才能减少请求响应时间,提升用户体验.

②数据的安全,在高并发多线程场景下,由于竟态条件,指令重排等影响,很容易出现数据不安全问题,需要避免.

③高并发场景下,容易造成服务器过载,造成单点故障.

...

为了改善高并发带来的种种问题,已经有了很多前车之鉴,现开篇总结之,虽然在过去几十篇里有总结过,但零零总总,不成体系,这里再次系统总结.


前端:

1.压缩源码和图片

JavaScript文件源代码可以采用混淆压缩的方式,CSS文件源代码进行普通压缩,JPG图片可以根据具体质量来压缩为50%到70%,PNG可以使用一些开源压缩软件来压缩,比如24色变成8色、去掉一些PNG格式信息等。

2.合理选择图片格式

如果图片颜色数较多就使用JPG格式,如果图片颜色数较少就使用PNG格式.

3.合并静态资源

包括CSS、JavaScript和小图片,减少HTTP请求。有很大一部分用户访问会因为这一条而取得最大受益.

4.开启服务端的Gzip压缩

这对文本资源非常有效,对图片资源压缩效果感人...

5.使用CDN静态资源加速

使用CDN加速或者一些公开库使用第三方提供的静态资源地址(比如jQuery、normalize.css)。一方面增加并发下载量,另一方面能够和其他网站共享缓存。这里推荐一个免费开源的CDN加速网站:https://www.bootcdn.cn/

6.根据情况延迟静态资源的缓存保存时间

如此,频繁访问网站的访客就能够更快地访问。不过,这里要通过修改文件名的方式,确保在资源更新的时候,用户会拉取到最新的内容。

7.把CSS放在页面头部,把JavaScript放在页面底部

这样就不会阻塞页面渲染,让页面出现长时间的空白。

8.尽量选用一些高性能前端框架,如Vue,Angular.

这里以Vue为例,Vue具有一些强大的功能和高级特性,可以使得页面渲染变得非常快,从而减少提高高并发场景下的部分延迟.

①Vue一般是单页面应用,这样如果有一个组件非常大(个人认为超过1M)就有必要对其进行异步组件处理,也就是在组件注册时采用箭头函数的语法对其进行优化:

#同步组件引入方式:
import Detail from '@/pages/home/Home'
 
{
      path: '/',
      name: 'Home',
      component: Home
}
 
 
#异步组件引入方式:
{
      path: '/city',
      name: 'City',
      component: () => import('@/pages/city/City')
}

这样在页面初次加载时就不会加载太久,在用到时异步加载,可以减轻服务器IO压力和提高初次访问时的页面加载速度.

②使用ES6箭头函数配合定时器,限制一些监听器的刷新频率,比如我们常用到的屏幕滚动时触发的纵坐标改变,如果不进行限制,所涉及的函数会被高频执行,影响性能.

③使用对一些不常发生改变的组件进行缓存,这样再次刷新页面时就不会重复渲染,从而提高加载速度.

④可以使用Vue的一些高级特性,比如服务端渲染,来提高页面的渲染速度.

9.尽量使用一些高性能的WEB服务器,比如NGINX.

①nginx对静态资源的访问性能是非常高的,可以每秒处理2万个以上的并发.

②合理配置nginx,对Nginx进行性能调优,比如尽量使用epoll模式,开启gzip压缩,对静态资源进行缓存等.

10.使用精灵图

在页面小图片过多但页面布局已经稳定的情况下,可以考虑使用精灵图,减少请求发送,提高性能.

前端部分就总结这么多,毕竟我是个做后端的,前端部分就知道这么点,还希望各位看客能在评论处不吝赐教.


后端:

1.扩容

扩容包括水平扩容和垂直扩容,垂直扩容是在硬件层面进行扩展,比如增大内存CPU数量等,垂直扩容难度和挑战比较小,但成本较高,尤其是在到达一定程度以后,而且有极限,不能无限扩展.水平扩容是指通过一些技术手段,将请求分发到不同的服务器上,以此来降低单台服务器压力.比如可以使用Nginx对后端项目进行负载均衡(常用),还有一些采用DNS甚至硬件来完成,小公司一般不会用.

2.缓存

在绝大多数情况下,服务器的压力都会集中在数据库,减少数据库的访问次数,就可以减轻服务器的压力.所以,在高并发场景下,缓存的作用是至关重要的,常见的缓存有对象级缓存,还有缓存数据库如memcache,redis,encache等.通过对一些数据不常发生改变,但查询操作较频繁的接口添加缓存,减少对后端数据库的访问,大幅提高服务器性能.

3.消息队列

消息队列可以将应用解耦,可以用来削峰,同时异步的操作可以减少请求响应时间,降低单台服务器压力,在一些场景下还可以配合quarz/elastic-job提高服务器的利用率,避免服务器白天过于繁忙,晚上过于空闲.

4.应用拆分

当应用膨胀到一定程度后,可以对应用进行拆分,拆分可以按模块甚至功能去拆,把控好现阶段要拆分的粒度,然后选用适合的rpc/微服务框架,拆分后的系统会比较易于管理和维护,采用分布式后也可以提高性能,但相应的风险和复杂度以及对人员/技术的要求也会上升.

5.限流

单台服务器的处理能力总是有限的,具体能承受多少QPS可以通过Apache Bench,jmeter等工具测出来,然后预计最高的并发量也能大致估算出来,两者相结合可以大致估算出单台服务器是否能承受峰值并发,如果不能,需要对服务进行限流,以保障服务器不会因为过载而宕机,限流可以通过redis等高性能数据库来实现,当然也可以使用spring-cloud的zuul来实现,前提是你的项目是微服务架构.

6.服务降级/熔断

通过对服务降级可以有效降低服务器负载,熔断机制则可以起到保护作用,单台服务器在已经过载的情况下,拒绝所有新的请求,从而逐步恢复正常,spring-cloud提供了hystrix组件,可以方便的实现服务降级/熔断.

7.数据库读写分离,分库分表

当该优化的都优化了,但数据库依旧承受不住相应的并发,这时候就需要对数据库进行读写分离,甚至水平和垂直拆分,来避免单库过载,单表数据量过大等问题影响数据库性能.遇到这种场景时,可以使用Mycat对数据库做读写分离,采取一主多从,多主多从的数据库架构,对于单表数据量过大的情况,还需要进行分库,甚至分表.Mycat分库分表我在Mysql章节已有总结,有兴趣可以去看.

8.使用多线程,并发编程.

JUC提供了很多并发容器和工具,帮助我们在高并发场景下高效安全的进行各种操作,充分利用CPU多核性能,提高服务器性能,降低请求耗时.

9.生产环境关闭不必要的日志打印

在生产环境下,尤其是高并发场景下,日志的打印会拖慢系统响应时间,占用服务器资源,所以可以关闭一些不必要的日志,将日志级别设为error级别.实际压测表明,此举可以大幅提高QPS.

未完待续...

你可能感兴趣的:(【高并发专题】)