抢先一步
VMware 提供培训和认证,为您的进步提速。
了解更多跨系统和平台的数据统一性是Cloud Event 规范独特而崇高的目标。随着其日益广泛的采用,人们希望开发者和架构师不再需要担心如何处理来自不同系统和平台的各种事件。. . 但这篇文章的重点不是重新讨论或重新论证 Cloud Events。简单的谷歌搜索会为您提供很多可读的内容来帮助回答“为什么选择 Cloud Events?”这个问题。本文及后续文章的目标是分享一些想法以及 Spring 在此为预测和应对 Cloud Events 更广泛的采用所做的工作。
Message 是 Spring 实现的 EIP Message,是表示 Cloud Event 的合适结构! 这是我们在此要证明的论点。如果属实,那么目前依赖于 Spring Messaging 的任何框架或应用程序将自动支持 Cloud Event 用例。所以。. .
根据官方网站的说法,Cloud Events 是“一种以通用方式描述事件数据的规范”。
如果您阅读该规范(它相当简单),您会很快意识到 Cloud Event 有效地定义了一种规范且平台无关的数据结构,用于跨系统和平台以统一的方式交换数据。该结构相当简单。它将一些载荷封装为 data
字段,并将额外的元数据封装为 attributes
(一个键/值结构)。attributes
本身分为定义明确的元数据字段(必需和可选)以及松散定义或未定义的字段,后者称为 extension attributes
。
目前就是这些了。
现在,对于那些熟悉 Message(核心企业集成模式之一)以及它在Spring Messaging 中的定义的人来说,你们可能会说:这看起来非常熟悉!这是理所当然的。
就像 Cloud Event 一样,Message 定义了一种规范且平台无关的数据结构,用于跨系统和平台以统一的方式交换数据。该结构非常简单。它将一些载荷封装为 payload
字段,并将元数据封装为 headers
(键/值结构)。
这为什么重要?与其他任何技术一样,在 Spring 中为 Cloud Events 提供集成实际上是在其众所周知且熟悉(对其用户而言)的 Spring 惯用法和抽象的范围内实现其概念所需的工作量问题。这就是为什么会想到Message。鉴于它与 Cloud Event 规范定义的结构几乎完美匹配,“Message 能否成为 Spring 中表示 Cloud Event 的合适抽象?”因为,如果答案是“是”,那么目前依赖于 Spring Messaging 的数万个框架和应用程序就可以自动支持 Cloud Event 用例,这意味着这些框架的用户以及框架本身都能够识别传入的 Cloud Event 实例并创建它们,所有这些都在规范定义的协议细节范围内,例如属性前缀、类型系统等等。
我们还需要研究一些典型的 Cloud Event 使用模式。我们这样做是为了隔离我们所说的功能性方面与非功能性(模板式)方面。因此,让我们描述其中的一些内容
此列表是典型使用模式的一小部分,但有助于说明问题领域。它还帮助我们开始理解和分离功能性方面与非功能性方面。有趣的是,大多数描述的模式都是非功能性方面的示例,这是经验丰富的 Spring 用户期望由框架处理的事情。例如,虽然用户被期望“生成某些内容”(功能性),但“将其封装到 Cloud Event 中”的部分应该由框架处理(非功能性)。消费 Cloud Event 时也适用同样的原则。虽然表述模糊,但通常意味着用户可能只关心 Cloud Event 的数据部分,很可能期望它是框架应该提取、转换和提供的领域特定对象的形式。所有这些再次是非功能性方面的示例。此外,还有 Cloud Event 属性及其前缀(例如 ce_
对比 ce-
等)的问题,这些前缀有效地描述了事件的来源或目的地,这也是人们期望框架处理的内容,特别是考虑到功能实现者可能甚至不知道事件的来源或目的地。
十多年来,Spring 通过基于 Message 的框架成功支持了转换、类型转换、路由、过滤以及更多消息传递模式(其中大部分由企业集成模式描述),在生产环境中运行着数以万计的用户应用程序。我们怎能忘记基础设施层面的问题,例如连接性、会话和事务管理、发送和接收、重试、错误处理、恢复等等?在 Spring 中,我们的一般座右铭是我们努力负责处理非功能性(模板式)问题,只留下功能性(业务逻辑)问题给您。因此,在给定集成的上下文中区分这两者并将尽可能多的工作外包给框架对我们来说始终很重要。我们还公开了工具、库和配置选项,允许您影响某些非功能性问题,因为出于各种原因可能仍然需要这样做。
那么,鉴于此,一个支持 Cloud Events 的典型 Spring 应用程序会是什么样子,特别是在Spring Boot 时代?
以下是一个应用程序示例,它接收一个作为 HTTP 请求的 Cloud Event,并生成一个作为 HTTP 响应的 Cloud Event
@SpringBootApplication
public static class SampleApplication
public static void main(String[] args) throws Exception {
SpringApplication.run(SampleApplication.class, args);
}
@Bean
Function<Person, Employee> hire() {
return person -> {
Employee employee = ...
return employee;
};
}
}
以下是另一个应用程序示例,它从 Apache Kafka 接收 Cloud Event 并将其发送到 RabbitMQ 消息代理
@SpringBootApplication
public static class SampleApplication
public static void main(String[] args) throws Exception {
SpringApplication.run(SampleApplication.class, args);
}
@Bean
Function<Person, Employee> hire() {
return person -> {
Employee employee = ...
return employee;
};
}
}
我们省略了函数的实现细节,因为它们与本文主题无关。框架并不真正关心您做什么。它只关心您期望什么——输入——以及您产生什么——输出——这些信息可以从函数签名中获得。
然而,我确信这并不是您心里所想的,您可能想知道为什么我展示的两个应用程序看起来不同,实际上却完全相同?并且在哪里说明一个应用程序是 REST 端点而另一个是消息处理程序?嗯,要回答这些问题,我们需要了解执行上下文,这来自于您的应用程序 classpath 中可用的 Spring Boot 自动配置。例如,为了使第一个应用程序的描述为真,您需要在 classpath 中添加 spring-cloud-function-web
依赖,它带来了所有必要的组件和额外的自动配置,将您的函数暴露为 REST 端点。至于第二个应用程序,我们可以简单地利用我们已经为 Apache Kafka、AMQP、Solace、HTTP、AWS、Google 等提供的丰富的绑定器库。这些绑定器和相关的自动配置将把示例代码转化为消息处理程序。
Message 是实现这一功能的核心,它是 Spring 中所有活动部件都理解的规范结构。这是一种能够清楚地传达意图和期望的结构。它从哪里来?它将去哪里?谁发送的?内容是什么?它代表一个 Cloud Event 吗?如果是,它是二进制模式还是结构化模式? 问题无穷无尽,但一个不变的事实是,Message 作为一种结构和概念,能够很好地回答这些问题。考虑到这一点,Cloud Event 成为另一种 Message。Spring Framework 可以像处理任何其他 Message 一样处理它,让您专注于业务逻辑,而不是底层细节。
所以,Message 不仅是表示 Cloud Event 的合适结构,它也是在 Spring 中处理 Cloud Event 用例的正确抽象。希望这一点已经清楚了,随着即将到来的对 Message 的 Cloud Event 支持,我们正在为依赖 Spring Messaging 的任何应用程序提供 Cloud Events 支持的道路上。
在后续文章中,我们将介绍即将到来的 Cloud Event 在多个 Spring 框架中的技术细节,以及使用Cloud Event Java SDK 与 Spring 的集成。您现在也可以开始查看一些示例