说明
- 项目运行的前提条件:服务注册中心已经启动。
- 本项目的服务注册与发现是基于 Spring Cloud Consul 实现。具体内容博主写在另一篇博客:
- 本博客是 Spring Cloud 微服务化(精简完整版)的一部分。
消息中间件
- 博主选择的是 Kafka。安装教程在另外一篇博客
创建项目
- 创建两个项目:
- 消息生产者:awesome-message-producer-server
- 主要有四部分关键内容:
- 依赖
- 配置
- 生成消息接口类(核心内容):MessageSource.java
- 控制器类(核心内容):SmsController.java
- 消息消费者:awesome-message-consumer-server
- 主要有四部分关键内容
- 依赖
- 配置
- 监听消息接口类(核心内容):MessageSink.java
- 消息消费者类(核心内容): SmsConsumer.java
- 消息生产者:awesome-message-producer-server
依赖
- 两个项目需要引入的依赖完全一样。
-
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-stream</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-stream-binder-kafka</artifactId> </dependency> <dependency> <groupId>org.springframework.kafka</groupId> <artifactId>spring-kafka</artifactId> </dependency>
生产者
- 消息生产者:awesome-message-producer-server
- application.yml
-
spring: cloud: stream: default-binder: kafka bindings: sms_message_producer: destination: sms-message
- 生成消息接口类:
-
package awesome.message.producer.server.source; import org.springframework.cloud.stream.annotation.Output; import org.springframework.messaging.MessageChannel; /** * @author: Andy * @time: 2019/4/20 19:53 * @since */ public interface MessageSource { String SMS_MESSAGE_PRODUCER = "sms_message_producer"; @Output(SMS_MESSAGE_PRODUCER) MessageChannel smsMessage(); }
-
- 控制器类:
-
package awesome.message.producer.server.controller; import awesome.message.producer.server.bean.SmsMessage; import awesome.message.producer.server.source.MessageSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.stream.annotation.EnableBinding; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.integration.support.MessageBuilder; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; /** * @author: Andy * @time: 2019/4/20 19:23 * @since */ @RestController @EnableBinding(MessageSource.class) public class SmsController { @Autowired private MessageSource messageSource; /** * 发送短信消息 * * * @param message * @return: {@link ResponseEntity<?> } * @author: Andy * @time: 2019/4/20 20:35 * @since */ @PostMapping("/api/message/sms_message") public ResponseEntity<?> sendSmsMessage(@RequestBody SmsMessage message){ try { messageSource.smsMessage().send(MessageBuilder.withPayload(message).build()); } catch (Exception e) { //todo: do something e.printStackTrace(); return new ResponseEntity<>("消息 SMS 发送失败!", HttpStatus.INTERNAL_SERVER_ERROR); } return new ResponseEntity<>("消息 SMS 发送成功!", HttpStatus.OK); } }
-
消费者
- 消息消费者:awesome-message-consumer-server
- application.yml
-
spring: cloud: stream: default-binder: kafka bindings: sms_message_producer: destination: sms-message group: message-sever-consumer
- 监听消息接口类:
-
package awesome.message.consumer.server.sink; import org.springframework.cloud.stream.annotation.Input; import org.springframework.messaging.SubscribableChannel; public interface MessageSink { String SMS_MESSAGE_CONSUMER = "sms_message_consumer"; @Input(SMS_MESSAGE_CONSUMER) SubscribableChannel smsMessages(); }
-
- 消息消费者类:
-
package awesome.message.consumer.server.consumer; import awesome.message.consumer.server.bean.SmsMessage; import awesome.message.consumer.server.sink.MessageSink; import org.springframework.cloud.stream.annotation.EnableBinding; import org.springframework.cloud.stream.annotation.StreamListener; import org.springframework.messaging.Message; /** * @author: Andy * @time: 2019/4/20 20:39 * @since */ @EnableBinding(MessageSink.class) public class SmsConsumer { @StreamListener(MessageSink.SMS_MESSAGE_CONSUMER) public void consumeSmsMessage(Message<SmsMessage> message){ System.out.println(String.format("Consumes message:[%s] ", message.getPayload().getContent())); } }
-
测试
- 生产者生成消息:
- 消费者消费消息: