在写这个文章前不得不吐槽目前国内一些blog的文章,尽是些复制粘贴的文章,提到点上但没任何的深入和例子。.........

经过测试下来总结一下RabbitMQ的Exchange的特性:

1、direct

生产者可以指定路由键,消费者可以指定路由键,但不能讲路由键设置为#(全部)。

2、topic

生产者可以指定路由键,消费者可以指定路由键,也可以不指定(或者是#)。

3、fanout

生产者和消费都忽略路由键。

在现实的场景里,通常是生产者会生产多个路由键的消费,然后多个消费来消费指定路由键的消息,但通常生产者的生产代码是同一份,如何在发消息的时候动态指定当前消息的路由键呢?

例子:门店平台系统集中处理多个门店的数据,然后分别将不同门店的数据发送到不同的门店(即:A门店只消费属于A门店的消息,B门店只消费属于B的消息)

看例子:

application.yml

 spring:
cloud:
stream:
# 设置默认的binder
default-binder: pos
binders:
scm:
type: rabbit
environment:
spring:
rabbitmq:
# 连接到scm的host和exchange
virtual-host: scm
pos:
type: rabbit
environment:
spring:
rabbitmq:
# 连接到pos的host和exchange
virtual-host: pos shop:
type: rabbit
environment:
spring:
rabbitmq:
# 连接到shop的host和exchange
virtual-host: shop bindings:
# ---------消息消费------------ # 集单开始生产消费
order_set_start_produce_input:
binder: pos
destination: POS_ORDER_SET_STRAT_PRODUCE
group: pos_group # 门店ID为1的消费者
shop_consumer_input_1:
binder: shop
destination: POS_ORDER_SET_STRAT_PRODUCE
group: shop_1_group #-----------消息生产-----------
# 集单开始生产通知生产
order_set_start_produce_output:
binder: pos
destination: POS_ORDER_SET_STRAT_PRODUCE rabbit:
bindings:
# 集单开始生产消费者
order_set_start_produce_input:
consumer:
exchangeType: topic
autoBindDlq: true
republishToDlq: true
deadLetterExchange: POS_ORDER_SET_STRAT_PRODUCE_POS_DLX
#bindingRoutingKey: '#'
# 门店1的消费者
shop_consumer_input_1:
consumer:
exchangeType: topic
autoBindDlq: true
republishToDlq: true
deadLetterExchange: POS_ORDER_SET_STRAT_PRODUCE_SHOP_1_DLX
bindingRoutingKey: 1
70 deadLetterRoutingKey: 1 # 生产者配置
order_set_start_produce_output:
producer:
exchangeType: topic
76 routingKeyExpression: headers.shopId
# routingKeyExpression: headers['shopId']

上面的配置文件配置了一个动态的基于shopId做路由的生产者配置,一个消费全部路由键的消费者,如果要配置指定路由键的可以在配置文件里设置bindingRoutingKey属性的值。

生产者java代码:

import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.support.MessageBuilder; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.longge.pos.production.mq.dto.OrderSetProductionMsg; import lombok.extern.slf4j.Slf4j; @Slf4j
public class MqSendUtil {
private static MessageChannel orderSetStartProduceChannel; public static void setSfOrderCreateChannel(MessageChannel channel) {
sfOrderCreateProduceChannel = channel;
} public static void sendOrderSetPrintMsg(OrderSetProductionMsg msg) {
// add kv pair - routingkeyexpression (which matches 'type') will then evaluate
// and add the value as routing key
log.info("发送开始生产的MQ:{}", JSONObject.toJSONString(msg));
orderSetStartProduceChannel.send(MessageBuilder.withPayload(JSON.toJSONString(msg)).setHeader("shopId", msg.getOrderSet().getShopId()).build());
//orderSetStartProduceChannel.send(MessageBuilder.withPayload(JSON.toJSONString(msg)).build());
}
}

动态路由的核心在于上面那个红色的字体的地方,这个是和配置文件里的  routingKeyExpression 的配置是匹配的。

SpringCloud Stream生产者配置RabbitMq的动态路由键的更多相关文章

  1. 使用Gateway配置路由以及动态路由

    1. 新建module cloud-gateway-gateway9527 2. pom.xml <!--注意不需要web模块依赖,否则报错--> <?xml version=&qu ...

  2. Cisco基础(二):三层交换vlan间通信、多交换机vlan间通信、三层交换配置路由、RIP动态路由配置、三层交换配置RIP动态路由

    一.三层交换vlan间通信 目标: VLAN实现了广播域的隔离,同时也将VLAN间的通信隔离了.三层交换技术使得VLAN间可以通信. 通过三层交换实现VLAN间通信 方案: 为了解决了传统路由器低速. ...

  3. 九. SpringCloud Stream消息驱动

    1. 消息驱动概述 1.1 是什么 在实际应用中有很多消息中间件,比如现在企业里常用的有ActiveMQ.RabbitMQ.RocketMQ.Kafka等,学习所有这些消息中间件无疑需要大量时间经历成 ...

  4. SpringCloud学习笔记(九、SpringCloud Stream)

    目录: 什么是SpringCloud Stream 如何使用SpringCloud Stream 消息分流 什么是SpringCloud Stream: SpringCloud Stream是一个用于 ...

  5. Spring Cloud Zuul的动态路由怎样做?集成Nacos实现很简单

    一.说明 网关的核心概念就是路由配置和路由规则,而作为所有请求流量的入口,在实际生产环境中为了保证高可靠和高可用,是尽量要避免重启的,所以实现动态路由是非常有必要的:本文主要介绍实现的思路,并且以Na ...

  6. Spring Cloud Gateway的动态路由怎样做?集成Nacos实现很简单

    一.说明 网关的核心概念就是路由配置和路由规则,而作为所有请求流量的入口,在实际生产环境中为了保证高可靠和高可用,是尽量要避免重启的,所以实现动态路由是非常有必要的:本文主要介绍 Spring Clo ...

  7. Vlan间通讯,动态路由

    Vlan间通讯,动态路由 案例1:三层交换vlan间通信 案例2:多交换机vlan间通信 案例3:三层交换配置路由 案例4:RIP动态路由配置 案例5:三层交换配置RIP动态路由 1 案例1:三层交换 ...

  8. IP路由__动态路由

    1.使用协议来查找网络并更新路由表的配置,就是动态路由.它比使用静态或默认路由方便,但它需要一定的路由器CPU处理时间和网络链接带宽.路由协议定义了路由器与相邻路由器通信时所使用的一组规则. 在互联网 ...

  9. Vue-Router学习第二弹动态路由\懒加载\嵌套路由

    在我们做项目时肯定会有出现动态路由: 举个栗子: 一个品种的商品页面会有同类不同样的商品就要在路由的后面加一个id: Vue的路由id是这样添加的: 两种动态路由 一种是params参数添加: 首先现 ...

随机推荐

  1. SqlServer基础语法(三)

    1.数据库备份的方法: 完整数据库备份GPOSDB 文件大小:23MB 日志备份 GPOSDB日志备份文件大小:211KB --完整备份 Backup DATABASE GPOSDB To disk= ...

  2. 开始写博客,学习Linq(2)

    linq的功能是什么? 它将极大地改变应用程序或组件处理数据的方式.这是第一个功能. LINQ to Objects.LINQ to SQL和LINQ to XML,是LINQ三大主要功能,当然LIN ...

  3. jQuery源码中的“new jQuery.fn.init()”什么意思?

    所有文章搬运自我的个人主页:sheilasun.me 引子 最近打算试试看看jQuery的源码,刚开个头就卡住了.无论如何都理解不了jQuery源码入口部分中的 return new jQuery.f ...

  4. Redis数据结构之哈希

    这个部分依旧分为两个步骤,一个是redis客户端,一个是java的客户端 一:Redis客户端 1.get与set 2.删除 3.增加 4.是否存在 hexists myhash2 age 5.获取长 ...

  5. 《Gradle权威指南》--Java Gradle插件

    No1: dependencies{ compile group: 'com.squareup.okhttp3',name:'okhttp',version:'3.0.1' } //缩写 depend ...

  6. 洛谷.3374.[模板]树状数组1(CDQ分治)

    题目链接 简易CDQ分治教程 //每个操作分解为一个有序数对(t,p),即(时间,操作位置),时间默认有序,用CDQ分治处理第二维 //对于位置相同的操作 修改优先于查询 //时间是默认有序的 所以可 ...

  7. 洛谷.2325.[SCOI2005]王室联邦(贪心)

    题目链接 比较水的题 然而.. 首先可以考虑DFS 每B个分一个块,但是这样链底不会和上边相连 于是考虑从底下开始分,即在DFS完一个点时才将其加入栈中:当子树size==B时出栈 最后在根节点可能会 ...

  8. BZOJ.3720.Gty的妹子树(树分块)

    题目链接 洛谷上惨遭爆零是为什么.. 另外这个树分块算法是假的. /* 插入删除只涉及一个数,故每次可以枚举一遍,而不是重构完后sort */ #include<cmath> #inclu ...

  9. 潭州课堂25班:Ph201805201 WEB 之 jQuery 第七课 (课堂笔记)

    jq 的导入 <body> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js">< ...

  10. 在web.xml中配置Spring的application.xml

    <context-param> <!-- 请记住这里的名称不能够乱写,必须一模一样,区分大小写 java类去启动项目 contextClass--> <param-nam ...