京东服务市场高并发下SOA服务化演进架构
作者:CQITer小编 时间:2019-03-18 09:59
京东服务市场是京东商家与第三方独立软件提供商(ISV)进行服务类的在线交易平台。作为京东生态圈重要的一环,伴随着整个京东的快速增长,也在快速的发展。随着服务市场访问、交易量指数级的增长,系统由原来的ALL IN ONE架构,快速的演进成为SOA架构。
木桶的容量由木桶最短的木板决定,高并发环境下,单个服务的性能决定了整个服务市场的性能。 “可用插件列表服务”是服务市场的核心服务之一,优化该服务性能的过程,带动整个服务市场服务架构的演进。
宏观的看,大到系统小到模块都由自身+外部依赖组成,性能优化主要从自身与外部依赖两个方面来进行。
一、优化自身
单线程到多线程的升级,尝试通过并行提高服务性能。

根据日志分析,整体调用中“服务详细信息”占用时间最多,并行虽然压缩了一些可并行服务的调用时间,但对于无法并行的“服务详细信息”环节,依然没有改善。要改善必须找到“商品服务”性能不高的原因。
可见自身优化能起一些作用,但外部依赖起着更决定性的作用。
二、解决外部依赖冲突
“商品服务”性能不高,这是为什么呢?先从“商品服务”的依赖开始分析。单独调用该服务,或压测该服务,性能都不差,但为何线上性能却不佳?
1. 不同服务外部依赖资源冲突
对“商品服务”依赖的资源进行梳理,发现“商品服务”与“类目服务”使用相同数据库资源,非调用高峰期资源足够不相互影响,大并发环境下两个服务开始争夺资源。
将依赖资源分开,不同的服务使用不同的资源,通过调用不同的数据源解决冲突。

2. 相同服务外部资源依赖冲突
解决了两个服务对数据库资源的依赖冲突,性能有所提高,但性能总有很大的波动,排除其他服务外部资源的依赖冲突,看看“商品服务”自身对资源是如何使用的。

“商品服务”所有功能都单一的依赖数据库资源。服务上线后,自身多个功能开始争抢数据库资源。
按使用场景进行外部依赖资源解耦:
为保证交易一致性,继续采用MySQL。MySQL的 INNODB引擎长于 OLTP 在线事务处理,为了保证数据强一致性的场景继续选择使用MySQL数据库。
客户端登录用户需要获得最新的数据反馈,且有PIN这个固定的维度。查询条件简单,能符合KEY-VALUE方式,Redis很适合这个场景。
大前端非登录状态下,访问的用户无须登录,有很大的访问量,更多的是获取服务的一些介绍。大数据量,可容忍一定程度的延迟,所以采用ES来进行查询支撑。
外部系统希望获得最新服务的变化,推的方式远强于轮训拉取的方式。通过MQ订阅服务的变化情况。
有复杂计算,但对实时性要求不高,服务统计分析系统通过大数据平台获取数据进行分析。
三、建立统一的内存缓存模型
计算机的世界里没有魔法,时间换空间、空间换时间是所有方案的基础。
参考常用的MySQL INNODB引擎,为加快查询速度会在内存中设置一块内存作为缓冲区,将查询结果从硬盘中加载到缓冲区,下次相同的查询直接使用缓冲区数据。同样的,如果要提高查询响应速度,必须把服务数据缓存到内存中。单机内存有限,无法容纳所有数据,且服务器重启时整个内存重建所耗费的时间也是无法接受的,于是选择用Redis与ES按照不同的使用场景来构造内存缓存。
1. 选择主动缓存
常规的缓存方案:查询构建+定期失效。对有大量重复查询的环境效果很好,但在实际情况下,在某些场景却无法发挥预想中的作用。

场景特征:
每个用户只会打开一次客户端,获取一次插件信息,不会重复频繁的去拉取列表。
访问集中在8点到9点这个时间段。
使用被动缓存的后果:
8点前Redis缓存内是空的。
8点到9点,所有的列表信息都是第一次获取,查询全部穿透缓存直接打到数据库。


