NServiceBus 简介
相比BizTalk更接近WCF
每当人们听到“服务总线”这个术语,他们变想象出了一个类似于BizTalk的位于所有通信中间的盒子。其实这样的描述是经纪人架构描述,而非总线架构描述。一个总线不一定是一个物理实体,在这方面,NServiceBus比起BizTalk它更类似于WCF。
没有物理的一个WCF可以指向网络拓扑。WCF是给定应用代码的运行中的程序基础设施的一部分,在这一点上,NServiceBus是相同的。就像可以写你自己的主机进程和显式激活WCF,用NServiceBus可以做同样的事情。 NServiceBus总线是虚拟运行在各种的应用进程的框架对象的集合。你可以认为这是一个对点对点网状,与你的代码一起运行,如下图所示:
不同点?
[就像苹果和橙子的不同点.]
NServiceBus的原则让它在过去几十年中是稳健的。 NServiceBus是基于排队的消息是久经考验撑起通过无数的技术转变,不仅仅是一个实现选择,这是一个主要的架构理念。在NServiceBus没有什么是作为一个阻塞调用的。
作为一个通用的通信技术,WCF并不强制使用排队的消息传递模式。 而NServiceBus是强制的,这对架构的影响是深远的。
当使用WCF支持的传统的RPC技术进行系统开发时,可以简单并直接的让其工作,这时,问题也开始出现,扩展性和容错性受到了RPC原则天生的限制,就这一点,解决这些问题几乎是不可能的,即使投入更多的硬件也没有什么效果,虽然WCF不会强制开发者但也不会阻止他们这样做。NServiceBus在一开始就引导远离这些问题。
NServiceBus与SOA
健壮的通信模式是单向通信,也被称作发射后忘记。由于它可能需要跨网络与另一台计算机通信的时间量是未知的,无界的,通信是基于在一个存储和转发的模型,如在下面的图中示出。
存储转发消息机制
在这个模型中,当客户端调用API发送一个消息给服务器进程时,在消息发送之前API返回控制给调用线程.这一点上,消息通过网络的传输成为了消息技术的职责,可能有很多不同的通信接口,服务器可能关闭了或是有防火墙降低了传输 。而正在发生的这一切客户端浑然不觉,像线程(给它分配的内存等)这样的关键资源不会保持到调用完成。这样可以防止客户端进程丧失稳定而许多线程和他们所有的内存耗尽来等待其他机器或过程的响应。
请求/响应和单向消息机制
常见的模式请求/响应被更准确的称之为同步远程过程调用。与使用单向消息的处理方式不同。不是让调用线程的堆栈来管理通信交互的状态,而是明确的。从一个网络角度来看请求/响应只不过是两个单向交互。如下图所示:
这种通信是对服务器尤其重要,因为现在有问题的网络连接后面的客户端服务器的稳定性影响不大。如果客户端崩溃,它发送请求,直到服务器发送一个响应之间的时间,服务器将不会有资源捆绑起来等待分钟和分钟,直到连接超时。
发布/订阅
在这种形式中,消息的发送方通常不会知道谁想要接受消息。
订阅
订阅者需要知道那个端点有责任给出消息。这个信息通常是契约中的一部分.
记住,发布者可能会选择用户感兴趣的消息在一个高度可用的方式来存储信息。这使得在多台机器上的多个进程向所有用户发布消息,而不管是否已经收到一个订阅消息或是没有收到。
订阅者不一定非得自行注册。通过使用返回地址模式,一个中央配置站可以发送多封邮件,每个订阅者,指定哪些用户端点订阅消息。
Another option that can be used is for multiple physical subscribers to make themselves appear as one single logical subscriber. This makes it possible to load balance the handling of messages between multiple physical subscribers without any explicit coordination on the part of the publisher or the part of any one subscriber. All that is needed is for all subscribers to specify the same return address in the subscription message.
Publishing
Publishing a message involves having the message arrive at all endpoints that previously subscribed to that type of message.
发布一个消息包含到达所有的端点之前认购该类型的消息。
Messages that are published often represent events or things that have happened; for instance, Order Cancelled, Product Out of Stock, and Shipping Delayed. Sometimes, the cause of an event is the handling of a previous command message, for instance Cancel Order. A publisher is not required to publish a message as a part of handling a command message although it is the simplest solution.
消息被发送时通常被表示为时间或者事情发生了,例如:订单取消,产品出库,发货推后。有时,一个事件的原因是处理前一条命令消息,例如取消订单。一个发布者不需要发布一条作为命令处理消息一部分的消息,即使这是一个简单的解决方案。
Since many command messages can be received in a short period of time, publishing a message to all subscribers for every command message multiplies the incoming load and, as such, is a less than optimal solution. A better solution has the publisher rolling up all the changes that occurred in a given period of time into a single published message. The appropriate period of time depends on the Service Level Agreement of the publisher and its commitment to the freshness of the data. For instance, in the financial domain the publishing period may be 10ms, while in the business of consumer e-commerce, a minute may be acceptable.
由于很多命令消息可以在很短的时间内收到,为每条命令消息发布消息给所有的订阅者加大了输入负载,一个更好的方案是
Another advantage of publishing messages on a timer is that that activity can be offloaded from the endpoint/server processing command messages, effectively scaling out over more servers.
Command query separation
Many systems provide users with the ability to search, filter, and sort data. While one-way messaging and publish/subscribe are core components of the implementation of these features, the way they are combined is not at all like a regular client-server request/response.
In regular client-server development, the server provides the client with all CRUD (create, read, update, and delete) capabilities. However, when users look at data they do not often require it to be up-to-date to the second (given that they often look at the same screen for several seconds to minutes at a time). As such, retrieving data from the same table as that being used for highly consistent transaction processing creates contention, resulting in poor performance for all CRUD actions under higher load.
A solution that avoids this problem separates commands and queries at the system level, even above that of client and server. In this solution there are two "services" that span both client and server: one in charge of commands (create, update, delete), and the other in charge of queries (read). These services communicate only via messages; one cannot access the database of the other, as shown in the following diagram:
The command service publishes messages about changes to data, to which the query service subscribes. When the query service receives such notifications, it saves the data in its own data store which may well have a different schema (optimized for queries like a star schema). The query service may also keep all data in memory if the data is small enough.