详细代码举例微服务中台监控,中台接口要能记录服务调用次数,服务调用来源,自定义注解,发送消息到MQ,数据交互平台从MQ消费消息,插入到数据库
时间: 2024-03-02 14:52:43 浏览: 139
好的,以下是一个简单的示例代码,帮助你实现所需的功能:
1. 引入 Actuator 相关依赖
在 pom.xml 文件中添加以下依赖:
```xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
```
2. 实现 AOP 切面
首先定义一个自定义注解 `@Monitor`,用于标记需要进行监控的接口方法。接着,定义一个切面 `ApiMonitorAspect`,在该切面中实现监控逻辑,包括记录调用次数、记录调用来源等。具体代码如下:
```java
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Monitor {
}
@Aspect
@Component
public class ApiMonitorAspect {
// 定义一个 Map,用于记录接口方法的调用次数
private Map<String, Integer> callCountMap = new ConcurrentHashMap<>();
@Around("@annotation(com.example.demo.annotation.Monitor)")
public Object monitorApi(ProceedingJoinPoint joinPoint) throws Throwable {
// 获取接口方法的参数和返回值
Object[] args = joinPoint.getArgs();
Object result = joinPoint.proceed();
// 记录接口方法的调用次数
String methodName = joinPoint.getSignature().toShortString();
Integer callCount = callCountMap.get(methodName);
if (callCount == null) {
callCount = 0;
}
callCountMap.put(methodName, callCount + 1);
// 记录接口方法的调用来源(这里假设调用来源是从 HTTP 头中获取的)
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String callSource = request.getHeader("callSource");
// 将调用次数和调用来源写入日志(这里使用 log4j2)
Logger logger = LogManager.getLogger(joinPoint.getTarget().getClass());
logger.info("method: {}, callCount: {}, callSource: {}", methodName, callCount + 1, callSource);
return result;
}
// 定义一个定时任务,定时将接口方法的调用次数写入 MQ
@Scheduled(cron = "0 0 * * * ?")
public void sendCallCountToMQ() {
// 将调用次数转换成 JSON 格式的字符串
ObjectMapper objectMapper = new ObjectMapper();
String callCountJson = null;
try {
callCountJson = objectMapper.writeValueAsString(callCountMap);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
// 将调用次数发送到 MQ
// ...
}
}
```
3. 标记需要监控的接口方法
在接口方法上添加 `@Monitor` 注解即可,例如:
```java
@RestController
public class ApiController {
@Autowired
private ApiService apiService;
@GetMapping("/api")
@Monitor
public String api(@RequestParam("param") String param) {
return apiService.process(param);
}
}
```
4. 发送消息到 MQ
使用 Spring Boot 集成的 RabbitMQ 或者 Kafka 组件发送消息即可。以 RabbitMQ 为例,需要在 application.yml 文件中添加 RabbitMQ 的配置信息,然后在代码中使用 RabbitTemplate 发送消息。具体代码如下:
```java
@Component
public class CallCountSender {
@Autowired
private RabbitTemplate rabbitTemplate;
public void send(String message) {
rabbitTemplate.convertAndSend("call_count_exchange", "call_count_key", message);
}
}
```
5. 消费 MQ 中的消息
首先定义一个消息消费者 `CallCountConsumer`,在该消费者中实现消息的消费逻辑,将消费到的消息插入到数据库中。具体代码如下:
```java
@Component
public class CallCountConsumer {
@Autowired
private CallCountRepository callCountRepository;
@RabbitListener(queues = "call_count_queue")
public void receive(String message) {
ObjectMapper objectMapper = new ObjectMapper();
try {
// 将 JSON 格式的字符串转换成 Map
Map<String, Integer> callCountMap = objectMapper.readValue(message, new TypeReference<Map<String, Integer>>() {});
// 将调用次数插入到数据库中
for (Map.Entry<String, Integer> entry : callCountMap.entrySet()) {
CallCount callCount = new CallCount();
callCount.setMethodName(entry.getKey());
callCount.setCallCount(entry.getValue());
callCountRepository.save(callCount);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
```
最后,需要在 application.yml 文件中添加 RabbitMQ 的配置信息和数据库的配置信息。例如:
```yaml
spring:
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
datasource:
url: jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: root
```
阅读全文