IceRPC之深入理解调度管道->快乐的RPC
作者引言
很高兴啊,我们来到了IceRPC之深入理解调度管道->快乐的RPC,为上篇的续篇,深入理解常见的调度类型, 基础引导,有点小压力,打好基础,才能让自已不在迷茫,快乐的畅游世界。
传入请求
了解如何处理传入的请求
接收传入的请求
调度器的调度方法接受传入的请求。该传入请求是由连接,在收到来自对等点的请求时创建的。
请求持有如下内容:
- 目标服务的路径
- 服务上的操作名称
- 请求字段
- 请求的有效负载
payload
传入请求还包含功能features。这些功能用于该调度管道内的本地通信;它们还用于管道中的调度与应用程序代码之间的通信。
请求有效负载 payload
传入请求的有效负载是表示操作参数的字节流。IceRPC 而言,该流中的字节数是未知的。
请求功能
调度管道中的调度员在调度期间相互传输信息是很常见的。C# 中,这些调度获取并设置请求的 IFeatureCollection 用于这些通信。
还可以使用这些功能与服务代码进行通信。例如,如果安装调度信息中间件,它会设置 IDispatchInformationFeature,并且可以在代码中检索此功能:
// In Slice service implementation
public ValueTask OpAsync(string message, FeatureCollection features, CancellationToken cancellationToken)
{
if (features.Get<IDispatchInformationFeature> is IDispatchInformationFeature dispatchInformation)
{
EndPoint from = dispatchInformation.ConnectionContext.TransportConnectionInformation.RemoteNetworkAddress;
Console.WriteLine($"dispatching request from {from}");
}
Console.WriteLine(message);
return default;
}
按照惯例,这些功能是使用接口类型进行键控的,例如上面示例中的 IDispatchInformationFeature
字段用于"传输连接"进行通信,而功能用于调度管道内的本地通信。IceRPC同时提供请求字段(由请求承载)和响应字段(由响应承载),但只提供请求特性:由于它都是本地的,因此不需要响应特性。
传出响应Outgoing response
了解如何创建传出响应。
创建传出响应
调度程序异步返回传出响应。
传出响应携带如下内容:
- 状态代码
- 错误消息,仅在状态代码非OK时设置
- 响应字段
- 响应的有效负载
payload
响应有效负载
响应的有效负载,是表示操作返回值的字节流。调用者(发送传入请求的连接)读取这些字节,并逻辑地复制到网络连接,直到不再有字节需要读取。
C#中,传出响应的有效负载,被分割为有效负载和有效负载延续,就像传出请求的有效负载一样。这种分割,使得响应有效负载的编码,对于Slice生成的代码来说,更加方便和高效,但在其他方面,是不必要的。出发响应有效负载,在概念上是一个连续的字节流。
中间件Middleware
了解如何安装和编写中间件。
拦截传入的请求
中间件是在传入请求到达目标服务之前拦截传入请求的代码。相同的代码还会在服务发送回呼叫者之前拦截服务提供的传出响应。
在技术层面上,中间件是调度程序,它保存另一个调度程序("下一个")并在下一个调度程序上调用调度,作为其自己的调度方法实现的一部分。下一个调度程序可以是另一个中间件、服务、路由器或其他类型的调度程序;就中间件而言,它只是另一个调度程序。
中间件可以包括在下一个调度程序调用调度之前(在处理请求之前)和在下一个调度程序调用调度之后(在收到响应之后)的逻辑。 中间件还可以通过返回缓存响应或返回错误(具有 Ok 以外的状态代码的响应)来短路调度管道。
例如,一个简单的 C# 中间件可能如下所示:
public class SimpleMiddleware : IDispatcher
{
private readonly IDispatcher _next;
public SimpleMiddleware(IDispatcher next) => _next = next;
public async ValueTask<OutgoingResponse> DispatchAsync(
IncomingRequest request,
CancellationToken cancellationToken)
{
Console.WriteLine("before _next.DispatchAsync");
OutgoingResponse response = await _next.DispatchAsync(request, cancellationToken);
Console.WriteLine($"after _next.DispatchAsync; the response status code is {response.StatusCode}");
return response;
}
}
安装中间件
可以使用路由器,创建调度管道并在此调度管道中安装一个或多个中间件。
路由 Router
了解如何根据路径路由传入的请求。
基于路径的路由
路由是根据请求的路径,将传入的请求,路由到其他调度器的调度器。它还可以沿着这条路线执行中间件。
title: Path-based request routing
---
flowchart LR
subgraph Router
direction LR
m1["middleware #1"] --> m2["middleware #2"] -- /greeter --> s1[" greeter service mapped at /greeter"]
m2 -- /user/joe --> s2["account service mounted at /user"]
m2 -- /user/bob --> s2
end
connection --> m1
这些其他调度程序使用map和mount方法在路由器上注册。
map将调度程序与路由器中的路径相关联。例如,可以将路径
/greeter映射到chatbot服务,这是一场完全匹配的。具有路径/greeter2或/greeter/foo的请求是不匹配。C#中,会像如下代码一样:
var router = new Router();
router.Map("/greeter", chatbot);
mount将调度程序与路由器中的路径前缀相关联。例如,您可以将路径前缀
/user挂载到account服务。具有路径/user或
/user/foo的请求是匹配的。而具有路径/,/user2的请求是不匹配。C#中, 代码如下:
var router = new Router();
router.Mount("/user", account);
映射子叶调度程序(例如服务和安装子路由器)很常见,但这并不是一个硬性规则。
以映射并安装完全相同的路径(例如/greeter)。路由器将带有路径/greeter的请求,引导到映射的调度器,并将带有路径/greeter/foo的请求,引导到安装的调度器。
如果路由器没有找到,传入请求路径的映射或安装调度程序,则它会返回具有状态代码 NotFound 的响应。
子路由
子路由器是在另一个"父"路由器注册的路由器。它有一个与其安装点相对应的前缀;当它查找通过map 或 mount注册的调度员时,它会删除该前缀。
title: Path-based request routing with a sub-router
---
flowchart LR
subgraph Router
direction LR
m1["middleware #1"] --> m2["middleware #2"] -- /greeter --> s1["service #1"]
end
subgraph Sub-router
m3["middleware #3"] -- /superAdmin --> s2["service #2"]
end
m2 -- /admin/superAdmin --> m3
connection --> m1
C# 中, 可以创建一个子路由, 并使用 Route 扩展方法单步安装:
var router = new Router();
// create a sub-router and mount it at /admin
router.Route("/admin", subRouter => subRouter.UseDispatchInformation().Map("/superAdmin", root));
此示例的根服务的完整路径是/admin/superAdmin。管理子路由器在尝试将此路径与其映射和挂载字典中的条目匹配之前,会从请求的路径中删除/admin。
在路由中安装中间件
路由可以在将请求,移交给映射或安装的调度程序之前执行一个或多个中间件。
在 C# 中,这些中间件通过类路由上的 Use{Name} 扩展方法注册。例如:
Router router = new Router().UseLogger(loggerFactory).UseCompressor();
router.Map("/greeter", new Chatbot());
安装这些中间件的顺序通常很重要。安装的第一个中间件,是第一个要执行的中间件。通过上面的示例,记录器中间件首先执行,然后在压缩器中间件上调用 DispatchAsync,最后压缩器中间件在/greeter 映射的 Chatbot 服务上调用 DispatchAsync。
路由总是将传入的请求发送到其注册的中间件,即使它最终返回带有状态代码
NotFound的响应。
收尾
基础概念难啊,不好写,怕写的不好,误导大家,大家看看,不用太深入,以官方为主。
作者结语
- 一直做,不停做,才能提升速度
- 翻译的不好,请手下留情,谢谢
- 如果对我有点小兴趣,如可加我哦,一起探讨人生,探讨道的世界。
- 觉得还不错的话,点个赞哦

IceRPC之深入理解调度管道->快乐的RPC的更多相关文章
- .Net Core MVC理解新管道处理模型、中间件
.Net Core中间件官网:https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/middleware/?view=aspnetcore ...
- Redis管道理解
Redis管道理解 简介 管道并不是Redis本身提供的功能,通常是客户端提供的功能: 管道就是打包多条无关命令批量执行,以减少多个命令分别执行消耗的网络交互时间(TCP网络交互),可以显著提升Red ...
- Linux学习笔记(13)-进程通信|命名管道
匿名管道只能在具有亲属关系的进程间通信,那么如果想要在不具有亲戚关系,想在陌生人之间通信,那又该怎么办呢? 别慌,Linux身为世界上*强大的操作系统,当然提供了这种机制,那便是命名管道-- 所谓命名 ...
- linux 有名管道(FIFO)
http://blog.csdn.net/firefoxbug/article/details/8137762 linux 有名管道(FIFO) 管道的缓冲区是有限的(管道制存在于内存中,在管道创建时 ...
- go语言调度器源代码情景分析之一:开篇语
专题简介 本专题以精心设计的情景为线索,结合go语言最新1.12版源代码深入细致的分析了goroutine调度器实现原理. 适宜读者 go语言开发人员 对线程调度器工作原理感兴趣的工程师 对计算机底层 ...
- Python之路(第三十九篇)管道、进程间数据共享Manager
一.管道 概念 管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信. 先画一幅图帮助大家理解下管道的基本原理 现有2个 ...
- Linux内核入门到放弃-进程管理和调度-《深入Linux内核架构》笔记
进程优先级 硬实时进程 软实时进程 普通进程 O(1)调度.完全公平调度器 抢占式多任务处理(preemptive multitasking):各个进程都分配到一定的时间段可以执行.时间段到期后,内核 ...
- Kubernetes容器调度
Kubernetes的调度器是Kubernetes众多组件的一部分,独立于API服务器之外.调度器本身是可插拔的,任何理解调度器和API服务器之间调用关系的工程师都可以编写定制的调度器.本文后面的介绍 ...
- 管道和FIFO 一
管道和FIFO 管道(pipe) 管道在Unix及Linux进程间通信是最基础的,很容易理解.管道就像一个自来水管,一端注入水,一端放出水,水只能在一个方向上流动,而不能双向流动.管道 ...
- Java中的管道流 PipedOutputStream和PipedInputStream
我们在学习IO流的时候可能会学字节流.字符流等,但是关于管道流的相信大部分视频或者教程都是一语带过,第一个是因为这个东西在实际开发中用的也不是很多,但是学习无止境,存在既有理.JDK中既然有个类那说明 ...
随机推荐
- MogDB/opengauss触发器简介(1)
MogDB/opengauss 触发器简介(1) 触发器是对应用动作的响应机制,当应用对一个对象发起 DML 操作时,就会产生一个触发事件(Event).如果该对象上拥有该事件对应的触发器,那么就会检 ...
- 罗小黑的秘密qsnctfwp
题目的附件 安装相关工具 在 Linux 中使用命令安装 gem :apt-get install gem 在 Linux 中使用命令安装 zsteg :gem install zsteg 这是一道图 ...
- 获取电脑真实的IP地址,忽略虚拟机等IP地址的干扰
/** * @author yins * @date 2018年8月12日下午9:53:58 */ import java.net.Inet4Address; import java.net.Inet ...
- Swagger2的介绍和使用
Swagger2介绍 前后端分离开发模式中,api文档是最好的沟通方式. Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务. 及时性 (接口变 ...
- numpy函数向量化,np.vectorize
import numpy as np import time def myfunc(a, b): if a>b: return a-b else: return a+b vfunc = np.v ...
- 当大火的文图生成模型遇见知识图谱,AI画像趋近于真实世界
简介: 模型免费开放!零基础也能一键进行AI艺术创作.本⽂简要介绍ARTIST的技术解读,以及如何在EasyNLP框架中使⽤ARTIST模型. 导读 用户生成内容(User Generated Con ...
- Linux系统诊断-内存基础
简介: Linux系统诊断-内存基础 1. 背景 谈及linux内存,很多时候,我们会关注free,top等基础命令.当系统遇到异常情况时,内存问题的根因追溯,现场诊断时,缺乏深层次的debug能力. ...
- 使用 Arthas 排查 SpringBoot 诡异耗时的 Bug
简介: 公司有个渠道系统,专门对接三方渠道使用,没有什么业务逻辑,主要是转换报文和参数校验之类的工作,起着一个承上启下的作用.最近,在优化接口的响应时间,优化了代码之后,但是时间还是达不到要求:有一个 ...
- 基于 ASK + EB 构建容器事件驱动服务
简介:本篇文章以"在线文件解压场景"为例为大家展示经典 EDA 事件驱动与容器如何搭配使用. 作者:冬岛.肯梦 导读 EDA 事件驱动架构( Event-Driven Archit ...
- Serverless 场景排查问题利器 : 函数实例命令行操作
简介:实例命令行功能的推出希望能消除用户使用 Serverless 的"最后一公里",直接将真实的函数运行环境展现给用户. 背景介绍 全托管的 Serverless 计算平台能给 ...