免费注册,打造高效身份管理
博客/开发者/Authing 实践|亿级流量系统架构的演进之路(建议收藏)
Authing 实践|亿级流量系统架构的演进之路(建议收藏)
Authing 官方2021.08.12阅读 837

随着人们数字化生活方式的改变,网络用户越多,对我们系统的考验就越大,如何承载高并发是整个行业都在思考的一件事情。我们来看一下生活中常见的高并发场景:


· 电商秒杀,大量用户同时在系统上进行抢购

· 12306 抢票,春节回家车票紧张,我们都会持续刷票或者使用抢票软件

· 银行交易系统,所有线上源源不断的交易(部分线下交易)都需要经过银行交易系统

 

高并发系统,也就是我们常说的三高系统:高并发,高性能,高可用。面向此类的三高系统,我们关注的属性是性能、可用性、伸缩性、扩展性、安全性,架构模式应该具有分布式化,集群化,自动化,异步化等特点的。

 

很多公司在初期时,都是单体应用的架构模式,单体应用的优点如下:


· 容易部署:这个不容置疑,整个项目就一个 war 包,部署特别方便。

· 容易运行/测试:这个也类似,我们在测试阶段只需要启动一个 war 包即可。


但是相比优点,这种架构缺点更加明显:


· 复杂性高:随着业务的不断迭代,项目的代码量会急剧的增多,项目模块也会随着而增加,模块与模块之间的关系就会变成的很复杂,整个项目就会变成的非常复杂,在新增和修改代码的时候都会做很多的测试,很容易会由于一处的变动影响之前业务的功能。

· 部署频率低:随便代码的增多,首先部署会越来越消耗时间,还有我们在修复一个很小很小的 bug 的时候整个项目都要重新部署,所以我们会集中一个时间点部署多个需求。

· 可靠性差:这个很容易理解,假如某个影响出现了死循环,导致内存溢出,会影响整个项目挂掉。

· 扩展性差:我们在新增业务的时候,代码层面会考虑在不影响现有的业务基础上编写代码,提高了代码的复杂性。


#01 


在单体应用架构模式不能满足我们需求的时候,下一步往往不是直接拆分应用,考虑到成本问题,会先进行应用内部优化。为了提升性能我们会做代码优化,使用池化技术,比如线程池,连接池等,将热点数据缓存,包括一些算法上的优化。


优化做好之后,随着业务的发展,遇到性能问题,下一步就是服务化拆分。那么服务化拆分具体该如何实施呢?


一个最有效的手段就是将不同的功能模块服务化,独立部署和运维。这种服务化拆分方式一种是纵向拆分,是从业务维度进行拆分。标准是按照业务的关联程度来决定,关联比较密切的业务适合拆分为一个微服务,而功能相对比较独立的业务适合单独拆分为一个微服务。还有一种服务化拆分方式是横向拆分,是从公共且独立功能维度拆分。标准是按照是否有公共的被多个其他服务调用,且依赖的资源独立不与其他业务耦合。


#02 


对系统架构做了比较大的改造,我们此时需要了解系统的性能怎么样,如何较为准确的知道性能呢,那就需要对系统进行压测。


说到压测,先介绍一下木桶理论。木桶理论又称短板理论,其核心思想是一只木桶盛水多少,并不取决于最高的木板,而取决于最短的那块木板。我们在压测时,也要找到系统的短板所在。


一个完整的压测闭环:压测目标、压测环境、压测模型、发现问题、解决问题、验证结果,这个闭环可能会重复,直到达成我们的压测目标。


那我们需要关注哪些指标呢?资源上一般要关注 CPU、内存、网络、I/O、数据库等,性能指标主要关注:QPS、TPS、RT、并发数、吞吐量、成功率、GC 等。实现指标监控的数据来源就是日志,我们可以按结果导向在各个服务上输出日志通过 ELK 来实现抽取并查看日志,并通过 Grafana 来实现监控的目的。


#03


服务化拆分完成后,随着流量的增长,单机部署的 MySQL,会导致 I/O 频率过高,数据库就会成为下一个短板,此时我们就需要对数据库进行优化。优化思路主要有以下几种:


· 主从复制,读写分离。单机 MySQL,读写都在一台MySQL上面完成,性能肯定不高。如果有三台 MySQL,一台 mater 只负责写操作,两台 salve 只负责读操作,性能就大大提高。

· 数量量达到千万级以后,主从架构可能还是不太合适,只能对读数据库进行扩展,无法对写进行扩展,写基本上还是集中在 master 中。所以我们还是需要减少单表的记录条数,进而减少数据查询的时间,提高吞吐量,也就是我们说的分表。

· 分表能解决单表数据量太大的问题, 但是无法解决数据库的并发处理能力,我们可以通过对一个关键字对分库数量取模的方式,对数据访问进行数据库的路由。

· 分库分表:既可以解决单表海量数据的问题, 又可以提高数据库的并发处理能力。


#04


当我们了解了整个系统的并发性能后,为了保障服务的高可用性,我们需要针对服务进行限流,熔断,降级等操作。限流可以使用拒绝策略和流量整形策略,需要根据业务场景来选择使用,常用的限流算法有计算器,漏桶,令牌桶等。


在微服务架构中,一个请求需要调用多个服务是非常常见的。如客户端访问 A 服务,而 A 服务需要调用 B 服务,B 服务需要调用 C 服务,由于网络原因或者自身的原因,如果 B 服务或者 C 服务不能及时响应,A 服务将处于阻塞状态,直到 B 服务 C 服务响应。此时若有大量的请求涌入,容器的线程资源会被消耗完毕,导致服务瘫痪。服务与服务之间的依赖性,故障会传播,造成连锁反应,会对整个微服务系统造成灾难性的严重后果。此时我们就需要对系统进行熔断和降级。


熔断就像保险丝,当某一个服务节点出现失败和超时达到一定的频率时,我们就需要让调用能够快速失败,而非阻塞调用,从而避免对其他的服务造成级联反应。


服务降级的策略有很多,以下列举部分常用方案:


· 页面降级:可视化界面禁用点击按钮、调整静态页面

· 延迟服务:如定时任务延迟处理、消息入MQ后延迟处理

· 写降级:直接禁止相关写操作的服务请求

· 读降级:直接禁止相关读的服务请求

· 缓存降级:使用缓存方式来降级部分读频繁的服务接口

· 停服务:关闭不重要的功能,为核心服务让出资源

 

要做到高可用,除了上述的策略还不够,当我们的量级上升后,还需做到异地多活等,如两地三中心,达到容灾效果。比如在多个地点分别建立一个机房,上层通过 DNS 会根据一定规则代理到较近的机房,当某机房出现故障或者升级时,其他机房也可以继续承载业务,达到业务不间断的效果。

文章作者

avatar

Authing 官方

0

文章总数

authing blog rqcode
关注 Authing 公众号
随时随地发现更多内容
authing blog rqcode
添加 Authing 小助手
加入 Authing 开发者大家庭
身份顾问在线解答
当前在线
如何打造完整的身份体系?
立即沟通
authing
添加企业微信,领取行业资料
authing
authing
下载 Authing 令牌,体验快速登录认证!
免费使用
在线咨询
电话咨询