背景
目前nodejs应用越来越广泛,但和java的dubbo体系接入困难,所以我们需要实现node端的dubbo provider逻辑。java的dubbo provider是和consumer在一个jar中,提供了服务配置、注册、集群与负载均衡、监控和多种协议。使用nodejs实现一个可用的dubbo provider SDK完全没有问题,最简单的实现则是在对应ZK集群注册接口与机器IP的映射关系,consumer便可以访问对应rpc接口。可是,在可用基础上,仍然需要提供相关配套设施如配置、注册和监控等,达到商业上的高可用。在评估了各种实现方案后,决定放弃开发node provider端sdk,使用node+agent的proxy模式。
agent是一个可与node服务交互通信的,并提供dubbo provider功能的java服务。agent部署在nodejs服务机器上,扮演dubbo服务的入口角色,同时node服务返回的数据类型由agent进行转换映射,如 object(node) -> Map(Java), 具体转换规则则由node接口提供方提供调用接口jar包,consumer使用jar包进行调用即可。
整体架构
其中 vitamin为基于数据库的统一配置平台,解耦各个系统的强依赖。
Node中间件
Node中间件提供dubbo接口上报和服务提供功能。上报http接口要暴露的Dubbo服务配置信息(interface+version+method)即映射关系,node的提供rpc服务以HTTP形式存在(兼容之前业务),由agent进行调用,数据类型为JSON。
Agent
-
根据Vitamin的实时配置向zookeeper注册dubbo服务(泛化)
-
泛化服务每个method会根据Vitamin中的映射关系找到对应的http本地接口(localhost)进行调用
-入参和返回值进行json和Java类型的转换
Node业务方
-
Node提供普通的HTTP+JSON服务,可复用历史接口
-
提供一个对应dubbo接口的jar包,需保证http接口json和jar中的model转换关系可行
上游业务
- 拿到jar包依赖之后,像普通dubbo服务一样调用即可
类型转换
Dubbo方法入参转换成NodeJs的http调用参数:强类型转弱类型,可直接转换
NodeJs服务返回的json转Dubbo方法返回值:弱类型转强类型
解决方案:Dubbo泛化服务返回Map,consumer端拿到这个Map会自动根据client.jar的方法返回值类型(支持泛型)进行相应的字段注入
可能存在的问题
-
agent不会在调用nodejs服务进行熔断,即nodejs服务大量超时可能会让agent连接池或线程池占满
-
agent进程的生命周期由node进程维护,通过基于配置中心的心跳机制检测agent进程是否存活
-
错误排查定位由于多了一层调用,更为复杂
-
可能存在的单机性能问题