嗨,欢迎回到另一期《真实世界无服务器》节目。今天我们邀请到了 Alex Zepeshat。嘿,伙计,你好吗?我很好,谢谢你邀请我。
Alex,你是 HookDeck 的首席执行官和联合创始人,HookDeck 是一款无服务器事件网关服务。我想我们之前在为我的时事通讯做一些赞助方面有过一些合作,并且看过你的服务。它看起来非常有趣。我认为从我们之前的电子邮件交流来看,你也是在
无服务器技术之上构建 HookDeck 的,比如使用 Cloudflare Workers 之类的东西。所以我真的非常有兴趣了解你们是如何在幕后构建 HookDeck 的,以及你们是如何找到 Cloudflare Workers 的,因为我和我想很多其他收听这个播客的人都是从 AWS 方面来的。所以真的只是想听听 HookDeck 与 AWS EventBridge 或 SNS 等有什么不同。在我们开始之前,是的,先介绍一下你自己和……
和 HookDeck。
是的,我的意思是,完全正确。我想我们在几个月前决定赞助你的播客,主要是因为你的 AWS 受众。就像我们看到越来越多的 Enbridge、Lambda 等重量级 AWS 用户迁移到 OakDeck。所以我们尝试在该领域进行赞助是有意义的。但我也很乐意从不同的角度来看待 OakDeck、Cloudflare 和我们使用的其他服务的这种服务。所以是的,
这可能有点偏离主题,但希望这是一个有建设性的偏离。关于我的一些情况。我一开始是作为一名产品设计师。我从事过各种各样的产品,从 B2C 到 B2B,最终从事电子商务。我们在蒙特利尔发展了这个相当大的订阅业务。
作为其中的一部分,我们构建了大量原始堆栈来支持它,因为 Shopify 并非今天的模样。在这背后,有如此多的 Webhook,来自 Stripe 和 Shopify 和 Intercom 和所有这些平台的 Webhook。而且,你知道,对于一些企业来说,Webhook 就像那些……
你运营业务所需的关键集成事件。而成功使用它们是如此困难。这就是 HookDeck 的诞生之处。所以我有点像设计师和产品工程师、技术专家,无论你称之为什幺。我发现这实际上是构建和喜欢开发工具、开发基础设施空间的绝佳组合。所以是的,这很棒。
是的,因为在这个特定领域,实际上有很多,我想,商业机会,因为你已经看到像 Segment 和其他一些公司也处于这种领域,你基本上是从第三方供应商和 Shopify 和其他电子商务平台获取有趣的事件,让你更容易……
到与你的业务相关的正确的应用程序代码,而不是管道。这就是无服务器的承诺,对吧?你可以专注于业务问题,而不是底层基础设施。
所以我想在这种情况下,你是否与 Segment 处于类似的领域,你位于你的应用程序和第三方事件之间?但是你是否也与 EventBridge 重叠?因为你提到人们正在从 EventBridge 迁移到 HookDeck,这不仅仅是调整第三方事件,还包括例如微服务环境中不同服务之间的你自己的业务事件。
是的,是的,完全正确。所以最终,我认为我们更经常将自己与 EventBridge 进行比较。我们创造了这个术语,我们仍在努力让人们团结在这个概念后面,即事件网关。实际上,它有点像受 API 网关启发,它可以桥接外部世界与你自己的
端点业务逻辑等等,但专门用于异步事件驱动应用程序,对吧?我们将 EventBridge 视为事件网关。我的意思是,这并没有太大的区别,对吧?EventBridge、事件网关,它们或多或少是同义词。
但实际上,我们只是想说事件网关是一个新的类别,一种思考来自系统外部的集成事件的方式,对吧?就 Shopify 或 Stripe 或 Twilio 或 GitHub 等集成而言,你可以随意命名。
甚至在某些情况下,例如我们正在查看 SDK、库、物联网设备、扫描仪等所有这些东西,对吧?就像事件来自你的网络拓扑结构之外,来自你的云之外等等。
然后将其与你的业务逻辑桥接起来。因为我认为在许多情况下,当你查看 Segment 甚至像,我将更进一步,甚至像 Zapier 等等时,这些都是为业务分析或业务运营人员构建的工具,对吧?它不是为工程师构建的。所以代理很有趣,而且肯定有很多共同点,但我认为主要区别在于这是为工程团队和 DevOps 团队构建的,他们需要操作服务规模并运行,
每秒数千次函数调用等等,对吧?更接近 EventBridge。我特别通过我们的方法与 EventBridge 相比得出的一个重要区别是,它作为队列启动。它作为 HTTP 推送队列而不是拉取队列运行,这令人惊讶地相当独特。就像你确实看到其他人这样做,例如 GCP PubSub,作为一种推送模式。
但是 Apple 在无服务器方面提供了大量的灵活性,因为你不需要工作人员来拉取这些队列。因此,在你可以运行业务逻辑的地方有很多机会。它不一定是 AWS。它可以是任何云。它可以是任何运行时,但仍然可以带来无服务器的好处。
或者至少是一些无服务器的好处。这就是我们如何看待这种桥梁,这种来自所有服务和设备等的集成事件与你的核心业务逻辑之间的连接器。
好的。有什么你可以向我们展示的吗?向我们快速演示一下它是什么样的?因为我必须承认,我自己还没有完全看到它。我已经浏览过你的网站并查看了你上面的一些信息,以及你发布的一些视频,但并没有完全看到产品本身的运行情况。所以我非常有兴趣自己了解更多信息。
是的,我知道。完全正确。让我们深入了解。我知道演示对于仅限音频的听众来说可能有点困难。因此,我将邀请你关注播客说明中将包含的 YouTube 链接。是的,是的,它将会在。是的,节目说明。谢谢。然后我会尽力提供比在普通共享屏幕上更多的上下文,以便通过音频收听的人可以跟随。
所以让我开始吧。好的,我们开始了。我想我想首先要从 Ogg Deck 的职责开始,你的生命周期比 EventBridge 早得多。我说这话的原因是,我们真的试图关注整个软件开发生命周期。所以你与 Ogg Deck 的体验真正开始的地方是在开发中。
所以在 Shopify 演示的这个特定上下文中,我将只使用 Shopify 作为这里的示例。当你提到完整的开发生命周期并从开发开始时,你是指更具体地谈论本地开发体验吗?
是的,感谢你的澄清。我说的是本地开发体验。来自系统外部的事件的一个常见问题是,这些事件是由外部系统生成的,对吧?因此,没有办法到达,比如说,你的本地环境。
过去已经构建了一些工具来进行这种隧道传输,但是所有这些隧道服务都是基于同步假设构建的。这意味着你有一个指向你的计算机或虚拟机或任何东西的单个打开的隧道。然后由于这种一对一的关系,在任何给定时间点都只有一个连接可能。
嗯,但这从根本上说是异步的。因此,这允许我们打破这种假设,并让你能够同时连接多个所谓的隧道到同一个 URL。当你与团队一起工作时,这非常好,对吧?你会经常看到的一件事是,在软件开发团队与 Shopify 或任何东西集成时,他们将不得不使用大量的不同 URL,或者,
他们将在彼此之间同步,就像,哦,这个开发人员正在使用这个,而我正在使用这个,我无法连接到这个等等,对吧。所以,是的,我们从本地开发开始。但是当我谈到 DLC 时,它是本地开发过程,是测试,是集成测试、部署和生产操作。
好的,是的,这些确实是人们遇到的常见问题,当然是在 EventBridge 方面。我已经开发了一些实践来使本地开发更容易一些,但它永远不会与,比如说,如果你想尝试检查你的 EventBridge 规则设置是否正确,你正在捕获事件并将它们正确地定向到你的 Lambda 函数。
总有一些事情你无法轻易捕捉到,除非部署到 AWS 并尝试一下。所以我真的很好奇你们是如何在这里做到这一点的。
是的,绝对的。我会深入探讨,但我认为这将是一个反复出现的主题。我说这话的原因是,实际上,我们只是对端到端开发人员体验给予了更多关注,对吧?所以有很多事情在任一系统中都是可行的。但它也归结为,
设置起来有多容易?它有多容易访问?开发人员体验如何等等,对吧?我认为在许多方面,我们已经非常关注这一点。所以我预计这将是我在这个演示过程中几次会得到的评论类型。但是,让我们来看一下。我只是在这里放了一些简单的东西。所以,在这种情况下,接收来自 Shopify 的 Webhook,也就是来自 Shopify 的事件。我订阅了两种类型的事件。订单创建和产品更新。
然后将其定向到我的两个本地服务。在我的本地计算机上,我目前正在运行产品服务和订单服务。
我已经在每个连接上设置了过滤器,我们称之为连接,以便能够告诉哪些事件我想发送到哪个服务,对吧?例如,在这种情况下,在缺货的情况下,我在主体属性上有一个过滤器,其中变体库存数量小于或等于零,对吧?然后在订单的情况下,我在编辑器属性上有一个过滤器,其中
X Shopify 主题以订单开头,对吧?所以在这个例子中,我正在告诉 a deck 在进入我的系统的所有事件和它需要到达的服务之间路由逻辑是什么。
接下来,我需要实际连接到它。在我的终端上,我会执行 - 对不起,我们可以快速回到上一屏吗?当然。因为在这个之前的屏幕上,我看到 Shopify 是事件源。我猜你正在转换它们,这些是 Webhook 事件。
然后这就是你为什么在标题上有过滤器的原因。然后你可以……所以你之前在那里的语法,小于或等于,我猜这是你们提供的特定于 CookDuck 的独特语法?
是的,这是正确的。我们有自己的过滤器语法。它的目的确实是超级简单明了。实际上,它不是 JSON 模式匹配评估器,而是一个值评估器。实际上并没有关于此的很好的标准。所以我们构建了自己的语法,顺便说一下,它是开源的。好的。
我喜欢你可以并排显示最后捕获的事件这一事实。哦,是的,绝对的。你可以测试你的过滤器等等,对吧?好的,这很酷。
好的。好的。所以要保持,顺便说一句,我喜欢你这样跳进去,在我看来,这是制作演示的正确方法,就像漫无目的地闲聊半个小时一样。对我来说,这并没有那么有趣。所以,所以我们提供 ODEX CLI。CLI 可以从你的终端启动。所以在这个例子中,我已经登录了我的帐户等等,但你也可以在没有帐户的情况下使用它。所以我们支持我们所谓的访客模式。因此,你实际上不需要向我们提供任何关于你的信息就可以使用它。
所以我要做的是运行 OogDecList in 9001。9001 是服务当前运行的端口。它们目前运行在同一个服务中,但它们可以在不同的端口上。
然后如果我启动这个命令,它会问我我想监听哪个源。所以我可以有我的 Shopify、我的 Github、我的 Twilio,我可以有选择地决定,我只想监听这些源的特定子集吗?我想听所有吗?所以在这个例子中,我将选择 Shopify。然后它会告诉我,好的,太棒了。你现在正在监听这两个连接,对吧?
所以接下来我们要做的是添加 Shopify。哪个是?好的,就在这里。所以我为 Shopify 准备了一个订单。我将购买这个真实世界无服务器马克杯并下订单。所以当我下订单时,这现在将生成一个 Webhook。
在任何一秒钟内,我们都可以看到两个请求都进入我的本地主机。我们可以看到有一个 200 HTTP 请求被发送到 localhost:9001,然后发送到我的两个服务。在这种情况下,有 /web/orders 和 /web/product。
所以这实际上只是一个简单的例子,只是展示了你在本地开发中拥有的那种灵活性。但我们也为你提供了关于它的完整可见性。因此,你可以看到所有与你自己或你的任何其他团队成员相关的事件。
并且有一个关于这些事件的完整故事。你可以检查请求数据是什么,也就是其他数据、主体,以及它们对该数据的响应。你可以,你知道,显然可以重试它。所以如果我要将它发送回我的服务,你知道,我正在开发,我犯了一些错误,我正在发送它。现在我们可以看到有一个第三个请求进来了,对吧。
无需过多细节,在开发方面你可以做更多的事情。我们有书签的概念,你可以创建类似 Postman 的所有你期望接收的事件的集合。你可以针对这些书签执行集成任务和开发任务。但我将省去一些细节,否则我们将在这里待一段时间。
当然。所以在那种情况下,在第一个屏幕中,我看到你已经有两个订阅到本地服务。然后当你启动然后转到 CLI 时,你启动另一个来告诉你想要监听这些事件。所以这两个是不同的东西吗,我在控制台中看到的和你在 CLI 中启动的?
不,它们是相同的。所以实际上它有点像你可以在控制台或仪表板本身看到它的状态的关系。所以,是的,它们是相同的。那么,在你开始在 CLI 中监听之前,为什么这些本地服务实际上在 HookDuck 仪表板中?
哦,对不起。我当时为演示准备好了。但是我们可以一起添加另一个。如果我们要添加另一个,那么我们将。所以你只需要在开始监听之前添加连接。正确。
好的,明白了。如果你熟悉 AWS EventBridge 或其他服务,那么理解它的方法实际上是,我们在这个例子中称之为源的源,Shopify,在大多数排队系统中相当于主题,对吧?然后连接本身就是订阅。最后,目标是消费者。所以在这个例子中,如果我们看一下屏幕,你的主题是 Shopify 事件,对吧?
我们有两个订阅,缺货和所有订单,它们将发送到两个目标或消费者,而这些消费者是产品服务和订单服务。好的。在这种情况下,你必须编写任何内容吗?你如何编写消费者?我想消费者代码是它,好吧,我想你说了,事件看起来像什么?它是否遵循某种你拥有的信封,以便事件被包装在一些元数据中等等?
所以最终,a deck 充当 HTTP 代理。这意味着我们获得的数据只是使用这些事件的 HTTP 定义,对吧?所以是标题、主体等等。我们不会将其包装在明确的信封中。这主要是为了跨平台的兼容性。稍后我们会详细介绍这一点。但是我们有转换的概念。
有些人会使用转换将数据格式化为信封。因此,使用这些转换,你基本上可以在所有传入的数据上运行后处理函数。所以 Shopify 显然不会将其发送到像特定的信封中,但你可以将其包装到自己的信封中。人们还会这样做,例如,如果你从 Shopify、WooCommerce、BigCommerce 或 Commerce Slayer 等获得,你可能还会有像
订单定义是正确的,所以你可以为传入的不同订单阴影提供不同的转换,并将其格式化为例如公共格式
是的,因为 DDD 领域的人们经常谈论的一件事是反腐败层的想法,你不想让你的业务领域与 Shopify Webhook 的契约紧密耦合。你想要在那里添加一些层,这样如果 Webhook 中发生更改,
有效负载你不需要重写所有业务逻辑,因为现在某些字段已更改,你想要集中并基本上使该更改仅在注入点处进行一层,以便在你的事件处理程序中,你将将其转换为你的应用程序理解的有效负载,我想到了这一点,我
Ebony City EventBridge 不说 HTTP。它,所有有效负载等等都包含在其自己的信封中,但它非常适合在你的服务中交换事件。你更多的是在谈论 HTTP 作为
我想作为你正在谈论的事件的语言,一切看起来都像 HTTP 请求,有有效负载,有标题等等。在这种情况下,你将如何使用它,比如说,在你的……因为你说它是为开发人员构建的,它是为构建自己服务的人构建的。让我说在我的服务之间,我并不真的想说 HTTP。
与另一个 HTTP API 交谈,我想发送一个事件,并且已经下达了订单或类似的东西。我该如何翻译?我需要翻译吗?或者我发送给 HookDeck 的内容无关紧要?
嗯,是的,因为没有像结构化的信封一样,所以它并不重要,对吧。从某种意义上说,信封是用户自定义的。所以如果你想要一个信封,那么你可以这样做。嗯,但这并不是强制执行的东西。我们最常看到的是,呃,
首先,Webhook 通常被使用。即使像在 Shopify 的情况下,如果你通过 EventBridge 接收它们,那也很好。但问题是,你可能也正在接收 BigCommerce 或 WooCommerce 或其他东西。而这些没有直接到 EventBridge 的信封支持,对吧。所以这意味着你必须经历它。
API 网关,你必须将其格式化为你自己的信封等等。所以我们看到大多数人已经有了 HTTP 端点处理程序。所以这带来的巨大好处是你实际上不必更改你的系统的工作方式或它做出的任何假设。因为如果你有一个端点将要接收 Webhook,可能将其排队到 SQS 或将其放入 Vembridge,将数据上传到 S3,等等。
该端点已经存在,并且已经了解它需要运行的业务逻辑。所以实际上,我们对 a deck 的看法是,它可以在两者之间插入自身,为你带来基于事件的平台的好处,而无需完全重组你的架构,因为你现在正在接收……
你知道,具有特定信封和特定协议等等的事件,对吧。嗯,所以像 HTTP 的优点,呃,在这种情况下是,呃,它对于你正在做的当前操作来说非常透明。嗯,很少会看到一个团队从一开始,第一个实现的版本 DDU 就是使用 EventBridge 和它带来的所有复杂性。它往往是像,哦,我将启动一个带有 HTTP 的 Lambda,呃,
通过 API 网关公开到 HTTP。而且,你知道,对于我们接收的前几千个 Webhook 来说,这可能没问题。在某些时候,你会取得一些成功,你会想,哦,糟糕,我需要重新考虑一下,对吧。所以这就是我们经常看到的。这也是我认为我们试图简化的采用路径。是的。
好的。我的意思是,我想那里的区别在于你非常关注电子商务视角,因为显然在这个领域,Shopify 和我想在这个领域中的许多其他供应商都将使用 Webhook 与你的系统进行通信。
我想我来自的地方,它有点像我工作的企业环境,那里没有 Webhook。实际上没有 Webhook。它完全是系统到系统,在你的,我不知道,银行或其他地方,以及所有内容。所以对我来说,查看这个,查看你的事件和事件看起来像
HTTP 消息在这方面融合在一起。我来自的地方,更接近 SOA 世界,就事件消息和信封以及你之前看到的一些更企业级的集成模式而言。
较少这种以 Webhook 为中心的,我想,观点。我想这就是为什么对我来说,看起来有点奇怪,好吧,这些只是 JSON 中的 HTTP 消息。我知道你们没有强制执行任何,好吧,你们没有强制执行这种特定格式,所以我只需要提出我自己的消息传递。但乍一看,一切看起来都像 HTTP 是一种奇怪的事情,即使它都在构建事件等等。这就是为什么,我想,对我来说,这种脱节来自哪里。
是的,不,我的意思是,这是很合理的。我认为这回到了你正在构建的环境类型,对吧?因为对于当今许多软件开发团队来说,Webhook 风靡一时,因为构建软件对于很大一部分人来说就是集成软件。所以这是否建立在 Twilio 或 Salesforce 上是另一个非常重要的因素,对吧?
你倾向于,或者至少我们倾向于看到的是,在这些集成和第三方周围有很多采用,并且卸载了你正在构建的许多系统复杂性。然后作为其中的一部分,
需要与它们集成并与它们的事件集成变得非常重要。例如,另一个通常在 deck 上很流行的系统是 Stripe 和所有支付平台。所以 Paddle、Checkout.com,所有这些提供商。所以实际上,我认为越来越多,尤其是在这个
在过去 5 到 10 年中建立的公司和初创公司中。对购买系统或使用第三方系统而不是构建自己的系统存在很强的偏见。然后你真正添加到其中的是你的业务中独特的东西,对吧?对你所做的业务逻辑、产品或服务而言独特的东西。当你查看这些类型的公司时,Webhook 无处不在。
因此,来自 Webhook 的 HTTP 假设是一种非常广泛传播的东西。现在很难找到一个不支持某种形式的出站 HTTP Webhook 的平台。
所以实际上,这个桥梁旨在使用这种语言,并尽可能简单地用于那些事件并非你自己生成的用例。它们不是域生成的事件。它们不是你负责的事件。它们是你……哦,我的电脑要休眠了。它们是你……
在本集中,我与 Hookdeck 的联合创始人兼 CTO Alex Bouchard 进行了交谈,以了解更多关于 Hookdeck 的信息以及它与 Amazon EventBridge 的区别。本集包含 Hookdeck 的现场演示,为了获得最佳观看体验,请在此处观看 YouTube 上的录制视频。Alex 向我演示了 Hookdeck,它具有一些不错的功能,可以解决 EventBridge 中常见的开发者体验问题。例如:将事件传递到本地目标;事件传递的审核历史记录;失败事件传递的问题页面;重播失败的事件。剧集链接:查看 Hookdeck;开场主题曲:凯文·麦克劳德的《快乐星期一》;链接:https://incompetech.filmmusic.io/song/3495-cheery-monday;许可证:http://creativecommons.org/licenses/by/4。</context> <raw_text>0 几乎是受害者,对吧。在某些情况下,对吧。因为我们添加了很多案例,例如,Shopify 会在很短的时间内向您发送一百万、两百万个事件,而人们无法处理这些事件等等,对吧。所以,这种特殊情况非常有趣的一点是,最终,
这是一个消息系统,您无法控制生产者,对吧?生产者将以任何它想要的方式、任何形状、任何速度向您发送任何它想要发送的内容。所以,这就是我们试图解决的挑战的一部分,对吧?
当然。我认为 EventBridge 也是如此。此外,EventBridge 也有自己的第三方事件数据端口。他们基本上为您完成 Webhook 的摄取,然后将其转换为一种不
不像 HTTP 的格式,而你们则恰恰相反。我想我还想了解一下构建异步过程方面的问题,其中一件关键的事情是如何处理错误和重试,因为所有事情都在后台异步失败。因此,在检测方面,在内置重试方面,你们……
你们怎么做?你们是否做了一些类似于 EventBridge 的事情,也就是说,你们得到了一些内置的重试和指数退避等等?是的,绝对的。所以也许我可以跳到我从生产标准视图准备的内容。我将深入探讨所有这些细节,因为在这里,我实际上设置了两个环境,一个是开发环境,另一个是生产环境。
在生产环境中,我们之前看到的那些相同服务,对吧?例如,在这种情况下,产品服务和订单服务正在针对 Lambda 函数。之前,我们正在查看本地主机,就像通过本地 HTTP 服务器一样。但在这种情况下,我们正在针对这些 Lambda 函数。顺便说一下,这是屏幕共享。哦,真的吗?好的。是的。
对不起,我认为我的电脑进入睡眠状态,然后屏幕共享在此过程中停止了。所以正在恢复。好的。现在我们看到的屏幕与之前类似,但我是在生产项目中而不是开发项目中。
- 好的,对。- 这里我们可以看到这些服务正在针对 Lambda URL,而不是我们之前看到的特定本地主机等等。- 所以在这种情况下,您期望您的 Lambda 函数使用函数 URL,这样您就可以……好的,对。
尽管我们正在支持直接触发 Lambda 函数的计费,这大约一个月后就会出现。我们还支持对 S3、SQS 和许多其他此类服务的内置支持。而且不仅仅是在 AWS 环境中,对吧?其他云提供商也是如此。
但是是的,对于所有相同的服务,这次都针对这些 Lambda URL。然后,如果我们快速查看一下我的 Lambda 函数,那么只是为了演示的目的,您有一个返回 HTTP 500 状态代码的函数,对吧?
所以要说到您的错误问题,如果我们查看我的事件。所以之前当我们一起在 Shopify 上执行此订单时,我实际上在开发环境中生成了船舶再生产事件,因为我有一个 Shopify 目标船舶。
然后我们可以看到我有一些 HTTP 500 错误。然后我还有一次下一次尝试。所以系统真正告诉我的就是将要进行重试,并且将在特定计划时间进行。这是基于您可以在 Hookdeck 中配置的重试逻辑。我们支持指数退避、线性退避。我们还支持自定义,
您可以通过响应服务器的重试后 HTTP 定义的重试计划。因此,您实际上可以完全控制重试何时发生以及围绕这些重试的计划。
这是针对所有自动化的内容。但是您也可以手动执行此操作。例如,我可以过滤所有失败的事件,在这种情况下我有五个。然后我可以手动重试它们,但我也可以根据条件批量重试,对吧?所以我可以说,重试所有匹配特定条件的事件。我可以超越这一点,对吧?我可以说我在正文中有一些特定数据。例如,也许是客户 ID,对吧?对不起,对不起。
是的,所以它可能是一个客户 ID,例如,从一到三或其他什么。然后你……哎呀,客户 ID。是的。
然后我实际上检查了客户 ID 是什么。所以现在这行不通。但关键是,您可以拥有这些复杂的条件并对其进行批量重试,对吧?所以与其构建所有现有内容的任意存档,不如让存档真正持久化。在任何给定时间点,您可以对其进行过滤、分割、切片和切块,使其具有意义。然后您可以重试
您定义的这些特定事件段,对吧?所以这给了您很大的灵活性。实际上,客户 ID 上没有任何内容为 1、2、3,所以这行不通。这很大程度上是故事的一部分。但我认为故事的另一部分是显而易见的能力。如果您在这里查看问题,我们有“问题”这个概念,对我们来说,这实际上是一种替换死信队列的方式。
因此,问题会将由于类似条件而失败的事件组合在一起,对吧?在这种情况下,您可以看到我们在缺货时有 HTTP 500,然后在所有订单上都有 HTTP 500。如果我要深入研究其中一个,我可以看到这些错误发生的时间线。我的服务器的响应是什么?在这种情况下,它只是返回一个小世界。与这些失败条件相关联的数据是什么,例如样本数据?然后,当我解决问题时,也许某个服务宕机了,我将其恢复了,对吧?
等等,然后我可以提交与该问题相关的批量重试,对吧?所以我们可以看到,好吧,我想重试这些日期之间所有事件,其中应该在这个连接上出现 500,等等。因此,您可以,而不是拥有死信队列,所有失败的内容最终都堆积在一起,您无法真正区分哪些是什么,
我们为您提供了对特定失败内容的非常具体的细分和深入分析能力,以及相应的解决步骤。我认为这是我真正感到自豪的事情,因为作为一名一直使用队列的人,死信队列基本上是我存在的祸根。所以这就是我们的方法。
是的,处理死信队列以及调查和重播它们的整个过程是一个相当复杂的过程。这不太好。您刚才向我展示的内容,能够看到所有单独的故障并能够从那里重播,但也能够看到它们已经被计算出来
按错误类型分类和分组,然后能够批量重新处理它们。从操作角度来看,这非常好。
是的,不,我绝对同意。我们有很多不同类型的错误,用于不同类型的失败条件。但是,我们有针对……我想也许最有趣的一个是针对反压的触发器。因此,如果您在处理时积累了一定数量的反压,那么我们将会……
提醒您,然后还会提供有关导致反压原因的具体指标。是您的响应时间吗?您的并发性是多少?然后为您提供解决步骤,例如增加您的并发性等等,对吧。因此,问题一直是一个非常强大的系统,它绝对使管理所有这些入站事件的操作过程变得简单得多。是的。
您提到了可观察性,我看到那里有指标。所以我想这是您可以看到的事情之一,例如接收、发送、失败的消息数量,也许按路径细分?
是的,实际上,让我们在这里查看我所有交付尝试。所以您可以在这里看到,这些都是我在特定消费者或目标上获得的所有事件,对吧?交付率,目前没有任何待处理的事件。响应延迟,即我花费的时间,所以看起来我们现在大约是 400、300 毫秒。
响应延迟是什么?这是端到端的,指的是您接收事件到调用目标之间的时间吗?我们确实有关于端到端时间的指标。这个指标具体来说是 Lambda 响应时间。因此,这将测量它离开 Hookdeck 服务器到我们从 Lambda 函数收到响应之间的时间。对,明白了。好的。
是的。这很重要,因为您可以根据并行性(每秒或并发)来配置交付率。例如,如果您的目标消耗量每秒有 5 个并发,那么显然,您交付这些事件的速度现在会受到服务器响应能力的影响。因此,能够做到这一点,哦,是的,好吧,我正在积累,我正在积累反压,因为我的服务器现在变慢了,因此消耗速度变慢了。
通过这些指标很容易看出,对吧?对。是的,这也很不错,因为我可能 50% 的时间都在问如何最大化并发性和吞吐量。另外 50% 的时间都在问如何限制我的 Lambda 并发性,因为 Lambda 非常可扩展,但我的下游系统不行。它运行一些遗留数据库
是的。
和 5 个并发请求或每秒 5 个请求,这取决于事情的进展而略有不同。所以这很有用。
是的,我知道。我认为现在这种标准模型中有趣的一点是,控制其并发性是目标或消费者的责任。但是,有两大核心问题使得这变得困难。第一个问题是,如果您正在扩展消费者数量,那么您不可避免地也会扩展并发性,并且跨所有消费者的聚合并发性非常难以控制。
在 Lambda 的情况下,AWS 特别为您提供了预配并发性概念。但实际上它所做的只是告诉 AWS,“好的,这是您想要并行执行的 Lambda 数量。”但是如果您使用的是 Fargate 或运行 Kubernetes 容器等等,
您的聚合并发性非常困难,因为现在您需要能够扩展工作程序的数量。但是,对于您添加的每个新工作程序,您也会增加并发性。所以我们稍微改变了一下。另一件好事是,无论用于运行服务的底层方法是什么,
所以现在,我们进行的大部分讨论都是关于 Lambda 的,但实际上是,我们看到各种运行时作为目标,对吧?通过对如何控制并发性有一个单一模型,而不是每个单独的运行时都有自己不同的控制并发性的方法,这实际上简化了它的思维模型。
因为如果您使用 Hookdeck,那么无论是什么在处理它,我都可以控制 Hookdeck 本身中的并发性。无论运行时是什么,控制它的方式都是一样的。是的。而且对于 Lambda,他们还有两件不同的事情,他们有保留并发性,我认为当您说预配并发性时,您实际上指的是这个。他们还有预配并发性,这是另一回事。是的。
这有点令人困惑。预配并发性更多的是关于定价方面的事情,对吧?这是关于保持 Lambda 函数的某些实例处于预热状态,这样您就不会看到冷启动。哦,是为了冷启动,对。是的,它更多的是为了冷启动而不是为了限制并发性。保留并发性实际上是最大并发性,但您不能称之为保留,因为您正在保留一些并发单元。
此函数的最大可见并发性。所以就像,同样,这种混乱是一个令人惊奇的混乱。那是 Lambda。此外,正如您所说,EC2、Fargate、ECS 等等,所有这些都有不同的并发控制机制。所以自己处理所有这些。此外,随着您开始添加越来越多的
目标,不同的目标可能有其自己的并发管理模型。因此,拥有一个并发性和交付率管理模型要容易得多。是的,绝对的。当我们查看演示和内容时,您知道,这显然是问题的简化版本。但现实情况是,当我们查看许多客户时,他们将拥有 20 个、50 个不同的目标或消费者。这些不一定都在同一个平台上运行。
底层运行时或硬件等等,对吧。嗯,所以说,哦,这就是你用 Lambda 解决问题的方法。它有,好吧,很好。但是现在作为一家特定公司工作的工程师,我现在需要在五个不同的地方而不是一个地方解决这个问题,对吧。嗯,很少看到它像所有整洁漂亮一样。人们积累了技术债务,他们的服务是几年前构建的,等等,对吧。嗯,所以,
我认为这大大简化了事情。所以在我的生产项目中,我还添加了另一个 S3 目标,因为我想分享一下,例如,如果您实际上……它不是一对一的关系,“哦,您得到您的面包车,它会去某个消费者”,这很简单。所以,在这种情况下,我实际上将其设置为我的目标的 S3 存储桶。
Hookdeck 的工作方式是它会将这些事件扇出,对吧?它基本上会创建它们的副本。因此,当它从 Shopify 传入时,我们将获得发送到 S3 的所有数据。但是对于那些缺货或订单的事件,我们将获得发送到这些特定连接的副本。
所以在 S3 中,我这里有一个转换,这就是我之前提到的内容。该转换将基本上删除一些 PII。所以我正在修剪用户电子邮件等等。然后我为 S3 设置文件名。在这种情况下,我使用 Shopify webhook ID 作为文件名。现在这样做是为了我们获得的每个事件,如果我们添加到 S3 存储桶,
现在我得到一个 JSON 文件,我可以将其保留在我的存档中,或者之后从那里触发 AWS 生态系统中的其他事件。现在,所有这些都非常以 AWS 为中心,但同样,人们经常将其发送到 Segment 和 Datadog 等等。所以它很少只是像一个千篇一律的,所有内容都去一个地方。好的,关于该转换的问题。这是……
所以我想您正在托管该代码,所以您正在运行该转换代码。所以我想这只是 JavaScript,还是您可以使用的 JavaScript 的某个子集?因为我想象它是在某个安全环境中运行的,您不希望人们在您的机器上运行东西,做他们不应该做的事情。
是的,是的,完全正确。这些运行在我们称为隔离 VM 中,我们为每个转换函数生成这些 VM,它们是完全隔离的执行上下文,彼此之间相互独立。现在关于转换的一件有趣的事情是,它们只是 JavaScript,但我们实际上正在研究基于 WebAssembly 的解决方案以支持多种语言。
但是这些函数是纯函数。这意味着您实际上无法执行 IO。所以没有像,您可以执行 HTTP 请求或读取文件或类似的事情。它们实际上就是,这就是为什么它们被称为转换的原因。但另一方面是它们非常高效。它们的目的基本上是不可能失败,尽管仍然有一些关于错误处理的逻辑。
但是这些的核心思想基本上是它们很轻量级,它们是免费的。我们不收取这些执行的费用。对。它允许您格式化这些数据,这些 HTTP 数据,您之前不太喜欢,变成这些信封或这种格式或标准化,并且,您知道,
对这些数据进行任何类型的逻辑。例如,人们会从 Wix 获取 webhook,这些 webhook 是 JWT 编码的,然后他们会使用转换将 JWT 解码为原始 JSON,对吧?
对。或者数据可能以 JZip 格式传入,您需要将其解压缩,例如解压缩。有很多不同的用例,人们需要用它们做的事情的广度和深度基本上就是为什么我们决定走这条路,让我们用户运行任意代码来能够将数据格式化为他们需要的内容。
好的,当然。这说得通。我看到了这个,它就像还没有输出。这意味着您实际上可以在此处的控制台中运行此传输函数测试吗?
是的,绝对的。例如,如果我们要,console.log,然后运行它,我们基本上会得到日志输出。我们可以看到我们得到的数据和我们写入的数据之间的差异。在这种情况下,路径被覆盖等等。是的。
好的,酷。这真的,这实际上非常好。您有一些非常好的细节,好的,这些事情很小,但是,好吧,我希望 EventBridge 有一些这些东西,这将使生活变得轻松得多。
是的,是的,不,绝对的。回到您关于 HTTP 信封的评论,这很有趣。我认为对于某些人来说,我们构建它的方式是显而易见的,因为他们实际上并没有太多接触 EventBridge 和更经典的类似
在大型企业中使用大型内部系统等等的事件驱动架构开发,对吧?他们思考事件的方式,或者我已经将 Webhook 称为事件驱动架构的入门毒品多年了。我认为对于
许多开发人员来说,例如,他们正在构建 Shopify 应用程序,并且他们取得了成功,并且它变得非常流行,这是他们第一次接触到,好吧,我将如何处理来自 Shopify 的每秒 500 个、1000 个事件,嗯,并且
对于来自这种背景的人来说,HTTP 信封非常有意义,因为这就是他们思考问题的方式。但是听到您对这方面的看法很有趣。我认为最终,这可能是除了开发者体验之外更大的区别之一。我很想知道随着时间的推移我们如何弥合这一差距,以及我们如何才能支持这两种思维模型。
是的,我认为您已经支持两者,因为您没有强制使用 HTTP 语法,您只是反映它们传入的方式。您没有强制任何东西,所以我仍然可以使用我习惯的格式来发送,正如我所说,更传统的事件驱动架构样式消息,而不是更 Webhook 样式的 HTTP 消息。
所以我认为您可以真正支持这一点。而且我认为这种差异在整体规划中可能更多的是表面的。这是首先出现的事情,但可能不是最重要的事情。我认为像您之前向我展示的处理故障和重播故障之类的事情,比其他任何事情都具有更大的操作价值。
那么,对于 EventBridge 通常提供的其他内容,例如模式发现之类的内容呢?是的。您熟悉 Dave Boyne 事件目录吗?是的。
所以实际上,我认为说其他服务将做得非常好是有道理的。因此,Phil 最近从团队中构建了一个 Hookdeck 到事件目录的导出器。我认为这就是我们思考问题的方式,实际上,将会有产品非常擅长进行这些模式文档、事件文档等等。
所以让我们与他们集成。这并不是说长期来看,我们可能会拥有类似于 EventBridge 的模式注册表类型产品等等。但是现在,现在,我们更倾向于与其他工具集成。
好的,这说得通。是的,我想我刚刚在这个播客中与 David 谈过。所以当您收听这个节目时,该剧集可能已经发布了。我们将更详细地介绍事件目录。是的,太棒了。是的,他在这个领域做了一些非常有趣的事情。同样,人们遇到的一个非常非常常见的问题。因此,听到您关于集成而不是尝试自己实现此功能的想法很有趣。
好的,我认为这是 HookDeck 的一个很好的概述。让我们更详细地讨论一下它的底层实现,因为您谈到了它是一个队列,并且您之前提到您正在使用 Cloudflare Workers 进行摄取,然后是 Google Cloud。对吗?
是的,部分正确。实际上是 Kafka 加 Redis,等等。我们正在为工作选择合适的工具,具体取决于不同的上下文。但是,总的来说,我们的架构分为两个完全独立的组件。我们有摄取,可以将其视为 API 层。该 API 层是所有事件被生产和
和消费的地方,对吧?然后第二部分是我们称为事件生命周期的东西,或者实际上它就像交付队列。因此,这些是将确定哪些事件需要去哪里、执行转换、进行交付、处理重试、重试逻辑、批量重试的操作等等的子系统,对吧?所以第一部分是完全无服务器的。第二部分是
部分无服务器的,它主要是 Kubernetes 类型集群,用于实际的操作方面。但是我们确实使用 PubSub、Kafka、Redis 作为各种不同情况的排队。是的,这些是两种不同的部分,它们都以自己的方式使用无服务器。
好的,在这种情况下,您的 Cloudflare Workers 运行在边缘,进行摄取,然后它们被发送到 Google Cloud,进入某些东西。同样,我想在发送到目标的途中,您正在使用 PubSub 和其他一些东西来处理各种约束,例如并发控制、重试等等。
实际上,我还忘记问了。例如,在事件驱动架构中,您经常看到的一件事是,它不仅仅是关于一个事件传入然后转到目标,而是肯定的是,这更多的是,我想,引用经典的事件驱动架构,事实上,事件消费者很快就会变成发布者,然后您就会有这些
事件链发生,HookDeck 如何帮助我们可视化这一点?因为通常情况下,您会在您的可观察性工具方面这样做,您会检测您的代码并使用其他工具来可视化这一点。但是 HookDeck 中是否有某些东西可以潜在地帮助
在发现您的订阅者以及在事件架构方面您的拓扑结构是什么方面?
是的,完全正确。回到这个话题,我认为能够声明您的生产者和消费者的好处在于它也允许您将其绘制出来,因为在 AWS 上下文中,您的消费者是自声明的。作为消费者,您想要监听特定队列或对特定事件做出反应。
但是由于消费者声明它,所以存在解耦。而在 Hookdeck 中,情况正好相反,您声明您的消费者在哪里、它们是谁、它们的端点是什么,对吧?因此,当您查看 Hookdeck 中的这种仪表板并查看为您生成的这些图表时,对吧?例如,我们刚才看到的那些节点网络,它使事情变得非常清晰,对吧?
然后我们还有回调的概念。因此,回到消费者变成发布者等等,回调的概念基本上是这样的想法,即响应事件,
可以生成一个新事件,对吧?然后也经历它自己的生命周期。因此,如果您的消费者返回特定数据,那么您可以说,好的,对于该特定数据,我希望它现在成为一个新事件。这个新事件现在可以去一个新的事件
一个新的目标,一个新的消费者等等。因此,您有了这种关系,例如,如果有一个事件实际上变成了一个动作,那么该动作现在可以是原始集成事件或到达您的端点的任何内容的结果。这就是我们思考问题的方式。我认为在这方面我们还可以做更多的事情。就这种东西的原生支持程度而言,它还处于早期阶段。
但是已经有很多人在使用它,并从中获得最大的收益。好的,这很有趣。我想这就是我能想到的所有问题了。在我们结束之前,还有什么我们没有谈到的你想提到的吗?好吧,我认为特别是在谈到,你知道,我们谈了很多关于AWS环境以及所有这些方面。
我之前提到的一个事情是,我们正在与许多这些服务建立直接集成,这样你就不必一定通过HTTP,对吧?因此,如果作为观众的你正在从事这项工作,或者有一些你希望看到的兼容性等等,
我们正在与这些环境中的许多用户交谈,以了解他们的需求是什么,我们可以做哪些最有用的不同集成点。所以我非常乐意听到你的想法。如果你对这方面有什么想法,以及你认为它适合在哪里。
但是是的,不,我的意思是,这就涵盖了所有内容。总是很乐意深入探讨Cloudflare和GCP之类的东西。但我将把它留给你。
实际上,这提到了一个关于与例如Lambda集成的很好的观点,现在使用函数UAL。安全模型是什么?我想,为了让你调用它,我是否必须公开我的函数UAL,或者我是否可以使用IAM角色?
是的,你可以通过服务帐户使用IAM角色。因此,你基本上提供一个带有服务帐户的Deck来使用,对吧?然后你可以授予对AWS环境中各个函数、存储桶或任何资源的权限。
好的,你是说我创建一个IAM角色,然后让你承担该角色?所以这是我需要知道你的……你将如何承担该角色?你将从你自己的AWS账户还是从……通过访问令牌来承担该角色。
是的,你会生成一个访问令牌,我们可以通过它来承担该角色。是的。好的。好的。明白了。好的。非常感谢。是的。所以如果你,我想如果任何人有任何问题,他们去哪里?他们想开始吗?他们只是去hookdeck.com然后自己尝试一下吗?
是的,我的意思是,在SelfServe,我们有一个慷慨的免费计划。你可以用它构建很多东西。你也可以直接联系我,在Twitter上是Alex Bouchard,自从昨天以来是蓝天,或者真的在我们的Slack开发者社区联系我们。我们会很乐意加入并与你进行对话。
好的,听起来不错。你的定价是基于使用级别、你发送的事件数量等等……好的,明白了。是的,非常类似于你从大多数云基础设施产品中期望的使用量定价。
好的,听起来不错。好的。是的,我会把这些链接放在下面的描述中,这样任何有兴趣查看HookDeck的人都可以去尝试一下。是的,非常感谢Alex来到节目中,向我们展示你一直在构建的东西。我必须说,我所看到的一些事情……我印象最深刻的一些事情是,你知道,
是一些每天都会让你受益的小改进,例如如何处理错误,如何重播失败的事件以及如何测试你的转换逻辑。但我认为可能最有趣的一个,可能是从开发的角度来看,就是本地开发,能够轻松地对我的本地环境重播事件。
但同样,对我来说,我总是负责运行我正在构建的东西,而不是仅仅编写代码。所以对我来说,处理错误和delta-q方面的事情,对我来说是亮点。这超级超级有趣。
听着,我还没遇到过一个不被所有这些事情搞得焦头烂额的人。所以我完全理解。我很感激有机会来分享更多关于它的事情。感谢你加入并挑战一些想法以及所有这些事情。我认为这就是我们将制作更好产品的方式。所以我感谢你。
不用客气。很高兴和你以及其他人交谈。我想下次再见。现在保重。好的,再见。好的。保重,是的。这就是另一集《真实世界无服务器》的全部内容。要访问节目笔记,请访问realworldserverless.com。如果你想学习如何构建可用于生产环境的无服务器应用程序,请查看我在productionreadyserverless.com上即将推出的课程。下次再见。