消息系统整合Spring Cloud Stream
简介
- Spring Cloud Stream 是一个用来为微服务应用构建消息驱动能力的框架。通过使用 Spring Cloud Stream,可以有效简化开发人员对消息中间件的使用复杂度,让系统开发人员可以有更多的精力关注于核心业务逻辑的处理。
- 程序模型:应用程序的核心部分(Application Core)通过 inputs 与 outputs 管道,与中间件连接,而管道是通过绑定器 Binder 与中间件相绑定的。
Stream RocketMQ 微服务
生产者应用
- 创建工程:任意复制前面的一个提供者工程,重命名为 09-stream-rocketmq-producer-8081,将其中的除启动类之外的其它代码全部删除。
- 添加依赖:仅需再添加一个 Spring Cloud Stream Kafka 相关的依赖即可。
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rocketmq</artifactId>
</dependency>
server:
port: 8081
spring:
application:
name: msc-stream-producer
cloud:
nacos:
discovery:
server-addr: 192.168.0.100:8848
stream:
rocketmq:
binder:
name-server: 192.168.254.130:9876
auto-create-topics: true
bindings:
output:
destination: persons
content-type: text/plain
@Component
@EnableBinding(Source.class)
public class MsgProducer {
@Autowired
@Qualifier(Source.OUTPUT)
private MessageChannel channel;
public String sendMsg(String msg) {
Map<String, Object> headers = new HashMap<>(1);
headers.put(MessageConst.PROPERTY_TAGS, "stream-rmq");
MessageHeaders msgHeaders = new MessageHeaders(headers);
Message<String> message = MessageBuilder.createMessage(msg, msgHeaders);
channel.send(message);
return msg;
}
}
@RestController
public class MessageController {
@Autowired
private MsgProducer producer;
@GetMapping("/msg/send")
public String send(@RequestParam String msg) {
return producer.sendMsg(msg);
}
}
消费者应用
- 创建工程:复制 09-stream-rocketmq-producer-8081 工程,重命名为 09-stream-rocketmq-consumer-8080,在其基础上进行修改,删除其生产者类与控制器类。
- 修改配置文件:
@Component
@EnableBinding(Sink.class)
public class MsgConsumer {
@StreamListener(Sink.INPUT)
public void receiveMsg(Object message) {
System.out.println(message);
}
}
测试
- 启动 09-stream-rocketmq-producer-8081 工程,调用接口发送消息 http://localhost:8081/msg/send?msg=abc,通过rocketmq-console查看消息是否发送成功:
生产者将消息发送给多个主题
- 在 09-stream-rocketmq-producer-8081 工程中进行修改
- 自定义管道:
public interface CustomSource {
String CHANNEL_NAME = "custom";
@Output(CustomSource.CHANNEL_NAME)
MessageChannel output();
}
- 测试访问地址:http://localhost:8081/msg/sendMulti?msg=123456,然后到 rocketmq-console 查看消息
另外两种消费者定义方式
@Component
@EnableBinding(Sink.class)
public class MsgConsumer {
@ServiceActivator(inputChannel = Sink.INPUT)
public void receiveMsg2(Object message) {
log.info("==>> ServiceActivator receive message: {}", message);
}
}
@Component
@EnableBinding(Sink.class)
public class MsgConsumer {
@Autowired
@Qualifier(Sink.INPUT)
private SubscribableChannel channel;
@PostConstruct
public void init() {
channel.subscribe(message -> {
byte[] payload = (byte[]) message.getPayload();
System.out.println(new String(payload) + ", " + message.getHeaders());
});
}
}
Dubbo Spring Cloud
概述
- Spring Cloud 默认情况下微服务间的通信采用的是 HTTP REST,其通信效率较 RPC 通信是比较低的。而 Dubbo 是一个 RPC 通信架构,不过其仅提供了服务发现与治理两大功能,即其生态不如 Spring Cloud 完整。
- Dubbo Spring Cloud 则是将两者完美结合一起,各取所长。
示例演示
定义提供者工程
- 创建工程:复制 02-provider-nacos-8081 工程,重命名为 10-provider-dubbo-8081,在其基础上进行修改。
- 添加依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
dubbo:
scan:
base-packages: com.yw.sca
registry:
address: spring-cloud://192.168.0.100
protocol:
name: dubbo
port: -1
- 访问地址 http://localhost:8081/provider/depart/list、http://localhost:8081/provider/depart/get/1
定义消费者工程
- 创建工程:复制 04-consumer-feign-8080 工程,重命名为 10-consumer-dubbo-8080,在其基础上进行修改。
- 修改 pom.xml 文件,与 10-provider-dubbo-8081 工程增加一样的依赖,同时将原来的 OpenFeign 依赖删除。
- 修改 DepartService 接口:
public interface DepartService {
boolean save(Depart depart);
boolean deleteById(int id);
boolean update(Depart depart);
Depart findById(int id);
List<Depart> list();
}
- 删除启动类上的@EnableFeignClients 注解,以及去掉原来的负载均衡配置。
- 修改配置文件:
spring:
application:
name: msc-consumer-depart
cloud:
nacos:
discovery:
server-addr: 192.168.0.100:8848
dubbo:
registry:
address: spring-cloud://192.168.0.100
cloud:
subscribed-services: msc-provider-depart
protocol:
name: dubbo
port: -1
- 访问地址:http://localhost:8080/consumer/depart/get/1、http://localhost:8080/consumer/depart/list
注意点
- 提供者和消费者的实体类都需要实现序列化,否者会报错:
总结