activeMQ(六) 集群

一、Replicated LevelDB:     官网讲解
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
增加IP 到域名的映射(/etc/hosts 文件)
在这里插入图片描述
修改 为相同的borkername

改为 replica levelDB (3个都配,这里列举一个)

<persistenceAdapter>
    <replicatedLevelDB
      directory="{activemq.data}/leveldb"
      replicas="3"
      bind="tcp://0.0.0.0:63631"
      zkAddress="localhost:2191,localhost:2192,localhost:2193"
      zkPassword="123456"
	  sync="local_disk"
      zkPath="/activemq/leveldb-stores"
      hostname="wh-mq-server"
      />
  </persistenceAdapter>

改端口 02 节点 =》 61617 03 节点 =》 61618
在这里插入图片描述
想要启动replica leavel DB 必须先启动所有的zookeper 服务,zookeper 的单机伪节点安装这里不细说了,主要讲zookeper 复制三份后改配置文件,并让之自动生成 myid 文件,并将zk的端口改为之前表格中对应的端口 。这是conf 下的配置文件
在这里插入图片描述
其具体配置为:

tickTime=2000
initLimit=10
syncLimit=5
clientPort=2191    // 自行设置
server.1=192.168.17.3:2888:3888
server.2=192.168.17.3:2887:3887
server.3=192.168.17.3:286:3886
dataDir=/zk_server/data/log1    // 自行设置

命令即可让它变为可执行脚本, ./zk_batch.sh start 即可 (即启动了三个zk 的服务)
同理写一个批处理关闭zk 服务的脚本和 批处理开启mq 服务 关闭 mq 服务的脚本。

完成上述之后连接zk 的一个客户端

./zkCli.sh -server 127.0.0.1:2191

连接之后:
在这里插入图片描述
表示连接成功
查看我的三个节点: 我的分别是 0…… 3 …… 4 …… 5
在这里插入图片描述
查看我的节点状态

get /activemq/leveldb-stores/00000000003

在这里插入图片描述
此次验证表明 00000003 的节点状态是master (即为63631 的那个mq 服务) 而其余的(00000004 00000005) activemq 的节点是 slave
如此集群顺利搭建成功 !
在这里插入图片描述
此次测试表明只有 8161 的端口可以使用 经测试只有 61 可以使用,也就是61 代表的就是master
在这里插入图片描述
测试集群可用性:
首先:
在这里插入图片描述
修改java代码

public static final String ACTIVEMQ_URL = "failover:(tcp://192.168.17.3:61616,tcp://192.168.17.3:61617,
tcp://192.168.17.3:61618)?randomize=false";

public static final String QUEUE_NAME = "queue_cluster";

测试:
在这里插入图片描述
测试通过连接上集群的 61616

MQ服务收到三条消息:
在这里插入图片描述
消息接收

MQ 服务也将消息出队

以上代表集群可以正常使用

此时真正的可用性测试:
杀死 8061 端口的进程 !!!

在这里插入图片描述
刷新页面后 8161 端口宕掉,但是 8162 端口又激活了
在这里插入图片描述
在这里插入图片描述
当 61616 宕机,代码不变发消息 自动连接到 61617 了在这里插入图片描述
这样! 集群的可用性测试成功!

二、面试题::      ?

1> 引入消息队列后 如何保证高可用性
    持久化、事务、签收、 以及带复制的 Leavel DB + zookeeper 主从集群搭建

2> 异步投递 Async send(默认异步)
    1、对于一个慢消费者,使用同步有可能造成堵塞,消息消费较慢时适合用异步发送消息
    2、 activemq 支持同步异步 发送的消息,默认异步。当你设定同步发送的方式和 未使用事务的情况下发持久化消息,这时是同步的。
    3、 如果没有使用事务,且发送的是持久化消息,每次发送都会阻塞一个生产者直到 broker 发回一个确认,这样做保证了消息的安全送达,但是会阻塞客户端,造成很大延时 。
    4、在高性能要求下,可以使用异步提高producer 的性能。但会消耗较多的client 端内存,也不能完全保证消息发送成功。在 useAsyncSend = true 情况下容忍消息丢失。

// 开启异步投递

activeMQConnectionFactory.setUseAsyncSend(true);  

在这里插入图片描述
url 后面加参数
开启ActivemqFactury 的Async 为true
将connection 设Async 为true

3 > 如何在投递快还可以保证消息丢失 ?
异步发送消息丢失的情况场景是: UseAsyncSend 为 true 使用 producer(send)持续发送消息,消息不会阻塞,生产者会认为所有的 send 消息均会被发送到 MQ ,如果MQ 突然宕机,此时生产者端尚未同步到 MQ 的消息均会丢失 。 故正确的异步发送方法需要接收回调

同步发送和异步发送的区别就在于
    同步发送send 不阻塞就代表消息发送成功
    异步发送需要接收回执并又客户端在判断一次是否发送

在代码中接收回调的函数 :

activeMQConnectionFactory.setUseAsyncSend(true);
    ……  
    
 for (int i = 1; i < 4 ; i++) {
    
    
     textMessage = session.createTextMessage("msg--" + i);
     textMessage.setJMSMessageID(UUID.randomUUID().toString()+"--  orderr");
     String msgid = textMessage.getJMSMessageID();
            messageProducer.send(textMessage, new AsyncCallback() {
    
    
                @Override
                public void onSuccess() {
    
    
                    // 发送成功怎么样
                    System.out.println(msgid+"has been successful send ");
                }

                @Override
                public void onException(JMSException e) {
    
    
                    // 发送失败怎么样
                    System.out.println(msgid+" has been failure send ");
                }
            });
}    
 

3> 延迟投递和定时投递
① 在配置文件中设置定时器开关 为 true
在这里插入图片描述
② 代码编写
Java 代码中封装的辅助消息类型 ScheduleMessage
可以设置的 常用参数 如下:

long delay = 3 * 1000 ;//延时时间秒
long perid = 4 * 1000 ;//每间隔多久一次延时
int repeat = 7 ;//共循环多少次
for (int i = 1; i < 4 ; i++) {
    
    
    TextMessage textMessage = session.createTextMessage("delay msg--" + i);
    // 消息每过 3 秒投递,每 4 秒重复投递一次 ,一共重复投递 7 次
    textMessage.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY,delay);
    textMessage.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_PERIOD,perid);
    textMessage.setIntProperty(ScheduledMessage.AMQ_SCHEDULED_REPEAT,repeat);
    messageProducer.send(textMessage);
}

4> ActiveMQ 的消息重试机制
在这里插入图片描述
最多六次还没发出就会,加入DLQ (死信队列)官网介绍 http://activemq.apache.org/redelivery-policy
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
5> 死信队列的一些设置

 //修改,当嫌6 次太多,设置为 3次     (消费端设置)
 // 三次的意思是不计算本来发送的第一次 ,之后再次发送的第三天就被废弃
 
RedeliveryPolicy  redeliveryPolicy = new RedeliveryPolicy();
redeliveryPolicy.setMaximumRedeliveries(3);
activeMQConnectionFactory.setRedeliveryPolicy(redeliveryPolicy);

在spring 中使用 死信机制 在这里插入图片描述
6> 如何保证消息不被重复消费,幂等性的问题 ?

幂等性其实就是解决重复提交,解决方案有如下:
1、 给消息分配一个全局id,只要消费过该消息,将<id,message>形式写入redis,那消费前先去redis查询一下就知道有没有重复消费了(textMessage.setJMSMessageID(UUID.randomUUID().toString()) ; )
2、如果是数据库插入操作,可以将这个消息作为唯一主键,重复消费就会冲突

猜你喜欢

转载自blog.csdn.net/jue6628/article/details/98235816