透过 In-memory Channel 看 Knative Eventing 中 Broker/Trigger 工作机制

In-memory Channel是当前Knative Eventing中默认的Channel, 也是一般刚接触Knative Eventing首先了解到的Channel。本文通过分析 In-memory Channel 来进一步了解 Knative Eventing 中Broker/Trigger事件处理机制。

事件处理概览

我们先整体看一下Knative Eventing 工作机制示意图:

通过 namespace 创建默认 Broker 如果不指定Channel,会使用默认的 Inmemory Channel。

下面我们从数据平面开始分析Event事件是如何通过In-memory Channel分发到Knative Service

Ingress

Ingress是事件进入Channel前的第一级过滤,但目前的功能仅仅是接收事件然后转发到Channel。过滤功能处理TODO状态。

func (h *handler) serveHTTP(ctx context.Context, event cloudevents.Event, resp *cloudevents.EventResponse) error {tctx := cloudevents.HTTPTransportContextFrom(ctx)if tctx.Method != http.MethodPost {resp.Status = http.StatusMethodNotAllowedreturn nil}// tctx.URI is actually the path...if tctx.URI != "/" {resp.Status = http.StatusNotFoundreturn nil}ctx, _ = tag.New(ctx, tag.Insert(TagBroker, h.brokerName))defer func() {stats.Record(ctx, MeasureEventsTotal.M(1))}()send := h.decrementTTL(&event)if !send {ctx, _ = tag.New(ctx, tag.Insert(TagResult, "droppedDueToTTL"))return nil}// TODO Filter.ctx, _ = tag.New(ctx, tag.Insert(TagResult, "dispatched"))return h.sendEvent(ctx, tctx, event)
}

In-memory Channel

Broker 字面意思为代理者,那么它代理的是谁呢?是Channel。为什么要代理Channel呢,而不直接发给访问Channel。这个其实涉及到Broker/Trigger设计的初衷:对事件过滤处理。我们知道Channel(消息通道)负责事件传递,Subscription(订阅)负责订阅事件,通常这二者的模型如下:

这里就涉及到消息队列和订阅分发的实现。那么在In-memory Channel中如何实现的呢?
其实 In-memory 的核心处理在Fanout Handler中,它负责将接收到的事件分发到不同的 Subscription。
In-memory Channel处理示意图:

事件接收并分发核心代码如下:

func createReceiverFunction(f *Handler) func(provisioners.ChannelReference, *provisioners.Message) error {return func(_ provisioners.ChannelReference, m *provisioners.Message) error {if f.config.AsyncHandler {go func() {// Any returned error is already logged in f.dispatch()._ = f.dispatch(m)}()return nil}return f.dispatch(m)}
}

当前分发机制默认是异步机制(可通过AsyncHandler参数控制分发机制)。

消息分发机制:

// dispatch takes the request, fans it out to each subscription in f.config. If all the fanned out
// requests return successfully, then return nil. Else, return an error.
func (f *Handler) dispatch(msg *provisioners.Message) error {errorCh := make(chan error, len(f.config.Subscriptions))for _, sub := range f.config.Subscriptions {go func(s eventingduck.SubscriberSpec) {errorCh <- f.makeFanoutRequest(*msg, s)}(sub)}for range f.config.Subscriptions {select {case err := <-errorCh:if err != nil {f.logger.Error("Fanout had an error", zap.Error(err))return err}case <-time.After(f.timeout):f.logger.Error("Fanout timed out")return errors.New("fanout timed out")}}// All Subscriptions returned err = nil.return nil
}

通过这里的代码,我们可以看到分发处理超时机制。默认为60s。也就是说如果分发的请求响应超过60s,那么In-memory会报错:Fanout timed out。

Filter

一般的消息分发会将消息发送给订阅的服务,但在 Broker/Trigger 模型中需要对事件进行过滤处理,这个处理的地方就是在Filter 中。

  • 根据请求获取Trigger信息。Filter中会根据请求的信息拿到 Trigger 名称,然后通过获取Trigger对应的资源信息拿到过滤规则
  • 根据Trigger 过滤规则进行事件的过滤处理
  • 最后将满足过滤规则的分发到Kservice

其中过滤规则处理代码如下:

func (r *Receiver) shouldSendMessage(ctx context.Context, ts *eventingv1alpha1.TriggerSpec, event *cloudevents.Event) bool {if ts.Filter == nil || ts.Filter.SourceAndType == nil {r.logger.Error("No filter specified")ctx, _ = tag.New(ctx, tag.Upsert(TagFilterResult, "empty-fail"))return false}// Record event count and filtering timestartTS := time.Now()defer func() {filterTimeMS := int64(time.Now().Sub(startTS) / time.Millisecond)stats.Record(ctx, MeasureTriggerFilterTime.M(filterTimeMS))}()filterType := ts.Filter.SourceAndType.Typeif filterType != eventingv1alpha1.TriggerAnyFilter && filterType != event.Type() {r.logger.Debug("Wrong type", zap.String("trigger.spec.filter.sourceAndType.type", filterType), zap.String("event.Type()", event.Type()))ctx, _ = tag.New(ctx, tag.Upsert(TagFilterResult, "fail"))return false}filterSource := ts.Filter.SourceAndType.Sources := event.Context.AsV01().SourceactualSource := s.String()if filterSource != eventingv1alpha1.TriggerAnyFilter && filterSource != actualSource {r.logger.Debug("Wrong source", zap.String("trigger.spec.filter.sourceAndType.source", filterSource), zap.String("message.source", actualSource))ctx, _ = tag.New(ctx, tag.Upsert(TagFilterResult, "fail"))return false}ctx, _ = tag.New(ctx, tag.Upsert(TagFilterResult, "pass"))return true
}

当前的机制是所有的订阅事件都会通过 Filter 集中进行事件过滤,如果一个Broker有大量的订阅Trigger,是否会给Filter带来性能上的压力? 这个在实际场景 Broker/Trigger 的运用中需要考虑到这个问题。

结论

作为内置的默认Channel实现,In-memory 可以说很好的完成了事件接收并转发的使命,并且 Knative Eventing 在接下来的迭代中会支持部署时指定设置默认的Channel。有兴趣的同学可以持续关注一下。

原文链接
本文为云栖社区原创内容,未经允许不得转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/518389.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

css-三种基本选择器

一、标签选择器 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><style>/* 标签选择器&#xff0c;会选择到页面上所有的这个标签的元素 */h1{color: #12ec4e;background: …

你知道吗?其实 Oracle 直方图自动统计算法存在这些缺陷!(附验证步骤)

作者 | 吴海存责编 | Carol出品 | CSDN 云计算&#xff08;ID&#xff1a;CSDNcloud&#xff09;封图| CSDN下载于视觉中国在某些场景下&#xff0c;表中某一列的数据分布会比较崎岖&#xff0c;使得CBO(cost base optimizer)在评估执行计划的时候可能会出现误差&#xff0c;从…

开源软件 Apache Dubbo 牵手 IDE 插件,开发部署提速不止 8 倍

自从产品经理银时小伙和他的团队在去年11月发布 Cloud Toolkit&#xff08;一款 IDE 插件&#xff09;以来&#xff0c;已帮助数以万计的开发者们提高了开发、测试、诊断以及应用部署效率。期间&#xff0c;他们还发布了 Contributor Ranking List&#xff0c;和开发者们一同定…

css-层次选择器

一、后代选择器 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><style>/* 后代选择器 */body ul p{background: red;}body p{background: yellow;}</style> </he…

技术人具备“结构化思维”意味着什么?

阿里妹导读&#xff1a;在日常工作中&#xff0c;我们时常会碰到这样的情况&#xff0c;有的人讲事情逻辑非常混乱&#xff0c;罗列了很多事项&#xff0c;却把握不到重点&#xff0c;无法把一件事情说清楚。这种思维混乱是典型的缺少结构化思维的表现。结构化思维非常重要&…

奇奇怪怪的知识增加了,大括号的历史你知道吗?

作者 | Michael McMillan译者 | 弯月&#xff0c;责编 | 夕颜封图 | CSDN下载自视觉中国出品 | CSDN&#xff08;ID:CSDNnews&#xff09;众所周知的标志代码块起始和结尾的大括号是什么时候开始成为编程语言的一部分的呢&#xff1f;或者更重要的是&#xff0c;代码块何时成了…

5年时间,我从开发做到总裁的秘籍--如何提升技术型管理者的领导力

对于深耕技术的一线开发者而言&#xff0c;大多数都希望把技术工作进行到底&#xff0c;或者一直从事和技术技术相关性更高的工作。但随着年龄和经验的增长&#xff0c;我对管理和技术的思考越来越多、越来越深入&#xff0c;和大多数人一样&#xff0c;站在这个路口——到底继…

css-结构伪类选择器

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><style>/* ul的第一个子元素 */body ul li:first-child{background: #12ec4e;}/* ul的最后一个子元素 */ul li:last-child…

闲鱼无障碍是怎么在端侧实现的

Hi&#xff0c;小伙伴们还记得之前刷屏的“闲鱼为1700万人&#xff0c;打造了一条盲道”的文章吗&#xff1f; 在今年4月&#xff0c;闲鱼和深圳市信息无障碍研究会取得了联系。在沟通过程中&#xff0c;我们了解到在移动互联网时代&#xff0c;视障人士同样可以通过手机&#…

面试造飞机系列:看架构师如何设计微服务接口

来源 | 后端技术学堂责编 | Carol封图| CSDN下载于视觉中国 在微服务设计中&#xff0c;服务间接口通信设计常见的有两种方式&#xff1a;RPC 和 REST&#xff0c;关于微服务和 RPC 的更多细节&#xff0c;可以参考我上一篇文章 面试都在问的微服务&#xff0c;一文带你彻底搞…

日均处理万亿数据!Flink在快手的应用实践与技术演进之路

董亭亭&#xff0c;快手大数据架构实时计算引擎团队负责人。目前负责 Flink 引擎在快手内的研发、应用以及周边子系统建设。2013 年毕业于大连理工大学&#xff0c;曾就职于奇虎 360、58 集团。主要研究领域包括&#xff1a;分布式计算、调度系统、分布式存储等系统。 本次的分…

css-字体样式

字体样式 <!--font-family: 字体font-size: 字体大小font-weight: 字体粗细color: 字体颜色--><style>body{font-family: "Arial Black", 楷体,serif;color: #cdbb21;}h1{font-size: 50px;}.p1{font-weight: bolder;}</style><!--字体风格 ob…

小网站的容器化(下):网站容器化的各种姿势,先跟着撸一波代码再说!

作者 | 王洪鹏责编 | Carol出品 | CSDN云计算&#xff08;ID&#xff1a;CSDNcloud&#xff09;封图| CSDN下载于视觉中国 上篇文章&#xff1a;小网站的容器化(上) 中我们大致描述了下个人网站在日常维护中的痛点&#xff0c;文章的后半部分我们添加了一个纯静态网站容器化的简…

阿里云应用高可用 AHAS 正式商用,可一键提升云上应用可用性

在分布式架构环境下&#xff0c;服务间的依赖日益复杂&#xff0c;可能没有人能说清单个故障对整个系统的影响&#xff0c;构建一个高可用的分布式系统面临着很大挑战。 7月17日&#xff0c;阿里云应用高可用服务AHAS 正式商用&#xff0c;包含架构感知、流控降级和故障演练三…

机器学习在高德起点抓路中的应用实践

导读&#xff1a;高德地图作为中国领先的出行领域解决方案提供商&#xff0c;导航是其核心用户场景。路线规划作为导航的前提&#xff0c;是根据起点、终点以及路径策略设置&#xff0c;为用户量身定制出行方案。 起点抓路&#xff0c;作为路线规划的初始必备环节&#xff0c;…

css-阴影和超链接伪类

阴影和超链接伪类 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><style>/* 默认的颜色 */a{text-decoration: none; /* 去掉下划线 */color: #000000; /* 修改颜色 */}…

时尚电商新赛道:揭秘 FashionAI 技术

雷音是阿里巴巴研究员、淘系技术部 FashionAI 负责人&#xff0c;在淘系技术嘉年华硅谷站&#xff0c;他分享了《时尚电商新赛道— FashionAI 中的技术》 &#xff0c;旨在揭秘&#xff1a;从面向机器学习的知识重建切入&#xff0c;提出了在 AI 能力的推动下&#xff0c;让人值…

MQ 技术产品井喷,今天来详聊一下腾讯开源消息中间件 TubeMQ | 原力计划

作者 | kimmking来源 | CSDN博客&#xff0c;责编 | 夕颜出品 | CSDN&#xff08;ID:CSDNnews&#xff09;随着分布式技术的发展&#xff0c;MQ技术产品也出现井喷。目前除了各类常用的MQ&#xff0c;比如Apache的ActiveMQ&#xff0c;Kafka&#xff0c;Pulsar&#xff0c;Rock…

MongoDB compact 命令详解

为什么需要 compact 一图胜千言 remove 与 drop 的区别 MongoDB 里删除一个集合里所有文档&#xff0c;有两种方式 db.collection.remove({}, {multi: true})&#xff0c;逐个文档从 btree 里删除&#xff0c;最后所有文档被删除&#xff0c;但文件物理空间不会被回收db.col…

css-背景图片和渐变

背景图片 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><style>/* 边框 border 1px粗细 solid样式 red颜色*/div{width: 1000px;height: 700px;border: 1px solid red;/*…