- Notifications
You must be signed in to change notification settings - Fork66
SOFARPC Node is a high-performance, high-extensibility, production-level Nodejs RPC framework.
License
sofastack/sofa-rpc-node
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
SOFARPC Nodejs 实现版本
简单说它是SOFARPC 的 Nodejs 版实现,但本质上它是一个通用的 Nodejs RPC 解决方案。Nodejs RPC 在阿里和蚂蚁内部已经发展了四五年时间,如今广泛应用于各类业务场景,并经历了多次双 11 大促的考验。功能方面从基本的服务发布、寻址、点对点远程调用能力;到各种路由、负载均衡策略;再到故障隔离、熔断等高级功能,已逐渐发展成一个高可扩展性、高性能、生产级的 RPC 框架。
SOFARPC Node 主要包含了四个子模块,分别是:
- client: RPC 的客户端实现
- server: RPC 的服务端实现
- registry: 服务注册中心抽象及实现(目前提供 zookeeper 实现)
- test: RPC 测试工具类
.└── lib ├── client ├── registry ├── server └──test
npm install sofa-rpc-node --save
sofa-rpc-node 默认的注册中心实现基于 zookeeper,所以需要先启动一个 zookeeper 实例
从 Homebrew 安装(macOs)
brew install zookeeper
启动 zk server(默认端口为 2181)
zkServer start# ZooKeeper JMX enabled by default# Using config: /usr/local/etc/zookeeper/zoo.cfg# Starting zookeeper ... STARTED
- 暴露一个 RPC 服务,并发布到注册中心
const{ RpcServer}=require('sofa-rpc-node').server;const{ ZookeeperRegistry}=require('sofa-rpc-node').registry;constlogger=console;// 1. 创建 zk 注册中心客户端constregistry=newZookeeperRegistry({ logger,address:'127.0.0.1:2181',// 需要本地启动一个 zkServer});// 2. 创建 RPC Server 实例constserver=newRpcServer({ logger, registry,// 传入注册中心客户端port:12200,});// 3. 添加服务server.addService({interfaceName:'com.nodejs.test.TestService',},{asyncplus(a,b){returna+b;},});// 4. 启动 Server 并发布服务server.start().then(()=>{server.publish();});
- 调用 RPC 服务(从注册中心获取服务列表)
const{ RpcClient}=require('sofa-rpc-node').client;const{ ZookeeperRegistry}=require('sofa-rpc-node').registry;constlogger=console;// 1. 创建 zk 注册中心客户端constregistry=newZookeeperRegistry({ logger,address:'127.0.0.1:2181',});asyncfunctioninvoke(){// 2. 创建 RPC Client 实例constclient=newRpcClient({ logger, registry,});// 3. 创建服务的 consumerconstconsumer=client.createConsumer({interfaceName:'com.nodejs.test.TestService',});// 4. 等待 consumer ready(从注册中心订阅服务列表...)awaitconsumer.ready();// 5. 执行泛化调用constresult=awaitconsumer.invoke('plus',[1,2],{responseTimeout:3000});console.log('1 + 2 = '+result);}invoke().catch(console.error);
- 调用 RPC 服务(直连模式)
const{ RpcClient}=require('sofa-rpc-node').client;constlogger=console;asyncfunctioninvoke(){// 不需要传入 registry 实例了constclient=newRpcClient({ logger,});constconsumer=client.createConsumer({interfaceName:'com.nodejs.test.TestService',serverHost:'127.0.0.1:12200',// 直接指定服务地址});awaitconsumer.ready();constresult=awaitconsumer.invoke('plus',[1,2],{responseTimeout:3000});console.log('1 + 2 = '+result);}invoke().catch(console.error);
- 测试 RPC Server 的方法(用于单元测试)
constrequest=require('sofa-rpc-node').test;const{ RpcServer}=require('sofa-rpc-node').server;constlogger=console;describe('test/server.test.js',()=>{letserver;before(asyncfunction(){server=newRpcServer({ logger,port:12200,});server.addService({interfaceName:'com.nodejs.test.TestService',},{asyncplus(a,b){returna+b;},});awaitserver.start();});after(asyncfunction(){awaitserver.close();});it('should call plus ok',asyncfunction(){awaitrequest(server).service('com.nodejs.test.TestService').invoke('plus').send([1,2]).expect(3);});});
- 暴露和调用 protobuf 接口
通过 *.proto 来定义接口
syntax="proto3";packagecom.alipay.sofa.rpc.test;// 可选optionjava_multiple_files=false;serviceProtoService {rpcechoObj (EchoRequest)returns (EchoResponse) {}}messageEchoRequest {stringname=1;Groupgroup=2;}messageEchoResponse {int32code=1;stringmessage=2;}enumGroup {A=0;B=1;}
服务端代码
constantpb=require('antpb');constprotocol=require('sofa-bolt-node');const{ RpcServer}=require('sofa-rpc-node').server;const{ ZookeeperRegistry}=require('sofa-rpc-node').registry;constlogger=console;// 传入 *.proto 文件存放的目录,加载接口定义constproto=antpb.loadAll('/path/proto');// 将 proto 设置到协议中protocol.setOptions({ proto});constregistry=newZookeeperRegistry({ logger,address:'127.0.0.1:2181',});constserver=newRpcServer({ logger, protocol,// 覆盖协议 registry,codecType:'protobuf',// 设置默认的序列化方式为 protobufport:12200,});server.addService({interfaceName:'com.alipay.sofa.rpc.test.ProtoService',},{asyncechoObj(req){req=req.toObject({enums:String});return{code:200,message:'hello '+req.name+', you are in '+req.group,};},});server.start().then(()=>{server.publish();});
客户端代码
constantpb=require('antpb');constprotocol=require('sofa-bolt-node');const{ RpcClient}=require('sofa-rpc-node').client;const{ ZookeeperRegistry}=require('sofa-rpc-node').registry;constlogger=console;// 传入 *.proto 文件存放的目录,加载接口定义constproto=antpb.loadAll('/path/proto');// 将 proto 设置到协议中protocol.setOptions({ proto});constregistry=newZookeeperRegistry({ logger,address:'127.0.0.1:2181',});asyncfunctioninvoke(){constclient=newRpcClient({ logger, protocol, registry,});constconsumer=client.createConsumer({interfaceName:'com.alipay.sofa.rpc.test.ProtoService',});awaitconsumer.ready();constresult=awaitconsumer.invoke('echoObj',[{name:'gxcsoccer',group:'B',}],{responseTimeout:3000});console.log(result);}invoke().catch(console.error);
虽然上面我们提供了示例代码,但是我们并不推荐您直接使用该模块,因为它的定位是 RPC 基础模块,只提供基本的 API,对于业务开发者可能并不是非常友好。我们的最佳实践是通过插件将 RPC 能力集成到Egg.js 框架里,提供更加直观友好的用户接口,让您就像使用本地方法一样使用 RPC。这块也会在近期开放,敬请期待!
请告知我们可以为你做些什么,不过在此之前,请检查一下是否有已经存在的Bug或者意见。
如果你是一个代码贡献者,请参考代码贡献规范。
gxcsoccer | fengmk2 | killagu | mansonchor | semantic-release-bot | ChangedenCZD |
|---|---|---|---|---|---|
KenyeeC | RabbitSion | hyj1991 | mytEcust | smile21 | onlylovermb |
chenfengjw163 |
This project follows the git-contributorspec, auto updated atMon May 22 2023 14:22:46 GMT+0800.
About
SOFARPC Node is a high-performance, high-extensibility, production-level Nodejs RPC framework.
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Uh oh!
There was an error while loading.Please reload this page.
Contributors14
Uh oh!
There was an error while loading.Please reload this page.