京麦开放平台架构演进与优化之路

深度分析东API接口,用Python脚本实现 开放平台提供了覆盖商品、订单、库存、支付等全链路的 API 接口,支持第三方系统(如 ERP、WMS、数据分析工具)东生态对接。其接口设计严格遵循 RESTful 规范,同时具备高安全性、高并发支持的特点。通过上述框架,可快速实现东 API 的对接,适用于多平台电商管理系统、供应链协同工具等场景。以下实现一个通用的东 API 调用框架,包含签名生成、请求处理、异常捕获,并以 “商品详情查询” 和 “订单搜索” 为例演示使用。),且每个接口的私有参数名固定(如商品 ID 在详情接口中为。 阅读详情

作者:张松然。2013年加入京东,目前在京东商城担任京麦卖家工作台服务端负责人。负责京麦平台化转型,实现服务对外开放。主导了京麦网关、京麦平台和消息推送等多个核心系统的开发和架构设计工作。三年间,与团队一起将京麦平台进化称为支撑每天几亿访问的分布式系统。在京东期间支持过多次618和双11大促,见证了京东的技术演进过程,在高性能高可用服务开发等方面积累了丰富的实战经验。

简介

—— 从全视角以时间线的方式,介绍京麦开放平台的发展演变和架构体系,重点讲解京麦HTTP网关和京麦TCP平台,如何实现API快速接入承载海量HTTP请求调用,以及如何建立TCP全双工的长链接会话通道;深度剖析基于Zookeeper的网关Register Center、基于Netty的平台TCP长链接Container、基于ElasticSearch、HBase的消息Search Engine等。

京麦(jingmai.jd.com)是京东面向卖家的多端多角色一站式协同工作台,其核心是为商家整合:店铺管理工具、经营咨询消息、商业伙伴关系,借此提升卖家的经营效率,促进彼此间的合作共赢。

京麦从2014年初创,逐步完成平台化转型,实现对外服务开放。

开发版图

不断优化京麦插件流程,搭建京麦开发者中心、运营中心、服务市场等,提供应用发布、订购、支付、结算等服务能力,构建京麦新生态。为商家提供多款服务应用,日活跃商家 1万+。

以打造高可用高性能服务以己任,优化网关调用、细化错误码、可追踪的调用日志等,开放服务接口 500+,日调用量上亿次,99% 的调用性能在 200ms 以下。

平台版图

完成平台与网关的隔离,保证平台服务的稳定性。改用 TCP 通信框架,以 ProtoBuf 为传输协议,建立 Session 会话机制,实现请求响应、通知应答的上下行通道,保持长链接在线 1万+。

重构消息通讯模型,以基于 ElasticSearch 存储的消息云端,实现 TCP 在线通知和 IOS Push 的半推半查的消息推送模型,并通过互通协议实现消息与插件的协同办公模式。

① 基于OAuth2的插件授权流程

京麦插件授权采用 OAuth2 协议,OAuth2 在客户端与服务提供商(Resource Server)之前,设置了一个授权层(Authorization Layer)。客户端不能直接登录服务提供商,只能登陆授权层,以此将用户和客户端区分开来。客户端登录授权层所用的令牌(token),与用户的密码不同。用户在登录的时候,指定授权层令牌的权限范围和有效期。

京麦通过用户在启动插件时,客户端通过授权层生成用户令牌(Token),用户通过令牌访问服务提供商获取数据。

② 基于HTTP和TCP长连接的消息推送

早期搭建 HTTP 和 TCP 长连接功能主要用于消息通知的推送。消息从消息源被发送出来,首先经过消息路由,消息路由解析定位 keep-alive 客户端,生成消息通知,交由 HTTP Push 或 TCP Push 推送到客户端,客户端收到通知后,再请求消息服务端,将消息实体拉取到客户端本地,存库进行展示。而消息推送的整个过程,通过消息追踪埋点进行统计和监控。

补充:HTTP 长连接采用 Servlet 3 的特性,TCP 长连接采用了 Netty 4 框架。

③ 移动端JSSDK

JSSDK 实现了客户端 Natvie 和 Html5 Java Script 的相互调用。客户端编程包括了 C++、iOS 和 Android,虽然实现不同,但基本逻辑类似,通过实现 JavaScript Bridge 和 Native Bridge,它类似两个队列,基于事件驱动和回调函数,采用异步通信方式,实现相互调用。

④ Gateway

网关作为京麦最重要的业务之一,承载海量调用,网关架构分为多层结构,每层中包含多级开关和限流策略。

到达网关的请求首先由网关接入层拦截处理,包括两部分:首先是网关防御校验,这里包含降级和限流,以及多级缓存等,数据校验正确之后,交由网关接入分发;网关分发会根据网关注册中心的数据进行协议解析,之后动态构建调用实例,完成泛化反射调用。

说的简单点,就是网关实现了动态将一个外部请求调用(http-json)转化成为内部请求调用,这个内部调用可以使 http,也可以是 JSF/dubbo 调用等。

Gateway Kernal

在网关内核的抽象模型中,最核心的就是注册中心和分发中心。

⑤ Register Center Of Gateway

网关注册中心作为网关内核一个高可用的元数据部件,如何保证网关集群元数据的一致性和灵活性?

网关注册中心采用 Zookeeper 作为中间件,并在网关配置读写操作过程中,进行了多级容灾策略。

以读为例:网关首先从内存中读取配置,如无数据,从 Zookeeper 读取,读取后同步到内存,并异步保存本次快照。如果 Zookeeper 数据变更,通过监听 Zookeeper 的 DataChangeWatcher 变更同步数据。如果 Zookeeper 宕机,重启服务器,系统还可以通过本地快照恢复最近一次的元数据配置。

⑥ Buried Point & Data Statistics

数据埋点和数据统计采用了大数据的方式对数据进行收集和规整。数据收集采用异步方式,数据首先被序列化成十六进制,采用 MMap(NIO) 的方式存储到本地文件中,再异步的通过消息队列发送给消息接收端,规整批量存储 HBase,HBase 以增量存储设计 rowKey,通过 ETL 存储 Hadoop,再通过 Hive 计算结果,存储到 MySQL。

⑦ Plugin Order Process

订单逻辑的复杂在于事务操作,以及异常流的补偿操作。订单确认支付采用异步的方式,创建订单成功之后即返回,通过消息队列在异常情况,不断重试保证业务正常运行。

⑧ TCP Container

为什么选择 TCP?

我们知道,网关是负责接口调用获取请求数据的,属于单向操作。而搭建客户端与服务平台的 TCP 双向通道,保持客户端与服务平台的会话状态,则可以提供更多、更灵活的技术实现和业务实现。

采用 Netty 作为 TCP 容器,在 ChannelPipe 中加载自定义 ChannelHandler,构建 Container 容器,将每个 TCP Connection 封装到一个 Session 会话中,保存在 Container 容器中,由 Container 容器构建 Session Layer 提供 Logic 请求调用。

How to Re-Connect?

TCP 长连接断开之后,如果重连? 我们知道,移动客户端可能由于网络抖动、弱网络情况下,遭遇非正常网络闪断,如果处理断开后的连接再重连后,找到上一次连接的会话呢?

这个解决得益于 Netty 的 ChannelHandlerContext,它可以存储一些自定义属性到 Channel 的上下文中。在每次成功建立请求的 Channel 里存入 SessionId,将它作为一个钩子,当网络闪断后,再次请求建立连接的 Channel,可以通过判断是否存在 SessionId 的钩子,进行处理。

⑨ Message Push

消息架构的改造的几个大项:

一、解耦消息接入层和消息推送层,消息接入层只负责Request-Response和Notice-Repley,而消息解析、适配、推送等逻辑处理都全部由消息推送层处理,而消息接入层和消息推送层之间则有消息队列异步进行通信。

二、消息存储由原来的半推半拉改为半推半查,即消息只推送通知,所以消息实体存储在云端。采用 ElasticSearch 作为消息搜索引擎,通过 Routing 实现靠性能查询。

三、优化推送方式,将 TCP 通知由异步改同步,计算消息送到率。

Optimize ElasticSearch:  query with routing

ElasticSerach 在进行 Query 查询时,会由命中节点分发给所有 Node,每个 Node  处理请求 Merge 后,返回给命中节点,命中节点在 Merge 所有 Node 返回的结果,最终返回。

这样请求性能很低,通过对 ElasticSearch 自定义 Routing,实现 Index 和 Query 保证在一个 Shard,极大的提供的 Query 性能。

Optimize Notify: async to sync

TCP 是一个异步请求,它不像 HTTP,TCP 只要把数据推送到网卡就会返回成功,那如果将下行通知与上行返回的应答进行关联呢?

我们通过实现 Futre 自定义 NotifyFutre,为每个下行通知分配一个 seq,并定义 NotifyFutre 的 timeout。即每个下行通知分配一个 seq 存储缓存中,等待客户端回应这个应答,如果应答, 则从缓存移出这个 seq,否则等待超时,自动从缓存中被移出。

东资深架构师深度解析《MySQL 实战》 张松然 本文为读《MySQL 实战》摘抄的读书笔记,原文更加精彩,推荐大家阅读,并表达对原作者的支持。 基础架构:一条 SQL 查询语句是如何执行的? MySQL 的基本架构示意图: MySQL 可以分为 Server 层和存储引擎层两部分。 Server 层包括连接器、查询缓存、分析器、优化器、执行器等,涵盖 MySQL 的大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等。 存储引擎层负责数据的存 阅读详情

相关推荐

开放平台 api

开放平台api,包括在线文档,接口说明,调用方式

东的Netty实践,京麦TCP网关长连接容器架构

早期京麦搭建HTTP和TCP长连接功能主要用于消息通知的推送,并未应用于API网关。随着逐步对NIO的深入学习和对Netty框架的了解,以及对系统通信稳定能力越来越高的要求,开始有了采用NIO技术应用网关实现API请求调用的想法,最终在2016年实现,并完全支撑业务化运行。由于诸多的改进,包括TCP长连接容器、Protobuf的序列化、服务泛化调用框架等等,性能比HTTP网关提升10倍以上,稳定性也远远高于HTTP网关。基于Netty构建京麦TCP网关的长连接容器,作为网关接入层提供服务API请求调用。客户端通过域名+端口访问TCP网关,域名不同的运营商对应不同的VIP,VIP发布在LVS上,

东SDK调用实例(open-api-sdk-2.0.jar)

对于调用东商城的API接口有很大帮助,省时又省力。轻松实现调用。

京麦开放平台的高可用架构之路

京麦东商家的多端开放式工作平台,是东十万商家唯一的店铺运营管理平台,为东商家提供在移动和桌面端的操作业务,京麦本身是一个开放的端体系架构,由东官方和 ISV为商家提供多样的应用服务。 京麦开发平台是东系统外部系统通讯的重要平台,技术架构从早期的单一Nginx+Tomcat部署,到现在的单一职责,独立部署,去中心化,以及自主研发了 JSF/HTTP等多种协议下的API网关、TCP消息推送、AP

所有商品API接口如何获取

如遇任何疑问或有进一步的需求,请随时我私信或者评论联系。

2401_88805485的博客 689

京麦 1的进阶

张松然,东商城 POP平台系统架构师。对构建高性能,高可用的大规模分布系统有丰富的开发经验,有多年NIO领域的设计、开发经验,对HTTP、TCP长连接技术有深入研究领悟。* 本文写于...

vivisran的博客 350

一次网关事故的总结

张松然,东商城,商家研发部架构师。丰富的构建高性能高可用大规模分布式系统的研发、架构经验。2013年加入东,目前负责京麦服务市场的系统研发工作。本文是记录2015年的一次线上事故,引...

vivisran的博客 649

揭秘东API:一键获取商品详情的秘籍

东API是开放平台提供的一系列接口,允许开发者访问东的商品数据,通过这些API,开发者可以创建应用程序,为用户提供更加丰富的服务。

wbryze的博客 605

东关键词API接口调用指南

东关键词API接口调用需完成六大步骤,全程需遵守开放平台的规范限制。

2503_92476011的博客 1253

东商品详情对接中常见错误异常情况处理(附源码)

东商品详情API接口是开放平台提供的一项服务,它允许开发者获取东平台上商品的详细信息,包括商品标题、价格、库存、图片、描述等。使用此接口,开发者可以方便地集成东商品的详细信息到自己的应用程序或服务中,提供更加丰富和准确的商品信息给用户。使用东商品详情API接口可以带来诸多优势,如自动化商品信息的获取和更新,提高工作效率;基于实时数据做出更加精准的商业决策;提供更加准确和全面的商品信息,增强客户体验;快速响应市场变化,提高市场竞争力。常见的错误和异常情况需要处理。

wbryze的博客 636

工业级Netty网关,东是如何架构的?

架构之路,充满了坎坷架构和高级开发不一样 , 架构问题是open/开放式的,架构问题是没有标准答案的正由于这样,很多小伙伴,尽管耗费很多精力,耗费很多金钱,但是,遗憾的是,一生都没有完成架构升级。所以,在架构升级/转型过程中,确实找不到有效的方案,可以来找40岁老架构尼恩求助.前段时间一个小伙伴,他是跨专业来做Java,现在面临转架构的难题,但是经过尼恩几轮指导,顺利拿到了Java架构师+大数据架构师offer。所以,如果遇到职业不顺,找老架构师帮忙一下,就顺利多了。

架构师尼恩 782

京麦TCP网关的Netty应用实践

张松然,东商城,商家研发部架构师。丰富的构建高性能高可用大规模分布式系统的研发、架构经验。2013年加入东,目前负责京麦服务网关的系统研发工作。京麦从2014年构建网关,从HTTP网...

vivisran的博客 603

【练习】东案例js(标题栏透明度,倒计时,轮播图自动播放)

1.sublime字体放大:command++   2.引入js文件,在引入css文件link下面script引入js文件 http://emmet.evget.com/   查找emmet快捷键的网页   script:src 3.scroll有兼容性问题,必须<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN...

weixin_40326021的博客 729

东API接口

今天分享给大家的是东部分API接口,想了解更多东API接口,请点击注册测试链接获取key和secret item_get - 获得JD商品详情 item_search - 按关键字搜索商品 item_get_app - 获得JD商品详情原数据

m0_67356460的博客 3884

直击Redis持久化磁盘IO痛点,让存储不再有负担!

原创 2017-09-26 张松然 DBAplus社群 作者介绍 张松然,东商城POP平台系统架构师。丰富的构建高性能高可用大规模分布式系统的研发、架构经验。2013年加入东,专注于商家开放平台API网关、消息推送、交易服务等解决方案。 Redis 常用数据类型 Redis 最为常用的数据类型主要有以下五种: String

u011277123的博客 3120

架构设计内容分享(五十七):工业级Netty网关,东是如何架构的?

通过源码分析,数据下行则通过NotifyProxy的方式发送数据,需要注意的是Netty是NIO,如果下行通知需要获取返回值,则要将异步转同步,所以NotifyFuture是实现java.util.concurrent.Future的方法,通过设置超时时间,在channelRead获取到上行数据之后,通过seq来关联NotifyFuture的方法。然而,随着对 NIO 技术的深入了解和对 Netty 框架的熟练掌握,以及对系统通信稳定性要求的提高,京麦开始尝试运用 NIO 技术来实现 API 请求调用。

之乎者也·的博客 1238

Netty干货分享:京麦的生产级TCP网关技术实践总结

1、引言 东的京麦商家后台2014年构建网关,从HTTP网关发展到TCP网关。在2016年重构完成基于Netty4.x+Protobuf3.x实现对接PC和App上下行通信的高可用、高性能、高稳定的TCP长连接网关。 早期京麦搭建HTTP和TCP长连接功能主要用于消息通知的推送,并未应用于API网关。随着逐...

weixin_34320724的博客 1131
上一篇: 京麦 1的进阶
下一篇: 谈京东京麦TCP网关的Netty应用实践
松然聊技术
博客等级 码龄18年 22粉丝 41原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值