nodeJs直连Java服务化dubbo协议长连接实现

来源:互联网 发布:淘宝店铺定位有哪些 编辑:程序博客网 时间:2024/06/04 08:10

需求背景

这个需求的出现来源于我们的某业务接口优化中遇到的一个瓶颈:

初期接口在调用php提供的第三方接口时,遇到访问高峰的情况会出现该接口timeout的情况(如下图 平常时接口时延75ms,高峰时到达368ms ),同时服务器上会出现及大量的TIME_WAIT连接数(高峰时 2W左右)。

时延表现

分析是由于大流量时, 每次接口调用都会调用一次rest api,继而产生大量的tcp短连接导致的。这种不稳定的因素对我们的集群产生了极大的压力,同时接口时延也不稳定的上升。当务之急是减少短连接数,取而代之使用长连接的方式去请求。

同时我也了解到,异构系统间采用http长连接的做法在公司内部php集群并不支持(现阶段公司内部只有少数业务有成熟的长连接方案),而又了解到java服务化方可以提供dubbo协议的接口请求。

因此就决定尝试使用dubbo协议跨过php这一层直接和java服务化做直连,这样既可以减少短连接数,同时也将调用链路变短了一层。

nodeJs直连dubbo的做法

调用dubbo服务的过程主要分以下几步:

首先需要连接上dubbo的zk配置中心(从java服务化那边得到地址),获取你需要的服务的dubbo节点连接信息(包括dubbo服务的host:port,服务名等等)

然后 使用sockets-pool(我们维护的)库 与获得的dubbo节点建立起起socket长连接,并维护在一个连接池队列中
在需要查询对应服务时,从连接池中获取可用连接,执行查询,然后释放该次连接到连接池。

demo代码如下:

        var ZD = require('node-zoodubbo');        var zd = new ZD({                // config the addresses of zookeeper                conn: '127.0.0.1:2181',                dubbo: '2.8.0.2',                root: 'dubbo'        });        // connect to zookeeperzd.connect();        //zd.getProvider('com.member.query', '1.0.0', function(res, data){//      console.log(res, data);//});// get a invoker with a service path        var invoker = zd.getInvoker('com.member.query', {                version: '1.0.0',                timeout: 2000,                pool: {                        max: 100,                        min: 10,                        maxWaitingClients: 500                       }           });        // excute a method with parametersvar method = 'memberInfo';        var arg1 = {                $class: 'com.member.memberRequestTO',                $: {                        uid: {                                $class: 'java.lang.String',                                $: '34625433'                        }                }        };        invoker.excute(method, [arg1])        .then(res => console.log(res))        .catch(e => console.log(e));

node-zoodubbo 连接包实现

流程

查看包地址

关于整个包及连接实现点击这里

带来的效果

采用restapi方式调用黑名单接口时,该接口平常访问时延在27ms左右,高峰时接口时延159ms。

采用dubbo长连接后,黑名单接口请求时延平均在3ms左右,高峰时任然不变。同时由于我们把ip的接口请求也自己本地化实现了一套,接口时延从(平常时75ms,高峰时368ms)降到如下情况

时延表现

平常时 25ms 提升 300%,高峰时 56ms 提升 660%

结合某业务接口优化谈一谈QPS的提升

优化前对某接口做了差不多5组压测,每波大概20min,集群当时是9台机器,每台机器4个接口进程,集群qps测到 1200就上不去了(单机 130)。当时与运维讨论了很久未果, 甚至怀疑是测试工具的问题。

在压测过程中,我的服务打点时间始终是正常的且只维持在30ms左右,开始怀疑是不是我们node框架koa2的问题,第二天我在单机使用ab测试了空koa框架发现单机可以到达3000qps,因此框架的qps是不成问题的。

然后对接口的ab结果最终单机真实qps为 240.

再次与运维讨论怀疑是负载均衡而非框架的问题。然后又去了解了我们的进程管理工具PM2其实也承担了对请求的负载分发的工作,虽然其底层采用RollIng算法并不是问题,但是 pm2对请求队列的消耗过程并非是 epoll 类似的做法。

之后为了验证这个猜想使用了nginx反向代理到本机的4个端口,每个端口只跑一个进程,这样等于绕开了pm2分发,只由nginx来做负载均衡,发现QPS可以到达

压测结果
(最终单机真实qps为 437)

至此我们初步确定QPS的部分瓶颈在pm2的请求转发,采用直接走nginx的方式 直接带来了性能 182%的提升

原创粉丝点击