http://activemq.apache.org/async-sends.html

producer发送消息有同步和异步两种模式,可以通过代码配置:

((ActiveMQConnection)connection).setUseAsyncSend(true);

producer默认是异步发送消息。在没有开启事务的情况下,producer发送持久化消息是同步的,调用send会阻塞直到broker把消息保存到磁盘并返回确认。

消息设置为持久:

MessageProducer producer = session.createProducer(destination);
producer.setDeliveryMode(DeliveryMode.PERSISTENT);

消息设置为非持久:

MessageProducer producer = session.createProducer(destination);
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);

producer发送消息的调用栈如下:

// ActiveMQSession
protected void send(ActiveMQMessageProducer producer, ActiveMQDestination destination,
Message message, int deliveryMode, int priority, long timeToLive,
MemoryUsage producerWindow, int sendTimeout, AsyncCallback onComplete) throws JMSException {
// 省略其他代码
// 消息的持久类型和和连接模式是或的:所以只要connection配置为异步,就走异步发送
if (onComplete==null && sendTimeout <= 0 && !msg.isResponseRequired() && !connection.isAlwaysSyncSend()
&& (!msg.isPersistent() || connection.isUseAsyncSend() || txid != null)) {
this.connection.asyncSendPacket(msg);
if (producerWindow != null) {
int size = msg.getSize();
producerWindow.increaseUsage(size);
}
} else { // 同步发送
if (sendTimeout > 0 && onComplete==null) {
this.connection.syncSendPacket(msg,sendTimeout);
}else {
this.connection.syncSendPacket(msg, onComplete);
}
}
}

producer发送同步消息的调用栈:

// org.apache.activemq.transport.ResponseCorrelator
public Object request(Object command) throws IOException {
FutureResponse response = asyncRequest(command, null);
return response.getResult();
} public FutureResponse asyncRequest(Object o, ResponseCallback responseCallback) throws IOException {
Command command = (Command) o;
command.setCommandId(sequenceGenerator.getNextSequenceId());
// 需要回复
command.setResponseRequired(true);
FutureResponse future = new FutureResponse(responseCallback);
IOException priorError = null;
synchronized (requestMap) {
priorError = this.error;
if (priorError == null) {
requestMap.put(new Integer(command.getCommandId()), future);
}
} if (priorError != null) {
future.set(new ExceptionResponse(priorError));
throw priorError;
} next.oneway(command);
return future;
}

producer发送异步消息的调用栈:

//org.apache.activemq.transport.ResponseCorrelator
public void oneway(Object o) throws IOException {
Command command = (Command)o;
command.setCommandId(sequenceGenerator.getNextSequenceId());
// 不需要回复
command.setResponseRequired(false);
next.oneway(command);
}

在不考虑事务的情况下:

producer发送持久化消息是同步发送,发送是阻塞的,直到收到确认。同步发送肯定是有流量控制的。

producer默认是异步发送,异步发送不会等待broker的确认, 所以就需要考虑流量控制了:

ActiveMQConnectionFactory.setProducerWindowSize(int producerWindowSize)

ProducerWindowSize的含义:producer每发送一个消息,统计一下发送的字节数,当字节数达到ProducerWindowSize值时,需要等待broker的确认,才能继续发送。

ActiveMQ producer同步/异步发送消息的更多相关文章

  1. kafka7 探索生产者同步or异步发送消息

    1.生产者:在发送完消息后,收到回执确认. 主要是在SimpleProducer.java中修改了发送消息的2行代码,用到了回调函数,修改如下: //发送消息 ProducerRecord<St ...

  2. Rocketmq异步发送消息

    package com.bfxy.rocketmq.quickstart; import java.util.List; import org.apache.rocketmq.client.excep ...

  3. 关于高并发下kafka producer send异步发送耗时问题的分析

    最近开发网关服务的过程当中,需要用到kafka转发消息与保存日志,在进行压测的过程中由于是多线程并发操作kafka producer 进行异步send,发现send耗时有时会达到几十毫秒的阻塞,很大程 ...

  4. 增加线程异步发送消息的方法二(Runnable)

    //获取当前时间:毫秒 long a = System.currentTimeMillis(); System.out.println("a :" + a); try { //更改 ...

  5. 增加线程异步发送消息的方法一(Thread)

    @RequestMapping(value="order/updateOrder.do") public String updateOrder(HttpServletRequest ...

  6. ActiveMQ实例2--Spring JMS发送消息

    参考文章:http://my.oschina.net/xiaoxishan/blog/381209#OSC_h3_7 一,步骤参照参考文献 二.新建的项目 三.补充 web.xml <?xml ...

  7. java 中Handler 和Runnable 的使用 异步发送消息 转

    public class MainActivity extends Activity { TextView text1, text2; Button button; Thread th; @Overr ...

  8. Kafka学习笔记(6)----Kafka使用Producer发送消息

    1. Kafka的Producer 不论将kafka作为什么样的用途,都少不了的向Broker发送数据或接受数据,Producer就是用于向Kafka发送数据.如下: 2. 添加依赖 pom.xml文 ...

  9. RocketMQ 源码学习笔记————Producer 是怎么将消息发送至 Broker 的?

    目录 RocketMQ 源码学习笔记----Producer 是怎么将消息发送至 Broker 的? 前言 项目结构 rocketmq-client 模块 DefaultMQProducerTest ...

随机推荐

  1. ECharts配置项之title(标题)

    1.标题居中 //left的值为'left', 'center', 'right' title:{ left:'center' } 2.主副标题之间的间距 title:{ //默认为10 itemGa ...

  2. C++使用thread类进行多线程编程

    C++11中引入了一个用于多线程操作的thread类,简单多线程示例: #include <iostream> #include <thread> #include <W ...

  3. <aop:aspect>与<aop:advisor>的区别

    在开发过程中,不少有Spring Aop的使用,在面向切面编程时,我们会使用< aop:aspect>:在进行事务管理时,我们会使用< aop:advisor>.那么,对于&l ...

  4. JS中的document.title可以获取当前网页的标题

    <!DOCTYPE html> <html> <head> <title>jb51.net</title> </head> &l ...

  5. 关于oracle函数listagg的使用说明

    做项目的过程中遇到过一个这样的需求,在“用户查询”前台加一个字段“用户角色”,要将用户的所有角色查询出来放到一个字段中,角色之间用“,”分隔. 发现一个办法是使用Oracle的listagg方法. W ...

  6. 扩展EF的Fluent API中的 OnModelCreating方法 实现全局数据过滤器

    1.生成过滤的表达式目录树 protected virtual Expression<Func<TEntity, bool>> CreateFilterExpression&l ...

  7. 《剑指offer》第六十四题(求1+2+…+n)

    // 面试题64:求1+2+…+n // 题目:求1+2+…+n,要求不能使用乘除法.for.while.if.else.switch.case // 等关键字及条件判断语句(A?B:C). #inc ...

  8. 关于JS历史

      js由来        95年那时,绝大多数因特网用户都使用速度仅为28.8kbit/s 的“猫”(调制解调器)上网,但网页的大小和复杂性却不断增加.为完成简单的表单验证而频繁地与服务器交换数据只 ...

  9. Java的三种代理模式(Proxy,CGLib)

    1.静态代理,这种不用说最不靠谱.每个类一个代理,代码量很大. 2.JDK代理.使用java.lang.reflect.Proxy进行代理,但是被代理的类必须要实现接口. 3.Cglib代理.不用实现 ...

  10. thinkphp5的Auth权限认证实战

    thinkphp5的Auth权限认证实战 一.总结 一句话总结:基于角色的权限管理(真正做一遍,就会发现很简单,不然一直都是半懂不懂的) 角色 权限 真正做一遍,就会发现很简单,不然一直都是半懂不懂的 ...