首页 > 其他分享 >springcloud-gateWay

springcloud-gateWay

时间:2023-10-24 10:46:43浏览次数:35  
标签:return exchange springcloud class public filter Override gateWay

基础模板

spring:
  cloud:
    gateway:
      routes:
      	-id: gulimall-search # 别重复就行
      	 uri: lb://gulimall-search #对应微服务的applicationName
      	 predicates:
      	   - Path=/api/search/**

predicates的概念

每一个route对应一个--->RouteDefinition

而route对应的predicates对应---->RouteDefinition的List predicates

如何生成对应的predicate?

由路由断言工厂实现(RoutePredicateFactory(接口)),总共有12个具体实现类

分别对应12种断言方式,至于用什么取决于 predicates:后的 每个element的内容例如- Path则是PathRoute....

类似Cookie的形式有所不同-->,前面是key,后面是value 要完全符合才可以使用

Cookie与Header在项目更新中灰度测试有用,可以给指定用户配上特定cookie或者header,来匹配上某个微服务中换上新代码的机器

  • 最常用是:Host,Path,Header

分布式登录要注意的问题

  • 登录功能在对应的微服务上,但是登录信息如token要统一在gateway解析
  • 解析后,需要把用户信息记录到每个要发到其他微服务的request上(通常放header)
  • 要预防openFeign发请求带没带原定要共享的数据

网关过滤器的执行流程

概念回想:

  1. dispatcherHandler-->根据predicatesmapping来转发给哪一个微服务
  2. 有一系列的过滤链--->(设计模式:责任链模式),每个过滤器有pre和post拦截,pre是在转发前,post是在转发后,和MVC一样,pre是按优先级正序,post是按优先级倒序
  3. 优先级最低的是负责转发的filter
  4. 在cloud里有一系列的内置的filter
    1. 如果要针对某个route在route ->> -id下弄一个filters(具体有哪些看官网)
    2. 如果是针对每一个route--->在gateway下,与routes同级,弄一个default-filters
  5. 要自定义filter/了解内置filter
    1. globalFilter:面向全部
    2. gateWayFilter:更加灵活,可以作用于任意指定的路由(yaml配置的route即是路由)

完整的概念过程:

  • 关于StripPrefix:指定的=1就是删除path的几段前缀,然后这个path是/a/c/这样的(是url去掉协议和域名or地址的剩余部分)
  • RewritePath,那里说明有误

自定义过滤器

gateWayFilter(必须在yaml中配置才会生效)

注意点

  1. 不是直接new,而是去弄一个factory(工厂模式(一个工厂只培养一个filter))
  2. 该工厂extends AbstractGatewayFilterFactory
  3. public class PrinthhGatewayFilterFactory,命名有规范,加粗为固定后缀,之后使用更方便
    1. 使用上直接在default-filters下当做一个ele来使用,---->使用固定后缀优势在于----> - Printhh就可以了
@Component
public class PrinthhGatewayFilterFactory extends AbstractGatewayFilterFactory<Object> {
    @Override
    public GatewayFilter apply(Object config) {
        return new GatewayFilter() {
            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                System.out.println("hhhh");
                ServerHttpRequest request = exchange.getRequest();
                return chain.filter(exchange);
            }
        };
    }
}

疑问?像Mono这种类型,假如要拒绝该怎么办?

带上参数plus版

@Component
public class PrinthhGatewayFilterFactory extends AbstractGatewayFilterFactory<PrinthhGatewayFilterFactory.Config> {
    @Override
    public GatewayFilter apply(PrinthhGatewayFilterFactory.Config config) {
        return new OrderedGatewayFilter(new GatewayFilter() {
            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                System.out.println(config.getA());
                System.out.println(config.getB());
                System.out.println(config.getC());
                return chain.filter(exchange);
            }
        },1);
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("a","b","c");
    }
	@Override
    public Class<Config> getConfigClass() {
        return Config.class;
    }
    @Data
    public static class Config{

        public String a;

        public String b;
        public String c;
    }
}

使用上:直接在 - Printhh=1,2,3就可以了(可以不按顺序,但是需要拆成对象的形式(更复杂))

带上过滤器顺序

@Component
public class PrinthhGatewayFilterFactory extends AbstractGatewayFilterFactory<PrinthhGatewayFilterFactory.Config> {
    @Override
    public GatewayFilter apply(PrinthhGatewayFilterFactory.Config config) {
        //重点!!!!!!
        return new OrderedGatewayFilter(new GatewayFilter() {
            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                System.out.println(config.getA());
                System.out.println(config.getB());
                System.out.println(config.getC());
                return chain.filter(exchange);
            }
        },1);
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("a","b","c");
    }

    @Override
    public Class<Config> getConfigClass() {
        return Config.class;
    }

    @Data
    public static class Config{

        public String a;

        public String b;
        public String c;
    }
}

GlobalFilter(及其容易)

  1. implements GlobalFilter, Ordered
  2. 添加@Component注解

不用在yaml里面去配置,默认生效,针对所有

public class MyGlobalFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        System.out.println("全局过滤器");
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 1;
    }
}

非对称加密(公钥加密只能私钥解密,私钥加密只能公钥解密)

通常是公钥放到网关,而私钥放到内部服务器

网关登录校验

  1. 首先,回答Mono拒绝的问题---->抛异常或者直接return一个response(记得设置下code)

注意点

  1. 通常校验时要考虑哪些是要放行的(springsecurity在配置文件里面有auth:....配置下通行路径(如果需要用REST,要自己带上GET:等))
  2. 比较时,可以用spring的private AntPathMatcher antPathMatcher;
  3. 拦截器中需要网关校验后要修改request(例如往header添加user-Info)
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    System.out.println("全局过滤器");
    //重点
    ServerWebExchange exc = exchange.mutate().request(builder -> builder.header("user", "UserInfo")).build();
    return chain.filter(exc);
}
  1. 在各个微服务中,需要添加Interceptor(同时要弄个MvcConfig implements WebMvcConfigurer ,在里面addInterceptor)来拦截request中header的user-Info,然后根据逻辑添加到ThreadLocal中(通常由于都要用到,所以放在common)

    1. 配置在common包通常扫描不到,需要配置spring.factories(新增目录META-INF,底下再放spring.factories)
    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
      com.seamount3.common.config.GuliFeignConfig,\
      //按上面的格式写多个,如果只有一个把,\去掉
    
    1. 或者弄一个注解类
    @Import(GuliFeignConfig.class)//重点
    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface EnableFeignConfig {
    }
    
    @Configuration
    //@ConditionalOnClass(DispatcherServlet.class),直接弄一个enable的注解得了,这里要注意像gateway用webflux时,要记得打开这个,同时记得gateway不能导入MVC依赖
    public class GuliFeignConfig
    
  2. openFeign也要添加一个requestInterceptor来拦截所有请求添加user-Info到header中

@Bean
public RequestInterceptor requestInterceptor(){
    return new RequestInterceptor() {
        @Override
        public void apply(RequestTemplate requestTemplate) {
            ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            if(requestAttributes!=null) {
                String cookie = requestAttributes.getRequest().getHeader("Cookie");
                if (StringUtils.hasText(cookie)) {
                    requestTemplate.header("Cookie", cookie);
                }
            }
        }
    };
}

标签:return,exchange,springcloud,class,public,filter,Override,gateWay
From: https://www.cnblogs.com/seamount3/p/17784188.html

相关文章

  • ingressgateway访问授权
    当externalTrafficPolicy设置为Local时,Istio会保留外部客户端的原始源IP地址,在IngressGateway层面进行IP访问控制时,你可以基于客户端的源IP地址来定义访问规则。kubectlpatchsvcistio-ingressgateway-nistio-system-p'{"spec":{"externalTrafficPolicy":"L......
  • SpringCloudAlibaba Seata在Openfeign跨节点环境出现全局事务Xid失效原因底层探究
    原创/朱季谦曾经在SpringCloudAlibaba的Seata分布式事务搭建过程中,跨节点通过openfeign调用不同服务时,发现全局事务XID在当前节点也就是TM处,是正常能通过RootContext.getXID()获取到分布式全局事务XID的,但在下游节点就出现获取为NULL的情况,导致全局事务失效,出现异常时无法正常回......
  • SpringCloudGateway网关整合swagger3+Knife4j3,basePath丢失请求404问题
    很多人都是照着别人的文章粘代码,我也是粘的,但是这样粘也会有问题,我搞这个Knife4j3的时候遇到两个问题,这里记录一下:第一个是basePath丢失,第二个解决basePath丢失完又引发了会引起application/json数据类型参数示例的问题。在集成SpringCloudGateway网关的时候,会出现没有basePat......
  • 【Azure APIM】解决APIM Self-hosted Gateway在AKS上,最开始访问时候遇见的404问题
    问题描述根据APIM官方文档,创建Self-hosted网关在AKS中( 使用YAML将自承载网关部署到Kubernetes :https://docs.azure.cn/zh-cn/api-management/how-to-deploy-self-hosted-gateway-kubernetes),但是访问AKS中Services的Endpoint,得到的确实404页面。{"statusCode":40......
  • SpringCloud专题面试
    1.微服务架构优缺点1)单体应用开发的效率比较低,由于代码量大,项目启动缓慢,部署麻烦,后期难以维护。2)服务拆分分为多个小应用,提高了开发效率,降低了代码的耦合程度,不同的服务可以采用不同的语言,提高了灵活性;小的改动进行快捷部署,方便维护。3)拆分的依据原则就是高内聚低耦合,每个服......
  • SpringCloud Sentinel原理介绍
    SpringCloud微服务保护技术一般都是:Hystrix和Sentinle,早期比较流行的是Hystrix框架,但目前国内实用最广泛的还是阿里巴巴的Sentinel框架,我们对这两种常见技术进行对比:SentinelHystrix隔离策略信号量隔离线程池隔离/信号量隔离熔断降级策略基于慢调用比例或异常比例基于失败比率实......
  • 服务链路追踪 —— SpringCloud Sleuth
    Sleuth简介随着业务的发展,系统规模变得越来越大,微服务拆分越来越细,各微服务间的调用关系也越来越复杂。客户端请求在后端系统中会经过多个不同的微服务调用来协同产生最后的请求结果,几平每一个请求都会形成一个复杂的分布式服务调用链路,在每条链路中任何一个依赖服务出现延迟超......
  • [SpringCloud 01] RestTemplate Ribbon Feign
    SpringCloud11.RestTemplatespringcloud是基于rest的框架,所以在调用其他服务的时候,可以支持用restTemplate来调用.可以在spring中首先用@Bean的方式把ResTemplate放入spring容器@ConfigurationpublicclassMyConfig{@BeanpublicRestTemplategetRestTem......
  • SpringCloud:Feign实现微服务之间相互请求
    文章目录......
  • 分布式事务 —— SpringCloud Alibaba Seata
    Seata简介传统的单体应用中,业务操作使用同一条连接操作不同的数据表,一旦出现异常就可以整体回滚。随着公司的快速发展、业务需求的变化,单体应用被拆分成微服务应用,原来的单体应用被拆分成多个独立的微服务,分别使用独立的数据源,业务操作需要调用三个服务来完成。此时每个服务内部......