Dubbo 是一个由阿里开源的 RPC 框架。
简单说下RPC框架的背景。
Dubbo 是一种 RPC 框架,应用在分布式服务。
首先我们可以先尝试下同语言下的 Dubbo 调用,从容易开始。
可以参考下 dubbo 官方文档 dubbo.apache.org/zh-cn/docs/…
这边简单尝试下,主要有两步:
首先建立一个服务提供方, 也就是上图 Provider 的角色;
接下来建立一个服务消费者, 也如同上图的 Consumer 的角色;
1.0 使用Spring Boot 建立一个Spring 微服务(可以参考) yuchenzhen.github.io/2018/08/24/…
**1.1. 建立一个 Interface **
// TestProviderService.java package com.dubbo.learn.dubbo; public interface TestProviderService { String Hello (String who); } 复制代码
// 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 ; } } 复制代码
@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 的配置包
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 里面注册成功。
// TestProviderService.java package com.dubbo.learn.dubbo; public interface TestProviderService { String Hello (String who); } 复制代码
// 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> 复制代码
#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 复制代码
项目目录结构如下:
启动后效果如下:
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 的接口了。
这边尝试使用了调用了同样逻辑的 dubbo 和 http 接口, 对比了一下两个实现的返回时间。
其中红色的是 dubbo 接口, 蓝色的是 http 接口。
项目地址:
github.com/yuchenzhen/…
github.com/yuchenzhen/…
github.com/yuchenzhen/…