最全花了3天总结的RabbitMQ实用技巧,有点东西(1),字节跳动+京东+美团+腾讯面试总结

最后

既已说到spring cloud alibaba,那对于整个微服务架构,如果想要进一步地向上提升自己,到底应该掌握哪些核心技能呢?

就个人而言,对于整个微服务架构,像RPC、Dubbo、Spring Boot、Spring Cloud Alibaba、Docker、kubernetes、Spring Cloud Netflix、Service Mesh等这些都是最最核心的知识,架构师必经之路!下图,是自绘的微服务架构路线体系大纲,如果有还不知道自己该掌握些啥技术的朋友,可根据小编手绘的大纲进行一个参考。

image

如果觉得图片不够清晰,也可来找小编分享原件的xmind文档!

且除此份微服务体系大纲外,我也有整理与其每个专题核心知识点对应的最强学习笔记:

  • 出神入化——SpringCloudAlibaba.pdf

  • SpringCloud微服务架构笔记(一).pdf

  • SpringCloud微服务架构笔记(二).pdf

  • SpringCloud微服务架构笔记(三).pdf

  • SpringCloud微服务架构笔记(四).pdf

  • Dubbo框架RPC实现原理.pdf

  • Dubbo最新全面深度解读.pdf

  • Spring Boot学习教程.pdf

  • SpringBoo核心宝典.pdf

  • 第一本Docker书-完整版.pdf

  • 使用SpringCloud和Docker实战微服务.pdf

  • K8S(kubernetes)学习指南.pdf

image

另外,如果不知道从何下手开始学习呢,小编这边也有对每个微服务的核心知识点手绘了其对应的知识架构体系大纲,不过全是导出的xmind文件,全部的源文件也都在此!

image

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

simpleSender.send();

ThreadUtil.sleep(1000);

}

return CommonResult.success(null);

}

}

  • 运行后结果如下,可以发现生产者往队列中发送消息,消费者从队列中获取消息并消费。

花了3天总结的RabbitMQ实用技巧,有点东西

花了3天总结的RabbitMQ实用技巧,有点东西

工作模式

=======================================================================

工作模式是指向多个互相竞争的消费者发送消息的模式,它包含一个生产者、两个消费者和一个队列。两个消费者同时绑定到一个队列上去,当消费者获取消息处理耗时任务时,空闲的消费者从队列中获取并消费消息。

模式示意图

========================================================================

花了3天总结的RabbitMQ实用技巧,有点东西

Spring AMQP实现

================================================================================

  • 添加工作模式相关Java配置,创建一个名为work.hello的队列、一个生产者和两个消费者;

/**

  • Created by macro on 2020/5/19.

*/

@Configuration

public class WorkRabbitConfig {

@Bean

public Queue workQueue() {

return new Queue(“work.hello”);

}

@Bean

public WorkReceiver workReceiver1() {

return new WorkReceiver(1);

}

@Bean

public WorkReceiver workReceiver2() {

return new WorkReceiver(2);

}

@Bean

public WorkSender workSender() {

return new WorkSender();

}

}

  • 生产者通过send方法向队列work.hello中发送消息,消息中包含一定数量的.号;

/**

  • Created by macro on 2020/5/19.

*/

public class WorkSender {

private static final Logger LOGGER = LoggerFactory.getLogger(WorkSender.class);

@Autowired

private RabbitTemplate template;

private static final String queueName = “work.hello”;

public void send(int index) {

StringBuilder builder = new StringBuilder(“Hello”);

int limitIndex = index % 3+1;

for (int i = 0; i < limitIndex; i++) {

builder.append(‘.’);

}

builder.append(index+1);

String message = builder.toString();

template.convertAndSend(queueName, message);

LOGGER.info(" [x] Sent ‘{}’", message);

}

  • 两个消费者从队列work.hello中获取消息,名称分别为instance 1和instance 2,消息中包含.号越多,耗时越长;

/**

  • Created by macro on 2020/5/19.

*/

@RabbitListener(queues = “work.hello”)

public class WorkReceiver {

private static final Logger LOGGER = LoggerFactory.getLogger(WorkReceiver.class);

private final int instance;

public WorkReceiver(int i) {

this.instance = i;

}

@RabbitHandler

public void receive(String in) {

StopWatch watch = new StopWatch();

watch.start();

LOGGER.info(“instance {} [x] Received ‘{}’”, this.instance, in);

doWork(in);

watch.stop();

LOGGER.info(“instance {} [x] Done in {}s”, this.instance, watch.getTotalTimeSeconds());

}

private void doWork(String in) {

for (char ch : in.toCharArray()) {

if (ch == ‘.’) {

ThreadUtil.sleep(1000);

}

}

}

}

  • 在controller中添加测试接口,调用该接口开始发送消息;

/**

  • Created by macro on 2020/5/19.

*/

@Api(tags = “RabbitController”, description = “RabbitMQ功能测试”)

@Controller

@RequestMapping(“/rabbit”)

public class RabbitController {

@Autowired

private WorkSender workSender;

@ApiOperation(“工作模式”)

@RequestMapping(value = “/work”, method = RequestMethod.GET)

@ResponseBody

public CommonResult workTest() {

for(int i=0;i<10;i++){

workSender.send(i);

ThreadUtil.sleep(1000);

}

return CommonResult.success(null);

}

}

  • 运行后结果如下,可以发现生产者往队列中发送包含不同数量.号的消息,instance 1和instance 2消费者互相竞争,分别消费了一部分消息。

花了3天总结的RabbitMQ实用技巧,有点东西

花了3天总结的RabbitMQ实用技巧,有点东西

花了3天总结的RabbitMQ实用技巧,有点东西

发布/订阅模式

==========================================================================

发布/订阅模式是指同时向多个消费者发送消息的模式(类似广播的形式),它包含一个生产者、两个消费者、两个队列和一个交换机。两个消费者同时绑定到不同的队列上去,两个队列绑定到交换机上去,生产者通过发送消息到交换机,所有消费者接收并消费消息。

模式示意图

========================================================================

花了3天总结的RabbitMQ实用技巧,有点东西

Spring AMQP实现

================================================================================

  • 添加发布/订阅模式相关Java配置,创建一个名为exchange.fanout的交换机、一个生产者、两个消费者和两个匿名队列,将两个匿名队列都绑定到交换机;

/**

  • Created by macro on 2020/5/19.

*/

@Configuration

public class FanoutRabbitConfig {

@Bean

public FanoutExchange fanout() {

return new FanoutExchange(“exchange.fanout”);

}

@Bean

public Queue fanoutQueue1() {

return new AnonymousQueue();

}

@Bean

public Queue fanoutQueue2() {

return new AnonymousQueue();

}

@Bean

public Binding fanoutBinding1(FanoutExchange fanout, Queue fanoutQueue1) {

return BindingBuilder.bind(fanoutQueue1).to(fanout);

}

@Bean

public Binding fanoutBinding2(FanoutExchange fanout, Queue fanoutQueue2) {

return BindingBuilder.bind(fanoutQueue2).to(fanout);

}

@Bean

public FanoutReceiver fanoutReceiver() {

return new FanoutReceiver();

}

@Bean

public FanoutSender fanoutSender() {

return new FanoutSender();

}

}

  • 生产者通过send方法向交换机exchange.fanout中发送消息,消息中包含一定数量的.号;

/**

  • Created by macro on 2020/5/19.

*/

public class FanoutSender {

private static final Logger LOGGER = LoggerFactory.getLogger(FanoutSender.class);

@Autowired

private RabbitTemplate template;

private static final String exchangeName = “exchange.fanout”;

public void send(int index) {

StringBuilder builder = new StringBuilder(“Hello”);

int limitIndex = index % 3 + 1;

for (int i = 0; i < limitIndex; i++) {

builder.append(‘.’);

}

builder.append(index + 1);

String message = builder.toString();

template.convertAndSend(exchangeName, “”, message);

LOGGER.info(" [x] Sent ‘{}’", message);

}

}

  • 消费者从绑定的匿名队列中获取消息,消息中包含.号越多,耗时越长,由于该消费者可以从两个队列中获取并消费消息,可以看做两个消费者,名称分别为instance 1和instance 2;

/**

  • Created by macro on 2020/5/19.

*/

public class FanoutReceiver {

private static final Logger LOGGER = LoggerFactory.getLogger(FanoutReceiver.class);

@RabbitListener(queues = “#{fanoutQueue1.name}”)

public void receive1(String in) {

receive(in, 1);

}

@RabbitListener(queues = “#{fanoutQueue2.name}”)

public void receive2(String in) {

receive(in, 2);

}

private void receive(String in, int receiver) {

StopWatch watch = new StopWatch();

watch.start();

LOGGER.info(“instance {} [x] Received ‘{}’”, receiver, in);

doWork(in);

watch.stop();

LOGGER.info(“instance {} [x] Done in {}s”, receiver, watch.getTotalTimeSeconds());

}

private void doWork(String in) {

for (char ch : in.toCharArray()) {

if (ch == ‘.’) {

ThreadUtil.sleep(1000);

}

}

}

}

  • 在controller中添加测试接口,调用该接口开始发送消息;

/**

  • Created by macro on 2020/5/19.

*/

@Api(tags = “RabbitController”, description = “RabbitMQ功能测试”)

@Controller

@RequestMapping(“/rabbit”)

public class RabbitController {

@Autowired

private FanoutSender fanoutSender;

@ApiOperation(“发布/订阅模式”)

@RequestMapping(value = “/fanout”, method = RequestMethod.GET)

@ResponseBody

public CommonResult fanoutTest() {

for(int i=0;i<10;i++){

fanoutSender.send(i);

ThreadUtil.sleep(1000);

}

return CommonResult.success(null);

}

}

  • 运行后结果如下,可以发现生产者往队列中发送包含不同数量.号的消息,instance 1和instance 2同时获取并消费了消息。

花了3天总结的RabbitMQ实用技巧,有点东西

花了3天总结的RabbitMQ实用技巧,有点东西

花了3天总结的RabbitMQ实用技巧,有点东西

路由模式

=======================================================================

路由模式是可以根据路由键选择性给多个消费者发送消息的模式,它包含一个生产者、两个消费者、两个队列和一个交换机。两个消费者同时绑定到不同的队列上去,两个队列通过路由键绑定到交换机上去,生产者发送消息到交换机,交换机通过路由键转发到不同队列,队列绑定的消费者接收并消费消息。

模式示意图

========================================================================

花了3天总结的RabbitMQ实用技巧,有点东西

Spring AMQP实现

================================================================================

  • 添加路由模式相关Java配置,创建一个名为exchange.direct的交换机、一个生产者、两个消费者和两个匿名队列,队列通过路由键都绑定到交换机,队列1的路由键为orange和black,队列2的路由键为green和black;

/**

  • Created by macro on 2020/5/19.

*/

@Configuration

public class DirectRabbitConfig {

@Bean

public DirectExchange direct() {

return new DirectExchange(“exchange.direct”);

}

@Bean

public Queue directQueue1() {

return new AnonymousQueue();

}

@Bean

public Queue directQueue2() {

return new AnonymousQueue();

}

@Bean

public Binding directBinding1a(DirectExchange direct, Queue directQueue1) {

return BindingBuilder.bind(directQueue1).to(direct).with(“orange”);

}

@Bean

public Binding directBinding1b(DirectExchange direct, Queue directQueue1) {

return BindingBuilder.bind(directQueue1).to(direct).with(“black”);

}

@Bean

public Binding directBinding2a(DirectExchange direct, Queue directQueue2) {

return BindingBuilder.bind(directQueue2).to(direct).with(“green”);

}

@Bean

public Binding directBinding2b(DirectExchange direct, Queue directQueue2) {

return BindingBuilder.bind(directQueue2).to(direct).with(“black”);

}

@Bean

public DirectReceiver receiver() {

return new DirectReceiver();

}

@Bean

public DirectSender directSender() {

return new DirectSender();

}

}

  • 生产者通过send方法向交换机exchange.direct中发送消息,发送时使用不同的路由键,根据路由键会被转发到不同的队列;

/**

  • Created by macro on 2020/5/19.

*/

public class DirectSender {

@Autowired

private RabbitTemplate template;

private static final String exchangeName = “exchange.direct”;

private final String[] keys = {“orange”, “black”, “green”};

private static final Logger LOGGER = LoggerFactory.getLogger(DirectSender.class);

public void send(int index) {

StringBuilder builder = new StringBuilder("Hello to ");

int limitIndex = index % 3;

String key = keys[limitIndex];

builder.append(key).append(’ ');

builder.append(index+1);

String message = builder.toString();

template.convertAndSend(exchangeName, key, message);

LOGGER.info(" [x] Sent ‘{}’", message);

}

}

  • 消费者从自己绑定的匿名队列中获取消息,由于该消费者可以从两个队列中获取并消费消息,可以看做两个消费者,名称分别为instance 1和instance 2;

/**

  • Created by macro on 2020/5/19.

*/

public class DirectReceiver {

private static final Logger LOGGER = LoggerFactory.getLogger(DirectReceiver.class);

@RabbitListener(queues = “#{directQueue1.name}”)

public void receive1(String in){

receive(in, 1);

}

@RabbitListener(queues = “#{directQueue2.name}”)

public void receive2(String in){

receive(in, 2);

}

private void receive(String in, int receiver){

StopWatch watch = new StopWatch();

watch.start();

LOGGER.info(“instance {} [x] Received ‘{}’”, receiver, in);

doWork(in);

watch.stop();

LOGGER.info(“instance {} [x] Done in {}s”, receiver, watch.getTotalTimeSeconds());

}

private void doWork(String in){

for (char ch : in.toCharArray()) {

if (ch == ‘.’) {

ThreadUtil.sleep(1000);

}

}

}

}

  • 在controller中添加测试接口,调用该接口开始发送消息;

/**

  • Created by macro on 2020/5/19.

*/

@Api(tags = “RabbitController”, description = “RabbitMQ功能测试”)

@Controller

@RequestMapping(“/rabbit”)

public class RabbitController {

@Autowired

private DirectSender directSender;

@ApiOperation(“路由模式”)

@RequestMapping(value = “/direct”, method = RequestMethod.GET)

@ResponseBody

public CommonResult directTest() {

for(int i=0;i<10;i++){

directSender.send(i);

ThreadUtil.sleep(1000);

}

return CommonResult.success(null);

}

}

  • 运行后结果如下,可以发现生产者往队列中发送包含不同路由键的消息,instance 1获取到了orange和black消息,instance 2获取到了green和black消息。

花了3天总结的RabbitMQ实用技巧,有点东西

花了3天总结的RabbitMQ实用技巧,有点东西

花了3天总结的RabbitMQ实用技巧,有点东西

通配符模式

========================================================================

通配符模式是可以根据路由键匹配规则选择性给多个消费者发送消息的模式,它包含一个生产者、两个消费者、两个队列和一个交换机。两个消费者同时绑定到不同的队列上去,两个队列通过路由键匹配规则绑定到交换机上去,生产者发送消息到交换机,交换机通过路由键匹配规则转发到不同队列,队列绑定的消费者接收并消费消息。

特殊匹配符号

=========================================================================

  • *:只能匹配一个单词;

  • #:可以匹配零个或多个单词。

模式示意图

========================================================================

花了3天总结的RabbitMQ实用技巧,有点东西

Spring AMQP实现

================================================================================

  • 添加通配符模式相关Java配置,创建一个名为exchange.topic的交换机、一个生产者、两个消费者和两个匿名队列,匹配*.orange..*.rabbit发送到队列1,匹配lazy.#发送到队列2;

/**

  • Created by macro on 2020/5/19.

*/

@Configuration

public class TopicRabbitConfig {

@Bean

public TopicExchange topic() {

return new TopicExchange(“exchange.topic”);

}

@Bean

public Queue topicQueue1() {

return new AnonymousQueue();

}

@Bean

public Queue topicQueue2() {

return new AnonymousQueue();

}

@Bean

public Binding topicBinding1a(TopicExchange topic, Queue topicQueue1) {

return BindingBuilder.bind(topicQueue1).to(topic).with(“.orange.”);

}

@Bean

public Binding topicBinding1b(TopicExchange topic, Queue topicQueue1) {

读者福利

由于篇幅过长,就不展示所有面试题了,感兴趣的小伙伴

35K成功入职:蚂蚁金服面试Java后端经历!「含面试题+答案」

35K成功入职:蚂蚁金服面试Java后端经历!「含面试题+答案」

35K成功入职:蚂蚁金服面试Java后端经历!「含面试题+答案」

更多笔记分享

35K成功入职:蚂蚁金服面试Java后端经历!「含面试题+答案」

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

式相关Java配置,创建一个名为exchange.topic的交换机、一个生产者、两个消费者和两个匿名队列,匹配*.orange..*.rabbit发送到队列1,匹配lazy.#发送到队列2;

/**

  • Created by macro on 2020/5/19.

*/

@Configuration

public class TopicRabbitConfig {

@Bean

public TopicExchange topic() {

return new TopicExchange(“exchange.topic”);

}

@Bean

public Queue topicQueue1() {

return new AnonymousQueue();

}

@Bean

public Queue topicQueue2() {

return new AnonymousQueue();

}

@Bean

public Binding topicBinding1a(TopicExchange topic, Queue topicQueue1) {

return BindingBuilder.bind(topicQueue1).to(topic).with(“.orange.”);

}

@Bean

public Binding topicBinding1b(TopicExchange topic, Queue topicQueue1) {

读者福利

由于篇幅过长,就不展示所有面试题了,感兴趣的小伙伴

[外链图片转存中…(img-iHe4tfzQ-1715613011905)]

[外链图片转存中…(img-x3h0bdtd-1715613011905)]

[外链图片转存中…(img-tnN58AYh-1715613011905)]

更多笔记分享

[外链图片转存中…(img-A1mBQe6U-1715613011905)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值