NetCore版RPC框架NewLife.ApiServer
2021-04-11 04:25
标签:没有 封装 wait 加解密 返回 相关 tcl 参数 重要 微服务和消息队列的基础都是RPC框架,比较有名的有WCF、gRPC、Dubbo等,我们的NewLife.ApiServer建立在网络库NewLife.Net之上,支持.Net Core,追求轻量级和高性能,只有最简单的远程调用功能。 现在是网络系列文章的第五篇,前面四篇快速过了一遍网络库基本用法,也做了压力测试并给出数字。 本章正式进入应用层面,并且采用.Net Core作为例程,说明我们一开始就支持.Net Core,也算是回答了很多支持者的疑问。 老规矩,先上代码:https://github.com/nnhy/NewLife.Net.Tests (例程RpcTest) ApiServer源码:https://github.com/NewLifeX/X/tree/master/NewLife.Core/Remoting ApiServer实在太小了,就让它和Net一起分别作为X组件核心库的一个目录。 ApiServer开始于2014年,我们为了建立物联网云平台,解决云端、硬件设备端、手机端、网页端相互通信,而建立的一套完整的通信体系。 公司业务需要,在ApiServer上建立了包括服务治理、注册发现、负载均衡、设备鉴权、通信加密、压缩、P2SP网络、WebSocket等等一系列模块。 这一套物联网云平台已经用在很多家公司上,根据NewLife两年解封惯例,大概在2019年开源放出大部分源码。 本文所指的ApiServer,仅指开源的RPC部分。 2017年4月1日晚,我们想知道ApiServer的表现,做了一次最大并发数测试,目标是单节点支持100万设备接入。 租用60台阿里云ECS,实际测试单节点最大支持84.5万模拟设备接入,设备端的心跳包(5~60s) 拖垮了32核服务端。 先看看例程最终效果: ApiServer主要特点如下: 新建.Net Core 2.0项目RpcTest,我们把服务端客户端代码写到一起。 服务暴露高仿MVC,一个控制器内可以暴露多个服务方法 这里暴露了两个服务,分别是 加法My/Add 和 加密My/RC4 ,控制器名称加上方法名,作为寻址路径。 不使用Api特性时,控制器类的所有共有方法都将暴露成为服务。 返回值比较简单支持,该什么类型就什么类型。理论上来说,支持Json序列化的类型,都可以作为参数和返回类型。 服务方法也可以指定名称,支持方法过滤接口 这里控制器和方法都加上了Api特性,特别指定了名称,公开服务 User/FindByID。 这里有个硬伤,如果不加Api特性,默认会把 OnActionExecuting/OnActionExecuted两个方法也暴露成为服务。 实现Api接口,是为了得到Session,这个不是必须的,因为控制器上下文ControllerContext.Current也可以得到这个Session。 这个Session代表着网络会话,可以取得各种跟网络相关的东西,甚至包括直接向客户端发送数据。 当然,也可以当做Web的Session来使用,内置有一个字典。 同一客户端的Api多次请求,都共用同一个Session对象,可用于做身份验证,从某种层面上来讲,ApiServer是“有状态”的。 动作过滤接口IActionFilter,让我们能够在本控制器所有服务执行前后进行拦截,包括参数预处理和异常拦截。 服务参数采用Json序列化封送,所以客户端服务端可以不必要求严格一致,跟Http类似,这一点在多版本管理上非常重要,不会说你加了个参数就强制要求所有客户端跟着升级。 服务方法内的各种异常,都将会被拦截并送到客户端,ApiException异常将会得到特殊处理,它包括了一个异常代码,也送到客户端。 没有异常代码的各种异常,都将使用默认错误代码500. 最后实例化ApiServer 中间打开的各种日志,纯属为了便于展示通信过程,实际应用中务必去除! ApiServer采用手工注册控制器的方式,避免了复杂的MVC路由系统。 内置有一个控制器ApiController,它的All服务用于向客户端返回所有可用服务列表。 服务端建立起来后,可以用码神工具的Api工具调试,(https://github.com/NewLifeX/X/tree/master/XCoder) 为了便于使用,封装一个客户端类 其实这个类不是必须的,看个人喜好吧。 这里做了4次不同调用,模拟了常见场景。 编译后跑起来就是开头的效果,感兴趣的同学还可以到Linux上试试,也可以新建Net40/Net45项目,同样可用。 并且,Net40项目还可以在树莓派上跑,基于Mono,码神工具(WinForm)也支持。 RpcTest例程概括性讲解了ApiServer的用法,大家可以去尝试、扩展。 实际工作中,我们正准备用于建立一个每天数十亿次调用的微服务系统。 我是大石头,打1999年起,19年老码农。目前在物流行业从事数据分析架构工作,日常工作都是亿万数据的读写使用。欢迎大家一起C#大数据! NetCore版RPC框架NewLife.ApiServer 标签:没有 封装 wait 加解密 返回 相关 tcl 参数 重要 原文地址:https://www.cnblogs.com/nnhy/p/newlife_apiserver.html一、 背景
二、功能特点
三、服务端例程
///
///
static void TestServer()
{
// 实例化RPC服务端,指定端口,同时在Tcp/Udp/IPv4/IPv6上监听
var svr = new ApiServer(1234);
// 注册服务控制器
svr.Register
四、客户端例程
///
static async void TestClient()
{
var client = new MyClient("tcp://127.0.0.1:1234");
// 指定编码器
client.Encoder = new JsonEncoder();
client.EncoderLog = XTrace.Log;
// 打开原始数据日志
var ns = client.Client;
ns.Log = XTrace.Log;
ns.LogSend = true;
ns.LogReceive = true;
client.Log = XTrace.Log;
client.Open();
// 定时显示性能数据
_timer = new TimerX(ShowStat, ns, 100, 1000);
// 标准服务,Json
var n = await client.AddAsync(1245, 3456);
XTrace.WriteLine("Add: {0}", n);
// 高速服务,二进制
var buf = "Hello".GetBytes();
var pk = await client.RC4Async(buf);
XTrace.WriteLine("RC4: {0}", pk.ToHex());
// 返回对象
var user = await client.FindUserAsync(123, true);
XTrace.WriteLine("FindUser: ID={0} Name={1} Enable={2} CreateTime={3}", user.ID, user.Name, user.Enable, user.CreateTime);
// 拦截异常
try
{
user = await client.FindUserAsync(123, true);
}
catch (ApiException ex)
{
XTrace.WriteLine("FindUser出错,错误码={0},内容={1}", ex.Code, ex.Message);
}
}
五、总结
下一篇:C# QR二维码DEMO
文章标题:NetCore版RPC框架NewLife.ApiServer
文章链接:http://soscw.com/index.php/essay/74097.html