使用 Spring AOP 和 Kafka 在微服务中集中处理错误

问题描述 投票:0回答:1

如何使用单独的模块在微服务架构中集中处理错误?我们的服务通过 Kafka 进行通信,不使用传统的控制器,我的第一个想法是 @controlleradvice 不适合此目的。如何有效地实现集中式错误处理程序?

我们开发了三个独立的微服务,每个微服务都有自己的异常处理。此外,还有一个通用 JAR 文件,我们可以在其中管理常见异常、实用程序和其他共享资源。

系统的设计已经改变,现在需要一个集中的错误处理模块或服务来协调错误处理。我已经探索了 Spring AOP 的解决方案。然而,我面临着一个挑战,因为我们的服务不使用控制器,而是依赖 Kafka 进行通信 - @controlleradvice 在这里有什么用吗?

到目前为止,我已经创建了一些配置。请参阅下面的代码片段以供参考。例如,我定义了一个 Aspect 类来处理异常。它拦截用@CommonError注释的方法。 @CommonError 注解用于将此错误处理作为依赖项应用于三个微服务中的相关类。

public class ErrorHandlingAspect {
    public ErrorHandlingAspect() {
        System.out.println("Initialize Aspect");
        log.debug("Initialize Aspect");
    }

    @Pointcut("@annotation(com.projects.errorhandling.annotation.CommonError)")
    public void ePointcut() {
        // this pointcut will be used to intercept all the methods that are annotated with @CommonError
    }

    @Around("ePointcut()")
    public Object handler(ProceedingJoinPoint joinPoint) throws Throwable {
        try {
            // Proceed with the execution of the service method
            return joinPoint.proceed();
        } catch (AccountNotFoundException ex) {  
        } 
    }

    @AfterThrowing(pointcut = "ePointcut()", throwing = "ex")
    public void handleGeneral(JoinPoint joinPoint, Exception ex) {
        if (!(ex instanceof AccountNotFoundException)) {
            log. Error("An exception occurred: " + ex.getMessage());
        }
    }
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(AppConfig.class)
public @interface CommonError {}
@Configuration
@EnableAspectJAutoProxy
public class AppConfig {
    @Bean
    public ErrorHandlingAspect centralAspect() {
        log.debug("Aspect created");
        return new Aspect();
    }
}

这是跨微服务集中错误处理的正确方法吗?它没有按预期工作。这种方法注定会失败吗?还是我的代码中存在一些故障?

spring-boot exception microservices aop aspectj
1个回答
0
投票

您的代码可能有很多问题,但它是不完整的,所以我不能简单地回答这个问题,并确信答案可以解决您的问题。 AOP 初学者经常会同时做出多个错误,这就是为什么 MCVE 如此重要。也许您有一个可以链接到的 GitHub 项目。

我可以肯定地说,你的注释有

@Target(ElementType.TYPE)
,而你的方面使用
@annotation
切入点,即你正在矛盾地搜索带注释的方法。两种情况都是互斥的。带注释的类型可以通过
@within
切入点进行匹配。

© www.soinside.com 2019 - 2024. All rights reserved.