1. 背 景
虽然现在很多人,动不动就提什么高并发、请求量多大,数据量多少多少,但我可以很认真地说,那都是他妈的在吹牛!
生产环境,真正有大请求量的,就那么几个业务场景,而且多是面向 C 端的客户,能有这种用户体量的公司,掐着手指头都能数得过来,所以不用信那个邪,随便来一个公司就说自己有多大的请求量,那是给你画大饼,忽悠你呢。
不过话说回来,人家吹牛那是人家的事,我们可以不信,但我们自己还是要有能应对高并发场景的能力。
假如,现在真有这样的机会,让你遇到上面所说的高并发场景,你会怎么设计后端的接口来对外提供服务?
我们粗略地以下图所示情况为业务背景,来谈一下我的设计思路。
2. 设计思路
上面是一个查询接口的业务背景,我这里假设就以微服务 A 来提供这个查询服务,将接口写在微服务 A 中,并且微服务 A 自己从数据库中获取数据,与其它微服务不存在依赖关系。
2.1 部署
部署方式,面对高并发肯定是采用集群的部署方式
才能保证服务的高可用。
2.2 限流&负载均衡
当用户点击按钮,发起查询,用户的请求从前端服务器走向后端,先到后端的网关层,网关层为了应对高并发,需要做这么几个事:
- 首先是
限流
,配置合适的限流算法,过滤一些流量(采用SpringGateWay+Hystrix实现) - 其次,由于采用集群的部署方式,所以这里要做
负载均衡
,将请求分发到不同的服务器 - 最后,网关本身最好也采用集群部署,不能挂掉
2.3 降级
由于微服务 A 没有依赖其它微服务,所以可以不用考虑熔断的情况,但需要做个降级
处理进行预防,用 Hystrix 或者 Sentine 实现都行。
2.4 缓存
可以考虑在具体的接口处理逻辑中引入 Redis,提高响应速度,当然 Redis 的部署方式,最好也用集群。
2.5 多线程
一般遇到高并发情况,我们往往会想到用多线程去应对,但提到多线程,往往会涉及到锁,而遇到锁,又会导致等待阻碍,产生耗时。
所以多线程到底要不要用,我在这里只能说可以考虑,但需要更进一步分析,把业务场景和要求更具体明确再定夺,多线程并不是万能的。
2.6 读写分离
由于微服务 A 是自己从数据库中获取数据,因此数据库服务器最好是一主多从(多主多从也行,只要不觉得复杂),读写分离,集群部署。
数据库表的设计、索引设计、字段大小设计等也要做好,那具体的就不展开了,这里仅顺带提一下。
2.7 MQ
在上面的这个场景里,由于是直接查询返回、实时性的,可能不是太好用 MQ 进行流量削峰,但遇到其它高并发场景,采用 MQ 也是一个处理方式。
3. 小结
一通分析下来,与其说是高并发接口的设计,倒不如说是应对高并发的一个系统设计。
单纯地设计高并发接口,其实就那么几点考虑:限流、降级、熔断、多线程处理、引入缓存、异步削峰、处理逻辑优化
。
高并发接口设计出来只是保证这个接口可用而已,系统其它部分不一定能兜得住,所以要想稳,还得从全局去考虑,从请求走过的全链路去考虑,进行设计。