All Projects → IronsDu → Gayrpc

IronsDu / Gayrpc

Licence: mit
Full Duplex C++ RPC Library,Use Protobuf, Support HTTP API .

Programming Languages

cpp
1120 projects

Projects that are alternatives of or similar to Gayrpc

Netty Learning Example
🥚 Netty实践学习案例,见微知著!带着你的心,跟着教程。我相信你行欧。
Stars: ✭ 2,146 (+1266.88%)
Mutual labels:  rpc, protobuf
Go Micro Boilerplate
The boilerplate of the GoLang application with a clear microservices architecture.
Stars: ✭ 147 (-6.37%)
Mutual labels:  rpc, protobuf
Getty
a netty like asynchronous network I/O library based on tcp/udp/websocket; a bidirectional RPC framework based on JSON/Protobuf; a microservice framework based on zookeeper/etcd
Stars: ✭ 532 (+238.85%)
Mutual labels:  rpc, protobuf
Cellnet
High performance, simple, extensible golang open source network library
Stars: ✭ 3,714 (+2265.61%)
Mutual labels:  rpc, protobuf
Twirp
PHP port of Twitch's Twirp RPC framework
Stars: ✭ 108 (-31.21%)
Mutual labels:  rpc, protobuf
Twirp
A simple RPC framework with protobuf service definitions
Stars: ✭ 5,380 (+3326.75%)
Mutual labels:  rpc, protobuf
Rpc Thunderdome
A comparison between Proteus RPC and other commonly used RPC frameworks
Stars: ✭ 22 (-85.99%)
Mutual labels:  rpc, protobuf
tsrpc
A TypeScript RPC framework, with runtime type checking and serialization, support both HTTP and WebSocket. It is very suitable for website / APP / games, and absolutely comfortable to full-stack TypeScript developers.
Stars: ✭ 866 (+451.59%)
Mutual labels:  protobuf, rpc
Protobuf
Protocol Buffers - Google's data interchange format
Stars: ✭ 52,305 (+33215.29%)
Mutual labels:  rpc, protobuf
Easyrpc
EasyRpc is a simple, high-performance, easy-to-use RPC framework based on Netty, ZooKeeper and ProtoStuff.
Stars: ✭ 79 (-49.68%)
Mutual labels:  rpc, protobuf
Flatbuffers
FlatBuffers: Memory Efficient Serialization Library
Stars: ✭ 17,180 (+10842.68%)
Mutual labels:  rpc, protobuf
Mrpc
🐿 netty,zookeeper,spring,kyro rpc framework.
Stars: ✭ 128 (-18.47%)
Mutual labels:  rpc, protobuf
Yarpc Go
A message passing platform for Go
Stars: ✭ 285 (+81.53%)
Mutual labels:  rpc, protobuf
Srpc
RPC based on C++ Workflow
Stars: ✭ 521 (+231.85%)
Mutual labels:  rpc, protobuf
rony
Fast and Scalable RPC Framework
Stars: ✭ 41 (-73.89%)
Mutual labels:  protobuf, rpc
Brpc Java
Java implementation for Baidu RPC, multi-protocol & high performance RPC.
Stars: ✭ 647 (+312.1%)
Mutual labels:  rpc, protobuf
cocolian-rpc
使用Apache Thrift作为容器,Google Protobuf作为协议的一个RPC框架。
Stars: ✭ 19 (-87.9%)
Mutual labels:  protobuf, rpc
twjitm-core
采用Netty信息加载实现长连接实时通讯系统,客户端可以值任何场景,支持实时http通讯、webSocket通讯、tcp协议通讯、和udp协议通讯、广播协议等 通过http协议,rpc协议。 采用自定义网络数据包结构, 实现自定义网络栈。
Stars: ✭ 98 (-37.58%)
Mutual labels:  protobuf, rpc
Grpc
An Elixir implementation of gRPC
Stars: ✭ 858 (+446.5%)
Mutual labels:  rpc, protobuf
Twisk
Golang RPC starter kit with Twirp
Stars: ✭ 113 (-28.03%)
Mutual labels:  rpc, protobuf

gayrpc

跨平台全双工双向(异步)RPC系统,也即通信两端都可以同时作为RPC服务方和客户端.

SonarCloud Platform

Build Status

Windows : Build status Linux:Build Status

动机

目前的RPC系统大多用于互联网行业后端系统,但他们之间更像一个单向图(不存在两个服务彼此依赖/互相调用),但游戏等行业中则两节点之间可能相互调用。 因此我们需要一个全双工RPC,在一个"链接"的两端均可开启服务和客户端,当然这里的"链接"是一个虚拟概念,它不一定基于TCP,也即"链接"的两端可以只存在逻辑链接而没有网络直连。

设计准则

  1. RPC支持拦截器,能够对Request或Response做一些处理(比如监控、认证、加解密、分布式跟踪)
  2. RPC核心不依赖网络和网络传输协议,即:我们可以开发任何网络应用和逻辑来开启RPC两端,将"收到"的消息丢给RPC核心,并通过某个出站拦截器来实现/决定把Request或Response以何种方式传递给谁。
  3. 此RPC是基于异步回调的,我认为这是目前C++里比较安全和靠谱的方式,除了回调地狱让人恶心……
  4. RPC系统核心(以及接口)是线程安全的,可以在任意线程调用RPC;且可以在任意线程使用XXXReply::PTR对象返回Response。
  5. RPC是并行的,也即:客户端可以随意发送Request而不必等待之前的完成。 且允许先收到后发出的Request的Response。
  6. RPC系统会为每一个"链接"生成一个XXXService对象,这样可以让不同的"链接"绑定/持有各自的业务对象(有状态)(而不是像grpc等系统那样,一个服务只存在一个service对象,这类RPC调用类似短链接:收到请求返回数据即可)
  7. 支持HTTP API(同理2,此功能通过具体通信协议和拦截器进行支持,RPC核心本身与此无关).

依赖

Windows下可使用 vcpkg 进行安装以下依赖库.

请注意,当使用Windows时,务必使用vcpkg install brynet --head安装brynet. 且务必根据自身系统中的protoc版本对gayrpc_meta.proto和gayrpc_option.proto预先生成代码,请在 src目录里执行:

 protoc --cpp_out=. ./gayrpc/core/gayrpc_meta.proto ./gayrpc/core/gayrpc_option.proto

代码生成工具

地址:https://github.com/IronsDu/protoc-gen-gayrpc,由liuhan编写完成。 首先将插件程序放到系统 PATH路径下(比如Linux下的/usr/bin),然后执行代码生成,比如(在具体的服务目录里,比如gayrpc/examples/echo/pb):

 protoc  -I. -I../../../src --cpp_out=. echo_service.proto
 protoc  -I. -I../../../src --gayrpc_out=. echo_service.proto

Example

https://github.com/IronsDu/gayrpc/tree/master/examples

Benchmark

Latency(single threaded):

connection num:1000
cost 16491 ms for 3000000 requests
throughput(TPS):187500
mean:5 ms, 5274983 ns
median:5 ms, 5132642 ns
max:57 ms, 57525470 ns
min:0 ms, 17231 ns
p99:19 ms, 19198630 ns

Throughput(two threaded):

Ubuntu 18.04 (i5 CPU)下,echo 300k QPS,当并发echo时 1000K QPS.

协议

目前实现的RPC通信协议底层采用两层协议.(注意!RPC核心库并不依赖具体通信协议!) 第一层采用二进制协议,且字节序统一为大端. 通信格式如下:

[data_len | op | data]
字段解释:
data_len : uint64_t;
op       : uint32_t;
data     : char[data_len];

op值为1时表示RPC消息,此为第二层协议!这时第一层协议中的data的内存布局则为:

[meta_size | data_size | meta | data]
字段解释:
meta_size  : uint32_t;
data_size  : uint64_t;
meta       : char[meta_size];
data       : char[data_size];

其中metaRpcMata的binary.data为某业务上的Protobuf Request或Response类型对象的binary或JSON.

RpcMata的proto定义如下:

syntax = "proto3";

package gayrpc.core;

message RpcMeta {
    enum Type {
        REQUEST = 0;
        RESPONSE = 1;
    };

    enum DataEncodingType {
        BINARY = 0;
        JSON = 1;
    };

    message Request {
        // 请求的服务函数
        uint64  method = 1;
        // 请求方是否期待服务方返回response
        bool    expect_response = 2;
        // 请求方的序号ID
        uint64  sequence_id = 3;
    };

    message Response {
        // 请求方的序号ID
        uint64  sequence_id = 1;
        // 执行是否成功
        bool    failed = 2;
        // (当failed为true)错误码
        int32   error_code = 3;
        // (当failed为true)错误原因
        string  reason = 4;
    };
    
    // Rpc类型(请求、回应)
    Type    type = 1;
    // RpcData的编码方式
    DataEncodingType encoding = 2;
    // 请求元信息
    Request request_info = 3;
    // 回应元信息
    Response response_info = 4;
}

服务描述文件范例

以下面的服务定义为例:

syntax = "proto3";

package dodo.test;

message EchoRequest {
    string message = 1;
}

message EchoResponse {
    string message = 1;
}

service EchoServer {
    rpc Echo(EchoRequest) returns(EchoResponse){
        option (gayrpc.core.message_id)= 1 ;//设定消息ID,也就是rpc协议中request_info的method
    };
}

处理请求或Response的实现原理

  1. 编写第一层通信协议的编解码
  2. 将第一层中的data作为第二层协议数据,反序列化其中的meta作为RpcMeta对象
  3. 判断RpcMata中的type
    1. 如果为REQUEST则根据request_info中的元信息调用method所对应的服务函数. 此时第二层协议中的data则为服务函数的请求请求对象(比如EchoRequest).
    2. 如果为RESPONSE则根据response_info中的元信息调用sequence_id对应的回调函数. 此时第二层协议中的data则为服务方返回的Response(比如EchoResponse)

发送请求的实现原理

client->echo(echoRequest, responseCallback)为例 参考代码:GayRpcClient.h

  1. 客户端分配 sequence_id,以它为key将 responseCallback保存起来.
  2. 将echoRequest序列化为binary作为第二层协议中的data
  3. 构造RpcMeta对象,将echo函数对应的id号作为request_info的method,并设置sequence_id.
  4. 将RpcMeta对象的binary作为第二层协议中的meta
  5. 用第二层协议的数据写入第一层协议进行发送给服务端.

发送Response的实现原理

replyObj->reply(echoResponse)为例 参考代码:GayRpcReply.h

  1. 首先replyObj里(拷贝)储存了来自于请求中的RpcMata对象.
  2. 将echoResponse序列化为binary作为第二层协议中的data
  3. 构造RpcMeta对象,将备份的RpcMeta对象中的sequence_id设置到前者中response_info的sequence_id.
  4. 将RpcMeta对象的binary作为第二层协议中的meta
  5. 用第二层协议的数据写入第一层协议进行发送给服务端.

编解码参考

https://github.com/IronsDu/gayrpc/tree/master/src/gayrpc/protocol

注意点

  • RPC核心并不依赖通信采用的协议,而且网络传输可以是TCP、UDP、WebSocket等等,亦或消息队列等等。
  • RPC服务方的reply顺序与客户端的调用顺序无关,也就是可能后发起的请求先得到返回.
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].