概述
版本号 | 作者 | SpringCloud Gateway版本号 | 备注 | |
---|---|---|---|---|
v0.0.1 | 若布与宫合 | 8416837 | 2.1.0.RELEASE | 反向代理 负载均衡 服务发现 监控埋点 |
原创文章转载请注明出处 https://blog.csdn.net/cc007cc009/article/details/92570640
文章目录
- [原创文章转载请注明出处 https://blog.csdn.net/cc007cc009/article/details/92570640](https://blog.csdn.net/cc007cc009/article/details/92570640)
- 用途
- 技术栈
- 过滤器
- 简介
- 内置的系统过滤器
- 路由定位器
- 自带管理接口
- 跨域
- 熔断器
- 重试
- 限流
- 异常处理
- 路由
- 动态路由
- 代码解释
- RouteDefinitionLocator
- RouteDefinitionWriter
- RouteDefinitionRepository
- ApplicationEventPublisherAware
- ApplicationEventPublisher
- RouteDefinition
- 辅助
- 跨域 - 此跨域非彼跨域
用途
- 安全
- 微服务代理
- 监控/埋点
- 限流
- 路径重写
技术栈
- 动态路由
- 熔断器
- 服务模式
过滤器
简介
- 过滤器种类
内置
自定义 - Filter责任链
过滤器责任链,管理过滤器执行顺序。 - 过滤器工作原理
过滤器可以在发送代理请求之前或之后执行.
内置的系统过滤器
- PrefixPath
- StripPrefix
springBoot yaml配置文件:
routes:
- id: routetest1
uri: https://www.baidu.com # 上游
predicates:
- Path=/service/baidu/s # 转发正确. 路由路径
filters:
- StripPrefix=2
路由定位器
- Demo
关键配置
spring:
cloud:
gateway:
discovery:
# 网关发现服务开启
locator:
# 默认关闭
enabled: true
# 默认关闭
lower-case-service-id: true
微服务API地址http://localhost:8002/system/sysDept/list
经网关代理后的地址:http://localhost:9999/service-name/system/sysDept/list
,service-name是服务注册名称。这时在网关添加过滤器,即可拦截请求了。
注意:通过服务名访问,不要定义路由特指。
通过网关访问成功:
注:localhost:9999为本地网关url。
- 负载均衡
通过网关访问微服务时,默认负载均衡。
过滤器
@Slf4j
public class RequestTimeFilter implements GatewayFilter, Ordered {
private static final String REQUEST_TIME_BEGIN = "requestTimeBegin";
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
exchange.getAttributes().put(REQUEST_TIME_BEGIN, System.currentTimeMillis());
return chain.filter(exchange).then(
Mono.fromRunnable(() -> {
Long startTime = exchange.getAttribute(REQUEST_TIME_BEGIN);
if (startTime != null) {
log.debug("{}=={},{}=={}",
"请求路径", exchange.getRequest().getURI().getRawPath(),
"消耗时间 ", (System.currentTimeMillis() - startTime) + "ms");
}
})
);
}
@Override
public int getOrder() { // 亦可注解
// order值与优先级成反比
return 0;
}
}
启动访问,过滤器没起效,这是因为还需要将该过滤器加入责任链。见下文
@Bean
public RouteLocator myRoutes(RouteLocatorBuilder builder) {
// 通过访问.../cecjx跳转到cecjx.com/cecjx cecjx路径会转交过去 PATH将作为远程应用的path
return builder.routes()
.route(p -> p
.path("/**/**")
.filters(f -> f.filter(new RequestTimeFilter()))
.uri("http://localhost:8002")
.order(0)// 起效了
.id("customer_filter_router")
)
.build();// 熔断测试要去掉contextPath
}
这样就起效了。
14:56:09 [reactor-http-nio-3] DEBUG c.j.gateway.filter.RequestTimeFilter - 请求路径==/system/sysDept/list,消耗时间 ==17ms
14:56:19 [reactor-http-nio-3] DEBUG c.j.gateway.filter.RequestTimeFilter - 请求路径==/system/sysDept/list3,消耗时间 ==15ms
- 全局过滤器
// 全局过滤器 优先执行
@Component
@Slf4j
public class TokenFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String token = exchange.getRequest().getQueryParams().getFirst("token");
if (token == null || token.isEmpty()) {
log.debug("token 为空,无法进行访问.");
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 0;
}
}
不传Token,无法访问
15:49:37 [reactor-http-nio-2] DEBUG com.jxbd.gateway.filter.TokenFilter - token 为空,无法进行访问.
传Token,访问成功.Token应加密到Https请求头.
自带管理接口
# 配置
management:
endpoints:
web:
exposure:
include: "*"
访问http://localhost:9999/actuator/gateway/routes
↓
不过这里我们不打算用自带的Restful接口,一来官方文档也没说新增网关参数怎么传,再者我们也不希望在网关暴露这些接口,第三路由信息也需要持久化起来.参照org.springframework.cloud.gateway.actuate.GatewayControllerEndpoint
,我们自己编程来动态改变网关。
跨域
熔断器
在路由配置熔断器
.route(p -> p
.host("*.hystrix.com")
.filters(f -> f
.hystrix(config -> config
.setName("mycmd")
.setFallbackUri("forward:/fallback")))
.uri("http://httpbin3.org"))
curl --dump-header - --header Host:www.hystrix.com http://localhost:9999/any # 因上游地址访问不通,触发熔断
因为访问不到http://httpbin3.org/any
,所以会触发熔断。
重试
限流
异常处理
- required a bean of type 'org.springframework.http.codec.ServerCodecConfigure
解决办法:去除spring-boot-starter-web
依赖
* Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.http.codec.ServerCodecConfigurer' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
解决方法:
去除spring-web依赖
Caused by: org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.
路由
路由断言种类:
路径
参数
主机
请求头
范围,如After、Before某个时间点、段
断言工厂:
我们主要使用路径路由,其实是做了个路径的反向代理。
将路径路由转发到上游服务器,与上游服务器的url拼接起来,如果使用Path断言,url会变得更长。
动态路由
- 是网关的核心功能之一,在不重启网关的情况下,即可更新路由和路由权限。
代码解释
RouteDefinitionLocator
public interface RouteDefinitionLocator { // 实现该接口:实时获取路由.不好用,因为调用时读取全部路由太耗资源了.
Flux<RouteDefinition> getRouteDefinitions(); // 不过调用时,并不是每次都走这个方法.
}
同时也要考虑网关集群时,路由亦需要使用中心化的存储器存储起来:redis、etcd、postgresql
RouteDefinitionWriter
public interface RouteDefinitionWriter { // 开发者实现该接口
Mono<Void> save(Mono<RouteDefinition> route); // 保存单个路由,只是将路由存入客户自定义的数据库.
Mono<Void> delete(Mono<String> routeId); // 删除单个路由
}
RouteDefinitionRepository
public interface RouteDefinitionRepository extends RouteDefinitionLocator, RouteDefinitionWriter {
} // 继承上述两个接口
ApplicationEventPublisherAware
public interface ApplicationEventPublisherAware extends Aware {
void setApplicationEventPublisher(ApplicationEventPublisher var1); // 监听
}
public interface Aware {
} // 空的
ApplicationEventPublisher
@FunctionalInterface
public interface ApplicationEventPublisher { // 事件监听 监听路由改变
default void publishEvent(ApplicationEvent event) { // ApplicationEvent 它的超类是EventObject
this.publishEvent((Object)event);
}
void publishEvent(Object var1);
}
RouteDefinition
按这个数据结构定义路由,并存储待使用。
@Validated
public class RouteDefinition {
@NotEmpty
private String id = UUID.randomUUID().toString(); // 默认uuid,一般会覆盖这个id,以便于后续操作.
@NotEmpty
@Valid
private List<PredicateDefinition> predicates = new ArrayList<>();
@Valid
private List<FilterDefinition> filters = new ArrayList<>();
@NotNull
private URI uri;
private int order = 0;
// ... 片段 ...
}
辅助
跨域 - 此跨域非彼跨域
- 1)开发模式下的跨域 查看参考 二次加工一下试试
- 2)生产
如何解决?
最后
以上就是苹果鲜花为你收集整理的网关-基于SpringCloud Gateway的扩展开发_v0.0.1原创文章转载请注明出处 https://blog.csdn.net/cc007cc009/article/details/92570640的全部内容,希望文章能够帮你解决网关-基于SpringCloud Gateway的扩展开发_v0.0.1原创文章转载请注明出处 https://blog.csdn.net/cc007cc009/article/details/92570640所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复