SRPC快速入门 - Sogou基于Workflow的自研RPC框架

什么是rpc

RPC(Remote Procedure Call),远程过程调用,它把网络交互类比为client调用server上的函数。RPC 的主要功能目标是让构建分布式计算(应用)更容易,在提供强大的远程调用能力时不损失本地调用的语义简洁性。为实现该目标,RPC 框架需提供一种透明调用机制,让使用者不必显式的区分本地调用和远程调用。

srpc特点

  • 序列化方案用的是protobuf
  • 服务器端采用workflow:每当有客户端调用时,服务端会创建一个特殊的任务,其基本工作和回调是分开的
  • 代理模式

安装

protobuf的安装

git clone -b 3.20.x https://github.com/protocolbuffers/protobuf.git protobuf.3.20
cd protobuf.3.20
sh autogen.sh
./configure
make
make install

srpc的安装

安装srpc的前置条件是要先安装 protbuf ,之后再来安装 srpc

git clone --recursive https://github.com/sogou/srpc.git
cd srpc
make
make install

快速开始

proto文件编写

syntax = "proto3";

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

message EchoResponse {
    string message = 1;
};

service Example {
    rpc Echo(EchoRequest) returns (EchoResponse);
};

生成srpc代码

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

输出

从中可以看出主要是生成了./srpc_test.srpc.h文件和 服务端文件./server.pb_skeleton.cc和客户端文件./client.pb_skeleton.cc

[Generator Begin]
proto file: [/home/xf/projects/test/./srpc_test.proto]
Successfully parse service block [message] : EchoRequest
Successfully parse service block [message] : EchoResponse
Successfully parse service block [service] : Example
Successfully parse method:Echo req:EchoRequest resp:EchoResponse
finish parsing proto file: [/home/xf/projects/test/./srpc_test.proto]
[Generator] generate srpc files: ./srpc_test.srpc.h 
[Generator Done]
[Generator] generate server files: ./server.pb_skeleton.cc, client files: ./client.pb_skeleton.cc
[Generator Done]

生成文件一窥

服务端代码

可以看出srpc服务端还是很简单的,只需要继承Service类重写Echo方法即可

/*
 * Server codes
 * Generated by SRPC
 */

class Service : public srpc::RPCService
{
public:
	// please implement these methods in server.cc

	virtual void Echo(EchoRequest *request, EchoResponse *response,
					srpc::RPCContext *ctx) = 0;

public:
	Service();
};

客户端代码

客户端相对来说要多很多内容

  1. Echo同步调用
  2. async_Echo异步调用
  3. create_Echo_task通过workflow的方式调用
/*
 * Client codes
 * Generated by SRPC
 */

using EchoDone = std::function<void (EchoResponse *, srpc::RPCContext *)>;

class SRPCClient : public srpc::SRPCClient
{
public:
	void Echo(const EchoRequest *req, EchoDone done);
	void Echo(const EchoRequest *req, EchoResponse *resp, srpc::RPCSyncContext *sync_ctx);
	WFFuture<std::pair<EchoResponse, srpc::RPCSyncContext>> async_Echo(const EchoRequest *req);

public:
	SRPCClient(const char *host, unsigned short port);
	SRPCClient(const struct srpc::RPCClientParams *params);

public:
	srpc::SRPCClientTask *create_Echo_task(EchoDone done);
};

还能看见srpc除了提供workflow的方式,还提供了http,brpc,trpc,trpchttp等方式调用

image-20240302223803173

服务端示例代码

#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;
}

编译示例

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

运行

./server
./client
#server
get_req:
message: "Hello, srpc!"
name: "workflow"

set_resp:
message: "Hi, workflow"
#client
message: "Hi, workflow"
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@马云

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值