初识MQ,JMS与RocketMQ

  ·在使用SpringCloud或Dubbo进行SOA架构后,不同的应用层模块(web)与业务层模块(service)要建立调用关系,也就是依赖/耦合

  ·当模块变多时,模块间的耦合度也会逐步上升,这就需要一个解耦工具:消息中间件

  ·另外,如果某个业务流程分为很多步,某一步特别耗时间且不稳定,整个业务的稳定性就会受很大影响,这时也需要用消息中间件来分离这些不稳定的业务过程

  消息中间件利用高效可靠的消息传递机制进行平台无关的数据交流,并基于数据通信来进行分布式系统的集成。通过提供消息传递和消息排队模型,它可以在分布式环境下扩展进程间的通信。

  在这里面,关键的部分是“消息传递”和“消息排队”,可以保证事件的顺序性,也可以在高并发下使用。

  执行过程长,且不需要返回结果的功能,可以利用MQ传递(MQ的异步通信特征)

  JMS(Java Message Service),是一套接口规范,在jdk中已定义好接口(类似于JDBC,只有JDBC无法操作数据库,需要具体的驱动来实现功能)。

  ·TextMessage(String)——普通文本(用得最多)

  ·MapMessage(Map)——键值对集合(用的次多)

  ·ObjectMessage(Serializable Object)——可序列化的对象

  ·BytesMessage(byte[])——字节数组

  ·StreamMessage(Stream)——流数据

  JMS的传递模式非常像观察者模式的思路:

  定义对象间的一种一对多的依赖关系,让多个观察者同时监听某一个主题现象,当一个对象的状态发生改变时,会通知所有观察者对象,所有依赖于它的对象都得到通知并被自动更新。

  观察者模式——https://my.oschina.net/LinkedBear/blog/1791975

  消息传递的方式有两种:

  ·Queue点对点(生产者与消费者的一对一关系)

  

 

  ·Topic发布-订阅(生产者与消费者的一对多关系)

  

 

  

 

  引用文章图片:https://blog.csdn.net/jasonhui512/article/details/53231566

  

 

  选用阿里巴巴的RocketMQ(现已被Apache接手),搭建Demo工程

  参考文档:http://rocketmq.apache.org/docs/simple-example/

  projectxmlns=http://maven.apache.org/POM/4.0.0xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance

  xsi:schemaLocation=http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd

  modelVersion4.0.0/modelVersion

  groupIdcom.linkedbear/groupId

  artifactIdRocketMQ-Demo/artifactId

  version0.0.1-SNAPSHOT/version

  properties

  rocketmq.version4.3.0/rocketmq.version

  /properties

  parent

  groupIdorg.springframework.boot/groupId

  artifactIdspring-boot-starter-parent/artifactId

  version2.0.0.RELEASE/version

  /parent

  dependencies

  dependency

  groupIdorg.springframework.boot/groupId

  artifactIdspring-boot-starter-web/artifactId

  /dependency

  !--RocketMQ--

  dependency

  groupIdorg.apache.rocketmq/groupId

  artifactIdrocketmq-client/artifactId

  version${rocketmq.version}/version

  /dependency

  !--热部署--

  dependency

  groupIdorg.springframework.boot/groupId

  artifactIdspring-boot-devtools/artifactId

  /dependency

  /dependencies

  build

  plugins

  plugin

  artifactIdmaven-compiler-plugin/artifactId

  configuration

  source1.8/source

  target1.8/target

  /configuration

  /plugin

  /plugins

  /build

  /project

  

 

  /**

  *生产者Controller

  *@TitleProducerController

  *@authorLinkedBear

  */

  @Controller

  publicclassProducerController{

  //此分组名必须保证全局唯一(考虑到负载均衡等后续问题),故封装为静态常量

  publicstaticfinalStringPRODUCE_GROUP_NAME=TestGroup;

  //MQ的运行地址

  publicstaticfinalStringMQ_IP=127.0.0.1:9876;

  @RequestMapping(/produceMessage)

  @ResponseBody

  publicMapString,ObjectproduceMessage()throwsException{

  //1.创建生产者连接(类似于JDBC中的Connection),要传入MQ的分组名

  DefaultMQProducerproducer=newDefaultMQProducer(PRODUCE_GROUP_NAME);

  //2.设置MQ的运行地址

  producer.setNamesrvAddr(MQ_IP);

  //3.开启连接

  producer.start();

  //4.构造消息(重载方法较多,此处选择topic,tag,message的三参数方法)

  Messagemessage=newMessage(test_topic,test_tag,(test_message。。。+Math.random()).getBytes());

  //5.发送消息,该方法会返回一个发送结果的对象

  SendResultresult=producer.send(message);

  System.out.println(result.getSendStatus());

  //6.关闭连接

  producer.shutdown();

  //此处将发送结果显示在页面上,方便查看

  MapString,Objectmap=newHashMap();

  map.put(消息,result.getSendStatus());

  returnmap;

  }

  }

  /**

  *消费者Controller

  *@TitleConsumerController

  *@authorLinkedBear

  */

  @Controller

  publicclassConsumerController{

  @RequestMapping(/getMessage)

  @ResponseBody

  publicvoidgetMessage()throwsException{

  //1.创建消费者连接,要传入MQ的分组名,该分组名在ProducerController中

  //此处创建的是pushConsumer,它使用监听器,给人的感觉是消息被推送的

  //pullConsumer,取消息的过程需要自己写

  DefaultMQPushConsumerconsumer=newDefaultMQPushConsumer(ProducerController.PRODUCE_GROUP_NAME);

  //2.设置MQ的运行地址

  consumer.setNamesrvAddr(ProducerController.MQ_IP);

  //3.设置消息的提取顺序

  consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);

  //4.设置消费者接收消息的Topic和Tag,此处对Tag不作限制

  consumer.subscribe(test_topic,*);

  //5.使用监听器接收消息

  consumer.registerMessageListener(newMessageListenerConcurrently(){

  @Override

  publicConsumeConcurrentlyStatusconsumeMessage(ListMessageExtmsgs,

  ConsumeConcurrentlyContextcontext){

  try{

  for(MessageExtmessageExt:msgs){

  Stringmessage=newString(messageExt.getBody(),utf-8);

  System.out.println(收到消息【主题:+messageExt.getTopic()+,正文:+message+】);

  }

  returnConsumeConcurrentlyStatus.CONSUME_SUCCESS;

  }catch(Exceptione){

  //转换出现问题,稍后重新发送

  returnConsumeConcurrentlyStatus.RECONSUME_LATER;

  }

  }

  });

  //6.启动消费者

  consumer.start();

  }

  }

  执行http://localhost:8080/produceMessage:

  

 

  

 

  执行http://localhost:8080/getMessage:

  

 

  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值