这几天研究 dubbo RPC 与 NodeJS 之间的通讯,并写了一个 NodeJS 作为消费者与 dubbo Java 端生产者通讯的库dubbo-node,其中 zookeeper 作为服务协同工具和注册中心。

Dubbo

Dubbo 是阿里巴巴开源的一个分布式 RPC 框架,是用 Java 语言实现的,支持多种数据协议,详细见官网dubbo.io

Dubbo-node

这个NPM package主要提供两个功能:

  • Node 端作为消费者去调用 RPC 方法与 Java 生产者端通信
  • 提供 CLI 工具从 Java Interface 生成 Node 端可引用的 RPC 服务和方法

对于功能 1,Node 端既可以直接作为消费者,也可以通过中转 Web 请求至 RPC 实现 Web API 服务。

对于功能 2,它能够减少开发者重复编写 RPC 服务方法代码。因为目前使用 Dubbo RPC 的服务主要由 Java 编写,而且不论是生产者还是消费者,所以它们共同引用的 Service 接口仍然是由 Java 编写。现在如果要增加一个 NodeJS 消费者,又需要编写 RPC 多个方法在 Node 端的实现。当然,这是一个重复的过程,应该由程序去完成。

Dubbo-node 由 TypeScript 编写,同时 CLI 工具也是直接生成 TypeScript 代码,这样能够提供不错的静态类型和代码提示支持。

使用 Dubbo-node

CLI 生成 services

dubbo2ts -i DemoService.java -o services -g dubbo -r LATEST -t 6000

生成示例 - DemoService.ts

import Dubbo from "dubbo-node-zookeeper";

export const ServiceHead = {
    interfac: "com.alibaba.dubbo.demo.DemoService",
    version: "LATEST",
    timeout: 6000,
    group: "dubbo",
    methods: {
        sayHello: name => [{ $class: "java.lang.String", $: name }],
        sayHello2: req => [{ $class: "com.alibaba.dubbo.demo.DemoReq", $: req }]
    }
};

export function sayHello(name: string) {
    return Dubbo.exec<string>("DemoService.sayHello", name);
}

export function sayHello2(req: any) {
    return Dubbo.exec<string>("DemoService.sayHello2", req);
}

export default {
    sayHello,
    sayHello2
};

生成示例 - index.ts(引入所有的 Services)

import { ServiceHead as DemoService } from "./DemoService";

export default {
    DemoService
};

使用 services

import Dubbo from "dubbo-node-zookeeper";
import services from "./services";
import { sayHello } from "./services/DemoService";
import express from "express";

new Dubbo({
    application: { name: "demo-provider" },
    register: "127.0.0.1:2181",
    dubboVer: "2.5.7",
    root: "dubbo",
    services
});

setInterval(function() {
    sayHello("Jack")
        .then(data => console.log(data))
        .catch(err => console.log(err));
}, 5000);

//或者中转http请求至RPC
const app = express();
app.get("/hello", (req, res) => {
    sayHello("Jack")
    .then(data => res.send(data))
    .catch(err => res.send(err))
})

以上代码可以参考Demo

运行示例 Dubbo RPC with Node