代码演示设计一个微服务中台监控,中台接口要能记录服务调用次数,服务调用来源,自定义注解,发送消息到MQ,数据交互平台从MQ消费消息,插入到数据库
时间: 2024-03-02 10:48:19 浏览: 79
好的,这是一个比较复杂的问题,需要分多个步骤来完成。我将提供一个大致的思路,您可以根据自己的实际情况进行调整。
1. 添加依赖
在 pom.xml 文件中添加以下依赖:
```xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
```
2. 配置文件
在 application.properties 中添加以下配置:
```properties
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
```
3. 自定义注解
定义一个自定义注解,用于标记需要监控的方法:
```java
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Monitor {
String value() default "";
}
```
4. 拦截器
定义一个拦截器,用于拦截被 @Monitor 注解标记的方法,记录调用次数和来源,并将数据发送到 MQ:
```java
@Component
@Aspect
public class MonitorAspect {
@Autowired
private AmqpTemplate amqpTemplate;
@Pointcut("@annotation(com.example.demo.annotation.Monitor)")
public void pointcut() {}
@Around("pointcut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
// 获取方法名和类名
String methodName = joinPoint.getSignature().getName();
String className = joinPoint.getTarget().getClass().getSimpleName();
// 记录调用次数和来源
String key = className + "." + methodName;
int count = getCountFromRedis(key);
count++;
setCountToRedis(key, count);
String source = getSourceFromHeader();
// 发送消息到 MQ
Map<String, Object> map = new HashMap<>();
map.put("className", className);
map.put("methodName", methodName);
map.put("count", count);
map.put("source", source);
amqpTemplate.convertAndSend("monitor-exchange", "monitor-routing-key", map);
// 执行方法
return joinPoint.proceed();
}
private int getCountFromRedis(String key) {
// 从 Redis 中获取调用次数
return 0;
}
private void setCountToRedis(String key, int count) {
// 将调用次数保存到 Redis 中
}
private String getSourceFromHeader() {
// 从请求头中获取调用来源
return "";
}
}
```
5. MQ 消费者
定义一个 MQ 消费者,用于消费发送到 MQ 中的消息,并将数据插入到数据库中:
```java
@Component
public class MonitorMessageConsumer {
@Autowired
private MonitorLogRepository monitorLogRepository;
@RabbitListener(queues = "monitor-queue")
public void handleMessage(Map<String, Object> map) {
// 将数据插入到数据库中
MonitorLog monitorLog = new MonitorLog();
monitorLog.setClassName((String) map.get("className"));
monitorLog.setMethodName((String) map.get("methodName"));
monitorLog.setCount((Integer) map.get("count"));
monitorLog.setSource((String) map.get("source"));
monitorLogRepository.save(monitorLog);
}
}
```
6. 数据库表
定义一个数据库表,用于保存监控数据:
```sql
CREATE TABLE `monitor_log` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`class_name` varchar(50) NOT NULL COMMENT '类名',
`method_name` varchar(50) NOT NULL COMMENT '方法名',
`count` int(11) NOT NULL DEFAULT '0' COMMENT '调用次数',
`source` varchar(50) DEFAULT NULL COMMENT '调用来源',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='监控日志表';
```
7. 测试
在需要监控的方法上添加 @Monitor 注解,启动应用程序,调用该方法,查看数据库中是否插入了监控数据。
以上是一个简单的微服务中台监控的设计思路,您可以根据自己的实际情况进行调整和完善。
阅读全文