Node.js通过Dubbo2.js调用Java
发布于 4 个月前 作者 kalengo 696 次浏览 来自 分享

1. Dubbo 是啥?

Dubbo 是一个由阿里开源的 RPC 框架。

简单说下RPC框架的背景。

From dubbo.apache.org

Dubbo 是一种 RPC 框架,应用在分布式服务。

2. 使用 Dubbo 实现 Java 互调

​ 首先我们可以先尝试下同语言下的 Dubbo 调用,从容易开始。

​ 可以参考下 dubbo 官方文档 http://dubbo.apache.org/zh-cn/docs/user/quick-start.html

​ 这边简单尝试下,主要有两步:

  1. 首先建立一个服务提供方, 也就是上图 Provider 的角色;

  2. 接下来建立一个服务消费者, 也如同上图的 Consumer 的角色;

服务提供方建立 Provider

1.0 使用Spring Boot 建立一个Spring 微服务 (可以参考)https://yuchenzhen.github.io/2018/08/24/SpringBoot-IDE-initial/

**1.1. 建立一个 Interface **

// TestProviderService.java

package com.dubbo.learn.dubbo;

public interface TestProviderService {
    String Hello (String who);
}

1.2 实现这个TestProviderServiceImpl

// TestProviderServiceImpl
package com.dubbo.learn.dubbo.impl;

import com.dubbo.learn.dubbo.TestProviderService;
import com.alibaba.dubbo.config.annotation.Service;

@Service(version="1.0.0")
public class TestProviderServiceImpl implements TestProviderService  {
    public String Hello(String who) {
        return "Hello world ! Dear Programer " + who ;
    }
}

1.3 启动程序主入口添加@EnableDubbo注解

// ProviderApplication.java
package com.dubbo.learn;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;

@SpringBootApplication
@EnableDubbo
public class ProviderApplication {

    public static void main(String[] args) {
        SpringApplication.run(ProviderApplication.class, args);
    }

}	

​ 为了引入这个@EnableDubbo注解,需要我们引入com.alibaba的包

<!--pom.xml-->
<dependency>
  <groupId>com.alibaba.boot</groupId>
  <artifactId>dubbo-spring-boot-starter</artifactId> 
  <version>0.2.1.RELEASE</version>
</dependency>
<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>dubbo</artifactId>
  <version>2.6.5</version>
</dependency>
<dependency>
  <groupId>org.apache.curator</groupId>
  <artifactId>curator-framework</artifactId>
  <version>2.11.1</version>
</dependency>

curator-framework是dubbo所使用的消息中心Zookeeper所需要的包
dubbo-spring-boot-starter是 dubbo spring 的配置包

1.4 最后我们把dubbo 的启动配置写到application.properties里面

# application.properties
server.port = 8829
#
dubbo.application.name=provider
dubbo.registry.protocol=zookeeper
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.scan.base-packages=com.dubboo.learn
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
dubbo.consumer.check=false

整个项目结构如图:

然后,启动就好。

启动之后,通过 dubbo Admin 网页客户端可以看见Provider的接口在 Regitry 里面注册成功。

服务消费者Consumer

1.0 使用Spring Boot 建立一个Spring 消费者的微服务

1.1 定义接口,这里的接口路径位置和包名最好一致 (不然要自己调整)

// TestProviderService.java
package com.dubbo.learn.dubbo;
public interface TestProviderService {
    String Hello (String who);
}

1.2 定义一个 Service调用该dubbo 接口

// TestConsumerService.java
package com.dubbo.learn;

import com.alibaba.dubbo.config.annotation.Reference;
import com.dubbo.learn.dubbo.TestProviderService;
import org.springframework.stereotype.Component;

@Component
public class TestConsumerService {
    @Reference(version = "1.0.0")
    TestProviderService testProviderService;

    public void consumer (String who) {
        String res = testProviderService.Hello(who);
        System.out.println("consumer : provider says " + res);
    }
}

在主程序函数调用该Service 的函数

// DubboConsumerApplication.java
package com.dubbo.learn;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import com.dubbo.learn.TestConsumerService;

@SpringBootApplication
public class DubboConsumerApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(DubboConsumerApplication.class, args);
        TestConsumerService testConsumer = run.getBean(TestConsumerService.class);
        testConsumer.consumer("White");
    }

}

@Reference这个注解就是用来调用 dubbo 对应的接口的。所以也是要引入跟服务端的那几个包

<!--pom.xml-->
<dependency>
  <groupId>com.alibaba.boot</groupId>
  <artifactId>dubbo-spring-boot-starter</artifactId> 
  <version>0.2.1.RELEASE</version>
</dependency>
<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>dubbo</artifactId>
  <version>2.6.5</version>
</dependency>
<dependency>
  <groupId>org.apache.curator</groupId>
  <artifactId>curator-framework</artifactId>
  <version>2.11.1</version>
</dependency>  

1.3 最后我们把dubbo 的启动配置写到application.properties里面

#application.properties
server.port=8830
dubbo.application.name=consumer
#注册中心地址
dubbo.registry.address=zookeeper://127.0.0.1:2181

dubbo.scan.base-packages=com.dubboo.learn.dubbo
dubbo.protocol.port=20880

项目目录结构如下:

启动后效果如下:

3. Node.js 如何通过 Dubbo 调用 Java

Node 这边通过 dubbo调用 Java 的 provider 的接口,我们尝试调用了几个包:sofa-rpc-node,node-zookeeper-dubbo,和dubbo2.js 。
其中 sofa-rpc-node 的对使用 egg.js框架的比较友好,node-zookeeper-dubbo 使用起来跟 sofa-rpc-node 差不多;但是有点麻烦的就是这两个包都需要写 proto3的接口定义。
而 dubbo2.js则比较方便,以下是使用 dubbo2.js 的示列

const { Dubbo, java, setting } = require('dubbo2.js')
const interfaceName = 'com.dubbo.learn.dubbo.TestProviderService'
const interfaceVersion = '1.0.0'
const dubboSetting = setting.match(
  interfaceName, { version: interfaceVersion }
)
const dubboService = dubbo => dubbo.proxyService({
  dubboInterface: interfaceName,
  version: '1.0.0',
  methods: {
    Hello (who) {
      return [
        java.String(who)
      ]
    }
  }
})
const service = {dubboService}
// 实例化Dubbo, 入参主要是名称和 dubbo 接口的设置
const dubbo = new Dubbo({
  application: {name: 'dubbo-node-test'},
  register: '127.0.0.1:2181',
  dubboSetting,
  service
})

module.exports = dubbo

代码就是这么简单, 把 Java 服务里面通过 dubbo 提供出来的接口(包括接口名,接口版本信息,接口方法) 注册一下。
得到Dubbo 实例之后,调用对应的 service就可以使用。
如下:

await dubbo.service.dubboService.Hello(who)

我们简单写了一个接口:

const KoaRouter = require('koa-router')
const dubbo = require('./dubbo')
const router = new KoaRouter({prefix: '/api/v1'})

router.use('/')

router.get('/testNodeDubbo', async (ctx, next) => {
  console.info(`[testNodeDubbo]:==:> start`)
  let {who} = ctx.request.query
  const res = await dubbo.service.dubboService.Hello(who)
  ctx.body = res
})

module.exports = router

调用结果:


这样就完成了 node 作为消费者通过 dubbo 去调用 java 的接口了。

4. Node.js 通过接口调用 Java 与 通过 Dubbo 调用 Java 的对比


这边尝试使用了调用了同样逻辑的 dubbo 和 http 接口, 对比了一下两个实现的返回时间。
其中红色的是 dubbo 接口, 蓝色的是 http 接口。

其他:

项目地址: https://github.com/yuchenzhen/Java-dubbo-provider https://github.com/yuchenzhen/Java-dubbo-client https://github.com/yuchenzhen/node-dubbo2-consumer/tree/master

1 回复

牛逼了,最近想学node直连dubbo,奈何没java基础(哭

回到顶部