AOP实现上下游泳道隔离RPC调用

在平时代码项目代码测试的过程中,"隔离"思想就经常被用上,比方说多个并行开发的需求都需要用到服务 A 的能力,但是又需要同时部署 A 不同的代码分支,这个时候"泳道隔离"机制就显得尤为重要了。"泳道隔离"即将相同代码仓库的不同代码分支部署到不同的泳道环境中,代码分支的上下游也可以部署到相同的泳道环境中,我们通过指定对应的泳道环境标就可以将请求打到不同的环境中,真正实现代码隔离,提高程序员并行开发的效率。

但是存在这样一种场景,在基准泳道环境 env_a 上部署了一个项目 project_1,但是我并不想让 project_1 直接调用其在 env_a 中部署好的下游服务 project_2,我反倒想让它 "复用" 另一个泳道环境,泳道环境比方说 env_b 中的 project_2,这个时候就可以在 java 启动项目时的环境变量中动态指定,从而实现"跨泳道"的调用。本文就是想记录下我们如何通过 AOP 机制实现这种跨泳道的泳道环境标设置,具体的跨调用原理可以理解为 泳道基建可以根据设置的环境标帮我们做请求的转发。

主要是复习下 AOP 的用法

  1. 环境依赖搭建
java 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.jxz</groupId>
    <artifactId>AOP_RPC</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.5.RELEASE</version>
    </parent>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

</project>
  1. 注解和切面相关

注解

java 复制代码
package com.jxz.aop;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @Author jiangxuzhao
 * @Description
 * @Date 2024/11/16
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ThriftEnv {
    String environmentVariable();
}

切面

java 复制代码
package com.jxz.aop;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @Author jiangxuzhao
 * @Description
 * @Date 2024/11/16
 */
@Aspect
@Component
@Slf4j
public class ThriftEnvAspect {


    @Pointcut("@annotation(com.jxz.aop.ThriftEnv)")
    public void pointCut() {

    }

    @Around(value = "pointCut()")
    public Object around(ProceedingJoinPoint jp) throws Throwable {
        Class<?> targetClass = jp.getTarget().getClass();
        log.info("目标类 = {}", targetClass);
        MethodSignature ms = (MethodSignature) jp.getSignature();
        log.info("目标方法签名 = {}", ms);
        Method method = targetClass.getMethod(ms.getName(), ms.getParameterTypes());
        log.info("目标方法 = {}", method);

        ThriftEnv annotation = method.getAnnotation(ThriftEnv.class);
        String env = annotation.environmentVariable();
        log.info("切换到目标泳道 = {}", env);

        return jp.proceed();
    }
}
  1. 调用下游 RPC 时使用注解
java 复制代码
package com.jxz.adapter;

import com.jxz.aop.ThriftEnv;
import org.springframework.stereotype.Service;

/**
 * @Author jiangxuzhao
 * @Description
 * @Date 2024/11/16
 */
@Service
public class AuthAdapter {

    @ThriftEnv(environmentVariable = "auth_thrift_env")
    public String queryAuth(String name) {
        return name + "_auth";
    }
}
  1. 在启动项目的环境变量中指定下游的泳道环境
相关推荐
丘山一郎4 小时前
Spring 中的IOC控制反转 和DI依赖注入
java·后端·spring
码视野4 小时前
基于 Spring Boot + Vue3 的【大学英语四六级 (CET-4/6) 作文智能评分与句式润色系统】设计与实现(含PRD/三端高保真源码/大屏)
java·前端·人工智能·spring boot·后端·vue3
MetaLite4 小时前
Spring-AOP自调用为什么失效-AopContext真能解决吗
java·后端·spring
大模型码小白4 小时前
AI 对话流性能调优:万级消息的虚拟滚动落地
java·大数据·前端·javascript·人工智能·算法·机器学习
许彰午4 小时前
14-字段级SM4加密与SM2签名
java·低代码·架构
许彰午6 小时前
13-describe元数据输出
java·低代码·架构·状态模式
李昊哲小课6 小时前
SpringBoot4 云端咖啡站 阶段二:数据访问与分层架构
spring boot·架构
用户3721574261357 小时前
Java 设置 Word 文档编辑限制并允许指定区域编辑
java
宠友信息7 小时前
社区类源码开发实践中的仿小红书系统技术要点分析
java·spring boot·redis·mysql·uni-app·vue·内容运营
用户3721574261357 小时前
Java 设置 PDF 表单域只读或扁平化
java