springboot2 springcloud Greenwich.SR3 构建微服务--5.rabbitMQ的使用

本文主要是介绍springboot2 springcloud Greenwich.SR3 构建微服务--5.rabbitMQ的使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

其实在统一配置中心的时候就应该开始说rabbitmq 了, 但是没有说, 所以这里专门说下rabbitmq.

rabbitmq 在配置中心作为消息的传递来使用了.

 

rabbitmq的原理, 具体使用, 请查阅这个

https://blog.csdn.net/u010398771/article/details/84136959

 

现在的mq开源的不要太多了, 我最先用的activemq, 后来阿里开源的rocketmq,

还有 kafka, rabbitmq. 最近看新闻,腾讯也开源了他们用java写的MQ, 名字不记得了...又是个亿万级别的服务, 牛掰哄哄的样子

其实rabbitMQ的安装很简单, 这里就不推荐大家先下载erlang 再安装rabbitmq 了, 更不推荐你去编译源码安装, 因为我安装过一次, 装的时候,电脑卡, 时间又长, 你可以直接在你的docker里面安装一个rabbitmq, 就可以使用了,很方便.

docker安装rabbitmq, 先搜索目前的镜像

docker search rabbitmq

先拉取下来, 再创建容器运行.注意拉取带有management 的rabbitmq , 这是带控制带的版本.

#拉取镜像
docker pull rabbitmq:3.7.17-management#运行
docker run -d -p 5672:5672 -p 15672:15672 --name myrabbitmq rabbitmq:3.7.17-management

登陆网页端, http://localhost:15672,  用户名和密码都是guest, 就可以看到了管理页面了, 可以看到目前没有消息到来和消费

 

rabbitmq的使用

1.添加依赖

 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

2.添加配置文件

#rabbitmq的配置
spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
#解决input 和 output中重名bean问题,需要配置这个....
spring.cloud.stream.bindings.input.destination: raw-sensor-data
spring.cloud.stream.bindings.output.destination: raw-sensor-data

 

2.1. queue 的  bean的配置

//名字都变成常量
public class MessageConstant {public final static String INPUT = "input";public final static String OUTPUT = "output";public final static String QUEUE_NAME = "myQueue";}
/*** 注入一个queue, 不要去手动创建!*/@Beanpublic Queue queue(){return new Queue(MessageConstant.QUEUE_NAME,true);}

3.就开始发送和接收消息了.


import com.example.order.constans.MessageConstant;
import com.example.order.dto.OrderDTO;
import com.example.order.message.StreamClient;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;import java.time.LocalDateTime;/*** @author zk* @Description:* @date 2019-09-20 16:24*/
@RestController
public class SendMessageController {/*** 往rabbitmq发送消息*/@Autowiredprivate AmqpTemplate amqpTemplate;@GetMapping("send")public String sendMessage() {//需要实现创建一个myQueue的队列amqpTemplate.convertAndSend(MessageConstant.QUEUE_NAME, "this is the first message");
//第二种消息发送amqpTemplate.convertAndSend("myOrder", "computer", "this is the first computer  message");amqpTemplate.convertAndSend("myOrder", "fruit", "this is the first message");return "success";}@Autowired(required = false)private StreamClient streamClient;/*** 发送字符串对象** @return*//*@GetMapping("send2")public String send2() {String msg = "time  is today, haha ";System.out.println("发送的消息是:" + msg);streamClient.output().send(MessageBuilder.withPayload(msg).build());return "success";}*//*** 发送java bean对象* 这个send3 不能和send2 使用的同一个变量.但是不能共存, 需要注释掉, 不然报错的...** @return*/@GetMapping("send3")public String send3(){OrderDTO dto = new OrderDTO();dto.setBuyerAddress("address");dto.setBuyerName("xiexin");streamClient.output().send(MessageBuilder.withPayload(dto).build());return "success";}}

4.消息接收端


import com.example.order.constans.MessageConstant;
import com.example.order.dto.OrderDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Component;/*** @author zk* @Description: 接受消息* @date 2019-09-20 16:21*/
@Component
@EnableBinding(StreamClient.class)
public class StreamReceiver {/*** 接受字符串*//*@StreamListener(MessageConstant.INPUT)public void process(Object msg) {System.out.println(msg);}*//*** 接受orderDTO对象*/@StreamListener(MessageConstant.INPUT)@SendTo(MessageConstant.OUTPUT)//处理完消息,再回发送个消息public Object process(OrderDTO msg) {System.out.println(msg);//发送消息return "这是消息";}/*** 接受上面的回传的消息*/@StreamListener(MessageConstant.OUTPUT)public void process2(String msg) {System.out.println(msg);}}
import com.example.order.constans.MessageConstant;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;/*** @author zk* @Description:mq 接收消息* @date 2019-09-20 15:29*/
@Component
public class MQReceiver {//1.手动创建队列//@RabbitListener(queues= MessageConstant.QUEUE_NAME)//2.自动创建队列//@RabbitListener(queuesToDeclare = @Queue(MessageConstant.QUEUE_NAME))//3.自动创建 exchange 和 queue绑定@RabbitListener(bindings = @QueueBinding(value = @Queue(MessageConstant.QUEUE_NAME),exchange = @Exchange("myExchange")))public void process(String message){System.out.println("接收到的消息是:"+message);}/*** 按照exchange 和 key 进行匹配.* 数码消息接受商* @param message*/@RabbitListener(bindings = @QueueBinding(exchange = @Exchange("myOrder"),key = "computer",value = @Queue("computerOrder")))public void computerProcess(String message){System.out.println("computer接收到的消息是:"+message);}/*** 水果消息接受商* @param message*/@RabbitListener(bindings = @QueueBinding(exchange = @Exchange("myOrder"),key = "fruit",value = @Queue("fruitOrder")))public void fruitProcess(String message){System.out.println("fruit接收到的消息是:"+message);}}
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.example.product.entity.ProductInfo;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;import java.util.HashMap;
import java.util.List;
import java.util.Map;@Component
public class ProductInfoReceiver {private final static String HASH_KEY="product_stock";@Autowiredprivate StringRedisTemplate stringRedisTemplate;/*** 传递整个对象的方法* @param message*///@RabbitListener(queuesToDeclare = @Queue("productInfo"))public void process0(String message) {//注意反序列化的时候,两个对象的前缀要求是一样的(包名)//ProductInfo info = JSON.parseObject(message, ProductInfo.class);List<ProductInfo> infos = JSON.parseObject(message, new TypeReference<List<ProductInfo>>() {});System.out.println("接受到的消息是:" + infos);//存储到redis中去.//stringRedisTemplate.opsForValue()// .set("product_stock_" + info.getProductId(), String.valueOf(info.getProductStock()));/*** 单值的key -value 可以储存, 现在多个的时候, 最好使用hash 的方式进行存储* 这种单值的存储方式不好...* product_stock        1       5*      key           field   value*/for (ProductInfo info : infos) {stringRedisTemplate.opsForHash().put(HASH_KEY,info.getProductId(),info.getProductStock());}}/*** 只传递id和剩余库存的方法* 这里的参数的接收对象一定和发送的一致,不然rabbitmq会报类型转换错误.* json转换后,就是json的数组或者json字符串了.上面的那个方法是个反例* @param message*/@RabbitListener(queuesToDeclare = @Queue("productInfo"))public void process(Map<String,Integer> message) {//注意反序列化的时候,两个对象的前缀要求是一样的(包名)System.out.println("接受到的消息是:" + message);//存储到redis中去.//stringRedisTemplate.opsForValue()// .set("product_stock_" + info.getProductId(), String.valueOf(info.getProductStock()));/*** 单值的key -value 可以储存, 现在多个的时候, 最好使用hash 的方式进行存储* 这种单值的存储方式不好...* product_stock        1       5*      key           field   value*/for (Map.Entry<String, Integer> entry : message.entrySet()) {stringRedisTemplate.opsForHash().put(HASH_KEY,entry.getKey(),String.valueOf(entry.getValue()));}}}
import com.example.order.constans.MessageConstant;
import org.springframework.cloud.stream.annotation.Input;
import org.springframework.cloud.stream.annotation.Output;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.SubscribableChannel;/*** @author zk* @Description:* @date 2019-09-20 16:19*/
public interface StreamClient {/*** 这里的input 和 output 必须是不同的字符串, 不然是同名的bean错误*/@Input(MessageConstant.INPUT)SubscribableChannel input();@Output(MessageConstant.OUTPUT)MessageChannel output();}

rabbitmq 的消息是根据 queue  exchange  key 做的分类存储,

所以上面的myqueue中的不同的key 会得到不同的接收者那里去.

 

 

 突然觉得我好懒啊, 不愿意好好写博客, 想各种偷懒, 这东西更像在写自己的随手笔记了,而不是在写让大部分都能够看懂的博客. 

随便代码往这里一贴, 然后加几句解释就完事了, 不讲原理, 因为不想打字.  不想说流程, 因为懒的去画很好看的图出来, 懒的理由还很充分! .

甚至这一系列的博文中可能一些小章节中有误,  看了代码应该运行不起来, 但是我还是贴出来, 某些还涉及到其他地方的点滴, 没有在博客中体现出来, 感觉我就是在发垃圾博客!!!! 

这次一口气写十篇关于springcloud 的博文, 但是现在看起来, 估计写完后质量非常的差. 完全不是我想象的那样子,既能够自己总结, 又能帮助别人提高.

反思下自己!!!! 

不过写文章确实很花时间, 就这种水平的博客, 想写一个出来, 也差不多得花10分钟 ! 所以有了对这10篇博客的重新修改

 

整个代码地址是:

https://github.com/changhe626/micro-service

Java Framework,欢迎各位前来交流java相关
QQ群:965125360
 

 

 

这篇关于springboot2 springcloud Greenwich.SR3 构建微服务--5.rabbitMQ的使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/986270

相关文章

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

Linux join命令的使用及说明

《Linuxjoin命令的使用及说明》`join`命令用于在Linux中按字段将两个文件进行连接,类似于SQL的JOIN,它需要两个文件按用于匹配的字段排序,并且第一个文件的换行符必须是LF,`jo... 目录一. 基本语法二. 数据准备三. 指定文件的连接key四.-a输出指定文件的所有行五.-o指定输出

Java中Redisson 的原理深度解析

《Java中Redisson的原理深度解析》Redisson是一个高性能的Redis客户端,它通过将Redis数据结构映射为Java对象和分布式对象,实现了在Java应用中方便地使用Redis,本文... 目录前言一、核心设计理念二、核心架构与通信层1. 基于 Netty 的异步非阻塞通信2. 编解码器三、

Linux jq命令的使用解读

《Linuxjq命令的使用解读》jq是一个强大的命令行工具,用于处理JSON数据,它可以用来查看、过滤、修改、格式化JSON数据,通过使用各种选项和过滤器,可以实现复杂的JSON处理任务... 目录一. 简介二. 选项2.1.2.2-c2.3-r2.4-R三. 字段提取3.1 普通字段3.2 数组字段四.

Linux kill正在执行的后台任务 kill进程组使用详解

《Linuxkill正在执行的后台任务kill进程组使用详解》文章介绍了两个脚本的功能和区别,以及执行这些脚本时遇到的进程管理问题,通过查看进程树、使用`kill`命令和`lsof`命令,分析了子... 目录零. 用到的命令一. 待执行的脚本二. 执行含子进程的脚本,并kill2.1 进程查看2.2 遇到的

SpringBoot基于注解实现数据库字段回填的完整方案

《SpringBoot基于注解实现数据库字段回填的完整方案》这篇文章主要为大家详细介绍了SpringBoot如何基于注解实现数据库字段回填的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解... 目录数据库表pom.XMLRelationFieldRelationFieldMapping基础的一些代

一篇文章彻底搞懂macOS如何决定java环境

《一篇文章彻底搞懂macOS如何决定java环境》MacOS作为一个功能强大的操作系统,为开发者提供了丰富的开发工具和框架,下面:本文主要介绍macOS如何决定java环境的相关资料,文中通过代码... 目录方法一:使用 which命令方法二:使用 Java_home工具(Apple 官方推荐)那问题来了,

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

Java AOP面向切面编程的概念和实现方式

《JavaAOP面向切面编程的概念和实现方式》AOP是面向切面编程,通过动态代理将横切关注点(如日志、事务)与核心业务逻辑分离,提升代码复用性和可维护性,本文给大家介绍JavaAOP面向切面编程的概... 目录一、AOP 是什么?二、AOP 的核心概念与实现方式核心概念实现方式三、Spring AOP 的关

详解SpringBoot+Ehcache使用示例

《详解SpringBoot+Ehcache使用示例》本文介绍了SpringBoot中配置Ehcache、自定义get/set方式,并实际使用缓存的过程,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录摘要概念内存与磁盘持久化存储:配置灵活性:编码示例引入依赖:配置ehcache.XML文件:配置