专栏名称: 京东成都研究院
京东商城成都研究院信息平台
目录
相关文章推荐
51好读  ›  专栏  ›  京东成都研究院

CDRD TALK | Golang如何跨语言集成公司基础组件JSF、UMP、JIMDB

京东成都研究院  · 公众号  · 成都  · 2017-11-24 17:54

正文

请到「今天看啥」查看全文


项目背景


印尼开放平台(OpenAPI)是我年初承接的一个项目,本项目的目的是把京东印尼电商平台的业务能力开放出去,使包括第三方电商平台(比如:Akulaku)、POP商家等能通过API的方式与京东印尼电商平台实现自动化业务对接。

印尼开放平台(OpenAPI)在技术上分为4个子系统,其中最核心的子系统就是开放平台网关。它是访问各种业务接口的总入口,承担着API调用的访问控制、鉴权、安全检查、流量控制、请求转发等重要功能,因此,对于网关来说,在稳定性和性能方面有着很高的要求。


目前,开放平台网关线上运行版本是基于tomcat的web应用,性能方面之前经过了几轮优化,优化的措施包括tomcat容器由tomcat7升级到tomcat8(自动开启NIO的Http11NioProtocol),日志框架由log4j升级到全异步的log4j2,元数据直接存本地内存等,以上优化结果能很好地支撑目前以及未来一段时间的业务访问量需求。

图1

但为了进一步提升性能,我们着手选用Golang语言尝试搭建一套新网关。Golang版网关在快速实现了第一个预发版本后, 我们与Java版的网关进行了一轮性能对比,对比结果是 Golang版网关比Java版网关TPS高大约3倍。


这个对比结果说明Golang在此网关场景下,能很好的支持更大的访问量要求,同时也存在一些问题,即目前京东的基础设施(比如:JSF,UMP,JIMDB)都基于Java生态开发,Golang语言并不能原生的支持,下面将陆续阐明如何解决Golang对JSF、UMP和JIMDB的集成问题:

1

Golang集成JSF的方案(作为客户端)

由于在网关场景下,Golang实现的网关是作为 客户端角色调用JSF服务端,所以本方案也仅是解决了Golang作为客户端去集成JSF。

图2

具体实现方案为,在同一个机器上启动一个Golang进程(以下简称Golang网关)和一个Java进程(以下简称JSF Local Proxy)。JSF Local Proxy用来桥接Golang网关和JSF服务端。


图3

JSF Local Proxy一方面为Golang网关开启TCP端口监听,另一方面采用JSF Generic方式发起到JSF服务器端的调用,并把结果返回到Golang网关。


在已实现的版本中,JSF Local Proxy的TCP监听使用的Netty框架(在Java框架中,Netty具有高性能的网络IO能力),Golang网关和JSF Local Proxy的数据交换采用的JSON文本协议,后续计划启用二进制传输协议; Golang网关采用TCP连接池保持与JSF Local Proxy组件的连接,提供更大的并发支持。


2

Golang集成UMP的方案

图4

如上图所示,Golang集成UMP的本质,是开发一个Golang版本的日志记录器(以下简称go_ump_profiler). UMP支持多种不同的格式日志,go_ump_profiler目前仅实现了自定义业务告警日志和TP性能监控日志。

接下来介绍下go_ump_profiler的使用,他的使用跟Java版本的ump profiler非常相似。如下图所示:

图5

那么go_ump_profiler内部是怎么实现的呢?


图6

go_ump_profiler内部最核心的对象是UmpLogStruct,按照UMP的日志规范定义日志文件基础路径,日志后缀,日志保留天数等。 实现的功能包括异步日志落盘,日志按触发条件生成和删除,内存合并记录减少落盘次数等。 技术上,主要采用了goroutine并发 + chan缓存的方式。

3

Golang集成JIMDB的方案

这里有一个背景,就是目前印尼机房的JIMDB版本依然是老版本,即是没有AP方式(即兼容redis协议的IP+TCP端口)直连支持的。所以接下来分享下Golang怎么同时集成JIMDB新版本和老版本。

图7

如上图7所示,当JIMDB新版本能支持AP方式接入时,只需要选择一个实现redis协议的golang三方库就可以了,我在本实现中使用的是redigo。同样采用了Redis连接池。


当使用JIMDB老版本时,JIMDB集群的路由规则是通过xml配置文件下发到客户端,由java客户端按配置文件解析,得到所有redis主分片信息,再基于特定的hash算法命令具体分片,进行数据读写的。

下面看下实现细节:

图8

如上图所示,首先通过ConfigPing带node和token参数,得到version,然后通过ConfigGet带参数version,node,token,得到配置文件xml。


图9

如上图,在得到xml的基础上,解析成嵌套对象,从对象中获取到writeGroups指定xml节点值,比如:redis.local:6379. 由于以上配置文件是只有一个写分片,所以只看到一个地址。如果是支持多个分片,就可以看到多个地址,多个地址采用hashArgo指定的hash算法进行数据寻址,定位redis分片。本实现目前只做了单分片地址的解析。


最后,用得到的Address:redis.local:6379, 采用AP方式一样RedisConnPool,进行数据储取。


总结


图10

本次分享了在Golang语言下如何集成公司的基础组件(JSF,UMP,JIMDB), 目前有很多的点还不完善,希望能与大家一起探讨!







请到「今天看啥」查看全文