zoukankan      html  css  js  c++  java
  • MQ选型对比RabbitMQ RocketMQ ActiveMQ Kafka(外加redis对比及其实现)

     rocketmq 4.3开始支持事务https://www.cnblogs.com/hzmark/p/rocket_txn.html

    参考:rabbitMQ、activeMQ、zeroMQ、Kafka、Redis 比较

    redis vs rabbitmq

    可靠消费

    Redis:没有相应的机制保证消息的消费,当消费者消费失败的时候,消息体丢失,需要手动处理
    RabbitMQ:具有消息消费确认,即使消费者消费失败,也会自动使消息体返回原队列,同时可全程持久化,保证消息体被正确消费

    可靠发布

    Reids:不提供,需自行实现
    RabbitMQ:具有发布确认功能,保证消息被发布到服务器

    高可用

    Redis:采用主从模式,读写分离,但是故障转移还没有非常完善的官方解决方案
    RabbitMQ:集群采用磁盘、内存节点,任意单点故障都不会影响整个队列的操作

    持久化

    Redis:将整个Redis实例持久化到磁盘
    RabbitMQ:队列,消息,都可以选择是否持久化

    消费者负载均衡

    Redis:不提供,需自行实现
    RabbitMQ:根据消费者情况,进行消息的均衡分发

    队列监控

    Redis:不提供,需自行实现
    RabbitMQ:后台可以监控某个队列的所有信息,(内存,磁盘,消费者,生产者,速率等)

    流量控制

    Redis:不提供,需自行实现
    RabbitMQ:服务器过载的情况,对生产者速率会进行限制,保证服务可靠性

    出入队性能

    对于RabbitMQ和Redis的入队和出队操作,各执行100万次,每10万次记录一次执行时间。
    测试数据分为128Bytes、512Bytes、1K和10K四个不同大小的数据。

    除了本身的特性外,我们纯属是因为使用了分布式架构,但是系统业务量不大,为了没有那么多的中间件,将redis作为消息队列进行解耦也是可以

    Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。

    Redis 客户端可以订阅任意数量的频道。

    下图展示了频道 channel1 , 以及订阅这个频道的三个客户端 —— client2 、 client5 和 client1 之间的关系:

    pubsub1

    当有新消息通过 PUBLISH 命令发送给频道 channel1 时, 这个消息就会被发送给订阅它的三个客户端:

    pubsub2

    发布命令

    [root@localhost bin]# ./redis-cli 
    127.0.0.1:6379> auth meredis
    OK
    127.0.0.1:6379> PUBLISH redisChat "Redis is a great caching technique"
    (integer) 0
    127.0.0.1:6379> publish hs:me:channel:Memedame abc
    (integer) 1
    127.0.0.1:6379> publish hs:me:channel:Memedame {"a":"b"}
    Invalid argument(s)
    127.0.0.1:6379> publish hs:me:channel:Memedame "{"a":"b"}"
    (integer) 1

    java中实现订阅

    package com.xxx.me.mq.listener;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annometion.Autowired;
    import org.springframework.dame.redis.connection.Message;
    import org.springframework.dame.redis.connection.MessageListener;
    import org.springframework.dame.redis.core.RedisTemplate;
    import org.springframework.dame.redis.serializer.RedisSerializer;
    
    /**
     * 
        消息格式要求:
        Map<String,Object>以及Map<String,List<Object>>,例如:"Dict",List<Dict>或"Param",Param。目前支持如下:
        Dict、Param
     * <p>Title: RedisMsgPubSubMemedameListener</p>  
     * <p>Description: </p>  
     * @author zjhua
     * @date 2019年1月25日
     */
    public class RedisMsgPubSubMemedameListener implements MessageListener {
        private Logger logger = LoggerFactory.getLogger(RedisMsgPubSubMemedameListener.class);
        
        @Autowired
        private RedisTemplate<String, Object> redisTemplate;
        
        @Override
        public void onMessage( final Message message, final byte[] pattern ) {
            RedisSerializer<?> serializer = redisTemplate.getValueSerializer();
            // message.getBody()是Redis的值,需要用redis的valueSerializer反序列化
            logger.info("Message receive-->pattern:{},message: {},{}", new String(pattern),
                    serializer.deserialize(message.getBody()),
                    redisTemplate.getStringSerializer().deserialize(message.getChannel()));
            logger.info(message.toString());
        }
    }

    发布

    redisTemplate.convermendSend("hs:me:channel:Memedame", json);

    xml

        <!-- 配置redis发布订阅模式 -->
        <bean id="redisMessageListenerConmeiner" class="org.springframework.dame.redis.listener.RedisMessageListenerConmeiner">
            <property name="connectionFactory" ref="connectionFactory" />
            <property name="messageListeners">
                <map>
                    <entry key-ref="memedameMessageListenerAdapter">
                        <bean class="org.springframework.dame.redis.listener.ChannelTopic">
                            <constructor-arg value="hs:me:channel:Memedame"></constructor-arg>
                        </bean>
                    </entry>
                </map>
            </property>
        </bean>
        
        <bean id="memedameMessageListenerAdapter" class="org.springframework.dame.redis.listener.adapter.MessageListenerAdapter">
            <constructor-arg ref="redisMsgPubSubMemedameListener"></constructor-arg>
        </bean>
    
        <bean id="redisMsgPubSubMemedameListener" class="com.xxx.me.mq.listener.RedisMsgPubSubMemedameListener"></bean>
  • 相关阅读:
    有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不 死,问每个月的兔子总数为多少?
    Tomcat 全攻略
    MySQL 查询in操作,查询结果按in集合顺序显示
    乱码问题解决之道
    Java程序员面试中的多线程问题
    APACHE多个服务器的配置
    Python读写文件
    php字符串处理函数大全
    python 执行系统命令
    jquery-mobile
  • 原文地址:https://www.cnblogs.com/zhjh256/p/6444398.html
Copyright © 2011-2022 走看看