????????京东,支付宝等支付机构会有在线上快捷给用户开二类三类卡,这些卡用户购买理财等产品,在开卡后会进行签约以及签约结果回查
????????业务组(即本次遇性能瓶颈处):负责提供签约业务相关服务(最终签约解约查询等还是调中台操作)
????????中台:负责最底层的签约 以及 用户签约信息查询
业务组服务器相关配置:
????????4个数据库库,每个库4个实例(2c4g),即16台机器[因异地问题实际可用8台]
? ? ? ? 业务网关:4台虚机 2c2g
前置 与 业务中间还有一个 业务网关,主要负责业务分发,结构如下
? ? ? ? 因预估此签约类型的流量会越来越少,并且考虑到用户体验,所以选择的是随机多活(即任意一个库挂了之后,将此业务发送到其他库---不用担心重复签约问题,底层幂等)
????????随机多活带来的问题:不确定当时签约业务在哪个分库,所以网关在做签约回查时只能并发扫描所有分库数据
? ? ? ? web服务器[非tomcat]设置的线程池队列为SynchronousQueue,仅仅在线上配置了最大线程数为200
? ? ? ? 业务线程池配置:核心5线程最大100线程、队列为ArrayBlockingQueue(size 100)、默认拒绝策略
????????查询请求进来后会占用 web服务器一个线程,然后使用业务线程池去并发查询所有分库数据[会创建4个任务并行跑],web线程阻塞等待结果
????????当时是在压测,大量的请求进来后,在业务阻塞队列中阻塞,因只有4个核心线程,故当时现场表现为:所有请求响应都特别慢被注册中心频繁下线且一会后上线来回循环,网关服务器CPU100%
? ? ? ?原因:当时整体压测tps为800多,平均到单台网关是200左右,正好打满web线程池,但是业务线程池始终只会有4个核心线程在执行查询任务,故请求任务都在阻塞队列中等待调度(业务线程池队列大小为1000,而最大任务数为:200web线程 * 4并发请求 = 800任务)
? ? ? ? 注:线程池基本原理:先用核心线程,然后放入阻塞队列,如队列满了则创建工作线程
? ? ? ? 虽然临时调整web线程池大小 或 业务线程池队列大小 可以解决这个问题,但是我们还是想直接把这个性能问题(坑)根除掉
????????修复线程池所引发的缺陷后的优化讨论:
????????????????采用用户尾号进行分库:即按照用户尾号00-99将数据均分到其中一个库,问题是:如其中一个库发生故障,会导致一段时间内损失四分之一的业务
????????????????进一步优化:采用之前oracle互为主备架构思想优化:4个库,分成2组,逻辑上互为主备(根据配置指定)
????????eg:????????????????
????????????????1库:用户尾号00-24、2库:25-49、3库:50-74、4库:75-99
????????????????1、3库互为主备,2、4互为主备[意味着某个库出现问题,业务网关会将请求 路由到对应备库的实例上]?????????
????????????????正常情况:每次签约 以及签约回查 只会调用一次
????????????????异常情况:01库挂了将业务分发到03库,当签约业务回查时:先去根据配置去01库查询,若数据不存在则再去备库03库,那么在数据库异常情况下,回查时至多会调用两个库
? ? ? ? 上述web线程池与业务线程池配置冲突问题 以及 优化方案希望对你有帮助