译MassTransit 创建消息消费者
创建消息消费者
一个消息消费者是一个 可以消费一个或多个消息类型的类,指定IConsumer<T>接口,T为消息类型
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
}
}
当消费者订阅接收端点时,由端点接收消费者所消费的消息。创建一个消费者实例(using a consumer factory, which is covered(覆盖) --> here <--)然后,通过Consume方法将消息(包裹在 ConsumeContext)传递给消费者。
Consume方法是异步的,并返回一个task。。MassTransit 等待该任务, 在此期间消息对其他接收端点不可用。如果consume 方法成功完成 (RanToCompletion 的task状态),则消息将被确认并从队列中删除。
注意:如果消费者错误(例如抛出异常,导致Faulted的任务状态),或者以某种方式被取消cancelled (被取消的Canceled任务状态),则异常被传播回管道,在那里它可以最终被重试或移动到错误队列。
连接消息消费者
对于消费者接收消息,消费者必须连接到接收端点。这是在总线配置期间进行的,尤其是在接收端点的配置中。
下面显示了将消费者连接到接收端点的示例。
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>();
});
});
该示例创建一个总线,该总线使用使用默认的用户名和密码(Guest/Guest)连接到在本地机器上运行的RabbitMQ,.在那个总线上.使用命名customer_update_queue创建单个接收端点。使用最简单的方法连接消费者,该方法接受具有默认构造函数的消费者类。
注意:当一个消费者连接到一个接收端点时,由连接到同一个接收端点的所有消费者所消费的组合消息类型被*subscribed*订阅到队列中。(in the case of RabbitMQ exchange bindings are created for the message types to the exchange/queue for the receive endpoint.)订阅方法因broker代理而异,在RabbitMQ Exchange绑定的情况下,将消息类型创建为接收端点的Exchange /queue。这些订阅是持久的,并在进程退出后保持不变。这样可以确保发布或发送的消息交付到接收端点消费者之一,即使进程终止。当进程启动时,队列中等待的消息将交付给消费者。
上面的示例使用默认构造函数消费者工厂来连接消费者。有几个其他的消费工厂支持,如下所示。
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");
});
});
});
连接到现有总线
一旦创建了总线,就会创建接收端点,无法修改。然而,总线本身提供了一个临时的(自动删除)队列,可以用来接收消息。为了将消费者连接到总线临时队列,可以使用一系列连接方法。
警告:临时队列将不接收已发布的消息。由于队列是临时的,当消费者连接时,不会创建绑定或订阅。这使得它对于临时消费者非常快,并且避免用临时绑定来击乱消息代理。
临时队列对于接收请求响应和故障(via the response/fault address header)和路由滑移事件(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
除了 ConnectConsumer 方法之外, 还包括每个消费者类型的方法 (ConnectHandler、ConnectInstance、ConnectSaga 和 ConnectStateMachineSaga)。
连接现有的消费者实例
虽然强烈建议使用每个消息的消费者实例,但可以连接一个现有的消费者实例,每个实例都将调用该实例。消费者必须是线程安全的,因为消费方法将同时从多个线程调用。若要连接现有实例,请参见下面的示例。
var busControl = Bus.Factory.CreateUsingRabbitMq(cfg =>
{
var host = ...; cfg.ReceiveEndpoint(host, "customer_update_queue", e =>
{
e.Instance(existingConsumer);
});
});
处理无法传递的消息
如果端点的配置改变,或者如果消息被错误地发送到端点,则可能接收到没有任何连接的消费者的消息类型。如果发生这种情况,则将消息移动到_skipped队列(由原始队列名称前缀)。保留原始消息内容,并添加附加标题来指示移动消息的主机。
处理没有消费者的消息
虽然创建消费者是首选的消息消费方式,但也有可能创建一个简单的消息处理程序。通过指定方法、匿名方法或lambda方法,消息可以在接收端点上被消耗。若配置简单的消息处理程序, 请参阅下面的示例。
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}"));
});
});
在这种情况下,对接收到的每个消息都调用该方法。没有创建消费者,也不执行生命周期管理。
通过 IObserver 观察消息
通过添加IObserver 接口,将观察者的概念添加到.NET Framework中。MassTransit 支持观察者直接连接接收端点。
可惜,观察者不是异步的。因此,当使用观测者时,无法对编译程序提供的异步支持进行良好的运行。
一个观察者使用内置的IObserver<T>接扣定义,如下所示。
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()
{
}
}
一旦创建,观察者连接到接收端点,类似于消费者。
var busControl = Bus.Factory.CreateUsingRabbitMq(cfg =>
{
var host = ...; cfg.ReceiveEndpoint(host, "customer_update_queue", e =>
{
e.Observer<CustomerAddressUpdatedObserver>();
});
});
译MassTransit 创建消息消费者的更多相关文章
- SpringCloud系列十一:SpringCloudStream(SpringCloudStream 简介、创建消息生产者、创建消息消费者、自定义消息通道、分组与持久化、设置 RoutingKey)
1.概念:SpringCloudStream 2.具体内容 2.1.SpringCloudStream 简介 SpringCloudStream 就是使用了基于消息系统的微服务处理架构.对于消息系统而 ...
- 译MassTransit 生产消息
生产消息 应用程序或服务可以使用两种不同的方法生产消息.可以使用Sead发送消息,也可以使用Publish发布消息.每个方法的行为是非常不同的,但是通过查看每个特定方法所涉及的消息类型,可以很容易理解 ...
- 译MassTransit 消息契约
消息契约 在MassTransit中,使用.NET .NET系统定义消息契约.消息可以使用类和接口来定义,但是,建议类型使用只读属性而不使用行为. 注意:强烈建议使用消息接口的接口,基于多年的经验,具 ...
- Intellij IDEA 创建消息驱动Bean - 接收JMS消息
除了同步方式的调用之外,有时还需要异步调用,用来处理不需要即时处理的信息,例如短信.邮件等,这需要使用EJB中的独特组件——消息驱动Bean(Message-Driven Bean,MDB),它提供了 ...
- pull类型消息中间件-消息消费者(二)
消费者的实例化 关于consumer的默认实现,metaq有两种: DefaultMQPullConsumer:由业务方主动拉取消息 DefaultMQPushConsumer:通过业务方注册回调方法 ...
- activemq消息生产者与消息消费者简单例子
消息生产者HelloQueueProducer.java package activemq.test; import javax.jms.Connection;import javax.jms.Con ...
- kafka 0.10.2 消息消费者
package cn.xiaojf.kafka.consumer; import org.apache.kafka.clients.consumer.ConsumerConfig; import or ...
- springcloud-Netflix创建服务消费者
目录 springcloud-Netflix创建服务消费者 Ribbon 创建服务消费者-Ribbon方式 ribbon的架构 Feign 创建包和基本项目结构 创建Feign访问服务的接口和访问co ...
- 创建服务消费者(Feign)
概述 Feign 是一个声明式的伪 Http 客户端,它使得写 Http 客户端变得更简单.使用 Feign,只需要创建一个接口并注解.它具有可插拔的注解特性,可使用 Feign 注解和 JAX-RS ...
随机推荐
- Sharepoint 2010 自定义WebService 找不到网站应用程序
错误描述:Net 开发WebService调用Microsoft.SharePoint.dll的服务器端对象模型,出现找不到网站的应用程序,或者出现500错误. 错误截图: [Webservice调用 ...
- 关于masm中PTR伪指令的一点思考
在masm中,PTR伪指令只能修饰内存变量类型,因为任何寄存器的大小都是已知的且不能改变的(如果PTR修饰的是寄存器,则它修饰的是寄存器本身而不是其指向的内容)所以不能用PTR改变寄存器的大小,例如: ...
- How--to-deploy-smart-contracts-on
The following smart contract code is only an example and is NOT to be used in Production systems. pr ...
- Thinkphp3.2简单解决多文件上传只上传一张的问题
html简单页面: index.html代码: <form action="{:U('index/upload')}" method="post" enc ...
- 《MySQL必知必会》读书笔记_2
通配符:(尾空格可能会干扰通配符匹配) % 匹配任意字符 _ 匹配任意单个字符 正则表达式:REGEXP 用法就是替换掉LIKE的位置,后面配合正则表达式. 默认不区分大小写,如果区分的话添加关键字B ...
- 我如何踏上IT路
第一次开技术博客,第一篇博文就聊聊自己是如何走上IT这条路的.一直听人说"搞IT的"颇含贬低色彩,也有IT前辈奉劝不要轻易踏上这条路,但最终我这个本是化学化工专业的门外汉还是义无反 ...
- 多台或者集群环境下如何保证spring定时器只执行一个
先说一下我们的系统, 在65和66上分别部署有weblogic节点,共计四个,在项目中我们的定时器会隔一段时间就从其它的五个系统中取数据,这时就出现了问题,本来取一次数据就可以的,现在重复执行了三次, ...
- require、缓存
什么是require? -Node使用CommonJS模块规范,内置require函数用于加载模块文件 -require的基本功能是>读入并执行一个javascript文件,然后返回该模块的ex ...
- OpenApi开放平台架构实践
背景 随着业务的发展,越来越多不同系统之间需要数据往来,我们和外部系统之间产生了数据接口的对接.当然,有我们提供给外部系统(工具)的,也有我们调用第三方的.而这里重点讲一下我们对外的接口. 目前,我们 ...
- 洛谷 P1490 解题报告
P1490 买蛋糕 题目描述 野猫过生日,大家当然会送礼物了(咳咳,没送礼物的同志注意了哈!!),由于不知道送什么好,又考虑到实用性等其他问题,大家决定合伙给野猫买一个生日蛋糕.大家不知道最后要买的蛋 ...