Rocketmq 入门--部属

入门文章:

看了那么多,讲的比较好的: https://m.aliyun.com/yunqi/articles/66110

比较全面的:https://blog.csdn.net/column/details/learningrocketmq.html


集群部属 rocketmq 4.2.0:

前提:安装 64bit jdk1.8+   maven(编译源码使用)

服务器分配
192.168.226.141  A          name service
192.168.226.128  B broker1 master
192.168.226.142  C broker1 slave
192.168.226.143  D broker2 master
192.168.226.144  E broker2 slvae

配置各机器机器host
192.168.226.141  A
192.168.226.128  B
192.168.226.142  C
192.168.226.143  D
192.168.226.144  E

下载
https://www.apache.org/dyn/closer.cgi?path=rocketmq/4.2.0/rocketmq-all-4.2.0-source-release.zip

编译
$ unzip rocketmq-all-4.2.0-source-release.zip
$ cd rocketmq-all-4.2.0/
$ mvn -Prelease-all -DskipTests clean install -U
$ cd distribution/target/apache-rocketmq

apache-rocketmq.zip 就是是编译后的可执行文件

把可以执行文件copy 到 ~ 目录下并解压
$ cp apache-rocketmq.zip ~ && unzip apache-rocketmq.zip -d rocketmq

目录说明
benchmark     用于基准测试
bin    可执行的命令
conf          配置文件(包含broker 配置,和日志文件的配置)     
lib   依赖的包
LICENSE  
NOTICE  
README.md

修改配置  (参考官网配置: https://rocketmq.apache.org/docs/rmq-deployment/)

这里使用2个主,每个主有一个备机、异步组刷盘方式 conf/2m-2s-async

主要修改
namesrvAddr=a:9876   #如果有多个,使用 ; 隔开 
brokerId=0      #主 broker 此值是0,备机的都大于0,  互为主备的服务 brokerName 相同
brokerRole=ASYNC_MASTER    # 备机是SLVAE

修改配置如下:  目录:rocketmq/conf/2m-2s-async
broker-a.properties 
brokerClusterName=DefaultCluster
brokerName=broker-a
brokerId=0
deleteWhen=04
fileReservedTime=48
brokerRole=ASYNC_MASTER
flushDiskType=ASYNC_FLUSH
namesrvAddr=a:9876

broker-a-s.properties
brokerClusterName=DefaultCluster
brokerName=broker-a
brokerId=1
deleteWhen=04
fileReservedTime=48
brokerRole=SLAVE
flushDiskType=ASYNC_FLUSH
namesrvAddr=a:9876

broker-b.properties
brokerClusterName=DefaultCluster
brokerName=broker-b
brokerId=0
deleteWhen=04
fileReservedTime=48
brokerRole=ASYNC_MASTER
flushDiskType=ASYNC_FLUSH
namesrvAddr=a:9876

broker-b-s.properties
brokerClusterName=DefaultCluster
brokerName=broker-b
brokerId=1
deleteWhen=04
fileReservedTime=48
brokerRole=SLAVE
flushDiskType=ASYNC_FLUSH
namesrvAddr=a:9876

注意:配置左右不能有空格,在源码中没有字符串 trim

扫描二维码关注公众号,回复: 1477332 查看本文章


修改jvm 启动参数:     参考官网:http://rocketmq.apache.org/docs/system-config/

$ vim bin/runserver.sh
内存大小和GC设置如下
JAVA_OPT="${JAVA_OPT} -server -Xms256m -Xmx256m -Xmn128m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"
JAVA_OPT="${JAVA_OPT} -XX:+AlwaysPreTouch -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m"

修改broker jvm 参数,修改内存大小
$ vim bin/runbroker.sh
JAVA_OPT="${JAVA_OPT} -server -Xms256m -Xmx256m -Xmn128m"

把修改后的rocketmq 发送到各服务器(其它机器省略了)

$ scp -r rocketmq  jamin@b:~

在各机器上创建日志目录(日志路径可以看相关配置,使用的是logback记录日志的)
$ cd ~ && mkdir -p logs/rocketmqlogs


启动nameserver,在机器A 上执行

$ nohup sh bin/mqnamesrv &


启动broker

b服务器上启动:
$ nohup sh bin/mqbroker -c conf/2m-2s-async/broker-a.properties &
c服务器上启动:
$ nohup sh bin/mqbroker -c conf/2m-2s-async/broker-a-s.properties &
d服务器上启动:
$ nohup sh bin/mqbroker -c conf/2m-2s-async/broker-b.properties &
d服务器上启动:
$ nohup sh bin/mqbroker -c conf/2m-2s-async/broker-b-s.properties &

都是java进程,可以使用jps查看是否启动
注:rocketmq 进行系统优化,使用NOOP调度算法
$ sudo ~/rocketmq/bin/os.sh

测试:

代码

/**
 * mq 配置信息
 */
public class RocketMQConfigure {

    /**
     * name server 地址,多个用分号隔开
     */
    public static String NAMESRV_ADDR = "192.168.226.141:9876";

    /**
     * broker 组名
     */
    public static String BROKER_GROUP = "test_broker_group";

    /**
     * consumer 组名
     */
    public static String CONSUMER_GROUP = "test_consumer_group";


    /**
     * 消息主题
     */
    public static String MESSAGE_TOPIC ="test_message_topic";

    /**
     * 消息key 前缀,消息key一般是业务的主键
     */
    public static String MESSAGE_KEY_PREFIX = "message_key_prefix:";

    /**
     * 消息tag
     */
    public static String MESSAGE_TAG_A ="test_tag_a";
    public static String MESSAGE_TAG_B ="test_tag_b";


    /**
     * 默认编码格式
     */
    public static String DEFAULT_CHARSET="UTF-8";

}

生产者:

/**
 * 简单生产者
 */
public class SimpleProducer {

    public static void main(String[] args)  throws Exception{

        //使用 默认生产者,参考官网
        DefaultMQProducer producer = new DefaultMQProducer(RocketMQConfigure.BROKER_GROUP);
        //设置name server 地址
        producer.setNamesrvAddr(RocketMQConfigure.NAMESRV_ADDR);

        try {
            //启动生产者
            producer.start();

            for (int i = 0; i < 10; i++) {
                //创建一个消息,指定 topic , tags, 消息体
                Message msg = new Message(RocketMQConfigure.MESSAGE_TOPIC ,RocketMQConfigure.MESSAGE_TAG_A,
                        ("Hello RocketMQ " +i).getBytes(RocketMQConfigure.DEFAULT_CHARSET));

                //发送消息到一个broker,默认是 SYNC即可靠消息传输。还有异步传输,单向传输 可以参考官网
                SendResult sendResult = producer.send(msg);
                System.out.printf("%s%n", sendResult);

            }
            
        } catch (MQClientException e) {
            e.printStackTrace();
        } finally {
            producer.shutdown();
        }
    }
    
}

消费者:

public class SimpleConsumer {

    public static void main(String[] args)  throws Exception{

        //使用 默认生产者,参考官网
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(RocketMQConfigure.CONSUMER_GROUP);
        consumer.setNamesrvAddr(RocketMQConfigure.NAMESRV_ADDR);

        //订阅消息,指定订阅消息的 topic 和 tag
        consumer.subscribe(RocketMQConfigure.MESSAGE_TOPIC, RocketMQConfigure.MESSAGE_TAG_A);

        //设置集群消息
        consumer.setMessageModel(MessageModel.CLUSTERING);

        //设置消息监听,这里使用并发的监听 MessageListenerConcurrently,还有一个顺序的监听 MessageListenerOrderly,可以查看源码
        consumer.registerMessageListener(new MessageListenerConcurrently() {
            @Override
            public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
                msgs.forEach(msg->{
                    System.out.println("消费消息:"+new String(msg.getBody()));
                });
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });
        consumer.start();
    }
}
测试结果:
先启动消费者
再启动生产者,生产者打印输出如下:
SendResult [sendStatus=SEND_OK, msgId=C0A8E28000002A9F0000000000000714, messageQueue=MessageQueue [topic=test_message_topic, brokerName=broker-a, queueId=0], queueOffset=4]
SendResult [sendStatus=SEND_OK, msgId=C0A8E28000002A9F00000000000007AB, messageQueue=MessageQueue [topic=test_message_topic, brokerName=broker-a, queueId=1], queueOffset=4]
SendResult [sendStatus=SEND_OK, msgId=C0A8E28000002A9F0000000000000842, messageQueue=MessageQueue [topic=test_message_topic, brokerName=broker-a, queueId=2], queueOffset=2]
SendResult [sendStatus=SEND_OK, msgId=C0A8E28000002A9F00000000000008D9, messageQueue=MessageQueue [topic=test_message_topic, brokerName=broker-a, queueId=3], queueOffset=2]
SendResult [sendStatus=SEND_OK, msgId=C0A8E28F00002A9F00000000000004B8, messageQueue=MessageQueue [topic=test_message_topic, brokerName=broker-b, queueId=0], queueOffset=2]
SendResult [sendStatus=SEND_OK, msgId=C0A8E28F00002A9F000000000000054F, messageQueue=MessageQueue [topic=test_message_topic, brokerName=broker-b, queueId=1], queueOffset=2]
SendResult [sendStatus=SEND_OK, msgId=C0A8E28F00002A9F00000000000005E6, messageQueue=MessageQueue [topic=test_message_topic, brokerName=broker-b, queueId=2], queueOffset=2]
SendResult [sendStatus=SEND_OK, msgId=C0A8E28F00002A9F000000000000067D, messageQueue=MessageQueue [topic=test_message_topic, brokerName=broker-b, queueId=3], queueOffset=2]
SendResult [sendStatus=SEND_OK, msgId=C0A8E28000002A9F0000000000000970, messageQueue=MessageQueue [topic=test_message_topic, brokerName=broker-a, queueId=0], queueOffset=5]
SendResult [sendStatus=SEND_OK, msgId=C0A8E28000002A9F0000000000000A07, messageQueue=MessageQueue [topic=test_message_topic, brokerName=broker-a, queueId=1], queueOffset=5]


测试总结:

1、从日志中可以看出,每个消息被分配到不同的 MessageQueue。
猜测:每个broker 管理多个 MessageQueue,这些MessageQueue 又通过 message topic 分组。所有就有了 MessageQueue [topic=test_message_topic, brokerName=broker-a, queueId=1] 类似这样的结构(知道的可以在留言)。

2、在consumer 中消费消息也可以通过定义 MessageQueue 拉取消息消费,代码如下:
DefaultMQPullConsumer pullConsumer  = new DefaultMQPullConsumer();
pullConsumer.fetchConsumeOffset(MessageQueue mq, boolean fromStore);

3、通过这两个方法获取 topic 的 MessageQueue,返回的都是Set<MessageQueue>
pullConsumer.fetchMessageQueuesInBalance(String topic)

pullConsumer.fetchSubscribeMessageQueues(String topic)




猜你喜欢

转载自blog.csdn.net/convict_eva/article/details/80510657
今日推荐