RocketMQ集群及整合SpringBoot

集群

单Master模式

      只有一个 Master节点

      优点:配置简单,方便部署

      缺点:这种方式风险较大,一旦Broker重启或者宕机时,会导致整个服务不可用,不建议线上环境使用


多Master模式

      一个集群无 Slave,全是 Master,例如 2 个 Master 或者 3 个 Master

      优点:配置简单,单个Master 宕机或重启维护对应用无影响,在磁盘配置为RAID10 时,即使机器宕机不可恢复情况下,由与 RAID10磁盘非常可靠,消息也不会丢(异步刷盘丢失少量消息,同步刷盘一条不丢)。性能最高。多 Master 多 Slave 模式,异步复制

      缺点:单台机器宕机期间,这台机器上未被消费的消息在机器恢复之前不可订阅,消息实时性会受到受到影响


多Master多Slave模式(异步复制)

      每个 Master 配置一个 Slave,有多对Master-Slave, HA,采用异步复制方式,主备有短暂消息延迟,毫秒级

      优点:即使磁盘损坏,消息丢失的非常少,且消息实时性不会受影响,因为Master 宕机后,消费者仍然可以从 Slave消费,此过程对应用透明。不需要人工干预。性能同多 Master 模式几乎一样

      缺点:Master 宕机,磁盘损坏情况,会丢失少量消息


多Master多Slave模式(同步双写)

      每个 Master 配置一个 Slave,有多对Master-Slave, HA采用同步双写方式,主备都写成功,向应用返回成功

      优点:数据与服务都无单点, Master宕机情况下,消息无延迟,服务可用性与数据可用性都非常高

      缺点:性能比异步复制模式略低,大约低 10%左右,发送单个消息的 RT会略高。目前主宕机后,备机不能自动切换为主机,后续会支持自动切换功能
双主双从


Broker配置信息

  • brokerClusterName:同一个集群中,brokerClusterName需一致

  • brokerId:0 表示 Master,>0 表示 Slave

  • namesrvAddr:配置多个用分号分隔

  • brokerIP1:默认系统自动识别,但是某些多网卡机器会存在识别错误的情况,建议都手工指定

  • brokerRole:选择Broker的角色

  • flushDiskType:选择刷盘方式

  • deleteWhen: 过期文件真正删除时间

  • fileReservedTime:Commitlog、ConsumeQueue文件,如果非当前写文件在一定时间间隔内没有再次被更新,则认为是过期文件,可以被删除,RocketMQ不会管这个这个文件上的消息是否被全部消费


故障转移/主备切换

      Master/Slave 部署模式,提供了一定的高可用性。但如果主节点挂了,还需要人为手动进行重启或者切换,无法自动将一个从节点转换为主节点。本质上是自动选主的问题,问题解决方案两个方向。

  • 利用第三方协调服务集群完成选主,比如 zookeeper 或者 etcd(raft)。这种方案引入了重量级外部组件,加重了部署运维和故障的诊断成本,比如在维护 RocketMQ 集群还需要维护 zookeeper 集群,并且 zookeeper 集群故障会影响到 RocketMQ 集群。
  • 利用 raft 协议来完成一个自动选主,raft 协议相比前者的优点是不需要引入外部组件,自动选主逻辑集成到各个节点的进程中,节点之间通过通信就可以完成选主。

      在rocketMQ中可以使用DLedger:
      直接在borker中配置即可,需要集群至少三台服务器,不然无法提供选举能力。

# broker配置
# dleger
enableDLegerCommitLog = true
dLegerGroup = broker-a
dLegerPeers = n0-192.168.100.110:40911;n1-192.168.100.111:40911;n2-192.168.100.112:40911
dLegerSelfId = n0
sendMessageThreadPoolNums = 4

整合SpringBoot

      pom引入两个依赖

		<dependency>
		    <groupId>org.apache.rocketmq</groupId>
		    <artifactId>rocketmq-common</artifactId>
		    <version>4.6.1</version>
		</dependency>
		<dependency>
		    <groupId>org.apache.rocketmq</groupId>
		    <artifactId>rocketmq-client</artifactId>
		    <version>4.6.1</version>
		</dependency>

Producer

      系统启动时初始化producer参数并启动

import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MQConfig {
	public static final Logger LOGGER = LoggerFactory.getLogger(MQConfig.class);

	@Value("${rocketmq.producer.groupName}")
	private String groupName;

	@Value("${rocketmq.producer.namesrvAddr}")
	private String namesrvAddr;

	@Bean
	public DefaultMQProducer getRocketMQProducer() {

		DefaultMQProducer producer;
		producer = new DefaultMQProducer(this.groupName);

		producer.setNamesrvAddr(this.namesrvAddr);

		try {
			producer.start();
			System.out.println("start....");

			LOGGER.info(String.format("producer is start ! groupName:[%s],namesrvAddr:[%s]", this.groupName,
					this.namesrvAddr));
		} catch (MQClientException e) {
			LOGGER.error(String.format("producer is error {}", e.getMessage(), e));
		}
		return producer;

	}
}

      Service消息发送类

import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.common.message.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class MQService {
	@Autowired
	DefaultMQProducer producer;
	
	
	public Object sendMsg(String string) {
		
		for (int i = 0; i < 1; i++) {
			Message message = new Message("topic01", "测试消息".getBytes());
			
			try {
				return producer.send(message);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} 
		}
		return null;
	}
}

Consumer

      系统启动时初始化Consumer参数并启动

import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MQConfig {
	
    
	public static final Logger logger = LoggerFactory.getLogger(MQConfig.class);
	
	@Value("${rocketmq.consumer.namesrvAddr}")
    private String namesrvAddr;
    @Value("${rocketmq.consumer.groupName}")
    private String groupName;
    @Value("${rocketmq.consumer.topics}")
    private String topics;
	
    @Bean
    public DefaultMQPushConsumer getRocketMQConsumer() throws Exception {
    	
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(groupName);
        consumer.setNamesrvAddr(namesrvAddr);
        consumer.subscribe(topics, "*");
        
        consumer.registerMessageListener(new MyMessageListener() );
        consumer.start();
        
        return consumer;
    }
}

      Service消息处理类

import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.common.message.MessageExt;

public class MyMessageListener implements MessageListenerConcurrently {
		@Override
		public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
			System.out.println("---获取消息---");
			for (MessageExt msg : msgs) {
				
				System.out.println(new String(msg.getBody()));;
			}
			return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
		}
}
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值