MassTransit_消费者的创建
Creating a message consumer
A message consumer is a class that consumes one or more message types, specified by theIConsumer<T>
interface, where T
is the message type.
public class UpdateCustomerConsumer :
IConsumer<UpdateCustomerAddress>
{
public async Task Consume(ConsumeContext<UpdateCustomerAddress> context)
{
await Console.Out.WriteLineAsync($"Updating customer: {context.Message.CustomerId}"); // update the customer address
}
}
When a consumer is subscribed to a receive endpoint, and a message consumed by the consumer is received by the endpoint, an instance of the consumer is created (using a consumer factory, which is covered –> here <–). The message (wrapped in a ConsumeContext
) is then delivered to the consumer via the Consume
method.
The Consume
method is asynchronous, and returns a Task. The task is awaited by MassTransit, during which time the message is unavailable to other receive endpoints. If the consume method completes successfuly (a task status of RanToCompletion), the message is acknowledged and removed from the queue.
Note
If the consumer faults (such as throwing an exception, resulting in a task status of Faulted), or is somehow cancelled (TaskStatus of Canceled), the exception is propagated back up the pipeline where it can ultimately be retried or moved to an error queue.
Connecting a message consumer
For a consumer to receive messages, the consumer must be connected to a receive endpoint. This is done during bus configuration, particularly within the configuration of a receive endpoint.
An example of connecting a consumer to a receive endpoint is shown below.
var busControl = Bus.Factory.CreateUsingRabbitMq(cfg =>
{
var host = cfg.Host(new Uri("rabbitmq://localhost/"), h =>
{
h.Username("guest");
h.Password("guest");
}); cfg.ReceiveEndpoint(host, "customer_update_queue", e =>
{
e.Consumer<UpdateCustomerConsumer>();
});
});
The example creates a bus, which connects to the RabbitMQ running on the local machine, using the default username and password (guest/guest). On that bus. a single receive endpoint is created with the name customer_update_queue. The consumer is connected using the simplest method, which accepts a consumer class with a default constructor.
Note
When a consumer is connected to a receive endpoint, the combined set of message types consumed by all of the consumers connected to the same receive endpoint are subscribed to the queue. The subscription method varies by broker, in the case of RabbitMQ exchange bindings are created for the message types to the exchange/queue for the receive endpoint.
These subscriptions are persistent, and remain in place after the process exits. This ensures that messages published or sent that would be delivered to one of the receive endpoint consumers are saved even is the process is terminated. When the process is started, messages waiting in the queue will be delivered to the consumer(s).
The above example connects the consumer using a default constructor consumer factory. There are several other consumer factories supported, as shown below.
var busControl = Bus.Factory.CreateUsingRabbitMq(cfg =>
{
var host = ...; cfg.ReceiveEndpoint(host, "customer_update_queue", e =>
{
// an anonymous factory method
e.Consumer(() => new YourConsumer()); // an existing consumer factory for the consumer type
e.Consumer(consumerFactory); // a type-based factory that returns an object (container friendly)
e.Consumer(consumerType, type => container.Resolve(type)); // an anonymous factory method, with some middleware goodness
e.Consumer(() => new YourConsumer(), x =>
{
// add middleware to the consumer pipeline
x.UseLog(ConsoleOut, async context => "Consumer created");
});
});
});
Connecting to an existing bus
Once a bus has been created, the receive endpoints have been created and cannot be modified. The bus itself, however, provides a temporary (auto-delete) queue which can be used to receive messages. To connect a consumer to the bus temporary queue, a series of Connect methods can be used.
Warning
Published messages will not be received by the temporary queue. Because the queue is temporary, when consumers are connected no bindings or subscriptions are created. This makes it very fast for transient consumers, and avoid thrashing the message broker with temporary bindings.
The temporary queue is useful to receive request responses and faults (via the response/fault address header) and routing slip events (via an event subscription in the routing slip).
var busControl = Bus.Factory.CreateUsingRabbitMq(cfg =>
{
var host = ...;
}); busControl.Start(); ConnectHandle handle = busControl.ConnectConsumer<FaultConsumer>();
...
handle.Disconnect(); // disconnect the consumer from the bus pipeline
In addition to the `ConnectConsumer`
method, methods for each consumer type are also included (`ConnectHandler`
, `ConnectInstance`
, `ConnectSaga`
, and `ConnectStateMachineSaga`
).
Connecting an existing consumer instance
While using a consumer instance per message is highly suggested, it is possible to connect an existing consumer instance which will be called for every message. The consumer must be thread-safe, as the`Consume`
method will be called from multiple threads simultaneously. To connect an existing instance, see the example below.
var busControl = Bus.Factory.CreateUsingRabbitMq(cfg =>
{
var host = ...; cfg.ReceiveEndpoint(host, "customer_update_queue", e =>
{
e.Instance(existingConsumer);
});
});
Handling undeliverable messages
If the configuration of an endpoint changes, or if a message is mistakenly sent to an endpoint, it is possible that a message type is received that does not have any connected consumers. If this occurs, the message is moved to a _skipped queue (prefixed by the original queue name). The original message content is retained, and additional headers are added to indicate the host which moved the message.
Handling messages without a consumer
While creating a consumer is the preferred way to consume messages, it is also possible to create a simple message handler. By specifying a method, anonymous method, or lambda method, a message can be consumed on a receive endpoint.
To configure a simple message handler, refer to the example below.
var busControl = Bus.Factory.CreateUsingRabbitMq(cfg =>
{
var host = ...; cfg.ReceiveEndpoint(host, "customer_update_queue", e =>
{
e.Handler<UpdateCustomerAddress>(context =>
return Console.Out.WriteLineAsync($"Update customer address received: {context.Message.CustomerId}"));
});
});
In this case, the method is called for each message received. No consumer is created, and no lifecycle management is performed.
Observing messages via IObserver
With the addition of the IObserver
interface, the concept of an observer was added to the .NET framework. MassTransit supports the direct connection of observers to receive endpoints.
Note
Unfortunately, observers are not asynchronous. Because of this, it is not possible to play nice with the async support provided by the compiler when using an observer.
An observer is defined using the built-in IObserver<T>
interface, as shown below.
public class CustomerAddressUpdatedObserver :
IObserver<ConsumeContext<CustomerAddressUpdated>>
{
public void OnNext(ConsumeContext<CustomerAddressUpdated> context)
{
Console.WriteLine("Customer address was updated: {0}", context.Message.CustomerId);
} public void OnError(Exception error)
{
} public void OnCompleted()
{
}
}
Once created, the observer is connected to the receive endpoint similar to a consumer.
var busControl = Bus.Factory.CreateUsingRabbitMq(cfg =>
{
var host = ...; cfg.ReceiveEndpoint(host, "customer_update_queue", e =>
{
e.Observer<CustomerAddressUpdatedObserver>();
});
});
MassTransit_消费者的创建的更多相关文章
- MassTransit_契约的创建
消息契约的命名规范 命令模式:动词+对象 事件模式:对象+动词 不同模式下要求不同的主键 Creating a message contract In MassTransit, a message c ...
- springcloud-Netflix创建服务消费者
目录 springcloud-Netflix创建服务消费者 Ribbon 创建服务消费者-Ribbon方式 ribbon的架构 Feign 创建包和基本项目结构 创建Feign访问服务的接口和访问co ...
- 161130、Dubbo+SpringMVC工程创建详解
Dubbo出现的目的是为了应对现在高并发,高数据量请求的问题.目前的垂直应用架构已经无法满足现在大数据的冲击,SOA就应运而生,而Dubbo在国内使用的还是比较多,稳定性也比较不错. 架构 节点角色说 ...
- Linux多线程之同步2 —— 生产者消费者模型
思路 生产者和消费者(互斥与同步).资源用队列模拟(要上锁,一个时间只能有一个线程操作队列). m个生产者.拿到锁,且产品不满,才能生产.当产品满,则等待,等待消费者唤醒.当产品由空到不空,通知消费者 ...
- 翻译:使用 Redux 和 ngrx 创建更佳的 Angular 2
翻译:使用 Redux 和 ngrx 创建更佳的 Angular 2 原文地址:http://onehungrymind.com/build-better-angular-2-application- ...
- nopCommerce 3.9 大波浪系列 之 事件机制(生产者、消费者)
一.nop事件机制简介 应用场景:客户支付成功后,需要发送短信.邮件告知客户订单支付成功(短信.邮件由不同模块实现) 实现方法: 1.定义支付成功OrderPaidEvent事件. 2.定义短信,邮箱 ...
- Springboot+ActiveMQ(ActiveMQ消息持久化,保证JMS的可靠性,消费者幂等性)
ActiveMQ 持久化设置: 在redis中提供了两种持久化机制:RDB和AOF 两种持久化方式,避免redis宕机以后,能数据恢复,所以持久化的功能 对高可用程序来说 很重要. 同样在Active ...
- Kafka技术内幕 读书笔记之(五) 协调者——消费者加入消费组
消费者客户端轮询的3个步骤:发送拉取请求,客户端轮询,获取拉取结果 . 消费者在发送拉取请求之前,必须首先满足下面的两个条件.- 确保消费者已经连接协调者, 即找到服务端中管理这个消费者的协调者节点 ...
- Redux 和 ngrx 创建更佳的 Angular 2
Redux 和 ngrx 创建更佳的 Angular 2 翻译:使用 Redux 和 ngrx 创建更佳的 Angular 2 原文地址:http://onehungrymind.com/build- ...
随机推荐
- 如何使用vs将现有的项目或者文件夹(尤其是多层目录的)添加到项目中
困扰我这么久的问题,哎,真心弱爆了! 1.将现有项目或文件夹拷贝到指定目录下 2.解决方案右上有个显示所有文件的按钮 然后选中所有要添加的文件,右击 选择包含到项目中即可
- Xamarin.Android之下拉刷新
一.前言 当今任何一个App中只要存在列表,基本上都会使用下拉刷新,而身为Xamarin一族的我们自然也不会落后,下面笔者将带领大家在Xamarin下实现Android中的下拉刷新的效果. 二.准备工 ...
- jeesite笔记
环境 Github上的不能初始化数据库:https://github.com/thinkgem/jeesite 官网上的可以: http://jeesite.com/ 用 Idea 打开,修改 \sr ...
- 重装Eclipse、离线安装ADT、Android SDK
由于最新的ADT.Android SDK需要最新版本的Eclipse才能使用,我无奈的只好升级Eclipse.看看自己的Eclipse已经两年没有升级了,也是时候升级了.升级前,有很多的顾虑.因为像这 ...
- 实验三 组合逻辑电路的VHDL设计
一.实验目的 熟悉QuartusⅡ的VHDL文本设计过程,学习简单组合逻辑电路的设计.仿真和测试方法. 二.实验内容 1. 基本命题 完成2选1多路选择器的文本编辑输入(mux21a.vhd)和仿真测 ...
- Atitit.常用的gc算法
Atitit.常用的gc算法 1.1. 记-清除算法1 1.2. 复制算法1 1.3. 标记-整理算法2 1.4. 分代收集算法2 1.1. 记-清除算法 最基础的收集算法,算法分为标记和清除两个阶段 ...
- 更改Windows系统的密码之后,SQL Server 2008服务无法启动
问题:更改Windows操作系统的密码之后,SQL Server 2008服务无法启动. 原因:SQL Server服务需要使用操作系统的某个登录账户. 解决:需要在服务的属性窗口中修改账户密码,然后 ...
- Dom4J解析xml文件动态转换为List<Bean>或者Map集合
大家在解析大量相似xml文件的时候是否会遇到这样一个问题:冗余的代码去set定义的实体对象Bean的值,基本都是一样的操作 而且毫无任何代码价值可言所以在这写了一个简单的例子,类封装了几个方法你只 ...
- ActiveMQ 使用
ActiveMQ资料大全 官方文档 入门:http://activemq.apache.org/getting-started.html 常见问题:http://activemq.apache.org ...
- MinStack
Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. pu ...