spring mvc拆分_Spring集成–强大的拆分器聚合器

spring mvc拆分

健壮是什么意思?

在本文的上下文中,健壮性是指在不立即返回给调用者的情况下管理流中的异常条件的能力。 在某些处理方案中, n m个回答足以做出结论。 通常具有这些趋势的示例处理场景是:

  1. 财务,保险和预订系统的报价。
  2. 扇出出版系统。

为什么我们需要鲁棒的分离器聚合器设计?

首先,可能需要对典型的Splitter Aggregator模式进行介绍。 拆分器是一种EIP模式,它描述了一种机制,用于将复合消息分解为多个部分,以便可以分别处理它们。 路由器是一种EIP模式,用于将消息路由到各个通道中-将它们瞄准特定的消息传递端点。 聚合器是一种EIP模式,用于整理和存储属于一个组的一组消息,并在该组完成后释放它们。

这三个EIP构造共同构成了一种强大的机制,可将处理划分为不同的工作单元。 Spring Integration(SI)使用与EIP相同的模式术语,因此该方法的读者将非常熟悉Spring Integration Framework的构造。 SI框架允许对所有这三个结构进行大量自定义,此外,就像在任何其他多线程配置中一样,只需使用异步通道即可使这些工作单元并行执行。

与SI Splitter Aggregator设计一起使用时,一个有趣的挑战是构建适当健壮的流,这些流在许多调用方案中都可以预测地运行。 一个简单的拆分器聚合器设计可以在许多情况下使用,并且无需大量定制SI构造即可运行。 但是,某些服务要求需要更强大的处理策略,因此需要更复杂的配置。 以下各节描述并显示了简单拆分器聚合器设计的实际外观,设计必须能够处理的处理类型,然后为更健壮的处理提供建议的解决方案。

简单的拆分器聚合器设计

以下Splitter Aggregator设计显示了一个简单的流程,该流程将文档请求消息接收到消息传递网关中,将消息分为两个处理路由,然后聚合响应。 请注意,该图是从OmniGraffle中的EIP构造构建的,而不是从STS内部的“集成图”视图。 为了简洁起见,图中没有显示通道。

SI的详细构造:

消息传递网关 –有三个消息传递网关。 有多种配置可用于网关规范,但可以显着地返回业务对象,异常和空值(超时后)。 最左边的网关是我们为其定义流程的服务网关。 路由器和聚合器之间的其他两个网关是外部系统,它们将提供对我们流程产生的业务问题的响应。

拆分器 –存在单个拆分器,它负责使用文档消息并生成消息集合以进行后续处理。 最常用的自定义拆分器的Java签名指定单个对象参数和用于返回的集合。

收件人列表路由器 –存在一个路由器,可以使用任何适当的路由器,选择与您的要求最接近的路由器–您可以轻松地按表达式或有效负载类型进行路由。 路由器的主要目的是路由分离器提供的消息集合。 这是一个非常典型的拆分器聚合器配置。

聚合器 –单个构造,负责将消息收集在一起,以便可以对网关响应进行进一步处理。 尽管可以使用属性和Bean定义来配置Aggregator,以提供替代的分组和发布策略,但是大多数情况下,默认的聚合策略就足够了。

拆分器聚合器操作的有趣方面

  1. 网关 –入站网关(最左边的一个)上可能有也可能没有定义错误处理bean引用。 如果是这样,那么该bean将有机会处理该网关右侧的流中引发的异常。 如果没有,任何异常将直接抛出网关。
  2. 网关 –可以在每个网关上设置一个可选的默认回复超时 ,设置此值有很大的含义,请确保它们被很好地理解。 超时将导致网关返回空值 。 如果上游网关也没有设置默认应答超时 ,则这是可能导致线程驻留的完全相同的条件。
  3. 分配器输入通道 –这可以是简单的直接通道,也可以是定义了调度程序的直接通道。 如果通道指定了调度程序,则此点的下游流将是异步的多线程的。 这也改变了上游网关的语义,因为它通常意味着原本不重要的default-reply-timeout变为活动状态。
  4. 拆分器 –拆分器必须返回单个对象。 拆分器返回的单个对象是一个集合java.util.List。 SI框架将采用该列表的每个成员,并将其馈入Splitter的输出通道 –与本示例一样,通常直接进入路由器。 “拆分器列表”返回的合同与在Java中的用法相同-它可能包含零个,一个或多个元素。 如果拆分器返回一个空列表,则路由器不太可能要做任何工作,因此流调用将完成。 但是,如果列表包含一项,则SI框架将从列表中提取该项并将其推送到路由器,如果路由成功,则流程将继续。
  5. 路由器 –在此示例中,路由器将仅将消息路由到两个网关之一。
  6. 网关 –在拆分器和聚合器之间使用的两个网关很有趣。 在此示例中,我使用通用网关EIP模式表示消息子系统,但未明确定义-我们可以使用HTTP出站网关,另一个SI流或任何其他外部系统。 当然,对于那些子系统中的每一个,许多响应都是可能的。 取决于协议和外部系统,消息请求可能无法发送,响应未能到达,调用了长时间运行的进程,网络错误或超时或常规处理异常。
  7. 聚合器 –单个聚合器将等待大量响应,具体取决于拆分器创建的内容。 在拆分器返回列表为空的情况下,将不会调用聚合器。 如果“拆分器”返回列表只有一个条目,则聚合器将等待一个网关响应来完成该组。 如果“拆分器”列表有n个条目,则聚合器将等待n个条目来完成该组。 可以将自定义关联策略,发布策略和消息存储库注入到一组丰富的配置方面。

简单拆分器聚合器操作的有趣方面

确定这种类型的简单网关是否足以满足要求的主要决定因素是了解发生故障时发生的情况。 如果您的SI流中发生任何异常导致流调用被放弃并且符合您的要求,则无需进一步阅读。 但是,如果您需要在其中一个网关发生故障后继续处理,那么本文的其余部分可能会引起您的更多兴趣。

拆分器和聚合器之间生成的任何来源的异常都将导致聚合器丢弃空的或部分的组。 异常将传播回最近的上游网关,以供自定义bean处理或由网关重新抛出。 请注意,聚合器上的自定义释放策略很难使用,尤其是与超时一起使用,但在这种情况下无济于事,因为异常将在调用聚合器之前传播回最左边的网关。

也可以在最内部的网关上配置异常处理程序,可以捕获异常消息,但是如何将消息从定制异常处理程序路由到聚合器以完成组,将聚合器通道定义注入到定制异常处理程序中呢? 这是一种较差的方法,可能涉及解包异常消息有效负载,将原始消息标头复制到新的SI消息中,然后添加原始有效负载–只有四到五行代码,但是很脏。

在生成异常之后,无法将异常消息( 未经修改 )路由到聚合器中以完成组。 原始消息(包含有关组和组位置的相关ID和序列ID的消息)被掩埋在SI消息异常有效载荷内。

如果在异常生成之后需要继续处理,则必须清楚,为了继续处理,必须进行以下操作:

  • 聚合组需要完成,
  • 返回到壁橱上游网关之前,必须捕获并处理所有异常,
  • 允许在聚合器中完成组的相关性和序列标识符埋在异常消息有效负载之内,并且将需要提取和设置绑定到聚合器的消息

更健壮的解决方案–邮件网关适配器模式

处理网关的异常和空返回值自然会导致一种设计,该设计在消息传递网关周围实现包装器。 这提供了否则将很难建立的控制级别。

这种适配器技术允许在将消息传递网关注入到Service Activator中并从中直接调用时,捕获并处理消息传递网关的所有返回。 消息传递网关不再直接响应聚合器,而是响应在Service Activator名称空间定义中配置的自定义Java代码Spring bean。 不出所料,不会发生异常的处理将继续正常进行。 那些经历异常情况或消息传递网关出现意外响应或缺少响应的流需要以某种方式处理消息,例如可以完成绑定到聚合的消息组。 如果Service Activator允许将异常传播到其支持bean之外,则该组将无法完成。 同样的情况不仅适用于异常,而且不包含前提条件组相关ID和序列标头的任何返回对象-这就是应用适配的地方。

捕获和处理来自消息传递网关的异常消息或空响应,如以下示例代码所示:

import com.l8mdv.sample.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.integration.Message;
import org.springframework.integration.MessageHeaders;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.util.Assert;public class AvsServiceImpl implements AvsService {private static final Logger logger= LoggerFactory.getLogger(AvsServiceImpl.class);public static final String MISSING_MANDATORY_ARG= "Mandatory argument is missing.";private AvsGateway avsGateway;public AvsServiceImpl(final AvsGateway avsGateway) {this.avsGateway = avsGateway;}public Message<AvsResponse> service(Message<AvsRequest> message) {Assert.notNull(message, MISSING_MANDATORY_ARG);Assert.notNull(message.getPayload(), MISSING_MANDATORY_ARG);MessageHeaders requestMessageHeaders = message.getHeaders();Message<AvsResponse> responseMessage = null;try {logger.debug("Entering AVS Gateway");responseMessage = avsGateway.send(message);if (responseMessage == null)responseMessage = buildNewResponse(requestMessageHeaders,AvsResponseType.NULL_RESULT);logger.debug("Exited AVS Gateway");return responseMessage;} catch (Exception e) {return buildNewResponse(responseMessage, requestMessageHeaders,AvsResponseType.EXCEPTION_RESULT, e);}}private Message<AvsResponse> buildNewResponse(MessageHeaders requestMessageHeaders,AvsResponseType avsResponseType) {Assert.notNull(requestMessageHeaders, MISSING_MANDATORY_ARG);Assert.notNull(avsResponseType, MISSING_MANDATORY_ARG);AvsResponse avsResponse = new AvsResponse();avsResponse.setError(avsResponseType);return MessageBuilder.withPayload(avsResponse).copyHeadersIfAbsent(requestMessageHeaders).build();}private Message<AvsResponse> buildNewResponse(Message<AvsResponse> responseMessage,MessageHeaders requestMessageHeaders,AvsResponseType avsResponseType,Exception e) {Assert.notNull(responseMessage, MISSING_MANDATORY_ARG);Assert.notNull(responseMessage.getPayload(), MISSING_MANDATORY_ARG);Assert.notNull(requestMessageHeaders, MISSING_MANDATORY_ARG);Assert.notNull(avsResponseType, MISSING_MANDATORY_ARG);Assert.notNull(e, MISSING_MANDATORY_ARG);AvsResponse avsResponse = new AvsResponse();avsResponse.setError(avsResponseType,responseMessage.getPayload(), e);return MessageBuilder.withPayload(avsResponse).copyHeadersIfAbsent(requestMessageHeaders).build();}
}

注意异常处理块的catch子句的最后一行。 此行代码将相关性和序列标头复制到响应消息中,如果要允许聚合组完成,则这是强制性的,并且在出现异常后总是必需的,如此处所示。

使用这种技术的后果

毫无疑问,在SI配置中引入消息传递网关适配器会使配置更加复杂,难以阅读和遵循。 此处的关键因素是在配置文件中不再存在线性关系。 这是因为Service Activator必须转发引用一个网关或一个在适配Service Activator之前定义的网关-在两种情况下,结果都是相同的。

资源资源

注意:-推动创建此元模式的软件的设计基于以下要求:单个中央风险评估服务将访问许多外部风险评估服务。 为了使服务的客户满意,尽管这些外部服务中的任何一项失败了,调用也必须并行进行并继续进行。 该要求导致了该项目的消息传递网关适配器模式的设计。

  1. Spring集成参考手册
  2. 在建立大型美国金融机构的风险评估流程的背景下,直接与Mark Fisher(SpringSource)讨论了解决此问题的方法。 尽管配置和代码受NDA和版权保护,但可以在本文中表达设计意图和类似代码。

参考: Spring Integration – TechiQuest博客上来自我们JCG合作伙伴 Matt Vickery的强大的Splitter Aggregator 。

翻译自: https://www.javacodegeeks.com/2013/06/spring-integration-robust-splitter-aggregator.html

spring mvc拆分

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

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

相关文章

mysql typeindex_explain mysql的type字段,索引的类型

4.type这列很重要,显示了连接使用了哪种类别,有无使用索引.从最好到最差的连接类型为const、eq_reg、ref、range、indexhe和ALL(1).system这是const联接类型的一个特例。表仅有一行满足条件.如下(t3表上的id是 primary key)mysql> explain select * from (select * from t3 …

JasperReports:棘手的部分

如果您使用Java进行编程的时间足够长&#xff0c;则有可能需要为业务用户生成报告。 就我而言&#xff0c;我已经看到几个项目使用JasperReports库来生成PDF和其他文件格式的报告。 最近&#xff0c;我荣幸地观察了Mike和他的团队使用上述报告库及其面临的挑战。 简而言之Jasp…

win mysql 2003错误_windows MySql 报1067错误 2003错误

1067错误原因是我把安装mysql的目录的名字改了。但是位于目录里面的my.ini配置文件没有修改&#xff0c;玛德我真傻逼。把my.ini的#Path to installation directory. All paths are usually resolved relative to this.basedir"D:/My_MySQL/"这下面一行的路径名改成目…

java heroku_Heroku和Java –从新手到初学者,第1部分

java heroku最近&#xff0c;我听说Heroku允许在Cedar堆栈中部署Java应用程序。 由于没有真正的软件构想&#xff0c;我决定尝试一下&#xff0c;仅配置SOMETHING以在Heroku上运行。 我对ReST有所了解&#xff08;我仍然想学习并练习&#xff09;&#xff0c;所以我决定我的第…

mysql 合服_风云私服合区的方法详解(mysql数据库合并)

只能合并帐号&#xff0c;MY的库不能合并。倒数据前请留好备份&#xff0c;防止发生以外&#xff0c;破坏你得数据&#xff0c;切忌.1)首先确认你的机器上必须装MySQL 以及 mysql-connector-odbc-5.1.1-win32.msimysql-connector-odbc-5.1.1-win32.msi 就是 MySQL ODBC 5.1,你可…

mysql自定义数据类型_MySQL中的数据类型

一.MySQL中的数值类型分类MySQL中数值类型主要有三类&#xff1a;数字类型&#xff0c;字符串类型&#xff0c;时间类型。1.数字类型1.1整数tinyint 1字节smallint 2字节mediumint 3字节int 4字节bigint …

分布式系统开发注意点_分布式系统开发注意事项

分布式系统开发注意点开发分布式软件系统时&#xff0c;要考虑许多因素。 如果您甚至不知道第一句话中我在说什么&#xff0c;那么让我为您提供一些见解&#xff0c;示例以及有关分布式系统的实例。 总览 分布式系统是指多个物理硬件设备与单独的离散用户交互并通过这些硬件设…

String#repeat来到Java吗?

JDK-8197594 &#xff08;“ String&#xff03;repeat”&#xff09;在其“描述”中包括以下内容&#xff1a;“长期以来&#xff0c;一直要求一种用于重复字符序列的String方法&#xff0c;没有后续操作。” 可以在JDK-8197594的“问题链接”中找到有关String类中用于重复字符…

mysql 什么是幻读_何为幻读?MySQL又是如何解决幻读的?

一、什么是幻读在一次事务里面&#xff0c;多次查询之后&#xff0c;查询的结果集的个数不一致的情况叫做幻读。而多出来或者少的哪一行被叫做 幻行二、为什么要解决幻读在高并发数据库系统中&#xff0c;需要保证事务与事务之间的隔离性&#xff0c;还有事务本身的一致性。三、…

电子电气架构——车载ECU刷写工具vFlash简介

电子电气架构——车载ECU刷写工具vFlash简介 我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 没有人关注你。也无需有人关注你。你必须承认自己的价值&a…

mysql执行系统命令_mysql 命令行执行 sql

1.直接输入sql执行MySQL> select now();---------------------| now() |---------------------| 2013-09-18 13:55:45 |---------------------1 row in set (0.00 sec)2.执行编写好的sql脚本mysql> source /home/1.sql---------------------| now() |-------------------…

jboss7.1.1 部署_在JBoss AS 7上部署BroadleafCommerce 2.0

jboss7.1.1 部署前2个步骤实际上与Broadleaf无关&#xff0c;但是提到该步骤是为了使其易于执行&#xff08;复制/粘贴&#xff09;这些步骤。 步骤&#xff03;1&#xff1a;在JBoss AS中配置数据源。 <datasource jta"true" jndi-name"java:jboss/datasou…

java中n次方怎么表示_java如何计算一个数的n次方

java递归算法&#xff0c;代码如下&#xff1a;public class Test3 { public double zhishu(double x,double y){ if(y>0){ return x*zhishu(x,y-1); }else if(y<0){ return (x*zhishu(x,-y-1)); }else{ return 1; } } public double fuzhishu(…

枚举集合的EnumSet

在上一篇博客文章中&#xff0c;我们发现了EnumMap用于带有枚举键的映射。 您可能已经观察到&#xff0c;还有一个专门针对枚举优化的Set &#xff1a; EnumSet 。 我们再次定义一个CoffeeType枚举&#xff1a; public enum CoffeeType {ESPRESSO, POUR_OVER, FRENCH_PRESS, …

linux下mkdir头文件_Linux中判断一个目录是否存在,如果不存在就创建这个目录

在操作文件目录时我们常常会考虑如下的功能&#xff1a;1、判断文件是否存在&#xff0c;并判断文件是否可写/目录是否存在Linux下&#xff1a;#includeint access(const char* pathname, int mode);参数介绍&#xff1a;返回值&#xff1a;成功0&#xff0c;失败-1pathname 是…

mac 连接hbase的图形化界面_MAC安装Hbase以及Hbase基本命令

安装Hbase1&#xff0e;官网下载安装包&#xff0c;我下载的是hbase-2.4.0-bin.tar.gz。2&#xff0e;解压&#xff1a;tar zxf hbase-2.4.0-bin.tar.gz3&#xff0e;安装JDK&#xff0c;并设置JAVA_HOME&#xff0c;通过vi ~/.bash_profile&#xff0c;设置环境变量export JAV…

ldap java_使用LDAP保护Java EE6中的Web应用程序

ldap java在上一篇文章中&#xff0c;我们解释了如何在通过传输层安全性&#xff08;TLS&#xff09;/安全套接字层&#xff08;SSL&#xff09;传输数据时保护数据。 现在让我们尝试了解如何为使用LDAP服务器进行身份验证的基于JEE 6的Web应用程序应用安全机制。 目的&#x…

mysql 一致性hash_一致性hash算法在分表分库中的应用

一致性hash算法结构图 分表分库结构图 可进行循环冗余存储&#xff0c;顺时针存储到下一个物理节点(非虚拟节点)package com.haiziwang.platform.kmcsms.route.algorithm;import java.util.Collection;import java.util.SortedMap;import java.util.TreeMap;/*** 一致性Hash算法…

生产中的性能分析

生产中的性能分析 如果您在Java应用程序的性能方面遇到了一些严重问题&#xff0c;那么很可能您会知道线程分析的价值。 但是您知道应该使用哪个分析器吗&#xff1f; 探查器使用两种基本技术-采样和仪器。 采样分析器 采样探查器包括定期向JVM询问所有当前活动线程的当前执行…

mysql用com_MySQL 使用教程

关于 MySQLMySQL 是最流行的开源数据库。本文简明的讲解了 MySQL 如何下载安装到使用的整个过程。MySQL 支持多种特性&#xff1a;使用 C和 C编写&#xff0c;并使用了多种编译器进行测试&#xff0c;保证了源代码的可移植性。支持 AIX、FreeBSD、HP-UX、Linux、Mac OS、Novell…