All Projects → sofastack → Sofa Rpc Node

sofastack / Sofa Rpc Node

Licence: mit
SOFARPC Node is a high-performance, high-extensibility, production-level Nodejs RPC framework.

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to Sofa Rpc Node

wapc-rust
Rust-based WebAssembly Host Runtime for waPC-compliant modules
Stars: ✭ 75 (-85.58%)
Mutual labels:  rpc, rpc-framework
Saluki
Spring Boot starter module for gRPC framework.
Stars: ✭ 267 (-48.65%)
Mutual labels:  rpc, rpc-framework
zero
Zero: A simple, fast, high performance and low latency Python framework (RPC + PubSub) for building microservices or distributed servers
Stars: ✭ 296 (-43.08%)
Mutual labels:  rpc, rpc-framework
simpleRPC
Simple RPC implementation for Arduino.
Stars: ✭ 28 (-94.62%)
Mutual labels:  rpc, rpc-framework
Sofa Rpc
SOFARPC is a high-performance, high-extensibility, production-level Java RPC framework.
Stars: ✭ 3,479 (+569.04%)
Mutual labels:  rpc-framework, sofastack
nerve-rpc
Nim RPC framework
Stars: ✭ 32 (-93.85%)
Mutual labels:  rpc, rpc-framework
Erpc
Embedded RPC
Stars: ✭ 262 (-49.62%)
Mutual labels:  rpc, rpc-framework
nodejs grpc
GRPC based API CRUD using Nodejs at both server and client side
Stars: ✭ 17 (-96.73%)
Mutual labels:  rpc, rpc-framework
Slacker
Transparent, non-incursive RPC by clojure and for clojure
Stars: ✭ 316 (-39.23%)
Mutual labels:  rpc, rpc-framework
Hprose Nodejs
Hprose is a cross-language RPC. This project is Hprose 2.0 for Node.js
Stars: ✭ 297 (-42.88%)
Mutual labels:  rpc, rpc-framework
hprose-as3
Hprose for ActionScript 3.0
Stars: ✭ 18 (-96.54%)
Mutual labels:  rpc, rpc-framework
Rpc Websockets
JSON-RPC 2.0 implementation over WebSockets for Node.js and JavaScript/TypeScript
Stars: ✭ 344 (-33.85%)
Mutual labels:  rpc, rpc-framework
http
Extension module of golang http service
Stars: ✭ 57 (-89.04%)
Mutual labels:  rpc, rpc-framework
Pudding
Pudding 是一款迷你级分布式服务框架
Stars: ✭ 24 (-95.38%)
Mutual labels:  rpc, rpc-framework
libcorpc
Libcorpc is a high performance coroutine base RPC framework
Stars: ✭ 20 (-96.15%)
Mutual labels:  rpc, rpc-framework
rony
Fast and Scalable RPC Framework
Stars: ✭ 41 (-92.12%)
Mutual labels:  rpc, rpc-framework
hrpc
Common interface definition based rpc implementation
Stars: ✭ 21 (-95.96%)
Mutual labels:  rpc, rpc-framework
jigsaw-rpc
jigsaw-rpc is an RPC framework written in TypeScript under Node.js
Stars: ✭ 14 (-97.31%)
Mutual labels:  rpc, rpc-framework
Armeria
Your go-to microservice framework for any situation, from the creator of Netty et al. You can build any type of microservice leveraging your favorite technologies, including gRPC, Thrift, Kotlin, Retrofit, Reactive Streams, Spring Boot and Dropwizard.
Stars: ✭ 3,392 (+552.31%)
Mutual labels:  rpc, rpc-framework
Easyrpc
EasyRPC是一个远程过程调用(Remote Procedure Call,简称RPC)的最小实现。它使用极少的类、方法演示了RPC的实现原理,是一个学习RPC工作原理的良好示例。
Stars: ✭ 329 (-36.73%)
Mutual labels:  rpc, rpc-framework

sofa-rpc-node

SOFARPC Nodejs 实现版本

NPM version build status Test coverage David deps Known Vulnerabilities npm download

一、SOFARPC Node 简介

简单说它是 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

安装并启动 zookeeper

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 服务,并发布到注册中心
'use strict';

const { RpcServer } = require('sofa-rpc-node').server;
const { ZookeeperRegistry } = require('sofa-rpc-node').registry;
const logger = console;

// 1. 创建 zk 注册中心客户端
const registry = new ZookeeperRegistry({
  logger,
  address: '127.0.0.1:2181', // 需要本地启动一个 zkServer
});

// 2. 创建 RPC Server 实例
const server = new RpcServer({
  logger,
  registry, // 传入注册中心客户端
  port: 12200,
});

// 3. 添加服务
server.addService({
  interfaceName: 'com.nodejs.test.TestService',
}, {
  async plus(a, b) {
    return a + b;
  },
});

// 4. 启动 Server 并发布服务
server.start()
  .then(() => {
    server.publish();
  });
  • 调用 RPC 服务(从注册中心获取服务列表)
'use strict';

const { RpcClient } = require('sofa-rpc-node').client;
const { ZookeeperRegistry } = require('sofa-rpc-node').registry;
const logger = console;

// 1. 创建 zk 注册中心客户端
const registry = new ZookeeperRegistry({
  logger,
  address: '127.0.0.1:2181',
});

async function invoke() {
  // 2. 创建 RPC Client 实例
  const client = new RpcClient({
    logger,
    registry,
  });
  // 3. 创建服务的 consumer
  const consumer = client.createConsumer({
    interfaceName: 'com.nodejs.test.TestService',
  });
  // 4. 等待 consumer ready(从注册中心订阅服务列表...)
  await consumer.ready();

  // 5. 执行泛化调用
  const result = await consumer.invoke('plus', [ 1, 2 ], { responseTimeout: 3000 });
  console.log('1 + 2 = ' + result);
}

invoke().catch(console.error);
  • 调用 RPC 服务(直连模式)
'use strict';

const { RpcClient } = require('sofa-rpc-node').client;
const logger = console;

async function invoke() {
  // 不需要传入 registry 实例了
  const client = new RpcClient({
    logger,
  });
  const consumer = client.createConsumer({
    interfaceName: 'com.nodejs.test.TestService',
    serverHost: '127.0.0.1:12200', // 直接指定服务地址
  });
  await consumer.ready();

  const result = await consumer.invoke('plus', [ 1, 2 ], { responseTimeout: 3000 });
  console.log('1 + 2 = ' + result);
}

invoke().catch(console.error);
  • 测试 RPC Server 的方法(用于单元测试)
'use strict';

const request = require('sofa-rpc-node').test;
const { RpcServer } = require('sofa-rpc-node').server;
const logger = console;

describe('test/server.test.js', () => {
  let server;
  before(async function() {
    server = new RpcServer({
      logger,
      port: 12200,
    });
    server.addService({
      interfaceName: 'com.nodejs.test.TestService',
    }, {
      async plus(a, b) {
        return a + b;
      },
    });
    await server.start();
  });
  after(async function() {
    await server.close();
  });

  it('should call plus ok', async function() {
    await request(server)
      .service('com.nodejs.test.TestService')
      .invoke('plus')
      .send([ 1, 2 ])
      .expect(3);
  });
});
  • 暴露和调用 protobuf 接口

通过 *.proto 来定义接口

syntax = "proto3";

package com.alipay.sofa.rpc.test;

// 可选
option java_multiple_files = false;

service ProtoService {
  rpc echoObj (EchoRequest) returns (EchoResponse) {}
}

message EchoRequest {
  string name = 1;
  Group group = 2;
}

message EchoResponse {
  int32 code = 1;
  string message = 2;
}

enum Group {
  A = 0;
  B = 1;
}

服务端代码

'use strict';

const antpb = require('antpb');
const protocol = require('sofa-bolt-node');
const { RpcServer } = require('sofa-rpc-node').server;
const { ZookeeperRegistry } = require('sofa-rpc-node').registry;
const logger = console;

// 传入 *.proto 文件存放的目录,加载接口定义
const proto = antpb.loadAll('/path/proto');
// 将 proto 设置到协议中
protocol.setOptions({ proto });

const registry = new ZookeeperRegistry({
  logger,
  address: '127.0.0.1:2181',
});

const server = new RpcServer({
  logger,
  protocol, // 覆盖协议
  registry,
  codecType: 'protobuf', // 设置默认的序列化方式为 protobuf
  port: 12200,
});

server.addService({
  interfaceName: 'com.alipay.sofa.rpc.test.ProtoService',
}, {
  async echoObj(req) {
    req = req.toObject({ enums: String });
    return {
      code: 200,
      message: 'hello ' + req.name + ', you are in ' + req.group,
    };
  },
});
server.start()
  .then(() => {
    server.publish();
  });

客户端代码

'use strict';

const antpb = require('antpb');
const protocol = require('sofa-bolt-node');
const { RpcClient } = require('sofa-rpc-node').client;
const { ZookeeperRegistry } = require('sofa-rpc-node').registry;
const logger = console;

// 传入 *.proto 文件存放的目录,加载接口定义
const proto = antpb.loadAll('/path/proto');
// 将 proto 设置到协议中
protocol.setOptions({ proto });

const registry = new ZookeeperRegistry({
  logger,
  address: '127.0.0.1:2181',
});

async function invoke() {
  const client = new RpcClient({
    logger,
    protocol,
    registry,
  });
  const consumer = client.createConsumer({
    interfaceName: 'com.alipay.sofa.rpc.test.ProtoService',
  });
  await consumer.ready();

  const result = await consumer.invoke('echoObj', [{
    name: 'gxcsoccer',
    group: 'B',
  }], { responseTimeout: 3000 });
  console.log(result);
}

invoke().catch(console.error);

最佳实践

虽然上面我们提供了示例代码,但是我们并不推荐您直接使用该模块,因为它的定位是 RPC 基础模块,只提供基本的 API,对于业务开发者可能并不是非常友好。我们的最佳实践是通过插件将 RPC 能力集成到 eggjs 框架里,提供更加直观友好的用户接口,让您就像使用本地方法一样使用 RPC。这块也会在近期开放,敬请期待!

三、相关文档

四、如何贡献

请告知我们可以为你做些什么,不过在此之前,请检查一下是否有已经存在的Bug或者意见

如果你是一个代码贡献者,请参考代码贡献规范

五、开源协议

MIT

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].