【BeetleX重构】gpRPC组件性能测试

        gpRPC是一个基于BeetleX新版本开发的RPC通讯组件,那gp又是什么意思呢?其实就是Google Protobuf的简称。那有人会问不是有个gRPC组件了为何还要去实现一个类似的gpRPC?实现gpRPC的主要目标就在BeetleX高吞吐复用的特性之上实现一个高性能并且使用方便的PRC组件。
        之前的组件测试已经表明Google Protobuf有着百万级别RPS的吞吐能力,毕竟那只是测试的代码在使用便利性上并不友好,封装gpRPC就可以实现基本接口代理的方式来操作RPC服务,在使用上就会变得非常简单,同样其性能也希望在32核的云主机上达到百万级别的吞吐能力。

组件开源地址:
//github.com/beetlex-io/BeetleX.Light.gpRPC

使用
        gpRPC组件是使用Google Protobuf的功能,所以在消息定义上还是采用proto文件来描述(可以借助于Grpc.Tools组件可以在VS中方便处理描述文件).

syntax = "proto3";


option csharp_namespace = "gpRPC.Messages";


message RegisterReq {
    uint32 Identifier=1;
    string FirstName = 2;
    string LastName = 3;
    string Email = 4;
    string Password=5;
    string Address=6;
    string City =7;
    string Remark=8;
}  
message RegisterResp{
    uint32 Identifier=1;
     bool Success = 2;
     int64 Time=3;
}


message User{
    string FirstName = 2;
    string LastName = 3;
    string Email = 4;
    string Password=5;
    string Address=6;
    string City =7;
    string Remark=8;
}


message UsersReq{
    uint32 Identifier=1;
    uint32 Count=2;
}


message UsersResp{
     uint32 Identifier=1;
     repeated User Items = 2;
     bool Success=3;
     string Error=4;
}

使用组件只有这个文件描述是不够的,因为要符合组件的处理规范还需要针对消息实现一些相关接口

[ProtocolObject(101u)]
public partial class RegisterReq : IIdentifier
{


}


[ProtocolObject(102u)]
public partial class RegisterResp : IIdentifier
{


}


[ProtocolObject(201u)]
public partial class UsersReq : IIdentifier
{


}


[ProtocolObject(202u)]
public partial class UsersResp : IIdentifier
{


}


public interface IUserHandler
{
    Task<RegisterResp> Register(RegisterReq req);


    Task<UsersResp> Users(UsersReq req);
}

每个类都需要实现IIdentifier接口和添加ProtocolObject属性标记,IIdentifier要用于维护请求响应匹配的关系,由于gpRPC支持单连接请求复用所以需要有一个ID值来维护请求和响应的关系。ProtocolObject则用于描述一个uint对应的类型用于组件匹配具体的对象类型。后面IUserHandler接口是gpRPC功能接口描述,它给客户端代理调用和服务端实现具体处理逻辑用的。

[RpcService]
public class UserHandler : IUserHandler
{
    public async Task<RegisterResp> Register(RegisterReq req)
    {
        RegisterResp resp = new RegisterResp();
        resp.Success = true;
        resp.Time = DateTime.Now.Ticks;
        return resp;
    }


    public async Task<UsersResp> Users(UsersReq req)
    {
        UsersResp resp = new UsersResp();
        for (int i = 0; i < req.Count; i++)
        {
            User user = new User();
            user.Address = $"guangzhouLongdong{i}";
            user.City = $"guzngzhou{i}";
            user.Email = "henryfan@msn.com";
            user.FirstName = $"fan{i}";
            user.LastName = $"henry{i}";
            user.Password = "122".PadLeft(i, 'a');
            user.Remark = $"{i}";
            resp.Items.Add(user);
        }
        return resp;
    }
}

以上是服务端实现的处理逻辑,实现的类需要使用RpcService标记便于服务器加载并和请求的消息匹配。

服务端
        消息和逻辑定义好后就可以通过gpRPC的RpcServer对象加载启动服务

RpcServer<ApplicationBase> server = new RpcServer<ApplicationBase>();
server.Options.SetDefaultListen(o =>
{
    o.Port = 8080;
});
server.RegisterMessages<RegisterReq>();
server.Options.AddLogOutputHandler<LogOutputToConsole>();
server.Options.LogLevel = LogLevel.Trace;
server.Start();

客户端
        客户端使用也非常方便,通过gpRPC的RpcClient对象创建接口实例即可以进行服务调处理

RpcClient client = "tcp://localhost:8080";
client.AddLogOutputHandler<LogOutputToConsole>();
client.RegisterMessages<RegisterReq>();
client.LogLevel = LogLevel.Trace;
IUserHandler handler = client.Create<IUserHandler>();
RegisterReq req = new RegisterReq();
req.Address = $"guangzhouLongdong";
req.City = $"guzngzhou";
req.Email = "henryfan@msn.com";
req.FirstName = $"fan";
req.LastName = $"henry";
req.Password = "122";
var resp = await handler.Register(req);

注意:RpcClient和创建的接口实例都是线程安全的,可以在任意线程中重复调用。

性能
        老规矩还是做一下性能测试,测试环境还是在A家云32核计算型的云主机上测。

一连接100并发

6f2fc89de2b5087a5a4754ccaa83cc0a.png

20连接2000并发

4d04ab1c48c988a01d2ef4bd8c322a3c.png

从测试结果来看20连接2000并发的量延时有些高,虽然RPS达到了110W,但发送IO竟然达到80万,这样看来消息合并利用率不高导致损耗有些高,如果能和Receive这样的利用率同样的吞吐CPU使用率会大大下降!

b8905b4ee0405c61f2710c25b81c37c2.png

看来需要调整一下组件的内部机制,如果批量IO优化好处理100万RPS的远程接口调用估计50%的CPU即可,希望优化能达到我预想的目标!

BeetleX

开源跨平台通讯框架(支持TLS)

提供HTTP,Websocket,MQTT,Redis,RPC和服务网关开源组件

个人微信:henryfan128    QQ:28304340
有丰富的高吐网络服务设计经验

关注公众号

2b41fbe95fd4e1a2444a405415fe47e4.jpeg

https://github.com/beetlex-io/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值