Spring Cloud Stream【消息分组和消息分区】

spring boot版本:2.1.10.RELEASE
spring cloud版本:Greenwich.SR4

上一篇博文 Spring Cloud Stream 初步了解了Spring Cloud Stream,并写了一个入门的例子,本文在上一篇的基础上,实现消息的分组和消息的分区。

stream-receiver 项目

(1)添加配置

#配置eureka注册中心
eureka.client.service-url.defaultZone=http://192.168.xxx.xxx:8761/eureka/,http://192.168.xxx.xxx:8762/eureka/
eureka.instance.prefer-ip-address=true

#rabbitmq配置
spring.rabbitmq.host=192.168.xxx.xxx
spring.rabbitmq.port=5672
spring.rabbitmq.username=admin
spring.rabbitmq.password=admin
spring.rabbitmq.virtual-host=/

# 对应 MQ 是 exchange
# 其中 inputProduct 是可变的, IReceiveService@Input注解中的值
# exchangeProduct是rabbitmq中交换器的名, 发送者和接收者需一致
spring.cloud.stream.bindings.inputProduct.destination=exchangeProduct
# 具体分组 对应 MQ 是 队列名称 并且持久化队列
spring.cloud.stream.bindings.inputProduct.group=groupProduct

(2)接收类接口

package com.ebook.stream;

import org.springframework.cloud.stream.annotation.Input;
import org.springframework.messaging.SubscribableChannel;

/**
 * @author:JZ
 * @date:2020/2/2
 */
public interface IReceiveService {

    String INPUT = "inputProduct";

    @Input(INPUT)
    SubscribableChannel receive();

}

(3)接收类接口的实现类

package com.ebook.stream;

import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.stereotype.Service;

/**
 * @author:JZ
 * @date:2020/2/2
 */

@Service
@EnableBinding({IReceiveService.class})
public class ReceiveService {
	
	//Product为自定义实体类
    @StreamListener(IReceiveService.INPUT)
    public void onReceive(Product product) {
        System.out.println("receive:" + product.toString());
    }

}
stream-sender 项目

(1)添加配置

#配置eureka注册中心
eureka.client.service-url.defaultZone=http://192.168.xxx.xxx:8761/eureka/,http://192.168.xxx.xxx:8762/eureka/
eureka.instance.prefer-ip-address=true

#rabbitmq配置
spring.rabbitmq.host=192.168.xxx.xxx
spring.rabbitmq.port=5672
spring.rabbitmq.username=admin
spring.rabbitmq.password=admin
spring.rabbitmq.virtual-host=/

# 对应 MQ 是 exchange,
# 其中 outputProduct 是可变的, 其对应的值是ISendService类中@Output注解中的值
# exchangeProduct是rabbitmq中交换器的名, 发送者和接收者需一致
spring.cloud.stream.bindings.outputProduct.destination=exchangeProduct

(2)发送接口

package com.ebook.stream;

import org.springframework.cloud.stream.annotation.Output;
import org.springframework.messaging.SubscribableChannel;

/**
 * @author:JZ
 * @date:2020/2/2
 */
public interface ISendService {

    String OUTPUT = "outputProduct";

    @Output(OUTPUT)
    SubscribableChannel send();

}

(3)在启动类中添加注解

package com.ebook.stream;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.stream.annotation.EnableBinding;

/**
 * @author:JZo
 * @date:2020/1/11
 */

@SpringBootApplication
@EnableEurekaClient
@EnableBinding({ISendService.class})//注册成bean
public class StreamSenderApplication {

    public static void main(String[] args) {
        SpringApplication.run(StreamSenderApplication.class, args);
    }

}

(4)运行测试类,发送消息

import com.ebook.stream.ISendService;
import com.ebook.stream.Product;
import com.ebook.stream.StreamGroupSender;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = StreamGroupSender.class)
public class StreamTest {

	@Autowired
	private ISendService send;
	
	@Test
	public void send() throws InterruptedException {
		//Product为自定义实体类
		Product product = new Product(1, "Spring Cloud");
		Message message = MessageBuilder.withPayload(product).build();
		this.send.send().send(message);
	}
}
消息分区

  通过以上配置可实现相同服务集群配置时,会将相同的消息均匀地发送到各个服务上。例如有10条相同的消息,集群中有2个服务,那么每个服务会接收到5条消息。

  如果想要相同消息在集群中被同一个服务消费那么可以添加如下配置。

在接收者服务中添加

#开启消费者分区功能
spring.cloud.stream.bindings.inputProduct.consumer.partitioned=true
#指定了当前消费者的总实例数量(集群中服务的数量)
spring.cloud.stream.instanceCount=2
#设置当前实例的索引号,从0开始
spring.cloud.stream.instanceIndex=0

在发送者服务中添加

#通过该参数指定了分区键的正则表达式规则
spring.cloud.stream.bindings.outputProduct.producer.partitionKeyExpression=payload
#指定了消息分区的数量。
spring.cloud.stream.bindings.outputProduct.producer.partitionCount=2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值