一、准备工作
安装和启动 nacos
从 Github 下载 nacos 最新的 release 包
解压后,进入
nacos/bin
目录
$ tar -xvf nacos-server-1.0.0.tar.gz
$ cd nacos/bin
- 启动 nacos
$ sh startup.sh -m standalone
下载 java 服务端工程
$ git clone git@github.com:gxcsoccer/dubbo-demo.git
$ cd dubbo-demo && mvn clean install
运行 Provider main
package org.eggjs.dubbo.provider;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Provider {
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"dubbo-demo-provider.xml"});
context.start();
System.in.read(); // press any key to exit
}
}
二、创建 egg-cloud 工程
使用 egg microservice 脚手架初始化工程
$ npm init egg --type microservice dubbo-consumer
初始化好以后,结构如下:
.
└── dubbo-consumer
├── README.md
├── app
│ ├── controller
│ │ └── home.js
│ └── router.js
├── assembly
│ ├── dubbo-demo-api-1.0-SNAPSHOT-sources.jar
│ └── dubbo-demo-api-1.0-SNAPSHOT.jar
├── config
│ ├── config.default.js
│ ├── plugin.js
│ └── proxy.js
├── package.json
└── test
└── app
└── controller
└── home.test.js
执行 npm i
安装依赖
$ npm i
三、配置调用的接口
将 java 工程编译好的接口 jar 包放置到 egg-cloud 工程根目录下的 assembly
子目录下(脚手架已经将该示例的 jar 包放到指定位置)
配置 $app_root/config/proxy.js
文件
'use strict';
module.exports = {
group: 'HSF',
version: '1.0.0',
services: [{
appName: 'dubbo',
api: {
UserService: {
interfaceName: 'org.eggjs.dubbo.UserService',
},
},
dependency: [{
groupId: 'eggjs',
artifactId: 'dubbo-demo-api',
version: '1.0-SNAPSHOT',
}],
}],
};
配置详细信息:
errorAsNull (可选): 是否将后台服务错误以 null 返回, 默认为 false, 不处理, 直接抛异常。
tpl (可选): 指定 proxy 的模板,如不指定则使用默认模板
services (必须): RPC 服务详细配置
appName (必须): 提供此 RPC 服务的应用名。
api (必须): jar 包里提供了很多服务(服务通常是类级别的), 用于指明为哪些服务生成 proxy 文件, 其中的 key 生成 proxy 文件的名字. value 是服务接口名。如果需要进行更加细粒度的配置, value 也支持以下对象格式:
interfaceName (可选): 服务接口.
version (可选): 服务的版本号,如:1.0.0; 1.0.0.daily。默认是 1.0。
group (可选): 服务组别,默认是 SOFA。
dependency (必须): 对应 Maven pom 中配置的 dependency。
tpl (可选): 指定当前 proxy 的模板,覆盖全局模板配置。
四、配置 RPC 参数
通过 $app_root/config/config.${env}.js
文件可以配置 rpc 的一些信息,比如这里我们配置 registry 的地址为 127.0.0.1:8848
nacos 的地址
'use strict';
exports.rpc = {
registry: {
type: 'nacos',
address: '127.0.0.1:8848',
},
};
五、生成 Proxy
运行 npm run rpc
命令来生成调用代理。运行完毕以后,会生成两个文件夹
$app_root/app/proxy
:存放调用代理的目录,下面会有一个 userService.js 文件$app_root/app/proxy_class
:从 jar 包导出的接口元数据会存放在这里
userService.js 长下面这个样子,它会自动帮你导出接口暴露的方法,并且帮你处理好 js 到 java 之间的类型映射问题。另外,proxy 文件还会将 java 接口定义的注释也导出,尽量做到和 java 调用 java 的体验一致
'use strict';
const path = require('path');
module.exports = function (app) {
const appName = 'dubbo';
let version = '1.0.0';
if (app.config.proxy && app.config.proxy.envVersion) {
version = app.config.proxy.envVersion[appName] || version;
}
const rpcClient = app.rpcClient;
if (!rpcClient) return;
const consumer = rpcClient.createConsumer({
interfaceName: 'org.eggjs.dubbo.UserService',
version,
targetAppName: appName,
group: 'HSF',
proxyName: 'userService',
responseTimeout: 3000,
});
/**
* 用户服务
*/
class UserService extends app.Proxy {
constructor(ctx) {
super(ctx, consumer);
}
// java source code: String sayHello(String name);
// returnType: java.lang.String
/**
* 打招呼
* @param name
* @return
*/
async sayHello(name) {
const args = [
{
$class: 'java.lang.String',
$: name,
}
];
return await consumer.invoke('sayHello', args, {
ctx: this.ctx,
});
}
// java source code: User echoUser(User user);
// returnType: org.eggjs.dubbo.User
/**
* 返回 user
* @param user
* @return
*/
async echoUser(user) {
const args = [
{
$class: 'org.eggjs.dubbo.User',
$: user,
}
];
return await consumer.invoke('echoUser', args, {
ctx: this.ctx,
});
}
}
return UserService;
};
$app_root/app/proxy_class
目录下导出了接口依赖的类型、枚举等元数据,比如 userService 接口依赖一个 User 类会被导出成下面形式,包含其属性和类型、缺省值等信息
module.exports = {
'org.eggjs.dubbo.User': {
'id': {
'type': 'int',
'defaultValue': 0,
},
'name': {
'type': 'java.lang.String',
},
'address': {
'type': 'java.lang.String',
},
'salary': {
'type': 'int',
'defaultValue': 0,
},
},
};
六、调用 Proxy
生成的 proxy 在运行时会被挂载在 ctx.proxy 对象上,你可以通过下面方式调用接口提供的方法,一般情况下你只需要传递 JSON 对象就好,就像调用本地函数一样
const result = await ctx.proxy.userService.echoUser({
id: 123456,
name: '宗羽',
address: '蚂蚁 C 空间',
salary: 100000000,
});
七、运行 & 调试
执行 npm run dev
启动应用
$ npm run dev
然后在浏览器里访问 http://127.0.0.1:7001 ,可以看到下面效果,说明调用已经成功了