XRPC的目标很是明确,就是给.net core平台实现一个百万级别的远程方法调用RPC通信组件。它的设计理念和GRPC同样,基于链接复用的机制实现高吞的性能;XRPC采用了HTTP2复用的思想,在协议设计上也相似文本和二进制相结合;在应用层面并没使用消息而是基于接口代理的方式让使用更简便。git
XRPC采用了基于文本+二进制相结合的通信协议,头以文本的方式表现主要是描述请求的位置和附加信息,这样设计的好处就是在实现网关的时候只须要解释头部就能作很好的负载策略。二进制处理并无像GPRC同样使 Protobuf,而是使用了在.net core平台下相对更高效的组件MessagePack。github
在早期不少RPC是基于独享连和链接池的方式进行构建,这样的好处就是实现起来方便简单,但这种设计就没法把不一样请求的请求混合到一个IO上。致使网络IO随并发消息的增加而增加,从而局限了性能的发挥。XRPC的设计是尽可能在最少链接状况发挥更高效的网络处理能力,这样就能够把N个请求的数据复用在一个IO上,而从让网络利用率大大提高。api
但这种设计的缺点就是使用起来很是复杂,不过在.NET
提供async/await
支持下总体设计和应用就变得相对简单和清晰不少了。如今模块已经完成基础功能版本,如下介绍一下如何使用。安全
组件如今只完成最基础的功能,后面会引用Actor
的一些基础元素,让在并发业务处理数据上更高效。能够经过Nuget
引用组件网络
Install-Package BeetleX.XRPC -Version x
XRPC是经过接口的方式来描述服务,经过接口制定相关服务的逻辑,具体实现以下:并发
[Controller(typeof(IUserService))] public class UserService : IUserService { public Task<User> Add(string name, string email, string city, string remark) { User user = new User(); user.Name = name; user.EMail = email; user.City = city; user.Remark = remark; return Task.FromResult(user); } public Task<List<User>> List(int count) { List<User> result = new List<User>(); for (int i = 0; i < count; i++) { User user = new User(); user.ID = Guid.NewGuid().ToString("N"); user.City = "GuangZhou"; user.EMail = "Henryfan@msn.com"; user.Name = "henryfan"; user.Remark = "http://ikende.com"; result.Add(user); } return Task.FromResult(result); } public bool Login(string name, string pwd) { return (name == "admin" && pwd == "123456"); } public User Modify(User user) { return user; } public void Save() { Console.WriteLine("user saved"); } }
class Program { private static XRPCServer mXRPCServer; static void Main(string[] args) { mXRPCServer = new XRPCServer(); //mXRPCServer.ServerOptions.DefaultListen.Port = 80; mXRPCServer.Register(typeof(Program).Assembly); mXRPCServer.Open(); Console.Read(); } }
经过Register
注册相关程序集,组件会把程序集中全部控制器加载到内存中,能够经过日志加载状况:async
client = new XRPCClient("localhost", 9090); client.Connect(); client.NetError = (c, e) => { Console.WriteLine(e.Error.Message); }; client.TimeOut = 10000;
定义一个XRPCClient
对象来进行远程访问,对象默认最大链接数是2,也能够根据本身实状况进行调整,不建增长这样会致使网络IO也会增长影响总体性能。性能
var api = client.Create<IUserService>(); var lresult = await api.Login("admin", "123456"); Console.WriteLine(lresult); var result = await api.Add("henry", "henryfan@msn.com", "gz", "http://github.com"); Console.WriteLine($"{result.Name}\t{result.EMail}\t{result.City}\t{result.Remark}"); await api.Save(); Console.WriteLine("save completed"); User user = new User(); user.ID = Guid.NewGuid().ToString("N"); user.Name = "henry"; user.EMail = "henryfan@msn.com"; user.City = "GuangZhou"; user.Remark = "http://github.com/ikende"; result = await api.Modify(user); Console.WriteLine($"{result.Name}\t{result.EMail}\t{result.City}\t{result.Remark}"); var items = await api.List(5); foreach(var item in items) { Console.WriteLine($"{item.Name}\t{item.EMail}\t{item.City}\t{item.Remark}"); }
经过Create方法能够建立接口代理,这个代理是线程安全的,正常状况只须要建立一个静态成员便可;建立接口后只须要调用相关方法便可完成远程方法的调用。测试
组件设计的性能目标是百万级别RPS的远程方法调用,不过在一台4核物机做为服务测试并无达到这个目标,不过测试结果还算比较理想,在以上示例代码Login方法,采用500个并发模拟的状况RPS达到将近70万。如下是不一样方法在不一样并发数下的测试结果。ui
详细测试代码:https://github.com/IKende/XRPC/tree/master/Samples/Performance