您的位置:首页 > 其它

性能优化:大规模,高并发系统的探讨

2017-09-23 00:00 393 查看
下面是我学习到的一些优化基本原则,大家一起来探讨

基本原则:

1、分层低耦合的架构设计,对业务功能进行模块化,服务化和组件化

像代码级别的maven就支持子模块的划分,很多优秀的开源都是这么做的,这样代码结构看起来非常清晰,对功能模块的梳理也比较容易一些,服务化大家都知道,最近大热的微服务,将大粒度的业务模块拆分成多个细粒度的微服务,服务解耦,然后通过服务接口相互调用,这样做再复杂的系统也就不是什么难事了,首先就是要对业务进行拆分了。

2、模块冗余,动态负载均衡,故障隔离,动态切换

我的理解呢就是一个应用发布到多个实例,比如我们发布到2台甚至多态tomcat这样,这样当前端请求穿透到后端的时候,我们可以通过负载均衡或者路由模块将请求分发到不同的tomcat应用实例上,这样每个实例的请求数就降低了,因为每个实例的请求是有上限的

所谓故障隔离:就是当一台tomcat实例挂掉了,不影响现在的业务,我再启动另外一个实例满足现在的请求,业务请求会自动切换到另外一个实例上,当然每个实例的服务最好是无状态的,以为有状态就不好切换了。

3、大量使用KV缓存,分布式缓存数据。

高并发的系统如果全部请求都是读取数据库,不管是来自页面请求、手机端、pad端还是来自其他设备的请求,后端服务都是直接读取数据库,那这个系统早晚会奔溃,也支撑不了多大的并发量,那使用缓存就可以缓解数据库的压力,分布式缓存我们可以选择像redis这样的做成集群。

4、数据读写分离、动静分离。动态资源静态化,让动态数据尽可能的轻、小。(静态化是性能提升的重要途径)

读写分离顾名思义就是将写的请求和读的请求分开,比如我有两个mysql数据库实例,一个负责写,一个负责读,业务需要写请求的时候将请求发到写数据库,需要读的时候发到读数据库,这中间怎么处理两个库的路由,我们可以通过spring aop切面编程注解的形式来分发两个读还是写。

所谓动态资源就是需要从数据库或其他资源系统及时读取的资源,需要消耗网络资源、IO资源等,那我们可以把动态资源转成静态资源,比如将文字数据转成HTML页面形式存储,这样请求就不会到后端读取数据库,直接读取HTML页面了。

5、对数据库进行分表、分片。

读写分离解决的读和写的问题,那库中如果数据超过500万,那我们可以把这个表看做一个大表,可能就要考虑对表进行分表,分表有很多种,通过业务id,通过时间维度或者通过其他业务属性来区分,总之就是要将一个大表的数据量减少,拆分成多个小表。

所谓分片:就是将数据储存到不同的数据库实例上,每台设备上的数据量要尽可能相近,数据分片一般都是使用Key或Key的哈希值来计算Key的分布,程序上要通过编写路由分片来命中请求需要访问哪一个分片,说白了就是数据库放这么多台设备上,我要去哪台设备上取呢,就需要程序根据hash key去选择

6、串行改并行,同步改异步。

一般来说我们编写程序都是顺序执行的,但如果遇到一个业务需要调用很多业务子系统,如果我们顺序执行,那么这个时间耗时很长,如果一个请求卡住,真个方法就卡住了,那我们可以通过多线程的方式并发处理多个子系统业务,最后将结果进行合并,这样效率就高多了,当然最好用线程池连管理多线程。

同步改异步的意思呢,就是原来A直接访问B,A和B是相互依赖的,那我们可以中间加一层消息队列,像有些mq产品,比如activemq、rocketmq,这样A和B就只依赖消息系统,A处理完业务发个消息给mq,自己就处理其他的业务了,根本就不需要等B的反馈,B可以启动一个线程来去消息队列中读取消息处理业务,A和B就解耦了。

7、跨机房延迟优化,读本地、异地写全局。

8、多运营商就近接入,例如电信、联通、移动、教育、BGP等。动态CDN加速。

9、谨防内存泄漏,避免内存频繁申请和释放(内存池),尽量减少内存拷贝。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息