compile("com.ice:phantom-common-rabbitmq:1.1.1")
@EnableAsync
@ComponentScan(basePackages = {"com.ice","com.kingboy"})
public class PhantomServiceTownApplication {
public static void main(String[] args) {
SpringApplication.run(PhantomServiceTownApplication.class, args);
}
}
<logger name="org.springframework" level="INFO" />
<logger name="org.hibernate" level="INFO" />
<logger name="com.kingboy.repository" level="DEBUG" />
<logger name="com.ice.amqp" level="DEBUG" />
spring:
datasource:
#禁止执行初始化脚本,否则会在rabbit数据源中执行当前服务的初始化脚本,创建大量无用的表
initialize: false
#rabbit服务数据源,用于记录服务间消息通讯消息
rabbit:
url: jdbc:mysql://xxx.com
username: root
password: 123456
rabbitmq:
host: xx.xxx.xx.xx
port: 5672
username: guest
password: guest
virtual-host: /
## 消息监听者配置
listener:
simple:
# 手动签收模式
acknowledge-mode: manual
# 初始化并发数
concurrency: 10
# 最大并发数
max-concurrency: 20
# 预处理消息数
prefetch: 5
## 消息发布者配置
#开启确认模式
publisher-confirms: true
#开启return模式
publisher-returns: true
#mandatory设置为true,return模式才会生效
template:
mandatory: true
#连接超时时间
connection-timeout: 15000
#无响应消息重试间隔(分钟)
retryInterval: 2
#最大重试次数
maxRetryCount: 3
#rabbit前缀,用于当前服务所创建的所有队列以及消息id的前缀
rabbitPrefix: town
-- 消息记录表
CREATE TABLE IF NOT EXISTS `rabbit_event_log` (
`id` varchar(128) NOT NULL COMMENT '消息唯一ID',
`routing_key` varchar(255) NOT NULL COMMENT '路由key:消息体java类型',
`message` varchar(4000) NOT NULL COMMENT '消息内容',
`try_count` int(4) NOT NULL DEFAULT '0' COMMENT '重试次数',
`status` varchar(20) NOT NULL COMMENT '状态',
`next_retry` datetime NOT NULL COMMENT '超时时间,下次重试时间',
`create_time` datetime NOT NULL COMMENT '创建时间',
`update_time` datetime NOT NULL COMMENT '修改时间',
`cause` varchar(255) DEFAULT NULL COMMENT '失败原因',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
CREATE TABLE IF NOT EXISTS `rabbit_message_log` (
`id` varchar(128) NOT NULL COMMENT '消息唯一ID',
`exchange` varchar(255) NOT NULL COMMENT '交换机',
`routing_key` varchar(255) NOT NULL COMMENT '路由key',
`message` varchar(4000) DEFAULT NULL COMMENT '消息内容',
`try_count` int(4) NOT NULL DEFAULT '0' COMMENT '重试次数',
`status` varchar(20) NOT NULL COMMENT '状态',
`next_retry` datetime NOT NULL COMMENT '超时时间,下次重试时间',
`create_time` datetime NOT NULL COMMENT '创建时间',
`update_time` datetime NOT NULL COMMENT '修改时间',
`cause` varchar(255) DEFAULT NULL COMMENT '失败原因',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
服务内部消息的发布与spring中
applicationContext.publishEvent(Object obj)
用法大致相同,唯一不同的是消息的发布使用的是PhantomRabbitHelper
类的publishEvent(Object obj)
方法,调用该方法时只需要将消息体对象作为参数传入
/**
* @author Ice, You're very best
* @date 2018/8/1 9:09
* @desc 操作日志发布
*/
@Component
public class OperationLogPublisher {
// @Resource
// ApplicationContext applicationContext;
@Resource
private PhantomRabbitHelper phantomRabbitHelper;
public void publishOperationLog(OperationLogPublishRequest operationLogPublishRequest) {
phantomRabbitHelper.publishEvent(operationLogPublishRequest);
}
public void publishOperationLog(OperationLogSaveDTO operationLogSaveDTO) {
phantomRabbitHelper.publishEvent(operationLogSaveDTO);
}
}
服务内部消息的监听与spring中的
@EventListener
用法也大致相同,唯一不同的是换成了@PhantomRabbitEventListener
,需要注意的是监听的对象类型要与上述例子中的发布消息体的类型完全一致
/**
* @author Ice, You're very best
* @date 2018/8/1 8:58
* @desc 操作日志监听
*/
@Component
public class OperationLogListener {
@Resource
private OperationLogService operationLogService;
@SneakyThrows
@PhantomRabbitEventListener
public void Listener(OperationLogPublishRequest operationLogPublishRequest) {
operationLogService.addOperationLog(operationLogPublishRequest);
}
@SneakyThrows
@PhantomRabbitEventListener
public void listener(OperationLogSaveDTO operationLogSaveDTO) {
operationLogService.addOperationLog(operationLogSaveDTO);
}
}
服务间通信发送方发布消息通过
PhantomRabbitHelper
类中的sendMessage(String prefix, String exchange, String routingKey, Object message)
方法,该方法除了消息体外,还需要指定接收方的rabbitPrefix(在接收方的配置文件中定义,上文中有例子),exchange(即接收方微服务的名称),以及routingKey(由接收方在注解中定义)
@GetMapping("/message")
public String message(){
Student jack = new Student(2, "jack", LocalDateTime.now());
phantomRabbitHelper.sendMessage("portal", "phantom-service-portal", "test.send.message", jack);
return "SUCCESS";
}
服务间通信接收方监听消息使用
@PhantomRabbitMessageListener
注解,需要注意的是监听的对象要与发送的消息体对象类型一致
@Component
public class TestListener {
@PhantomRabbitMessageListener(routingKey = "test.send.message")
public void listener(Student student){
System.out.println("TestMessageListener : " + student);
}
}