Spring-AMQP学习
ConnectionFactory(连接工厂)
连接和资源管理
- CachingConnectionFactory:
- channelCacheSize:控制缓存的channel数
- channelCheckoutTimeout:当这个属性大于0的时候,channelCacheSize变为对一个连接上的通道数的限制,当达到限制,阻塞并等待通道可用,或到达超时,抛出超时异常
- setConnectionNameStrategy():設置连接名的策略
- setPublisherConfirms():启用确认信息
- setPublisherReturns():启用返回信息
AbstractRoutingConnectionFactory:(为多个连接工厂提供lookupKey来映射)
SimpleRoutingConnectionFactory:获取当前线程绑定的lookupKey
SimpleResourceHolder.bind(rabbitTemplate.getConnectionFactory(), vHost); rabbitTemplate.convertAndSend(payload); SimpleResourceHolder.unbind(rabbitTemplate.getConnectionFactory());
LocalizedQueueConnectionFactory:使用队列名作为lookupKey,这种连接工厂用于长连接
- 添加客户端连接配置
connectionFactory.getRabbitConnectionFactory().getClientProperties().put("foo","bar")
Amqp Template(模板)
RabbitTemplate:
添加RetryTemplate
@Bean public RabbitTemplate rabbitTemplate() { RabbitTemplate rabbitTemplate = new RabbitTemplate(); rabbitTemplate.setConnectionFactory(cachingConnectionFactory()); RetryTemplate retryTemplate = new RetryTemplate(); ExponentialBackOffPolicy backOffPolicy = new ExponentialBackOffPolicy(); backOffPolicy.setInitialInterval(500); backOffPolicy.setMaxInterval(10000); retryTemplate.setBackOffPolicy(backOffPolicy); rabbitTemplate.setRetryTemplate(retryTemplate);//设置connect失败之后的策略 return rabbitTemplate; }
启用 Publisher Confirms
rabbitTemplate.setMandatory(true); //注册返回调用 rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() { /** * Returned message callback. * * @param message the returned message. * @param replyCode the reply code. * @param replyText the reply text. * @param exchange the exchange. * @param routingKey the routing key. */ @Override public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) { } });
启用 Publisher Return
cachingConnectionFactory.setPublisherConfirms(true); //注册提交确认回调 rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() { /** * Confirmation callback. * * @param correlationData correlation data for the callback. * @param ack true for ack, false for nack * @param cause An optional cause, for nack, when available, otherwise null. */ @Override public void confirm(CorrelationData correlationData, boolean ack, String cause) { } });
setChannelTransacted(true):启用事务,会在txCommit()抛出
操作的作用域:利用invoke方法来规划每个操作的作用域
//设置操作作用域 rabbitTemplate.invoke(new RabbitOperations.OperationsCallback<Object>() { /** * Execute any number of operations using a dedicated * {@link Channel} as long as those operations are performed * on the template argument and on the calling thread. The channel will be * physically closed when the callback exits. * * @param operations The operations. * @return The result. */ @Override public Object doInRabbit(RabbitOperations operations) { return null; } });
信息的集成:可以自定义对消息的复写
// 消息复写 MessagingMessageConverter messagingMessageConverter = new MessagingMessageConverter(); MessageConverter messageConverter = new MessageConverter() { /** * Convert a Java object to a Message. * * @param object the object to convert * @param messageProperties The message properties. * @return the Message * @throws MessageConversionException in case of conversion failure */ @Override public Message toMessage(Object object, MessageProperties messageProperties) throws MessageConversionException { return null; } /** * Convert from a Message to a Java object. * * @param message the message to convert * @return the converted Java object * @throws MessageConversionException in case of conversion failure */ @Override public Object fromMessage(Message message) throws MessageConversionException { return null; } }; messagingMessageConverter.setPayloadConverter(messageConverter); rabbitTemplate.setMessageConverter(messagingMessageConverter);
发送信息(sending messages):
- send方法:(其中exchange和routekey存在默认值,为fanout模式,routekey为”“)
MessageProperties messageProperties=new MessageProperties(); messageProperties.setContentType("application/json"); rabbitTemplate.send("exchange.name","routeKey",new Message("message".getBytes(),messageProperties));
convertAndSend
- Message Builder Api(消息构建Api)
Message message = MessageBuilder.withBody("message".getBytes()).setContentType(MessageProperties .CONTENT_TYPE_TEXT_PLAIN).setMessageId("123").setHeader("bar", "baz").build();
or
MessageProperties messageProperties = MessagePropertiesBuilder.newInstance().setContentType(MessageProperties .CONTENT_TYPE_TEXT_PLAIN).setMessageId("123").setHeader("bar", "baz").build(); Message message1 = MessageBuilder.withBody("message".getBytes()).andProperties(messageProperties).build();
- batching(批量处理):BatchingRabbitTemplate,batch Messages 发送根据Batching strategy
public interface BatchingStrategy { MessageBatch addToBatch(String exchange, String routingKey, Message message); Date nextRelease(); Collection<MessageBatch> releaseBatches(); }
SimpleBatchingStragety:支持批量发送信息到一个exchange或routeKey
batchSize-批量消息数目
bufferLimit-批量信息最大缓冲大小
timeout-在没有新的消息加入,发送批消息的时间- send方法:(其中exchange和routekey存在默认值,为fanout模式,routekey为”“)
消息接收
- polling Consumer:(轮询)
- recive方法:
Message receive(String queueName, long timeoutMillis) throws AmqpException;
<!-- 接受Pojo -->
Message receiveAndConvert(String queueName, long timeoutMillis) throws AmqpException;
<!-- 异步消息接受和回复 -->
<R, S> boolean receiveAndReply(String queueName, ReceiveAndReplyCallback<R, S> callback,
ReplyToAddressCallback<S> replyToAddressCallback) throws AmqpException
- recive方法:
Message Listener:利用监听器处理
使用MessageListenerAdapter:
Container(容器):一个连接队列和listener的桥梁
SimpleMessageListenerContainer:
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(); container.setConnectionFactory(cachingConnectionFactory()); container.setQueueNames("some.queue"); MessageListener listener = new MessageListener() { @Override public void onMessage(Message message) { System.out.println(message); } }; //设置监听器 container.setMessageListener(listener); //设置优先级 container.setConsumerArguments(Collections.<String, Object>singletonMap("x-priority", Integer.valueOf(10)));
DirectMessageListenerContainer:
- 使用注解@RabbitListener
- 使用@EnableRabbit启用注解,
- 配置RabbitListenerContainerFactory:
- SimpleRabbitListenerContainerFactory
- DirectRabbitListenerContainerFactory
- 使用注解为方法进行队列和ecxchange的绑定
- @sendTo回复消息,必须设置可以回复
Consumer Events(消费者事件):任何一个消费者经历失败,将抛出一个ListenerContainerConsumerFailedEvent
- ListenerContainerConsumerFailedEvent
container:那个容器出错
reason: 一个原本的失败原因
fatal:是否为重大的,如果不为可以重启Consumer
throwable 自定义异常日志打印:
ConditionalExceptionLogger logger=new ConditionalExceptionLogger() { @Override public void log(Log logger, String message, Throwable t) { } }; //自定义异常日志行为 cachingConnectionFactory.setCloseExceptionLogger(logger);
其他在容器生态圈发布的事件:
AsyncConsumerStartedEvent:当消费者启动的时候
AsyncConsumerRestaredEvent:只有SimpleMessageListenerContainer会产生
AsyncConsumerTerminatedEvent:消费者常规停止
AsyncConsumerStoppedEvent:只有SimpleMessageListenerContainer会产生,消费者停止
ConsumeOkEvent:当从服务器接受到一个consumeok
ListenerContainerIdleEvent:监听容器闲置,
- ListenerContainerConsumerFailedEvent