Su的技术博客

  • 首页
  • 原创
  • 视频
  • Java
  • MySQL
  • DDD
  • 事故复盘
  • 架构方案
  • AI
  • Other
  • 工具
    • AI工具集
    • 工具清单
    • JSON在线格式化
    • JSON在线比较
    • SQL在线格式化
  • 打赏
  • 关于
路很长,又很短
  1. 首页
  2. Java
  3. 正文
                           

【京东】京东购物车如何提升30%性能

2023-02-17 988点热度 0人点赞 0条评论

01
背景



购物车面临的挑战:

1)新业务:随着业务形态的丰富,购物车在不断支持各种新业务,依赖的外部接口也随之增加;

2)下沉:一些前端调用的接口下沉到购物车中台;

3)前置:结算流程很多业务前置到购物车中,如优惠券、京豆;

4)扩容:为改善用户体验购物车可容纳的商品数量在不断增长;

这些导致购物车依赖的RPC接口数量及分页调用次数都在不断增加。购物车作为交易流程开端,本身流量较大,在业务复杂化的背景下,如何提高性能保证用户体验,成为购物车面临的较大挑战。



02
全异步化改造方案


通过增加服务器资源虽然能在一定程度上解决问题,但会带来较大的成本开销,也与工匠精神相悖。能否通过技术手段提升性能呢?通过分析,异步化改造成为解决这一问题的有效手段。

1)不同RPC并行

购物车依赖接口达几十个,各接口间存在复杂依赖关系。必须先梳理各接口间依赖,识别哪些可以并行。然后将原有代码拆分为两部分:RPC异步请求和结果处理,按照依赖关系,让RPC最大限度并行执行,减少在结果处理阶段异步响应等待时间,从而达到提升性能的目的。



2)批量接口多分页并行

购物车依赖接口多为批量接口,且单次调用有数据量限制,需将数据拆分为多个分页调用。那么多个分页间也可以并行,改造中封装了异步分页工具,使业务层对分页逻辑无感知,异步工具自动将超过接口上限的数据拆分为多个分页并行调用,提升单接口响应速度。

3)底层采用JSF异步调用

异步调用基于京东RPC框架JSF,推荐使用1.7.5以后版本,支持CompletableFuture。



03
问题及解决


异步化改造的总体方案并不复杂,但是在实际落地过程中,遇到了很多细节问题:

1)异常重试需精细化

同步调用时,如果超时会重试调用。改为异步后重试会失效,因为在调用时一般不会报错,需要在结果处理阶段获取异步响应超时后,再进行重试。

另外,多分页并行时,当某一页请求超时后,应该只重试出错的分页。底层对分页调用进行了封装,上层业务代码在获取数据时无法感知是哪一页超时,所以必须在异步调用时将现场信息保存在包装类中,一起返回给业务层,在Get数据超时后,单独重试出错的分页。

发生异常时,并不是所有情况都需要重试,当遇到限流等异常时,不能进行重试。底层工具需要自动过滤限流异常,当然也支持自定义规则。

2)异步RPC监控更复杂

底层RPC耗时监控需要拆分为两部分,在分页调用时记为开始时间,在异步结果到达后,记为结束时间。如果调用异常或Get超时,需要标记本次调用失败。对于重试同样需要记录调用耗时,且正常调用与重试调用需分开记录。

除了需要监控RPC耗时外,还需要监控结果处理阶段Get等待时长,这个时间才是真正对应用性能有影响的时间。由于底层是分页调用,所以业务调用次数和底层RPC调用次数并不相同。

3)分页异步结果不能合并,否则无法获取异常Provider信息

底层异步调用结果,必须通过包装类原样返回给上层,除了上边提到的需要单分页重试外,另一个原因是必须保留异步结果,在分页超时后才能输出超时的Provider信息。这是由于Provider信息依赖JSF框架的JSFCompletableFuture,如果在底层合并结果,会导致信息丢失。

4)每页超时时间需单独控制



分页调用过程如上图所示,在结果处理时,每页Get超时时间需要单独控制,因为获取结果是顺序进行,获取后边的分页时,前边分页等待的时间也应计算在内,以保证整个获取结果的时间不超过单个分页的最大超时时间。计算公式如下:

超时=RPC超时时间 > (当前时间-异步调用开始时间) ? RPC超时时间 – (当前时间-异步调用开始时间) : 0

5)分页均衡

为避免最后一页数据过少造成数据倾斜,需要将请求数据均分到每一页,以最大限度提高整个请求的性能。



04
收益


改造完成后购物车核心接口耗时减少30%,保证用户体验,节省大量服务器资源。后续增加新的RPC接口时,只要处在调用拓扑的非关键路径上,对购物车性能没有太大影响。另外,容量增加时除少数不能分页调用的接口外,对性能影响已经比较小。


本文仅供学习!所有权归属原作者。侵删!文章来源: 京东零售技术

更多文章:

  1. 从代码到设计的性能优化指南
  2. log4j2同步日志引发的性能问题
  3. 接口优化的常见方案实战总结
  4. 高效开发与设计:提效Spring应用的运行效率和生产力
  5. mysql-connect-java驱动从5.x升级到8.x的CST时区问题
  6. 【视频】NettyInAction作者:统治一切的框架Netty- One Framework to rule them all
  7. 笔记 | 5种网络IO模型
  8. Redis为什么这么快?
  9. 单体分层应用架构剖析
  10. 浅析Redis大Key
标签: 京东 批量 RPC 并行 购物车 性能优化 异步
最后更新:2023-02-19

coder

分享干货文章,学习先进经验。

打赏 点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

广告
最新 热点 推荐
最新 热点 推荐
Anthropic Code with Claude 开发者大会:开启 AI Agent 新时代 视频笔记-微服务架构P4:必懂5种设计模式 视频笔记:微服务架构P4 设计模式:每服务数据库、API 网关和事件驱动架构 干货 | 论Elasticsearch数据建模的重要性 马蜂窝消息总线——面向业务的消息服务设计 基于 MySQL Binlog 实现可配置的异构数据同步 视频笔记:Google发布Agent2Agent协议 视频笔记:什么是微服务,为什么是微服务?
基于 MySQL Binlog 实现可配置的异构数据同步马蜂窝消息总线——面向业务的消息服务设计视频笔记:微服务架构P4 设计模式:每服务数据库、API 网关和事件驱动架构干货 | 论Elasticsearch数据建模的重要性视频笔记-微服务架构P4:必懂5种设计模式Anthropic Code with Claude 开发者大会:开启 AI Agent 新时代
Kafka如何选择合适的分区数,你选对了吗 殷浩详解DDD系列 第一讲 - Domain Primitive 应用分层架构最佳实践:Alibaba COLA 4.0 6种限流实现,附代码![通俗易懂] 系统设计 | 应用系统缓存 一次误删除MySQL主库的恢复操作 浅析设计模式2 —— 策略模式 Elasticsearch 使用误区之四——不合理的使用 track_total_hits

CRUD (1) Event Sourcing (1) graphql (1) id (1) NoSQL (1) quarkus (1) rest (1) RocketMQ (2) Spring Boot (1) zk (1) zookeeper (1) 上下文 (1) 事务消息 (1) 二级缓存 (1) 值对象 (1) 关系数据库 (1) 分布式缓存 (1) 原子性 (1) 唯一ID (1) 商品 (1) 多对多 (1) 子域 (1) 字符集 (1) 客户端心跳 (1) 幂等 (2) 干货 (1) 并发 (1) 应用场景 (1) 应用架构图 (1) 康威定律 (2) 异步复制 (1) 微服务架构 (3) 总体方案 (1) 技术方案 (2) 技术架构 (2) 技术架构图 (1) 技能 (1) 持续集成 (1) 支撑域 (1) 故障恢复 (1) 数据架构图 (1) 方案选型 (1) 日记 (1) 服务发现 (1) 服务治理 (1) 服务注册 (2) 机房 (1) 核心域 (1) 泄漏 (1) 洋葱架构 (1) 消息队列 (5) 源码剖析 (1) 灰度发布 (1) 熔断 (1) 生态 (1) 画图工具 (1) 研发团队 (1) 线程 (2) 组织架构 (1) 缓存架构 (1) 编码 (1) 视频 (20) 读写分离 (1) 贵州 (1) 软件设计 (1) 迁移 (1) 通用域 (1) 集群化 (1) 雪花算法 (1) 顺序消息 (1)

推荐链接🔗
  • AI工具集
  • 工具箱🛠️

COPYRIGHT © 2014-2025 verysu.com . ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

粤ICP备15033072号-2