
场景:当我们在做接口平台的时候,我们需要在每一个接口结束调用相关的方法进行记录次数,但是这时候就有问题了,如果我们需要在每一个接口调用的时候到要执行的话难道不能「提取出来」吗?
答案时肯定的,但是我们要用什么技术?AOP ?网关?
AOP 这个 Spring 非常重要的特性,那么该如何实现这个项目的相关接口执行之后调用统计方法呢?
@Aspect
@Component
public class MethodExecutionCounterAspect {
// 定义切点,可以根据自己的需求进行配置
@After("execution(* com.example.yourpackage.YourService.*(..))")
public void afterMethodExecution(JoinPoint joinPoint) {
// 记录方法执行次数
// 查询数据库进行加一
methodExecutionCount++;
System.out.println("Method executed: " + joinPoint.getSignature());
System.out.println("Method execution count: " + methodExecutionCount);
// 执行目标方法
Object result = joinPoint.proceed();
// 可以在这里添加额外的逻辑,根据需要修改 result
return result;
}
}

但是 AOP 也有缺点,只能在单个项目中使用,虽然我们可以封装成 SDK 但是还是需要在每一个项目中引入和调用,有没有更简单的呢?当然那就是 网关使用网关之后就可以做 **「统一」**管理

网关
什么是网关?理解成火车站的检票口,统一 去检票。
作用
统一去进行一些操作、处理一些问题。
比如:
路由
负载均衡
统一鉴权
跨域
统一业务处理(缓存)
访问控制
发布控制
流量染色
接口保护
限制请求
信息脱敏
降级(熔断)
限流:学习令牌桶算法、学习漏桶算法,学习一下 RedisLimitHandler
超时时间
统一日志
统一文档
路由
起到转发的作用,比如有接口 A 和接口 B,网关会记录这些信息,根据用户访问的地址和参数,转发请求到对应的接口(服务器 / 集群)
/a => 接口A
/b => 接口
官方文档 官方文档永远都是最重要的,记住这一点!
负载均衡
在路由的基础上
/c => 服务 A / 集群 A(随机转发到其中的某一个机器)
uri 从固定地址改成 lb:xxxx
统一处理跨域
网关统一处理跨域,不用在每个项目里单独处理,这个的原因是网关一般是挡在最前面的原因。文档
发布控制
灰度发布,比如上线新接口,先给新接口分配 20% 的流量,老接口 80%,再慢慢调整比重。文档
spring:
cloud:
gateway:
routes:
- id: weight_high
uri: https://weighthigh.org
predicates:
- Weight=group1, 8
- id: weight_low
uri: https://weightlow.org
predicates:
- Weight=group1, 2
这里的 Weight=group1 意识是把这两个断言设置成一组
流量染色
给请求(流量)添加一些标识,一般是设置请求头中,添加新的请求头。这样就可以区分是不是经过了网关,没有经过网关的就不会有对应的请求头,可以防止直接请求后端接口
spring:
cloud:
gateway:
routes:
- id: after_route
# path 的内容会拼到这个的后面进行请求
uri: http://localhost:8123
predicates:
- Path=/api/**
# 流量染色
filters:
- AddRequestHeader=yupi, handsome
统一接口保护
降级(熔断):https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#fallback-headers
超时时间:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#http-timeouts-configuration
统一业务处理
把一些每个项目中都要做的通用逻辑放到上层(网关),统一处理,比如本项目的次数统计
统一的访问控制
黑白名单,比如限制 DDOS IP
统一日志
统一的请求、响应信息记录
统一文档
将下游项目的文档进行聚合,在一个页面统一查看
建议用:https://doc.xiaominfo.com/docs/middleware-sources/aggregation-introduction
网关的分类
全局网关(接入层网关):作用是负载均衡、请求日志等,不和业务逻辑绑定
业务网关(微服务网关):会有一些业务逻辑,作用是将请求转发到不同的业务 / 项目 / 接口 / 服务
网关实现
Nginx(全局网关)、Kong 网关(API 网关,Kong),编程成本相对高一点,还需要学新的语言
Spring Cloud Gateway(取代了 Zuul)性能高、可以用 Java 代码来写逻辑,适于学习
Spring Cloud Gateway 用法
路由(根据什么条件,转发请求到哪里)
断言:一组规则、条件,用来确定如何转发路由
过滤器:对请求进行一系列的处理,比如添加请求头、添加请求参数
创建项目需要安装的依赖

请求流程:
客户端发起请求
Handler Mapping:根据断言,去将请求转发到对应的路由
Web Handler:处理请求(一层层经过过滤器)
实际调用服务

两种配置方式
配置式(方便、规范)
1) 简化版spring: cloud: gateway: routes: - id: after_route uri: https://example.org predicates: - Cookie=mycookie,mycookievalue- 全称版
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- name: Cookie
args:
name: mycookie
regexp: mycookievalue
- 编程式(灵活、相对麻烦)
@SpringBootApplication
public class DemogatewayApplication {
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("path_route", r -> r.path("/get")
.uri("http://httpbin.org"))
.route("host_route", r -> r.host("*.myhost.org")
.uri("http://httpbin.org"))
.route("rewrite_route", r -> r.host("*.rewrite.org")
.filters(f -> f.rewritePath("/foo/(?<segment>.*)", "/${segment}"))
.uri("http://httpbin.org"))
.route("hystrix_route", r -> r.host("*.hystrix.org")
.filters(f -> f.hystrix(c -> c.setName("slowcmd")))
.uri("http://httpbin.org"))
.route("hystrix_fallback_route", r -> r.host("*.hystrixfallback.org")
.filters(f -> f.hystrix(c -> c.setName("slowcmd").setFallbackUri("forward:/hystrixfallback")))
.uri("http://httpbin.org"))
.route("limit_route", r -> r
.host("*.limited.org").and().path("/anything/**")
.filters(f -> f.requestRateLimiter(c -> c.setRateLimiter(redisRateLimiter())))
.uri("http://httpbin.org"))
.build();
}
}
开启日志
logging:
level:
org:
springframework:
cloud:
gateway: trace
断言
After 在 xx 时间之后
场景:一般某个活动的结束、开始就需要这种
断言Before 在 xx 时间之前
Between 在 xx 时间之间
请求类别
请求头(包含 Cookie)
查询参数
客户端地址
权重
过滤器
基本功能:对请求头、请求参数、响应头的增删改查
添加请求头
添加请求参数
添加响应头
降级
限流
重试
依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-circuitbreaker-reactor-resilience4j</artifactId>
</dependency>
Comments
Join the discussionNo comments yet. Be the first to comment.