Redola.Rpc 的一个小目标

Redola.Rpc 的一个小目标:20000 tps

   Concurrency level: 8 threads
Complete requests: 20000
Time taken for tests: 0.886 seconds
Time per request: 0.044 ms (avg)
Requests per second: 22573 [#/sec] (avg)
   Concurrency level: 8 threads
Complete requests: 10000
Time taken for tests: 0.424 seconds
Time per request: 0.042 ms (mean)
Requests per second: 23584 [#/sec] (avg)

测试环境使用 AWS 虚拟机 AWS EC2 C4 Instance Model c4.2xlarge,配置如下:

Processor: Intel(R) Xeon(R) CPU E5-2666 v3 @ 2.90GHz
vCPU: 8
Memory: 15 GiB
Storage: 30G EBS-Only
Bandwidth: 1,000 Mbps
OS: Windows Server 2012 R2

Redola.Rpc 是什么?

  • Redola.Rpc 是一个基于 C# 的轻量级 RPC 框架;
  • Redola.Rpc 是一个源代码托管在 GitHub 上的开源项目;
  • Redola.Rpc 是一个发布在 nuget.org 上的可安装软件包;

  源代码开源地址:https://github.com/gaochundong/Redola

  样例测试代码:https://github.com/gaochundong/Redola/tree/master/Tests

Redola.Rpc 的特点

  • 简单粗暴,一看就懂;
  • 简单的注册中心,消除配置障碍;
  • 支持 Request / Response 阻塞模型;
  • 支持任意服务间的消息推送;
  • 内置 protobuf 序列化,提供可替换接口;

Redola.Rpc 内部结构

Redola.Rpc 基于 Cowboy.Sockets 进行构建,使用 TCP Socket 进行服务间通信,默认使用 .NET APM TCP Socket 模式。通过 Actor 模型抽象封装 Socket 连接与交互,实现 Actor 之间的 Register、Lookup、Handshake、KeepAlive 等功能;

Redola.Rpc 概念模型

  • Actor Peer:代表一个 Actor 节点,任意 Actor 之间均可通信;
  • Actor Master:作为 Actor 节点注册中心,用于服务的注册与发现;
  • Actor Identity:一个 Actor 的身份描述,包括 Type、Name、Address、Port 等;
  • RPC Service:用于实现具体的 RPC 服务,一个 Actor 可以注册多个 RPC Service;

Redola.Rpc 通信模型

Actor Peer 与 Actor Peer 之间通过 TCP 长连接进行通信。Actor 封装了 TCP 中关于 TcpClient 和 TcpServer 的抽象,对外不再暴露 Client 和 Server 的概念,仅以 Peer 呈现,Peer 与 Peer 之间是平等的。Actor Master 与其他 Peer 的区别仅是承担了 Register 和 Lookup 的职责。

Actor Peer 间通过 Actor Master 查询到需要通信的对端 Actor Peer 的 Actor Identity,会首先进行 Handshake 交换 Actor Identity,用以记录对方的身份。Handshake 之后,即可进行预定义注册的 RPC 消息通信。

为掌握对端 Peer 的活跃情况,通过内置的 KeepAlive 机制进行服务间保活,每隔约定时间进行消息交互,若超时时间内未获得保活回复,则自动断开连接。KeepAlive 同时做了一定的优化,若服务间在保活时间内有任何 Send 或 Receive 消息操作,则视为有服务间通信,即对端为活跃状态,会延迟发送保活请求。

假设 Actor 1 (Tyep:hello, Name:hello-001, Address:192.168.1.139, Port:8888) 需要与 Actor 2 (Type:world, Name:world-001, Address:192.168.1.158, Port:7777) 进行通信,则仅需发送消息时指定 Actor 2 的身份 (world, world-001),其中 world 为 Actor 2 的类型,world-001 为该 world 类型下名称为 world-001 的 Actor Peer。

Redola.Rpc 基本契约

  • 任意 Actor 均需向 Actor Master 注册,提供自身 Actor Identity 信息;
  • 仅指定 Actor Type 发送消息,则会随机 Lookup 一个该 Type 的 Actor 进行通信;
  • Actor 不区分 Client 和 Server 角色,角色由使用者设计;
  • RPC 调用接口有同步和异步之分,由使用者选择;
  • 支持 Request/Response 同步阻塞模式,可设置阻塞超时时间;
  • 消息注册后,通过反射匹配消息处理方法,On + MessageType 契约编程;
  • RPC 限流在消息处理侧实施,默认 RateLimiter 限制 CPU 相同数量线程;
  • 内部 TCP 配置 Buffer Pool 连续内存会伴随连接数和吞吐增加,单 Buffer 8K 大小;
  • 若 RPC 传递消息大于 84K,.NET 将 Buffer 分配到 LOH 上,GC 未必及时回收;

Redola.Rpc 的依赖库

有那么多 RPC 框架,为什么要自己写一个?

演进出来的,那就是一个故事了。

起初,我们作为一个初创公司,还在尝试思考清楚我们要做的东西究竟应该是什么样子,毕竟市场上少有同类竞品,那么首先设计一个原型是合理的。所以,我们只有一个应用程序,用于定时拉取第三方合作伙伴的 WebService 数据,并通过设计的算法进行计算处理,然后写入数据库;

有了数据,总要找地方展现吧,于是招聘了 Unity3D 前端开始做炫酷的 App,有实时数据推送的展现要求,所以前后端通信使用了 WebSocket 协议,也就产生了 Cowboy.WebSockets;

第三方合作伙伴的 WebService 显然不只一个接口,多个接口并发拉取,每 100 毫秒拉取一次,线程繁忙影响了计算处理和写入数据库;好,将数据拉取分离出去,并进行前期的数据清洗和过滤,然后再发给算法计算引擎;这时,就有了 2 个服务,一个负责拉取数据 Feed,一个负责计算入库 Engine,通过 Cowboy.Sockets 进行 TCP 消息通信;

终于有更多的数据可供展现了,当然 U3D App 也快开发完成了,App 不可能就装在一个手机上吧,万一发布到 AppStore 上火了呢?引入了接入层 Gateway 系列服务,用于保持 WebSocket 长连接和数据推送;好,现在有了 2 + n 个服务了,并且 n > 5 还做了软负载均衡;

算法引擎 Engine 计算完后,要将数据分发到这 n 个 Gateway 服务上,臣妾就这两颗 CPU,着实做不到啊!分发成了瓶颈,万一 n 成长到 50 怎么办?好,将数据推送委托给新服务 Bolt 服务,专门做推送给 Gateway;

引擎算法发现需要更多输入源数据参与计算,好吧,引入更多第三方数据 Feed 提供商,每家一个服务做拉取;艾玛~ 每家实际上是多个服务拉取~ 还有要求主动推送的 ~

哎呀,对于同一领域对象,每家的描述 ID 显然不一样,毕竟不是一个公司,手工匹配好烦,眼睛都快瞎了,做个 Mapping 自动服务根据特征专门负责匹配 ID,匹配好了再发给引擎,妈妈再也不用担心我的 ID;

数据简直不要太多,计算引擎 Engine 边计算边入库,常年 100% CPU 啊我的哥;拆!先将预处理数据入库,再将计算的结果入库;

什么?数据库写入有延迟?线程被阻塞,又跟我的 CPU 过不去!拆,引流写操作到 MQ 消息队列,加上 Durability 落地,爱阻塞谁阻塞谁,爱啥时候写啥时候写。

隔壁老王看了一眼我们的 U3D App,矮油不错哦,狂拽酷霸吊炸天啊!你们这数据算法和计算引擎有些超出我的知识范围,我有一些新的产品想法,要么你们帮我实现 H5,要么你们提供 API 我们自己实现 H5,反正我的想法必须实现,你看这是 20% 预付款你们下个星期能不能上线 API 啊?王哥,有钱还能有办不成的事儿?是吧,说,你都要啥推送接口?Socket + Protobuf 可以吧?HTTP 也行?

刚回国的尼古拉斯赵四听闻有 API 开放能力,那必须接入啊,共享经济实现共赢嘛,有钱大家一起赚,只是这 API 接口能不能修改成 RESTful + 反向 POST?

我相信,明天还会有新需求的!要善待今天的自己,底层封装成 Redola.Rpc 框架!

版权声明:本篇文章《Redola.Rpc 的一个小目标》由作者 Dennis Gao 发表自博客园个人技术博客,未经作者本人同意禁止以任何的形式转载,任何自动的或人为的爬虫转载行为均为耍流氓。

Redola.Rpc 的一个小目标的更多相关文章

  1. 先定一个小目标,自己封装个ajax

    你是否发现项目中有很多页面只用到了框架不到十分之一的内容,还引了压缩后还有70多kb的jquery库 你是否发现项目中就用了两三个underscore提供的方法,其他大部分的你方法你甚至从来没有看过 ...

  2. 定一个小目标:明年1024能成功转行web前端,光荣地成为一个程序员!

    第一次在博客园写博,我为什么要选择这里吗? 据说博客园这里的IT大牛如云,作为一个求知若渴的小白,我屁颠屁颠的跟着过来了. 于是今天早上兴高采烈的注册了账号,迫不及待的打开我的博客,呃!注册账号成功了 ...

  3. 先定一个小目标:10天自学C语言编程,教你如何改变一生

    C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构.C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出(或实现 ...

  4. 实现一个小目标,动动小指,分享可得iphone7/ipad/U盘|奥威软件

    为什么很多人喜欢冬天呢?是因为冬天有着“床边挂起长长棉袜,而你做着甜甜美梦”的平安夜?还是因为冬天有着“具有无法言述的浪漫情怀”的圣诞节? 是不是还沉浸在平安夜,圣诞节的双节狂欢中, 好像不管长到多大 ...

  5. 先订一个小目标,把微信小程序搞懂

    目标:系统性学习微信小程序. 第一阶段:熟悉微信小程序及前端开发(结合web前端学习) 第二阶段:了解设计及后端 第三阶段:学习后端.

  6. 【先定一个小目标】怎么解决mysql不允许远程连接的错误

    最近使用Navicat for MySQl访问远程mysql数据库,出现报错,显示“1130 - Host'xxx.xxx.xxx.xxx' is not allowed to connect to ...

  7. 【先定一个小目标】windows下安装RabbitMQ消息服务器

    RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统.他遵循Mozilla Public License开源协议. 1:安装RabbitMQ 需要先安装Erlang语言开发包.下载地址  ...

  8. 【先定一个小目标】Windows下安装MongoDB 3.2

    1.MongoDB 安装 官网提供了三个版本下载: - MongoDB for Windows 64-bit 适合 64 位的 Windows Server 2008 R2, Windows 7 , ...

  9. 【先定一个小目标】在Windows下的安装Elasticsearch

    ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口.Elasticsearch是用Java开发的,并作为Apach ...

随机推荐

  1. 深究标准IO的缓存

    前言 在最近看了APUE的标准IO部分之后感觉对标准IO的缓存太模糊,没有搞明白,APUE中关于缓存的部分一笔带过,没有深究缓存的实现原理,这样一本被吹上天的书为什么不讲透彻呢?今天早上爬起来赶紧找了 ...

  2. 23种设计模式--建造者模式-Builder Pattern

    一.建造模式的介绍       建造者模式就是将零件组装成一个整体,用官方一点的话来讲就是将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示.生活中比如说组装电脑,汽车等等这些都是建 ...

  3. Android ViewPager打造3D画廊

    本文已授权微信公众号:鸿洋(hongyangAndroid)在微信公众号平台原创首发. 网上有很多关于使用Gallery来打造3D画廊的博客,但是在关于Gallery的官方说法中表明: This cl ...

  4. angular2系列教程(十一)路由嵌套、路由生命周期、matrix URL notation

    今天我们要讲的是ng2的路由的第二部分,包括路由嵌套.路由生命周期等知识点. 例子 例子仍然是上节课的例子:

  5. 使用HttpClient的优解

    新工作入职不满半周,目前仍然还在交接工作,适应环境当中,笔者不得不说看别人的源码实在是令人痛苦.所幸今天终于将大部分工作流畅地看了一遍,接下来就是熟悉框架技术的阶段了. 也正是在看源码的过程当中,有一 ...

  6. 使用Expression实现数据的任意字段过滤(1)

    在项目常常要和数据表格打交道. 现在BS的通常做法都是前端用一个js的Grid控件, 然后通过ajax的方式从后台加载数据, 然后将数据和Grid绑定. 数据往往不是一页可以显示完的, 所以要加分页: ...

  7. 程序员必须要知道的Hadoop的一些事实

    程序员必须要知道的Hadoop的一些事实.现如今,Apache Hadoop已经无人不知无人不晓.当年雅虎搜索工程师Doug Cutting开发出这个用以创建分布式计算机环境的开源软...... 1: ...

  8. 一个简单的网站web项目的详解

    有不对的术语,或者不好理解的部分,欢迎大家批评指正,谢谢大家! 近期做的网站web项目,实现登录功能,查询功能.首先把这个项目分为几个模块来处理,当前用户模块,历史用户模块,历史记录模块,数据库模块, ...

  9. keepalived从机接管后主机恢复不抢占VIP

    在lvs+keepalived环境中,为了减小keepalived主从切换带来的意外风险,,设置主机恢复后不抢占VIP.待进行vrrp协议通告备机不可用时切换.主要修改两个地方.(红色部分) 只需修改 ...

  10. weinre- 调试移动端页面

    相信很多前端的小伙伴一定会遇到一个问题, 比如我编写完一个页面,某个地方需要进行调整细节或者是哪个地方怎么调整都不对,在pc端还好,有google,firefox之类可以调节页面的工具,虽说这些工具有 ...