GORM 陷阱 (第一部分)
你是 Grails 的新手吗?或者你可能遇到了你的第一个 GORM“怪癖”?如果是这样,那么你会想阅读关于 GORM 陷阱的这个系列文章。这些文章不仅会突出那些经常让人措手不及的小怪癖,还会解释 GORM 为何会这样表现。
希望你已经知道 GORM 是 Grails 附带的数据库访问库。它基于可能是最流行的 Java ORM:Hibernate。正如你所料,Hibernate 是一个强大灵活的库,它为 GORM 带来了巨大的好处。但使用它是有代价的:许多...
你是 Grails 的新手吗?或者你可能遇到了你的第一个 GORM“怪癖”?如果是这样,那么你会想阅读关于 GORM 陷阱的这个系列文章。这些文章不仅会突出那些经常让人措手不及的小怪癖,还会解释 GORM 为何会这样表现。
希望你已经知道 GORM 是 Grails 附带的数据库访问库。它基于可能是最流行的 Java ORM:Hibernate。正如你所料,Hibernate 是一个强大灵活的库,它为 GORM 带来了巨大的好处。但使用它是有代价的:许多...
Eclipse Virgo 的第一个里程碑版本 (2.1.0.M01) 现已根据 Eclipse Public License 提供下载。它包含一个应用服务器,称为 Virgo Web Server,以及一个独立的内核。
这个里程碑的目标是让 dm Server 2.0.x 用户能够相对无痛地迁移到它,并拥有一个同样稳定的环境。SpringSource 为 Virgo 提供商业支持,我们鼓励所有 dm Server 用户迁移到 Virgo。目前与用户的主要沟通渠道是 Virgo 论坛。还有一个 Virgo 开发者邮件列表和一个每周的 Virgo 社区电话会议...
经过数周的微调和社区反馈,Spring Framework 3.0.3 现已发布。此版本修复了针对 Spring 3.0.2 报告的百余个小问题,特别是在 JSP 标签库、Portlet 会话处理以及 ConversionService 细节方面。再次地,此版本跟上了最近的第三方版本:OpenJPA 2.0 final、Hibernate 3.5.2 和 JBoss 6.0.0 M3,所有这些版本现在都与 Spring 3 完全兼容并受支持。
请注意,与此同时,所有主要的持久化提供者都发布了支持 JPA 2.0 的 GA 版本,甚至...
更新 我修改了第一段,以澄清 RabbitMQ 和 JMS 之间的关系。
RabbitMQ 是一个轻量级、可靠、可伸缩且可移植的消息代理。但与许多 Java 开发者熟悉的消息代理不同,它不基于 JMS。相反,你的应用程序通过一个平台中立的、线级协议与它通信:高级消息队列协议 (AMQP)。幸运的是,已经有一个 Java 客户端库,并且 SpringSource 正在努力实现一流的 Spring 和 Grails 集成——所以不用担心使用 RabbitMQ 需要进行低级操作。你甚至可以找到暴露 JMS 接口的 AMQP 客户端库。但是 AMQP 的操作方式与 JMS 有足够大的差异,这可能会给习惯于 JMS 模型的 Java 开发者带来困扰。
为了简化过渡,我将在本文中探讨支撑 AMQP 的基本概念以及三个常见的使用场景。最后,你将有望对配置 RabbitMQ 并通过 Spring 和 Grails 提供的 API 使用它有足够的了解。
与任何消息系统一样,AMQP 是一个处理发布者和消费者的消息协议。发布者产生消息,消费者获取并处理它们。消息代理(如 RabbitMQ)的工作是确保发布者的消息发送到正确的消费者。为了做到这一点,代理使用两个关键组件:交换机和队列。下图展示了它们如何将发布者连接到消费者
正如你所见,设置非常简单直接。发布者将消息发送到指定的交换机,而消费者则从队列中拉取消息(或者队列根据配置将消息推送到消费者)。当然,首先必须建立连接,那么发布者和消费者如何相互发现呢?通过交换机的名称。通常,发布者或消费者会创建一个指定名称的交换机,然后公开该名称。如何公开取决于具体情况,但可能会将其放在公共 API 文档中或发送给已知客户端。
消息如何从交换机路由到队列?问得好。首先,队列必须连接到给定的交换机。通常,消费者会创建一个队列并同时将其连接到交换机。其次,交换机收到的消息必须与队列匹配——这个过程称为“绑定”。
要理解绑定,了解 AMQP 消息的结构很有帮助
消息的头部 (headers) 和属性 (properties) 基本上是键/值对。它们之间的区别在于,头部是由 AMQP 规范定义的,而属性可以包含任意的、应用程序特定的信息。实际的消息内容只是一串字节,所以如果你想在消息中传递文本,那么你应该标准化一种编码。UTF-8 是个不错的选择。如果需要,你可以在消息头部指定内容类型和编码,但这显然不太常见。
这与绑定有什么关系?其中一个标准头部称为routing-key代理正是使用它来将消息匹配到队列。每个队列都指定一个“绑定键”,如果该键与routing-key头部的值匹配,队列就会收到消息。
交换机类型的概念使事情稍微复杂化了。AMQP 规范定义了以下四种类型
交换机类型 | 行为 |
---|---|
Direct | 绑定键必须与路由键精确匹配 - 不支持通配符。 |
Topic | 与 Direct 相同,但在绑定键中允许使用通配符。'#' 匹配零个或多个由点分隔的单词,'*' 精确匹配一个此类单词。 |
Fanout | 路由键和绑定键被忽略 - 所有发布的消息都会发送到所有已绑定的队列。 |
Headers |
更新 我修正了关于通配符的信息,它们基于点分隔的单词或术语工作。
例如,假设发布者将路由键为“NYSE”的消息发送到名为“Stocks”的 topic 交换机。如果消费者创建一个连接到“Stocks”的队列,并使用绑定键“#”、“*”或“NYSE”,那么该消费者将收到消息,因为这三个绑定键都匹配“NYSE”。然而,如果消息发布到 direct 交换机,那么如果绑定键是“#”或“*”,消费者将不会收到消息,因为这些字符被视为字面值,而不是通配符。有趣的是,“#.#”也将匹配“NYSE”,尽管路由键没有点。
现在考虑一条路由键为“NYSE.TECH.MSFT”的消息。考虑到消息发送到 topic 交换机,哪些绑定键会匹配它?
绑定键 | 匹配? |
---|---|
NYSE.TECH.MSFT | 是 |
# | 是 |
NYSE.# | 是 |
*.* | 否 |
NYSE.* | 否 |
NYSE.TECH.* | 是 |
NYSE.*.MSFT | 是 |
这真的就是全部了。通过支持每个队列多个消费者以及每个交换机多个队列,提供了灵活性。事实上,一个单独的队列甚至可以绑定到多个交换机。现在让我们看一些这样的场景。
AMQP 代理可以作为客户端和服务之间的 RPC 机制。一般的设置如下所示,使用 direct 交换机
一般顺序如下
从客户端的角度来看,调用可以是阻塞的或非阻塞的。然而,执行其中一种的难易程度取决于所使用的客户端库。
RPC 场景的关键是确保客户端和服务对初始请求使用相同的交换机,并且客户端知道如何指定路由键。
至于回复队列,它通常由客户端创建,然后填充reply_to头部。此外,虽然你可以为回复使用与请求不同的交换机,但更常见的是对请求和回复使用相同的交换机。
JMS 有 topic 队列的概念,确保发布者的消息发送给所有订阅者。通过将多个队列绑定到交换机,你可以在 AMQP 中轻松实现相同的行为,如下所示
更好的是,队列可以通过绑定键过滤它们接收的消息。如果消费者想接收所有消息,那么它可以指定绑定键为“#”——即“匹配任意数量单词”的通配符。对于普通开发者来说,有点令人困惑的是,“*”匹配零个或一个(由点分隔的)单词,正如前面提到的那样。
想象你有一个应用程序,其中有许多需要执行的任务。使用 AMQP,你可以连接多个消费者,以便每个任务都发送给其中一个且仅一个消费者。发布者不关心哪个消费者完成任务,只关心任务完成。这就是工作分发。
配置它非常简单直接,如下图所示
因此,你有一个队列绑定到交换机,并且有多个消费者共享该队列。这种设置保证了无论有多少消费者,只有一个消费者会处理给定的消息。
这些是 AMQP 代理的三种主要使用模式。虽然我分别描述了每种模式,但将它们组合使用是很常见的。例如,在 RPC 模式中,你可以让多个服务共享同一个队列(工作分发)。如何配置交换机和队列完全取决于你,现在你应该有足够的理解来为你的情况制定合适的设置。
在 SpringSource 的 Groovy & Grails 培训课程中,我们强调 Grails 是站在巨人的肩膀上。其中一个巨人就是 Spring。没有它,Grails 根本不可能发展得如此迅速。它可能也没有那么灵活,无法轻松地与企业 Java 系统集成。只需看看可用的插件数量:许多都基于具有 Spring 支持的 Java 库。
在这篇文章中,我想首先看看 Grails 如何使用 Spring,然后介绍如何利用其原始力量和灵活性的各种方法。
这里有一些...
Grails 是一个优秀框架,用于快速轻松地开发 Web 应用程序。你还可以使用大量插件来提供功能或使与其他系统的集成变得轻松愉快。这都很好,但在本文中我想谈谈当你的应用程序增长,并且你开始淹没在控制器、领域类和其他文件的海洋中时会发生什么。
这种模式真正的美妙之处在于,你可以将这些单元聚合成更粗粒度的关注点,因此你最终会在多个层面使用这种模式。例如,假设上面提到的那个 Web 服务...
此版本修复了一些 Bug,发布说明可在JIRA 查看。此版本可从 SpringSource.org 上的项目页面下载。
该项目正在捐赠给 Eclipse 基金会,更名为 Virgo。我们的目标是在适当的时候发布 Virgo 的一个基线版本,该版本的功能将与 dm Server 2.0 等效。更多信息请参阅 Virgo 网站。SpringSource 将为 Virgo 提供商业支持,如同为 dm Server 提供支持一样。
Spring Insight 团队很荣幸地宣布发布 Spring Insight 1.0.0.M3。此版本包含大量新增强功能,可为您带来更高的生产力,并让您的应用程序更快地上线。Spring Insight 作为 tc Server Developer Edition 和 SpringSource Tool Suite 的一部分提供,但您可以在 http://springsource.org/insight 获取新的开发者版本。设置时间通常只需 10 秒。
Spring Insight 团队正在努力开发下一个版本,我们的开发进展顺利,迫不及待地想听到您的反馈和建议。请从 http://springsource.org/insight 获取此版本,并在社区论坛中给我们留言...
《Spring Python 1.1》图书出版了!Spring Python 借鉴了 Spring Framework 和 Spring Security 的概念,并将其应用于 Python 世界。
在这本书中,你将使用依赖注入、面向方面编程、数据访问、事务管理、远程调用和安全来编写代码。稍后在第一个案例研究中,你将构建一个银行 Web 应用,并看到如何协同使用所有这些组件来快速满足你的需求。在第二个案例研究中,你将在构建航班预订系统时集成 Python 和 Java。
书中充满了代码...