为什么80%的码农都做不了架构师?>>>   

本人觉得这一章很重要,那就是 Spring默认的channel 的实现 DirectChannel,这个要大家多按照原文理解,开发者为何提供这样的一个channel,以及该channel适用的场景。

DirectChannel

TheDirectChannelhas point-to-point semantics(语义) but otherwise is more similar to thePublishSubscribeChannelthan any of the queue-based channel implementations described above. It implements theSubscribableChannelinterface instead of thePollableChannelinterface, so it dispatches(分发) Messages directly to a subscriber(订阅者). As a point-to-point channel, however, it differs from thePublishSubscribeChannelin that it will only send each Message to a single subscribed(理解这句话,如果有多个订阅者 该Channel 仅仅选择其中一个订阅者发送,而忽略其他订阅者)MessageHandler.

(PS:DirectChannel 从字面理解是 基于 点对点 传输模式。事实上,他更像是一个 PublishSubscribeChannel 的实现,除了内部实现消息队列机制以外。 该类实现了 SubscribableChannel 接口 而不是 PollableChannel 接口。所以他会直接分发消息给订阅者。 同时作为 点对点 的传输队列,他有不同于传统意义的 PublishSubscribeChannel。他每次仅仅发消息发送给订阅者之一)

In addition to(除了) being the simplest point-to-point channel option, one of its most important features is that it enables a single thread to perform(扮演,充当) the operations on "both sides" of the channel. For example, if a handler is subscribed to aDirectChannel, then sending a Message to that channel will trigger invocation of that handler'shandleMessage(Message)method directly in the sender's thread, before the send() method invocation can return.(这里要是有个时序图就好了,第一次阅读这里是无法理解的,NND,坑爹的老外,伤不起的外语水平)

(PS:除了上述提到的点对点传输模式是 DirectChannel 的特性外,还有一个比较重要的特征就是,该通道允许单线程同时 充当 发送 与接受的角色,例如:一个订阅者 注册到 DirectChannel后,当一个消息发送到该 channel,则直接触发handleMessage(Message)方法在 send 方法执行完之前。)

The key motivation(动机) for providing a channel implementation with this behavior(行为) is to support transactions(事务) that must span across the channel while still benefiting(受益) from the abstraction and loose coupling that the channel provides. If the send call is invoked within the scope of a transaction, then the outcome of the handler's invocation (e.g. updating a database record) will play a role in determining the ultimate result of that transaction (commit or rollback).

(PS:这样做的动机是 为了 让通道两端的操作能包含在一个事务中。大概意思是这样子的,其余的读者自己理解)

Note
Since theDirectChannelis the simplest option and does not add any additional overhead that would be required for scheduling(调度) and managing the threads of a poller, it is the default channel type within Spring Integration. The general idea is to define the channels for an application and then to consider which of those need to provide buffering or to throttle input, and then modify those to be queue-basedPollableChannels. Likewise, if a channel needs to broadcast messages, it should not be aDirectChannelbut rather aPublishSubscribeChannel. Below you will see how each of these can be configured.

(PS:由于 DirectChannel 的简单性,使其无需增加任何额外的开销即可提供调度以及管理线程轮询,这是 Spring Integration 内部默认实现的channel。如果顶一个应用程序的channel,首先需要考虑的是 该channel是否需要提供队列缓存功能,之后是是否需要提供基于优先级策略的PollableChannels, 如果你仅仅是为了实现消息广播,则采用PublishSubscribeChannel是正确的选择而不是DirectChannel。 如下将针对这些配置进行展开描述 )

TheDirectChannelinternally delegates to a Message Dispatcher to invoke its subscribed Message Handlers, and that dispatcher can have a load-balancing(负载均衡) strategy. The load-balancer determines how invocations(调用) will be ordered in the case that there are multiple handlers subscribed to the same channel. When using the namespace support described below, the default strategy is "round-robin"(轮询) which essentially(本质上,基本的) load-balances across the handlers in rotation(轮流).

(PS:DirectChannel 可以充当消息分发的角色定位,并且该分发是基于负载均衡策略。负载均衡实现了对订阅该通道 的消息订阅者按照顺序循环调用。其内部实现的默认策略是 循环 机制。这个是负载均衡的最基本的一种实现。 )

Note
The "round-robin" strategy is currently the only implementation available out-of-the-box(开箱即用) in Spring Integration. Other strategy implementations may be added in future versions.

(PS:这种循环的负载均衡策略已经被 Spring Integration实现,它属于开箱即用 的一种功能。其他的策略需要在以后的版本中加入)

The load-balancer also works in combination with(与.....组 合) a boolean failover(故障转 移) property. If the "failover" value is true (the default), then the dispatcher will fall back to(回滚到) any subsequent(随后的) handlers as necessary when preceding(前面的) handlers throw Exceptions. The order is determined by an optional order value defined on the handlers themselves or, if no such value exists, the order in which the handlers are subscribed(订阅).

(PS:负载均衡 常与 故障转移 配合使用,对于DirectChannel的 failover 值,默认是 开启的。当前一个订阅者调用发生异常 分发器会回滚当前状态到下一个订阅者重新处理,其调用的顺序是由handlers自身的 order 属性决定。如果不存在这样的值 则有订阅者默认的顺序决定。 )

If a certain(某些) situation requires that the dispatcher always try to invoke the first handler, then fallback in the same fixed order sequence every time an error occurs, no load-balancing strategy should be provided. In other words, the dispatcher still supports the failover boolean property even when no load-balancing is enabled. Without load-balancing, however, the invocation of handlers will always begin with the first according to their order. For example, this approach works well when there is a clear definition of primary, secondary, tertiary, and so on. When using the namespace support, the "order" attribute on any endpoint will determine that order.

(PS:假如在某一场景下需要分发器总是尝试调用第一个 handler,发生异常 回滚也是采用固定的序列,不需要负 载均衡的策略支持。换句话说:分发器支持在关闭负载均衡的模式下仍旧对 failover 有效。因此,调用handlers顺序总是 按照第一次排序的顺序进行。例如 当清晰的定义了 第一 、第二 、第三 等顺序,那么这种工作机制将会很好的运行)

Note
Keep in mind that load-balancing and failover only apply when a channel has more than one subscribed Message Handler. When using the namespace support, this means that more than one endpoint shares the same channel reference in(引用) the "input-channel" attribute.

(PS:值得一提的是,无论是负载均衡 还是 故障转移 应用的场景至少该通道多于一个订阅者订阅,当采用命名空间时, 这意味者至少一个以上的endpoint分享统一 channel 通过 input-channel 属性。)

ExecutorChannel

TheExecutorChannelis a point-to-point channel that supports the same dispatcher configuration asDirectChannel(load-balancing strategy and the failover boolean property). The key difference between these two dispatching channel types is that theExecutorChanneldelegates to an instance ofTaskExecutorto perform the dispatch. This means that the send method typically will not block, but it also means that the handler invocation may not occur in the sender's thread. It therefore does not support transactions spanning the sender and receiving handler.

(PS:ExecutorChannel 是 点对点 通道的实现,同时他支持 DirectChannel 的分发器特性,(负载均衡与故障转移)。 两者之间一个显著的不同之处是 ExecutorChannel 内部是通用一个 TaskExecutor 实例实现的。这意味着调用该 通道的 send 方法不会发生阻塞,同时这将意味着 对handler的调用将不会与sender 公用统一线程, 该模式不支持事务,发送与接受分别受限与不同的线程 )

Tip
Note that there are occasions(场合) where the sender may block. For example, when using a TaskExecutor with a rejection-policy(数量限制) that throttles(节 流) back on the client (such as theThreadPoolExecutor.CallerRunsPolicy), the sender's thread will execute the method directly anytime the thread pool is at its maximum capacity and the executor's work queue is full. Since that situation would only occur in a non-predictable way, that obviously(明显) cannot be relied upon for(依 靠,依赖) transactions.

(PS:注意在某些场合下,调用ExecutorChannel 的send 也有可能被阻塞。例如 ,当使用的 TaskExecutor 受管以一个数量限制的客户端(线程池),当池中没有可用的线程是,或者执行队列 当前没有空位是,则会被阻塞。因为这种情况的发生是不可预测的)

Scoped Channel

Spring Integration 1.0 provided aThreadLocalChannelimplementation, but that has been removed as of 2.0. Now, there is a more general way for handling the same requirement(需求) by simply adding a "scope" attribute to a channel. The value of the attribute can be any name of a Scope that is available within the context. For example, in a web environment, certain(特定的,这里是指:session、request、goal等) Scopes are available, and any custom Scope implementations can be registered with the context. Here's an example of a ThreadLocal-based scope being applied to a channel, including the registration of the Scope itself.

(PS:在Spring Integration 1.0 版本中,提供了基于线程范围的 ThreadLocalChannel实例,但是在2.0中被移除了。 现在提供一个更加通用的方法来满足该需求,那就是通过 channel 的scope的属性。该属性的值可以是在Spring 容器中可被识别的任何值。例如在 web环境中,一些特定的Scope 是可用的。 并且这些都已经被注册到Spring 容器中。如下的代码 展示了 基于线程 范围生命周期的配置,包括这侧 线程Scope 到Srping容器)

<int:channel id="threadScopedChannel" scope="thread"><int:queue /></int:channel><bean class="org.springframework.beans.factory.config.CustomScopeConfigurer"><property name="scopes"><map><entry key="thread" value="org.springframework.context.support.SimpleThreadScope" /></map></property></bean>

The channel above also delegates to a queue internally, but the channel is bound to(绑定) the current thread, so the contents of the queue are as well. That way the thread that sends to the channel will later be able to receive those same Messages, but no other thread would be able to access them. While thread-scoped channels are rarely(很少,极少) needed, they can be useful in situations(场景) whereDirectChannelsare being used to enforce(执行) a single thread of operation but any reply Messages should be sent to a "terminal" channel. If that terminal channel is thread-scoped, the original sending thread can collect its replies from it.

(PS : 上述的channel 同时作用于其内部的队列。由于channel 绑定了当前的工作线程,所以其内部队列同样被作用。 这样线程不经可以发送,还可以接受这些消息。当时其他线程是无法访问该channel的。事实上,基于thread-scoped 的channle 很少被用到。一个比较有用的场景是 当通过 DirectChannels 在单线程下执行一个消息发送后任何响应的消息 可以发送到这个终端的 channel 中。如果这个channel 是基于 thread-scoped,那么原先的发送线程可以通过他获取任何响应的消息)

转载于:https://my.oschina.net/qfhxj/blog/95369

#翻译NO.5# --- Spring Integration Framework相关推荐

  1. #翻译NO.3# --- Spring Integration Framework

    为什么80%的码农都做不了架构师?>>>    2.4 Message Endpoints A Message Endpoint represents the "filte ...

  2. #翻译NO.4# --- Spring Integration Framework

    为什么80%的码农都做不了架构师?>>>    Part III. Core Messaging This section covers all aspects of the cor ...

  3. Spring Integration Framework简介

    我们非常了解Spring框架和JMS . 在本文中,我们将介绍称为Spring Integration的企业集成框架 . Spring Integration是一个开源企业集成框架,可增强Spring ...

  4. amqp rabbitmq_通过Spring Integration和RabbitMQ获得高可用性的AMQP支持的消息通道

    amqp rabbitmq Spring Integration消息通道默认情况下将消息存储在内存中. 这是因为内存速度快,易于实现,并且不会增加网络成本. 但是,在某些情况下,这可能会引起问题,因为 ...

  5. 通过Spring Integration和RabbitMQ获得高可用性的AMQP支持的消息通道

    Spring Integration消息通道默认情况下将消息存储在内存中. 这是因为内存速度快,易于实现,并且不会增加网络成本. 但是,在某些情况下,这可能会引起问题,因为如果应用程序崩溃或服务器意外 ...

  6. streaming api_通过Spring Integration消费Twitter Streaming API

    streaming api 1.概述 众所周知, Spring Integration具有用于与外部系统交互的大量连接器. Twitter也不例外,而且很长一段时间以来,因为Spring Social ...

  7. 通过Spring Integration消费Twitter Streaming API

    1.概述 众所周知, Spring Integration具有用于与外部系统交互的大量连接器. Twitter也不例外,而且很长一段时间以来,因为Spring Social一直是一个开箱即用的解决方案 ...

  8. Spring Integration完整示例

    本文是我们名为" Spring Integration for EAI "的学院课程的一部分. 在本课程中,向您介绍了企业应用程序集成模式以及Spring Integration如 ...

  9. 什么是Spring Integration?

    随着Spring Integration项目逐渐获得越来越多的采用和兴趣,企业集成或企业开发领域的开发人员很可能会遇到它. 他们可能会发现它很有趣,但并没有完全理解它的含义,所要解决的问题,可以从中获 ...

最新文章

  1. 远程仓库与 fetch 命令——Git 学习笔记 20
  2. C++中多态性学习(上)
  3. LNMP_静态文件不记录日志,配置缓存
  4. Java: 在dos窗口输入密码,不要把密码直接显示出来,原来可以这么简单
  5. Oracle 关于事物的描述
  6. 超几何分布_常见概率分布
  7. 安全公司正在借 AI 之力,预测、防御并抵抗网络攻击
  8. 第二十七章:五姓七望
  9. python怎么启动服务器_如何在Python单元中从命令行启动服务器
  10. 会计电算化是对用电子计算机处理,会计电算化的意义是什么
  11. Windows Server 2003 R2中的DFS复制与管理
  12. 4行代码,Python搞定美图秀秀!
  13. 合成PDF文档,合并PDF文档
  14. 【软件工程】第一章 软件工程概述 考试重点 复习记录
  15. 如何把大写金额变为小写数字_如何将小写金额转换为大写金额?这几个公式你至少要学会一个……...
  16. ESP8266 在Arduino 使用ST7789 OLED
  17. 内存spd规范_CL14真香,聊聊内存条时序到底是什么?
  18. MIT计算机专业本硕连读几年,麻省理工一般读几年?
  19. 【掌控板-arduino】3.1 SH1106显示图片
  20. 手把手搭建springcloud微服务,使用Eureka

热门文章

  1. Vscode Python输出窗口中文乱码的解决办法
  2. 北斗导航 | 基于MATLAB的卫星轨道模拟
  3. 计算机视觉与深度学习 | 使用HOG特征进行数字分类
  4. mysql表中有重复的元组_MySQL查询找到重复的元组并显示计数?
  5. NASA 顶级程序员是如何编程的?这里有十大准则
  6. CEdit 控件 更新内容的 方法(可以自动滚动至末尾)
  7. mysql数据库五大约束_数据库基础知识:数据库中的约束和三大范式
  8. windows上dmg转换cdr_云主机装黑果实践(6):处理云主机上变色龙启动后置过程:驱动和黑屏...
  9. 如何打造园本特色_立足城市特色 打造赛事品牌——年轻成马如何走向国际化...
  10. 使用gnuplot绘制直方图