SpringBoot基于AOP的本地/远程调用动态路由实践指南
作者:小马不敲代码
这篇文章主要为大家详细介绍了SpringBoot基于AOP的本地/远程调用动态路由实践指南,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
01为什么我们要“无缝切换”
MVP 阶段:单体最快,写完就可以上线。
流量暴涨后:微服务才能横向扩展,但把本地 userService.findById() 改成 feignClient.findById() 真要命——全链路改一遍,风险高、工期长。
理想状态:同一段业务代码,今天跑本地,明天改一行配置就跑远程,零代码侵入。
02核心设计一张图
┌---------------┐
│ 业务代码 │ ← 只认接口 UserService
└-------┬-------┘
│ 注入
┌-------┴----------------┐
│ 统一抽象层 │
│ 根据配置动态选择实现 │
├------------┬-----------┤
│ UserServiceLocalImpl │ UserServiceRemoteImpl │
└------------┴-----------┘
03一步步落地
先画好契约——接口层
// **统一接口** = 本地实现 + 远程 Feign 共用 public interface UserService { User getUserById(Long id); List<User> listAllUsers(); User saveUser(User u); void updateUser(User u); void deleteUser(Long id); }
本地实现
@Service @ConditionalOnProperty(name = "service.mode", havingValue = "local", matchIfMissing = true) public class UserServiceLocalImpl implements UserService { @Autowired private UserRepository repo; // 直连数据库,不走网络 @Override public User getUserById(Long id) { return repo.findById(id).orElse(null); } @Override public List<User> listAllUsers() { return repo.findAll(); } /* 其余方法省略 */ }
注解
- @ConditionalOnProperty:Spring Boot 的条件装配神器,配置文件里写 local 就激活。
- 直接依赖 DAO,零网络损耗,单元测试也能秒起。
远程实现——Feign
// 1. 声明式 HTTP 客户端 @FeignClient(name = "user-service", fallback = UserServiceFallback.class) public interface UserServiceFeignClient { @GetMapping("/api/users/{id}") User getUserById(@PathVariable("id") Long id); @GetMapping("/api/users") List<User> listAllUsers(); @PostMapping("/api/users") User saveUser(@RequestBody User u); @PutMapping("/api/users") void updateUser(@RequestBody User u); @DeleteMapping("/api/users/{id}") void deleteUser(@PathVariable("id") Long id); } @Service @ConditionalOnProperty(name = "service.mode", havingValue = "remote") public class UserServiceRemoteImpl implements UserService { @Autowired private UserServiceFeignClient feignClient; // 代理,真正发 HTTP @Override public User getUserById(Long id) { return feignClient.getUserById(id); } /* 其余方法省略 */ }
注解
- @FeignClient:Ribbon + Hystrix 自动集成,负载均衡、熔断降级开箱即用。
- fallback:远程挂了直接走兜底逻辑,雪崩不存在的。
自动配置
@Configuration @EnableFeignClients(basePackages = "com.example.feign") public class ServiceAutoConfiguration { @Bean @ConditionalOnProperty(name = "service.mode", havingValue = "remote") public UserService userServiceRemote(UserServiceFeignClient client) { return new UserServiceRemoteImpl(client); } @Bean @ConditionalOnProperty(name = "service.mode", havingValue = "local", matchIfMissing = true) public UserService userServiceLocal(UserRepository repo) { return new UserServiceLocalImpl(repo); } }
配置
# application.yml service: mode: local # 改成 remote 秒变微服务
进阶玩法:细粒度路由 + 智能负载
按模块单独开关
service: user: local order: remote product: local
AOP 动态选路(伪代码)
@Aspect @Component public class SmartRoutingAspect { @Around("@annotation(SmartRouting)") public Object route(ProceedingJoinPoint pjp) { // 统计 RT、错误率,实时计算 local vs remote 分值 boolean goLocal = loadBalancingService.shouldGoLocal(pjp.getSignature()); return goLocal ? pjp.proceed() : feignInvoke(pjp); } }
04优缺点
到此这篇关于SpringBoot基于AOP的本地/远程调用动态路由实践指南的文章就介绍到这了,更多相关SpringBoot调用动态路由内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!