vlambda博客
学习文章列表

最近,CNCF云原生全景图收录了一个国产轻量级RPC框架

 
最近,CNCF云原生全景图收录了一个国产轻量级RPC框架

大家好,我是马建仓。

今天在互联网摸鱼发现:一个在 Gitee 上开源的轻量级 RPC 框架「SRPC」 已经被收录到 CNCF 云原生计算基金会的 Landscape 中Cloud Native Computing Foundation云原生交互全景图的 Orchestration & Management -Remote Procedure Call 一栏里。

最近,CNCF云原生全景图收录了一个国产轻量级RPC框架

CNCF 是 Linux基金会旗下的基金会,也是目前开源界运作最活跃的基金会之一。

CNCF Landscape 是 CNCF 中的一个重要的项目,它主要为云原生开发者们提供一个资源地图,帮助企业和开发人员快速理解云原生体系的全貌。

关于申请流程等问题,大家可以去项目开发者的发文中查看:

最近,CNCF云原生全景图收录了一个国产轻量级RPC框架https://zhuanlan.zhihu.com/p/497444507

总而言之,祝贺搜狗开源的 Workflow 团队,我们也借此机会来和大家聊聊 SRPC 这个项目。

什么是 RPC?

全称为:Remote Procedure Call,即远程过程调用。

RPC 做了什么?

通俗的说,有两台服务器A、B。一个应用部署在 A 上,若想要调用 B 上应用提供的函数/方法,由于内存空间的限制,不能直接调用,因此需要通过网络来表达调用的语义和传达调用的数据。

我们为什么需要 RPC 框架?

SRPC 的开发者认为,他对 RPC 的理解是:框架 < 协议 < 生态。

即,框架基本只是协议的一种实现,重视性能与易用,协议是为了让大家互通,便于使用;而生态则是基于两者之上,能够更完善项目,丰富支持项目的用户。

 SRPC 是什么?

最近,CNCF云原生全景图收录了一个国产轻量级RPC框架

比起 SRPC,开发者可能更熟悉 Workflow。早在 2020 年 7 月底,搜狗公司就开源了企业内部的工业级 C++ 服务器引擎 Workflow,三个月后也开源了 Workflow 的生态项目—— SRPC

https://gitee.com/sogou/workflow

具体的说,SRPC 是一个基于 Workflow 打造的轻量级 RPC 框架,通过解析部分 IDL(接口描述文件)和进行代码生成,实现了与 Workflow 底层通信框架的对接和非常简洁的用户接口。

它也是全搜狗业务线上使用的企业级 RPC 系统,目前每天承载上百亿的请求量,涵盖搜广推及其他类型业务。

https://gitee.com/sogou/srpc 

开源许可证: Apache-2.0

项目层级

  • 用户代码(client 的发送函数/server的函数实现)

  • IDL序列化(protobuf/thrift serialization)

  • 数据组织 (protobuf/thrift/json)

  • 压缩(none/gzip/zlib/snappy/lz4)

  • 协议 (SRPC-std/bRPC-std/Thrift-framed/tRPC)

  • 通信 (TCP/HTTP)

各层级可以相互拼装,利用函数重载、派生子类实现父类接口和模版特化等多种多态方式,来实现内部使用同一套代码的高度复用。

SRPC 整体代码量大约1万行,内部使用多种泛型编程的方式,实现纵向解耦合、横向可扩展。

最近,CNCF云原生全景图收录了一个国产轻量级RPC框架

功能特点

1.高性能、低延迟、低开发与接入门槛、可看作性能较优的 Thrift 框架或 bRPC 框架。

  • 支持一键迁移 基于 Protobuf/Thrift 描述文件的项目

最近,CNCF云原生全景图收录了一个国产轻量级RPC框架

2.支持多种数据布局、多种压缩及多种通信协议。

  • 多种数据布局:Protobuf serialize/Thrift Binary serialize/json serialize

  • 压缩:gzip、zlib、snappy、lz4

  • 通信协议:TCP、HTTP、SCTP、SSL、HTTPS

3.内置可以与其他 RPC 框架的 server/client 无缝互通的 client/server。

  • 例如百度 bRPC,腾讯tRPC(唯一开源的tRPC协议实现),Google 的 gRPC,以及 Meta 的 Thrift 协议
最近,CNCF云原生全景图收录了一个国产轻量级RPC框架

4.兼容 Workflow 的串并联任务流。

SRPC 除了提供同步、半同步接口外,其异步接口可以利用 Context 拿到 Series 来打通 Workflow 任务流,这就意味着 SRPC 可以把 RPC 调用当作任务流来组建。

使用方式:

  • 提供创建任务的接口来创建一个 RPC 任务

  • 可以把 RPC 任务放到任务流图中,回调函数里也可以拿到当前的任务流

  • Workflow所支持的其他功能,包括 upstream、计算调度、异步文件IO等

5.AOP 模块化插件管理 

数据可上报到 OpenTelemetry(tracing链路数据上报) OpenTelemetry 是 CNCF 的第二大项目,包括了 Tracing、Log、Metrics 等等多个维度的统计数据收集与展示

Tracing链路数据上报方式:

int main()
{
    SRPCServer server;

    // jaeger http collector ip:port
    RPCSpanOpenTelemetry span_otel("http://127.0.0.1:55358"); 
    server.add_filter(&span_otel);

    // print the tracing info on the screen
    RPCSpanDefault span_log; 
    server.add_filter(&span_log);

    ...
  • 轻松上报其他云原生系统

模块化插件架构图

最近,CNCF云原生全景图收录了一个国产轻量级RPC框架

如何快速入门?

典型案例

syntax = "proto3";//这里proto2和proto3都可以,srpc都支持
message EchoRequest {
    string message = 1;
    string name = 2;
};
message EchoResponse {
    string message = 1;
};
service Example {
    rpc Echo(EchoRequest) returns (EchoResponse);
};

代码生成

protoc example.proto --cpp_out=./ --proto_path=./
srpc_generator protobuf ./example.proto ./

服务器抄送

#include <stdio.h>
#include <signal.h>
#include "example.srpc.h"
using namespace srpc;
class ExampleServiceImpl : public Example::Service
{
public:
    void Echo(EchoRequest *request, EchoResponse *response, RPCContext *ctx) override
    {
        response->set_message("Hi, " + request->name());
        printf("get_req:\n%s\nset_resp:\n%s\n",
                request->DebugString().c_str(), response->DebugString().c_str());
    }
};
void sig_handler(int signo) { }
int main()
{
    signal(SIGINT, sig_handler);
    signal(SIGTERM, sig_handler);
    SRPCServer server_tcp;
    SRPCHttpServer server_http;
    ExampleServiceImpl impl;
    server_tcp.add_service(&impl);
    server_http.add_service(&impl);
    server_tcp.start(1412);
    server_http.start(8811);
    getchar(); // press "Enter" to end.
    server_http.stop();
    server_tcp.stop();
    return 0;
}

客户端抄送

#include <stdio.h>
#include "example.srpc.h"
using namespace srpc;
int main()
{
    Example::SRPCClient client("127.0.0.1", 1412);
    EchoRequest req;
    req.set_message("Hello, srpc!");
    req.set_name("workflow");
    client.Echo(&req, [](EchoResponse *response, RPCContext *ctx) {
        if (ctx->success())
            printf("%s\n", response->DebugString().c_str());
        else
            printf("status[%d] error[%d] errmsg:%s\n",
                    ctx->get_status_code(), ctx->get_error(), ctx->get_errmsg());
    });
    getchar(); // press "Enter" to end.
    return 0;
}

实现

在 Linux系统下的编译示例如下,其他平台建议到 tutorial 目录下使用完整的 cmake 文件协助解决编译依赖问题。

g++ -o server server.cc example.pb.cc -std=c++11 -lsrpc
g++ -o client client.cc example.pb.cc -std=c++11 -lsrpc

项目架构



如果你对本期推荐感兴趣,也欢迎各位转发、点赞、在看。


各位开发者如果你对 RPC 框架有其他的见解,欢迎在后台留言与我们一同讨论也欢迎给我推荐有趣的开源项目,如果收录进 Gitee 星球之后,将有小礼品噢~


如果你想了解更多关于本期推荐项目的内容,也可以点击阅读原文,前往作者仓库给他点个 Star。



往期推荐