本文转自http://www.cnblogs.com/zhuxiaojie/p/5564187.html

目录: 

  1. 一:JMQ的两种消息模式
  2. 1.1:点对点的消息模式
  3. 1.2:订阅模式
  4. 二:点对点的实现代码
  5. 2.1:点对点的发送端
  6. 2.2:点对点的接收端
  7. 三:订阅/发布模式的实现代码
  8. 3.1:订阅模式的发送端
  9. 3.2:订阅模式的接收端
  10. 四:发送消息的数据类型
  11. 4.1:传递javabean对象
  12. 4.2:发送文件
  13. 五:ActiveMQ的应用
  14. 5.1:保证消息的成功处理
  15. 5.2:避免消息队列的并发
  16. 5.2.1:主动接收队列消息
  17. 5.2.2:使用多个接收端
  18. 5.3:消息有效期的管理
  19. 5.4:过期消息,处理失败的消息如何处理

六:ActiveMQ的安全配置

  6.1:管理后台的密码设置

6.2:生产消费者的连接密码

一:JMQ的两种消息模式

消息列队有两种消息模式,一种是点对点的消息模式,还有一种就是订阅的模式.

1.1:点对点的消息模式

点对点的模式主要建立在一个队列上面,当连接一个列队的时候,发送端不需要知道接收端是否正在接收,可以直接向ActiveMQ发送消息,发送的消息,将会先进入队列中,如果有接收端在监听,则会发向接收端,如果没有接收端接收,则会保存在activemq服务器,直到接收端接收消息,点对点的消息模式可以有多个发送端,多个接收端,但是一条消息,只会被一个接收端给接收到,哪个接收端先连上ActiveMQ,则会先接收到,而后来的接收端则接收不到那条消息

1.2:订阅模式

订阅/发布模式,同样可以有着多个发送端与多个接收端,但是接收端与发送端存在时间上的依赖,就是如果发送端发送消息的时候,接收端并没有监听消息,那么ActiveMQ将不会保存消息,将会认为消息已经发送,换一种说法,就是发送端发送消息的时候,接收端不在线,是接收不到消息的,哪怕以后监听消息,同样也是接收不到的。这个模式还有一个特点,那就是,发送端发送的消息,将会被所有的接收端给接收到,不类似点对点,一条消息只会被一个接收端给接收到。

二:点对点的实现代码

这里使用java来实现一下ActiveMQ的点对点模式。

ActiveMQ版本为 5.13.3

项目使用MAVEN来构建

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.apache.activemq</groupId>
  4. <artifactId>activemq-core</artifactId>
  5. <version>5.7.0</version>
  6. </dependency>
  7. </dependencies>

都是当前最新的版本

2.1:点对点的发送端

  1. import javax.jms.Connection;
  2. import javax.jms.ConnectionFactory;
  3. import javax.jms.DeliveryMode;
  4. import javax.jms.Destination;
  5. import javax.jms.JMSException;
  6. import javax.jms.MessageProducer;
  7. import javax.jms.Session;
  8. import javax.jms.TextMessage;
  9.  
  10. import org.apache.activemq.ActiveMQConnectionFactory;
  11.  
  12. public class PTPSend {
  13. //连接账号
  14. private String userName = "";
  15. //连接密码
  16. private String password = "";
  17. //连接地址
  18. private String brokerURL = "tcp://192.168.0.130:61616";
  19. //connection的工厂
  20. private ConnectionFactory factory;
  21. //连接对象
  22. private Connection connection;
  23. //一个操作会话
  24. private Session session;
  25. //目的地,其实就是连接到哪个队列,如果是点对点,那么它的实现是Queue,如果是订阅模式,那它的实现是Topic
  26. private Destination destination;
  27. //生产者,就是产生数据的对象
  28. private MessageProducer producer;
  29.  
  30. public static void main(String[] args) {
  31. PTPSend send = new PTPSend();
  32. send.start();
  33. }
  34.  
  35. public void start(){
  36. try {
  37. //根据用户名,密码,url创建一个连接工厂
  38. factory = new ActiveMQConnectionFactory(userName, password, brokerURL);
  39. //从工厂中获取一个连接
  40. connection = factory.createConnection();
  41. //测试过这个步骤不写也是可以的,但是网上的各个文档都写了
  42. connection.start();
  43. //创建一个session
  44. //第一个参数:是否支持事务,如果为true,则会忽略第二个参数,被jms服务器设置为SESSION_TRANSACTED
  45. //第二个参数为false时,paramB的值可为Session.AUTO_ACKNOWLEDGE,Session.CLIENT_ACKNOWLEDGE,DUPS_OK_ACKNOWLEDGE其中一个。
  46. //Session.AUTO_ACKNOWLEDGE为自动确认,客户端发送和接收消息不需要做额外的工作。哪怕是接收端发生异常,也会被当作正常发送成功。
  47. //Session.CLIENT_ACKNOWLEDGE为客户端确认。客户端接收到消息后,必须调用javax.jms.Message的acknowledge方法。jms服务器才会当作发送成功,并删除消息。
  48. //DUPS_OK_ACKNOWLEDGE允许副本的确认模式。一旦接收方应用程序的方法调用从处理消息处返回,会话对象就会确认消息的接收;而且允许重复确认。
  49. session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
  50. //创建一个到达的目的地,其实想一下就知道了,activemq不可能同时只能跑一个队列吧,这里就是连接了一个名为"text-msg"的队列,这个会话将会到这个队列,当然,如果这个队列不存在,将会被创建
  51. destination = session.createQueue("text-msg");
  52. //从session中,获取一个消息生产者
  53. producer = session.createProducer(destination);
  54. //设置生产者的模式,有两种可选
  55. //DeliveryMode.PERSISTENT 当activemq关闭的时候,队列数据将会被保存
  56. //DeliveryMode.NON_PERSISTENT 当activemq关闭的时候,队列里面的数据将会被清空
  57. producer.setDeliveryMode(DeliveryMode.PERSISTENT);
  58.  
  59. //创建一条消息,当然,消息的类型有很多,如文字,字节,对象等,可以通过session.create..方法来创建出来
  60. TextMessage textMsg = session.createTextMessage("呵呵");
  61. for(int i = 0 ; i < 100 ; i ++){
  62. //发送一条消息
  63. producer.send(textMsg);
  64. }
  65.  
  66. System.out.println("发送消息成功");
  67. //即便生产者的对象关闭了,程序还在运行哦
  68. producer.close();
  69.  
  70. } catch (JMSException e) {
  71. e.printStackTrace();
  72. }
  73. }
  74. }

2.2:点对点的接收端

  1. import javax.jms.Connection;
  2. import javax.jms.ConnectionFactory;
  3. import javax.jms.Destination;
  4. import javax.jms.JMSException;
  5. import javax.jms.Message;
  6. import javax.jms.MessageConsumer;
  7. import javax.jms.MessageListener;
  8. import javax.jms.Session;
  9. import javax.jms.TextMessage;
  10.  
  11. import org.apache.activemq.ActiveMQConnectionFactory;
  12.  
  13. public class PTPReceive {
  14. //连接账号
  15. private String userName = "";
  16. //连接密码
  17. private String password = "";
  18. //连接地址
  19. private String brokerURL = "tcp://192.168.0.130:61616";
  20. //connection的工厂
  21. private ConnectionFactory factory;
  22. //连接对象
  23. private Connection connection;
  24. //一个操作会话
  25. private Session session;
  26. //目的地,其实就是连接到哪个队列,如果是点对点,那么它的实现是Queue,如果是订阅模式,那它的实现是Topic
  27. private Destination destination;
  28. //消费者,就是接收数据的对象
  29. private MessageConsumer consumer;
  30. public static void main(String[] args) {
  31. PTPReceive receive = new PTPReceive();
  32. receive.start();
  33. }
  34.  
  35. public void start(){
  36. try {
  37. //根据用户名,密码,url创建一个连接工厂
  38. factory = new ActiveMQConnectionFactory(userName, password, brokerURL);
  39. //从工厂中获取一个连接
  40. connection = factory.createConnection();
  41. //测试过这个步骤不写也是可以的,但是网上的各个文档都写了
  42. connection.start();
  43. //创建一个session
  44. //第一个参数:是否支持事务,如果为true,则会忽略第二个参数,被jms服务器设置为SESSION_TRANSACTED
  45. //第二个参数为false时,paramB的值可为Session.AUTO_ACKNOWLEDGE,Session.CLIENT_ACKNOWLEDGE,DUPS_OK_ACKNOWLEDGE其中一个。
  46. //Session.AUTO_ACKNOWLEDGE为自动确认,客户端发送和接收消息不需要做额外的工作。哪怕是接收端发生异常,也会被当作正常发送成功。
  47. //Session.CLIENT_ACKNOWLEDGE为客户端确认。客户端接收到消息后,必须调用javax.jms.Message的acknowledge方法。jms服务器才会当作发送成功,并删除消息。
  48. //DUPS_OK_ACKNOWLEDGE允许副本的确认模式。一旦接收方应用程序的方法调用从处理消息处返回,会话对象就会确认消息的接收;而且允许重复确认。
  49. session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
  50. //创建一个到达的目的地,其实想一下就知道了,activemq不可能同时只能跑一个队列吧,这里就是连接了一个名为"text-msg"的队列,这个会话将会到这个队列,当然,如果这个队列不存在,将会被创建
  51. destination = session.createQueue("text-msg");
  52. //根据session,创建一个接收者对象
  53. consumer = session.createConsumer(destination);
  54.  
  55. //实现一个消息的监听器
  56. //实现这个监听器后,以后只要有消息,就会通过这个监听器接收到
  57. consumer.setMessageListener(new MessageListener() {
  58. @Override
  59. public void onMessage(Message message) {
  60. try {
  61. //获取到接收的数据
  62. String text = ((TextMessage)message).getText();
  63. System.out.println(text);
  64. } catch (JMSException e) {
  65. e.printStackTrace();
  66. }
  67. }
  68. });
  69. //关闭接收端,也不会终止程序哦
  70. // consumer.close();
  71. } catch (JMSException e) {
  72. e.printStackTrace();
  73. }
  74. }
  75. }

三:订阅/发布模式的实现代码

3.1:订阅模式的发送端

  1. import javax.jms.Connection;
  2. import javax.jms.ConnectionFactory;
  3. import javax.jms.DeliveryMode;
  4. import javax.jms.Destination;
  5. import javax.jms.JMSException;
  6. import javax.jms.MessageProducer;
  7. import javax.jms.Session;
  8. import javax.jms.TextMessage;
  9.  
  10. import org.apache.activemq.ActiveMQConnectionFactory;
  11.  
  12. public class TOPSend {
  13. //连接账号
  14. private String userName = "";
  15. //连接密码
  16. private String password = "";
  17. //连接地址
  18. private String brokerURL = "tcp://192.168.0.130:61616";
  19. //connection的工厂
  20. private ConnectionFactory factory;
  21. //连接对象
  22. private Connection connection;
  23. //一个操作会话
  24. private Session session;
  25. //目的地,其实就是连接到哪个队列,如果是点对点,那么它的实现是Queue,如果是订阅模式,那它的实现是Topic
  26. private Destination destination;
  27. //生产者,就是产生数据的对象
  28. private MessageProducer producer;
  29.  
  30. public static void main(String[] args) {
  31. TOPSend send = new TOPSend();
  32. send.start();
  33. }
  34.  
  35. public void start(){
  36. try {
  37. //根据用户名,密码,url创建一个连接工厂
  38. factory = new ActiveMQConnectionFactory(userName, password, brokerURL);
  39. //从工厂中获取一个连接
  40. connection = factory.createConnection();
  41. //测试过这个步骤不写也是可以的,但是网上的各个文档都写了
  42. connection.start();
  43. //创建一个session
  44. //第一个参数:是否支持事务,如果为true,则会忽略第二个参数,被jms服务器设置为SESSION_TRANSACTED
  45. //第二个参数为false时,paramB的值可为Session.AUTO_ACKNOWLEDGE,Session.CLIENT_ACKNOWLEDGE,DUPS_OK_ACKNOWLEDGE其中一个。
  46. //Session.AUTO_ACKNOWLEDGE为自动确认,客户端发送和接收消息不需要做额外的工作。哪怕是接收端发生异常,也会被当作正常发送成功。
  47. //Session.CLIENT_ACKNOWLEDGE为客户端确认。客户端接收到消息后,必须调用javax.jms.Message的acknowledge方法。jms服务器才会当作发送成功,并删除消息。
  48. //DUPS_OK_ACKNOWLEDGE允许副本的确认模式。一旦接收方应用程序的方法调用从处理消息处返回,会话对象就会确认消息的接收;而且允许重复确认。
  49. session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
  50. //创建一个到达的目的地,其实想一下就知道了,activemq不可能同时只能跑一个队列吧,这里就是连接了一个名为"text-msg"的队列,这个会话将会到这个队列,当然,如果这个队列不存在,将会被创建
  51.  
  52. //=======================================================
  53. //点对点与订阅模式唯一不同的地方,就是这一行代码,点对点创建的是Queue,而订阅模式创建的是Topic
  54. destination = session.createTopic("topic-text");
  55. //=======================================================
  56.  
  57. //从session中,获取一个消息生产者
  58. producer = session.createProducer(destination);
  59. //设置生产者的模式,有两种可选
  60. //DeliveryMode.PERSISTENT 当activemq关闭的时候,队列数据将会被保存
  61. //DeliveryMode.NON_PERSISTENT 当activemq关闭的时候,队列里面的数据将会被清空
  62. producer.setDeliveryMode(DeliveryMode.PERSISTENT);
  63.  
  64. //创建一条消息,当然,消息的类型有很多,如文字,字节,对象等,可以通过session.create..方法来创建出来
  65. TextMessage textMsg = session.createTextMessage("哈哈");
  66. long s = System.currentTimeMillis();
  67. for(int i = 0 ; i < 100 ; i ++){
  68. //发送一条消息
  69. producer.send(textMsg);
  70. }
  71. long e = System.currentTimeMillis();
  72. System.out.println("发送消息成功");
  73. System.out.println(e - s);
  74. //即便生产者的对象关闭了,程序还在运行哦
  75. producer.close();
  76.  
  77. } catch (JMSException e) {
  78. e.printStackTrace();
  79. }
  80. }
  81. }

3.2:订阅模式的接收端

  1. import javax.jms.Connection;
  2. import javax.jms.ConnectionFactory;
  3. import javax.jms.DeliveryMode;
  4. import javax.jms.Destination;
  5. import javax.jms.JMSException;
  6. import javax.jms.MessageProducer;
  7. import javax.jms.Session;
  8. import javax.jms.TextMessage;
  9.  
  10. import org.apache.activemq.ActiveMQConnectionFactory;
  11.  
  12. public class TOPSend {
  13. //连接账号
  14. private String userName = "";
  15. //连接密码
  16. private String password = "";
  17. //连接地址
  18. private String brokerURL = "tcp://192.168.0.130:61616";
  19. //connection的工厂
  20. private ConnectionFactory factory;
  21. //连接对象
  22. private Connection connection;
  23. //一个操作会话
  24. private Session session;
  25. //目的地,其实就是连接到哪个队列,如果是点对点,那么它的实现是Queue,如果是订阅模式,那它的实现是Topic
  26. private Destination destination;
  27. //生产者,就是产生数据的对象
  28. private MessageProducer producer;
  29.  
  30. public static void main(String[] args) {
  31. TOPSend send = new TOPSend();
  32. send.start();
  33. }
  34.  
  35. public void start(){
  36. try {
  37. //根据用户名,密码,url创建一个连接工厂
  38. factory = new ActiveMQConnectionFactory(userName, password, brokerURL);
  39. //从工厂中获取一个连接
  40. connection = factory.createConnection();
  41. //测试过这个步骤不写也是可以的,但是网上的各个文档都写了
  42. connection.start();
  43. //创建一个session
  44. //第一个参数:是否支持事务,如果为true,则会忽略第二个参数,被jms服务器设置为SESSION_TRANSACTED
  45. //第二个参数为false时,paramB的值可为Session.AUTO_ACKNOWLEDGE,Session.CLIENT_ACKNOWLEDGE,DUPS_OK_ACKNOWLEDGE其中一个。
  46. //Session.AUTO_ACKNOWLEDGE为自动确认,客户端发送和接收消息不需要做额外的工作。哪怕是接收端发生异常,也会被当作正常发送成功。
  47. //Session.CLIENT_ACKNOWLEDGE为客户端确认。客户端接收到消息后,必须调用javax.jms.Message的acknowledge方法。jms服务器才会当作发送成功,并删除消息。
  48. //DUPS_OK_ACKNOWLEDGE允许副本的确认模式。一旦接收方应用程序的方法调用从处理消息处返回,会话对象就会确认消息的接收;而且允许重复确认。
  49. session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
  50. //创建一个到达的目的地,其实想一下就知道了,activemq不可能同时只能跑一个队列吧,这里就是连接了一个名为"text-msg"的队列,这个会话将会到这个队列,当然,如果这个队列不存在,将会被创建
  51.  
  52. //=======================================================
  53. //点对点与订阅模式唯一不同的地方,就是这一行代码,点对点创建的是Queue,而订阅模式创建的是Topic
  54. destination = session.createTopic("topic-text");
  55. //=======================================================
  56.  
  57. //从session中,获取一个消息生产者
  58. producer = session.createProducer(destination);
  59. //设置生产者的模式,有两种可选
  60. //DeliveryMode.PERSISTENT 当activemq关闭的时候,队列数据将会被保存
  61. //DeliveryMode.NON_PERSISTENT 当activemq关闭的时候,队列里面的数据将会被清空
  62. producer.setDeliveryMode(DeliveryMode.PERSISTENT);
  63.  
  64. //创建一条消息,当然,消息的类型有很多,如文字,字节,对象等,可以通过session.create..方法来创建出来
  65. TextMessage textMsg = session.createTextMessage("哈哈");
  66. long s = System.currentTimeMillis();
  67. for(int i = 0 ; i < 100 ; i ++){
  68. //发送一条消息
  69. textMsg.setText("哈哈" + i);
  70. producer.send(textMsg);
  71. }
  72. long e = System.currentTimeMillis();
  73. System.out.println("发送消息成功");
  74. System.out.println(e - s);
  75. //即便生产者的对象关闭了,程序还在运行哦
  76. producer.close();
  77.  
  78. } catch (JMSException e) {
  79. e.printStackTrace();
  80. }
  81. }
  82. }

四:发送消息的数据类型

上面的代码演示,全部都是发送字符串,但是ActiveMQ支持哪些数据呢?

大家可以看一下  javax.jms.Message 这个接口,只要是这个接口的数据,都可以被发送。

或者这样看起来有点麻烦,那么看到上面的代码,创建消息,是通过session这个对象来创建的,那我们来看一下这里有哪些可以被创建的呢?

  1. //纯字符串的数据
  2. session.createTextMessage();
  3. //序列化的对象
  4. session.createObjectMessage();
  5. //流,可以用来传递文件等
  6. session.createStreamMessage();
  7. //用来传递字节
  8. session.createBytesMessage();
  9. //这个方法创建出来的就是一个map,可以把它当作map来用,当你看了它的一些方法,你就懂了
  10. session.createMapMessage();
  11. //这个方法,拿到的是javax.jms.Message,是所有message的接口
  12. session.createMessage();

4.1:传递javabean对象

传递一个java对象,可能是最多的使用方式了,而且这种数据接收与使用都方便,那么,下面的代码就来演示下如何发送一个java对象

当然了,这个对象必须序列化,也就是实现Serializable接口

  1. //通过这个方法,可以把一个对象发送出去,当然,这个对象需要序列化,因为一切在网络在传输的,都是字节
  2. ObjectMessage obj = session.createObjectMessage();
  3. for(int i = 0 ; i < 100 ; i ++){
  4. Person p = new Person(i,"名字");
  5. obj.setObject(p);
  6. producer.send(obj);
  7. }

那么在接收端要怎么接收这个对象呢?

  1. //实现一个消息的监听器
  2. //实现这个监听器后,以后只要有消息,就会通过这个监听器接收到
  3. consumer.setMessageListener(new MessageListener() {
  4. @Override
  5. public void onMessage(Message message) {
  6. try {
  7. //同样的,强转为ObjectMessage,然后拿到对象,强转为Person
  8. Person p = (Person) ((ObjectMessage)message).getObject();
  9. System.out.println(p);
  10. } catch (JMSException e) {
  11. e.printStackTrace();
  12. }
  13.  
  14. }
  15. });

4.2:发送文件

发送文件,这里用BytesMessage

  1. BytesMessage bb = session.createBytesMessage();
  2. bb.writeBytes(new byte[]{2});

至于这里的new Byte[]{2},肯定不是这样写的,从文件里面拿流出来即可

接收的话

  1. consumer.setMessageListener(new MessageListener() {
  2. @Override
  3. public void onMessage(Message message) {
  4.  
  5. BytesMessage bm = (BytesMessage)message;
  6. FileOutputStream out = null;
  7. try {
  8. out = new FileOutputStream("d:/1.ext");
  9. } catch (FileNotFoundException e2) {
  10. e2.printStackTrace();
  11. }
  12. byte[] by = new byte[1024];
  13. int len = 0 ;
  14. try {
  15. while((len = bm.readBytes(by))!= -1){
  16. out.write(by,0,len);
  17. }
  18. } catch (JMSException | IOException e1) {
  19. e1.printStackTrace();
  20. }
  21.  
  22. }
  23. });

五:ActiveMQ的应用

5.1:保证消息的成功处理

消息发送成功后,接收端接收到了消息。然后进行处理,但是可能由于某种原因,高并发也好,IO阻塞也好,反正这条消息在接收端处理失败了。而点对点的特性是一条消息,只会被一个接收端给接收,只要接收端A接收成功了,接收端B,就不可能接收到这条消息,如果是一些普通的消息还好,但是如果是一些很重要的消息,比如说用户的支付订单,用户的退款,这些与金钱相关的,是必须保证成功的,那么这个时候要怎么处理呢?

我们可以使用  CLIENT_ACKNOWLEDGE  模式

之前其实就有提到当创建一个session的时候,需要指定其事务,及消息的处理模式,当时使用的是

  1. session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
  1. AUTO_ACKNOWLEDGE

这一个代码的是,当消息发送给接收端之后,就自动确认成功了,而不管接收端有没有处理成功,而一旦确认成功后,就会把队列里面的消息给清除掉,避免下一个接收端接收到同样的消息。

那么,它还有另外一个模式,那就是 CLIENT_ACKNOWLEDGE

这行要写在接收端里面,不是写在发送端的

  1. session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);

这行代码以后,如果接收端不确认消息,那么activemq将会把这条消息一直保留,直到有一个接收端确定了消息。

那么要怎么确认消息呢?

在接收端接收到消息的时候,调用javax.jms.Message的acknowledge方法

  1. @Override
  2. public void onMessage(Message message) {
  3. try {
  4. //获取到接收的数据
  5. String text = ((TextMessage)message).getText();
  6. System.out.println(text);
  7. //确认接收,并成功处理了消息
  8. message.acknowledge();
  9. } catch (JMSException e) {
  10. e.printStackTrace();
  11. }
  12. }

这样,当消息处理成功之后,确认消息,如果不确定,activemq将会发给下一个接收端处理

 注意:只在点对点中有效,订阅模式,即使不确认,也不会保存消息

5.2:避免消息队列的并发

JMQ设计出来的原因,就是用来避免并发的,和沟通两个系统之间的交互。

5.2.1:主动接收队列消息

先看一下之前的代码:

  1. //实现一个消息的监听器
  2. //实现这个监听器后,以后只要有消息,就会通过这个监听器接收到
  3. consumer.setMessageListener(new MessageListener() {
  4. @Override
  5. public void onMessage(Message message) {
  6. try {
  7. //获取到接收的数据
  8. String text = ((TextMessage)message).getText();
  9. System.out.println(text);
  10. //确认接收,并成功处理了消息
  11. message.acknowledge();
  12. } catch (JMSException e) {
  13. e.printStackTrace();
  14. }
  15. }
  16. });

之前的代码里面,实现了一个监听器,监听消息的传递,这样只要每有一个消息,都会即时的传递到程序中。

但是,这样的处理,在高并发的时候,因为它是被动接收,并没有考虑到程序的处理能力,可能会压跨系统,那要怎么办呢?

答案就是把被动变为主动,当程序有着处理消息的能力时,主动去接收一条消息进行处理

实现的代码如下:

  1.       if(当程序有能力处理){//当程序有能力处理时接收
  2. Message receive = consumer.receive();
               //这个可以设置超时时间,超过则不等待消息 
                recieve.receive(10000);
  3. //其实receive是一个阻塞式方法,一定会拿到值的
  4. if(null != receive){
  5. String text = ((TextMessage)receive).getText();
  6. receive.acknowledge();
  7. System.out.println(text);
  8. }else{
  9. //没有值嘛
  10. //
  11. }
  12. }

通过上面的代码,就可以让程序自已判断,自己是否有能力接收这条消息,如果不能接收,那就给别的接收端接收,或者等自己有能力处理的时候接收

5.2.2:使用多个接收端

ActiveMQ是支持多个接收端的,如果当程序无法处理这么多数据的时候,可以考虑多个线程,或者增加服务器来处理。

5.3:消息有效期的管理

这样的场景也是有的,一条消息的有效时间,当发送一条消息的时候,可能希望这条消息在指定的时间被处理,如果超过了指定的时间,那么这条消息就失效了,就不需要进行处理了,那么我们可以使用ActiveMQ的设置有效期来实现

代码如下:

  1. TextMessage msg = session.createTextMessage("哈哈");
  2. for(int i = 0 ; i < 100 ; i ++){
  3. //设置该消息的超时时间
  4. producer.setTimeToLive(i * 1000);
  5. producer.send(msg);
  6. }

这里每一条消息的有效期都是不同的,打开ip:8161/admin/就可以查看到,里面的消息越来越少了。

过期的消息是不会被接收到的。

过期的消息会从队列中清除,并存储到ActiveMQ.DLQ这个队列里面,这个稍后会解释。

5.4:过期消息,处理失败的消息如何处理

过期的、处理失败的消息,将会被ActiveMQ置入“ActiveMQ.DLQ”这个队列中。

这个队列是ActiveMQ自动创建的。

如果需要查看这些未被处理的消息,可以进入这个队列中查看

  1. //指定一个目的地,也就是一个队列的位置
  2. destination = session.createQueue("ActiveMQ.DLQ");

这样就可以进入队列中,然后实现接口,或者通过receive()方法,就可以拿到未被处理的消息,从而保证正确的处理

六:ActiveMQ的安全配置

6.1:管理后台的密码设置

我们都知道,打开ip:8161/admin/ 就是activemq的管理控制台,它的默认账号和密码都是admin,在生产环境肯定需要更改密码的,这要怎么做呢?

在activemq/conf/jetty.xml中找到

  1. <pre name="code" class="html"> <bean id="securityConstraint" class="org.eclipse.jetty.util.security.Constraint">
  2. <property name="name" value="BASIC" />
  3. <property name="roles" value="admin" />
  4. <!-- 把这个改为true,当然,高版本的已经改为了true -->
  5. <property name="authenticate" value="true" />
  6. </bean>

高版本的已经默认成为了true。所以我们直接进行下一步即可

在activemq/conf/jetty-realm.properties文件中配置,打开如下

  1. ## ---------------------------------------------------------------------------
  2. ## Licensed to the Apache Software Foundation (ASF) under one or more
  3. ## contributor license agreements. See the NOTICE file distributed with
  4. ## this work for additional information regarding copyright ownership.
  5. ## The ASF licenses this file to You under the Apache License, Version 2.0
  6. ## (the "License"); you may not use this file except in compliance with
  7. ## the License. You may obtain a copy of the License at
  8. ##
  9. ## http://www.apache.org/licenses/LICENSE-2.0
  10. ##
  11. ## Unless required by applicable law or agreed to in writing, software
  12. ## distributed under the License is distributed on an "AS IS" BASIS,
  13. ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. ## See the License for the specific language governing permissions and
  15. ## limitations under the License.
  16. ## ---------------------------------------------------------------------------
  17.  
  18. # Defines users that can access the web (console, demo, etc.)
  19. # username: password [,rolename ...]
  20. #用户名,密码,角色
  21. admin: admin, admin
  22. user: user, user

注意:大家重点看倒数第二行,那里三个分别是用户名,密码,角色,其中admin角色是固定的

6.2:生产消费者的连接密码

注意:activemq默认是不需要密码,生产消费者就可以连接的

我们需要经过配置,才能设置密码,这一步在生产环境中一定要配置

找到activemq/conf/activemq.xml,并打开
在<broker>节点中,在<systemUsage>节点上面,增加如下的一个插件

  1. <plugins>
  2. <simpleAuthenticationPlugin>
  3. <users>
  4. <authenticationUser username="${activemq.username}" password="${activemq.password}" groups="users,admins"/>
  5. </users>
  6. </simpleAuthenticationPlugin>
  7. </plugins>

这样就开启了密码认证
然后账号密码的配置在activemq/conf/credentials.properties文件中

打开这个文件如下

  1. ## ---------------------------------------------------------------------------
  2. ## Licensed to the Apache Software Foundation (ASF) under one or more
  3. ## contributor license agreements. See the NOTICE file distributed with
  4. ## this work for additional information regarding copyright ownership.
  5. ## The ASF licenses this file to You under the Apache License, Version 2.0
  6. ## (the "License"); you may not use this file except in compliance with
  7. ## the License. You may obtain a copy of the License at
  8. ##
  9. ## http://www.apache.org/licenses/LICENSE-2.0
  10. ##
  11. ## Unless required by applicable law or agreed to in writing, software
  12. ## distributed under the License is distributed on an "AS IS" BASIS,
  13. ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. ## See the License for the specific language governing permissions and
  15. ## limitations under the License.
  16. ## ---------------------------------------------------------------------------
  17.  
  18. # Defines credentials that will be used by components (like web console) to access the broker
  19.  
  20. #账号
  21. activemq.username=admin
  22. #密码
  23. activemq.password=123456
  24. guest.password=password

这样就配置完毕了。

欢迎关注

ativemq使用教程的更多相关文章

  1. Angular2入门系列教程7-HTTP(一)-使用Angular2自带的http进行网络请求

    上一篇:Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数 感觉这篇不是很好写,因为涉及到网络请求,如果采用真实的网络请求,这个例子大家拿到手估计还要自己写一个web ...

  2. Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数

    上一篇:Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数 之前介绍了简单的路由以及传参,这篇文章我们将要学习复杂一些的路由以及传递其他附加参数.一个好的路由系统可以使我们 ...

  3. Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数

    上一篇:Angular2入门系列教程-服务 上一篇文章我们将Angular2的数据服务分离出来,学习了Angular2的依赖注入,这篇文章我们将要学习Angualr2的路由 为了编写样式方便,我们这篇 ...

  4. Angular2入门系列教程4-服务

    上一篇文章 Angular2入门系列教程-多个组件,主从关系 在编程中,我们通常会将数据提供单独分离出来,以免在编写程序的过程中反复复制粘贴数据请求的代码 Angular2中提供了依赖注入的概念,使得 ...

  5. Angular2入门系列教程1-使用Angular-cli搭建Angular2开发环境

    一直在学Angular2,百忙之中抽点时间来写个简单的教程. 2016年是前端飞速发展的一年,前端越来越形成了(web component)组件化的编程模式:以前Jquery通吃一切的田园时代一去不复 ...

  6. wepack+sass+vue 入门教程(三)

    十一.安装sass文件转换为css需要的相关依赖包 npm install --save-dev sass-loader style-loader css-loader loader的作用是辅助web ...

  7. wepack+sass+vue 入门教程(二)

    六.新建webpack配置文件 webpack.config.js 文件整体框架内容如下,后续会详细说明每个配置项的配置 webpack.config.js直接放在项目demo目录下 module.e ...

  8. wepack+sass+vue 入门教程(一)

    一.安装node.js node.js是基础,必须先安装.而且最新版的node.js,已经集成了npm. 下载地址 node安装,一路按默认即可. 二.全局安装webpack npm install ...

  9. Virtual Box配置CentOS7网络(图文教程)

    之前很多次安装CentOS7虚拟机,每次配置网络在网上找教程,今天总结一下,全图文配置,方便以后查看. Virtual Box可选的网络接入方式包括: NAT 网络地址转换模式(NAT,Network ...

随机推荐

  1. bzoj1296【SCOI2009】粉刷匠

    1296: [SCOI2009]粉刷匠 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 1479  Solved: 837 [id=1296" ...

  2. Android网络开发之基本介绍

    Android平台浏览器采用WebKit引擎,名为ChormeLite,拥有强大扩展特性,每个开发者都可以编写自己的插件. 目前,Android平台有3种网络接口可以使用,分别是:java.net, ...

  3. 【LeetCode】32. Longest Valid Parentheses (2 solutions)

    Longest Valid Parentheses Given a string containing just the characters '(' and ')', find the length ...

  4. 【LeetCode】35. Search Insert Position (2 solutions)

    Search Insert Position Given a sorted array and a target value, return the index if the target is fo ...

  5. C# 添加Windows服务,定时任务

    源码下载地址:http://files.cnblogs.com/files/lanyubaicl/20160830Windows%E6%9C%8D%E5%8A%A1.zip 步骤 一 . 创建服务项目 ...

  6. PLSQL_标准删除的方式Delete/Drop/Truncate区别和比较(概念)

    2014-06-02 Created By BaoXinjian

  7. 线程模型、pthread 系列函数 和 简单多线程服务器端程序

    一.线程有3种模型,分别是N:1用户线程模型,1:1核心线程模型和N:M混合线程模型,posix thread属于1:1模型. (一).N:1用户线程模型 “线程实现”建立在“进程控制”机制之上,由用 ...

  8. Oschina 安卓client源代码学习之中的一个

    今天主要研究一下两个功能 (1)双击返回键退出程序 (2)接近完美地退出程序 (1) 在非常多应用程序里都有一个功能,就是点击返回键,之后提示你再点击返回键就退出程序. 之前一直非常好奇这是怎么实现的 ...

  9. iOS网络框架 AFNetworking

    -(void)GetActivationUser{ NSString *url = @"http://app.xxxx.com/music/search?key=%E9%AC%BC%E5%9 ...

  10. JavaScript - 返回头部

    制作浮动top $(window).scroll( function() { var scrollValue=$(window).scrollTop(); scrollValue > 600 ? ...