远程调用 - 985ch/egg-sachikawa GitHub Wiki
在很多情况下,后端服务器都会需要调用其他服务器来完成工作,而通常这种对接都需要编写为数不少的代码来完成。对于那些在整个项目中只需要在一个地方完成对接的业务来说,这样做问题不大。但是如果对接某个服务器的代码在整个项目中反复出现,直接在业务代码中完成这种对接就不合适了。因此我们准备了远程调用插件egg-rpc-like来对这些远程调用进行封装。
egg-rpc-like严格来说并不是一个完整的RPC插件,而是一个操作封装插件。这个插件允许开发者通过编写封装规则来把任何操作封装成函数的格式,其中包括又不限于远程http访问,数据库访问和真正的RPC操作。同时它还自带了两种封装规则用于封装http请求。
一般情况下,建议所有对第三方的请求都使用远程调用插件进行封装。
和其他框架插件不同,远程调用不提供可以直接使用的方法,也并非用于实现具体功能,而是提供给开发者一个可以精简业务代码的工具。此外,由于该插件的使用具有一定的门槛,因此在将其用于调用第三方服务的时候,建议让有经验的开发者来完成对远程调用的封装。
同框架项目互相调用示例
服务提供方实现并导出RPC方法
// app/service/cache.js
module.exports = app => {
class MyService extends app.Service {
// 获取用户信息
async getUserInfo(guid, host, ip) {
/* 在这里完成业务 */
}
// 更新用户信息
async updateUserInfo(userID, host, ip) {
/* 在这里完成业务 */
}
}
return MyService;
};
// app/http/get/rpc.js
'use strict';
const list = {
async getUserInfo(s, args) { return s.cache.getUserInfo(...args); },
async updateUserInfo(s, args) { return s.cache.updateUserInfo(...args); },
};
module.exports = app => {
return {
path: '/rpc/:operate',
ip: app.config.ipWhiteList.inter,
async controller() {
const op = list[this.params.operate];
if (!op) {
this.status = 404;
this.body = 'not found';
return;
}
try {
const args = JSON.parse(this.request.query.arg);
const result = await op(this.service, args);
this.body = { data: result };
} catch (e) {
this.logger.error(e);
this.body = {
err: -1,
msg: e.message,
};
}
},
};
};
在请求方里封装RPC方法并调用
// config/config.{env}.js
module.exports = {
default: {
$generator: generator.functionCurl,
},
clients: {
user: {
host: env('SERVER_PUB_USERAUTH_URL') + '/rpc',
$members: ['getUserInfo', 'updateUserInfo'],
},
},
};
const data = await ctx.rpcl.user.getUserInfo(guid, host, ip);
可以看到,在对远程调用封装之后,接口业务的代码看起来就像普通的方法调用一样,让代码简洁了很多。
更多关于远程调用的内容请查阅egg-rpc-like项目