• Rocket MQ


    零、定义:一个消息中间件,貌似是参考kafaka做的,是面向集群和大数据的

    一、官网

    二、部署

      1、先看看这个quick start http://rocketmq.apache.org/docs/quick-start/

      2、docker安装centos最新版,目前是8,参考,因为docker run 启动后没办法直接再修改端口,所以,我安装启动用的:docker run -it -p 9876:9876 -p 8080:8080 -p 10911:10911 centos  /bin/bash

      3、安装maven,并添加阿里源(参考https://www.cnblogs.com/gabin/p/13810848.html

    yum install maven

      4、在/opt下载安装

        4.1、下载:curl https://mirrors.tuna.tsinghua.edu.cn/apache/rocketmq/4.7.1/rocketmq-all-4.7.1-source-release.zip -o rocketmq.zip

        4.2、没有zip的话,自己安装下:yum install zip

        4.3、解压 unzip rocketmq.zip

        4.4、进入目录 cd rocketmq-all-4.7.1-source-release

        4.5、编译(没增加阿里云源的就看运气吧,哦对了还有网速,反正我执行了挺久,娃哈哈):mvn -Prelease-all -DskipTests clean install -U

        4.6、进入编译好的文件目录:cd distribution/target

        4.7、拷贝到/opt: cp -r rocketmq-4.7.1/* /opt/rocketmq

        4.8、进入执行目录:cd /opt/rocketmq

        4.9、后面直接参考 【三、启动】吧 

    三、启动

    • nameserver:无状态的注册中心(注册中心结合微服务的Eureka理解,无状态是因为name server之间并不通信,也不保持同步)  
      • nohup sh bin/mqnamesrv &
    • broker:理解为微服务中的一个具体服务,可以有多个,多个broker连接nameserver就形成一个集群
      • # n代表name server的地址,9876是name server的默认端口
        nohup sh bin/mqbroker -n localhost:9876 &

      问题1:ps:broker启动失败,启动内存设置过大

      vim /opt/rocketmq/bin/runbroker.sh

      这行改一下:JAVA_OPT="${JAVA_OPT} -server -Xms8g -Xmx8g -Xmn4g"

      我是改成:JAVA_OPT="${JAVA_OPT} -server -Xms1g -Xmx1g -Xmn512m"

      反正改到可以启动(改小值)

      问题2:demo No route info of this topic

      我用的是4.7.1的服务,然后客户端用4.7.0,4.7.1有问题

      还有试一下这个:mqbroker -n localhost:9876 autoCreateTopicEnable=true

       反正感觉坑还挺多的

      示例参考 https://github.com/gabinlin/study/tree/master/rocketmq

    四、安装监控系统

      由于没有自带监控,需要自己下载一个扩展项目,监控后台部署:https://github.com/apache/rocketmq-externals,这下面的rocketmq-console,可以直接用spring-boot启动(application.properties修改下参数rocketmq.config.namesrv-addr=localhost:9876)

      这边顺便补个安装到服务器上的步骤吧

      1、先安装git:yum install git

      2、下载源码(当然也可以直接下载文件,不一定要用git clone,说实话git clone还挺慢的。。。。但是好处就是有更新版本,可以直接更新后重新编译):git clone https://github.com/apache/rocketmq-externals

      3、实在是慢,还是建议直接下源码文件吧。。。。

      4、总算好了:cd rocketmq-externals/rocketmq-console

      5、打包安装包:mvn package -Dmaven.test.skip=true

      6、启动,cd target;:java -jar rocketmq-console-ng-2.0.0.jar --rocketmq.config.namesrv-addr=localhost:9876

      7、好了访问本地8080端口,这个docker启动centos的时候已经映射好了

    五、发送消息(Demo代码待补)

      1、同步消息:简单来说就是A给Broker发送消息,需要同步收到Broker的回执  

      2、异步消息:简单来说就是A给Broker发送消息,可以异步收到Broker的回执(通过回调的方式),相当于n条消息发送完之后再来看发送的结果(这个描述并不严谨,但大致逻辑是这样的)

      3、单向消息:简单来说就是A给Broker发送消息,不需要回执,不管收到没,反正我发了

      4、事务消息:二阶段提交的一种做法,先举个例子:比如我去接我老婆下班,

      场景1、

        我:老婆,可以去接你了吗(发送一个HAFT Msg,待确认的消息)

        老婆:可以,我今天不加班,可以准时下班(收到Broker的回复)

        我:好的,那我出发了(收到回复之后执行本地方法)

        我:老婆,我到了,你可以下来了(执行完本地方法后,给broker发送确认提交的消息)

        老婆:那我下来了(broker获取到本地方法执行的结果后,执行不同的操作,这边是提交,下面再举个回滚的例子)

      场景2、

        我:老婆,可以去接你了吗(发送一个HAFT Msg,待确认的消息)

        老婆:可以,我今天不加班,可以准时下班(收到Broker的回复)

        我:好的,那我出发了(收到回复之后执行本地方法)

        我:老婆,我这边领导临时安排任务过不去了(本地方法执行失败后,给broker发送回滚的消息)

        老婆:那我自己打车回去(broker获取到本地方法执行的结果后,执行不同的操作,这边是回滚)

      场景3、

        我:老婆,可以去接你了吗(发送一个HAFT Msg,待确认的消息)

        老婆:可以,我今天不加班,可以准时下班(收到Broker的回复)

        我:好的,那我出发了(收到回复之后执行本地方法)

        我:领导直接过来催任务了,没时间给老婆回信息(本地方法执行的结果一直没有发给broker)

        老婆:打个电话问一下,怎么还没来,还没人接,等着跪搓衣板吧(事务消息的回查机制,查询本地事务的执行情况)

        老婆:打了n次还没人接,算了我自己打车回家(多次查询不到结果,就放弃,这边其实也有可能得到的是:老婆,再等等,我也不确定什么时候可以下班,这种则属于消息回复状态中的UNKNOW状态)

      场景4、

        我:老婆,可以去接你了吗(发送一个HAFT Msg,待确认的消息)

        老婆:可以,我今天不加班,可以准时下班(收到Broker的回复)

        我:好的,那我出发了(收到回复之后执行本地方法)

        我:领导直接过来催任务了,没时间给老婆回信息(本地方法执行的结果一直没有发给broker)

        老婆:打个电话问一下,怎么还没来

        我:来了来了,刚才领导临时有个事处理下,还好是个小问题,我三下五除二给解决了,我现在已经到你楼下了

        老婆:那我下来了

       

    六、对于事务消息的思考:

      刚学用这个的时候我也很迷糊,这玩意咋用呀?

      后面我突然想起来,以前系统里面用过一个东西。

      就是比如我们支付成功,订单状态扭转,要给用户发送微信通知。这个时候,是有可能这个支付成功的代码提交失败的,那这个时候可能消息就发送出去了。咋办?

      比较直接的做法就是注册个Commit事务的监听方法,在事务提交成功之后才发送消息,那又衍生另外一个问题:啊,万一我发送消息还没成功,服务器挂了怎么办

      哈哈,我们之前的系统是不管消息发不发送成功的,因为觉得不重要,但这里要是个重要的事务性逻辑,那可不能这么干,所以呢,结合刚才的事务性消息的大致原理和流程,我们改进一下

      我在本地方法开始执行前发送一个预提交的信息到broker,然后本地方法执行完成之后,给broker发送确认(如果失败,则做业务补偿方案:自动或人工都可以)。确认完我们干另外一件事情,如果此时broker一直收不到结果,那么会触发回查机制(这个就是一致性的重点了,回查机制确保这个消息最终会被发送出去,或者不需要发送就结束)。

      这个流程其实像是TCC的一个流程,或者就是吧,不太确定。

      反正经过这个改造,我们可以确认在订单确认支付成功之后才发送短信,而且也不会因为发送短信的时候服务器宕机而不再重新发送。

      题外话:其实我们之前是直接存储一个本地事件表,如果提交成功,本地事件表就会有一条记录,根据这条记录继续操作发送微信通知,哈哈。就是需要另外扩展一个本地事件表的机制,还有就是实时性比不上监听的模式

    暂时还有docker无法访问内部IP的问题,等有时间了解下,再弄 

  • 相关阅读:
    JavaScript引用类型
    Java08_方法
    网络爬虫(一)
    openCV(四)——鼠标绘制
    openCV(三)——视频
    openCV(二)——基础绘制函数
    openCV(一) 读取保存图像
    JAVA07-数组
    JAVA06-while循环,do while循环
    JAVA05-switch多重选择
  • 原文地址:https://www.cnblogs.com/gabin/p/13807986.html
Copyright © 2020-2023  润新知