在写这个文章前不得不吐槽目前国内一些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. openstack学习-nove控制节点部署(四)

    nove在openstack非常重要,主要负责创建虚拟机 nova计算服务 API :负责接收和响应外部请求.支持openstack API,EC2 API Cert:负责身份认证EC 2 Sched ...

  2. Lineage逻辑回归分类算法

    Lineage逻辑回归分类算法 线性回归和逻辑回归参考文章: http://blog.csdn.net/viewcode/article/details/8794401 http://www.cnbl ...

  3. js自定义修改复选框单选框样式,清除复选框单选框默认样式

    之前做项目的时候,也遇到过需要按照设计稿把<input type="checkbox">和<input type="radio">的默认 ...

  4. SQLite中SELECT基本形式

    SQLite中SELECT基本形式 每个数据库通常都包含多个表,而每个表又包含多条数据.要获取数据库中的数据,就需要SQL语言提供的查询语句SELECT.本章将讲解和SELECT语句相关的内容,其中包 ...

  5. Python学习——异常处理

    1.异常基础: 在编程过程中为了增加友好性,在程序出现bug时一般不会将错误信息显示给用户,而是现实一个提示的页面 基本语法: try: pass except Exception as e: pri ...

  6. Javascript日常编码中的一些常见问题

    一.尽量少用全局变量   这是一个疑问最少,同时流传最 广的一条.Javascript使用函数管理作用域,全局变量最大的问题在于同名变量冲突.这种隐患产生比较直接的两个原因就是Javascript语言 ...

  7. emlog编辑器探寻之旅

    本文同步于我的个人博客 emlog编辑器探寻之旅 一直想要寻找一个好用的emlog文本编辑器,寻觅了很久,从默认的KindEditor编辑器开始,用了几天就感觉特别难用,很多需求根本满足不了.后来想要 ...

  8. Python3内置函数——reversed() = 翻转我的世界

    认识reversed单词 reversed 英[rɪ'vɜ:st] 美[rɪ'vɜst] adj. 颠倒的:相反的:(判决等)撤销的 v. 颠倒(reverse的过去式和过去分词):翻转 help(r ...

  9. [SNOI2017]一个简单的询问

    [SNOI2017]一个简单的询问 题目大意: 给定一个长度为\(n(n\le50000)\)的序列\(A(1\le A_i\le n)\),定义\(\operatorname{get}(l,r,x) ...

  10. 关于Oracle游标out参数多层调用的BUG,ORA-06504

    数据库版本 Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - 64bit 测试代码 declare p_cur sys_refcu ...