标签搜索
Spring Cloud Gateway 使用
记录笔记的地方

Spring Cloud Gateway 使用

skwax
2021-08-10 / 0 评论 / 23 阅读 / 正在检测是否收录...

Spring Cloud Gateway

基础使用

//依赖
spring-cloud-starter-gateway
//不能添加springweb依赖,网关采用netty,web采用tomcat
  • application.yml
//application.yml
server: 80
spring:
    application:
    #服务名称
        name: gateway
    cloud:
        #配置网关
        gateway:
            discovery: 
                locator:
                    enable: true #启用DiscoveryClient网关集成,可以实现服务发现
            #配置网关路由转发规则,是否转发以及转发路径
            routes: 
                - id: route1
                    #负载均衡 + 服务名称
                  uri: lb://demo
                  #谓词:是否匹配,可用正则,共11种谓词,以下为Path
                  predicates:
                      - Path=/test, /index, /test*/**
            #过滤器,提供31种,可对请求和响应进行操作
            filters:
                - AddRequestHeader=Context-Type, application-json
                
        #服务注册发现
        nacos: 
            discovery: 
                server-addr: 192.168.2.8:8848
            password: nacos
            username: nacos
        #哨兵
        sentinel:
            eager: true
            transport:
                dashboard: 192.168.2.8:8849

集成Swagger3.0.0

pom.xml 添加

<dependency>
     <groupId>io.springfox</groupId>
     <artifactId>springfox-boot-starter</artifactId>
     <version>${swagger.version}</version>
</dependency>

添加 SwaggerProvider

/**
 * 聚合系统接口
 *  @author Skwax
 */
@Component
@Primary
public class SwaggerProvider implements SwaggerResourcesProvider
{
    /**
     * swagger3默认的url后缀
     */
    private static final String SWAGGER3URL = "/v3/api-docs";

    /**
     * 网关路由
     */
    private final RouteLocator routeLocator;

    /**
     * gateway配置文件
     */
    private final GatewayProperties gatewayProperties;

    /**
     * 网关应用名称
     */
    @Value("${spring.application.name}")
    private String self;

    @Autowired
    public SwaggerProvider(RouteLocator routeLocator, GatewayProperties gatewayProperties) {
        this.routeLocator = routeLocator;
        this.gatewayProperties = gatewayProperties;
    }

    /**
     * 对于gateway来说这块比较重要 让swagger能找到对应的服务
     *
     * @return
     */
    @Override
    public List<SwaggerResource> get() {
        List<SwaggerResource> resources = new ArrayList<>();
        List<String> routes = new ArrayList<>();
        routeLocator.getRoutes().subscribe(route -> routes.add(route.getId()));
        //从配置文件中获取并配置SwaggerResource
        gatewayProperties.getRoutes().stream()
                //过滤路由
                .filter(routeDefinition -> routes.contains(routeDefinition.getId()))
                //循环添加,从路由的断言中获取,一般来说路由都会配置断言Path信息,这就不多说了
                .forEach(route -> {
                    route.getPredicates().stream()
                            //获取Path信息
                            .filter(predicateDefinition -> ("Path").equalsIgnoreCase(predicateDefinition.getName()))
                            //开始添加SwaggerResource
                            .forEach(predicateDefinition -> resources.add(swaggerResource(route.getId(),
                                    predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0")
                                            .replace("**", SWAGGER3URL))));
                });

        return resources;
    }

    private SwaggerResource swaggerResource(String name, String location) {
        SwaggerResource swaggerResource = new SwaggerResource();
        swaggerResource.setName(name);
        swaggerResource.setLocation(location);
        swaggerResource.setSwaggerVersion(DocumentationType.OAS_30.getVersion());
        return swaggerResource;
    }
}

集成Sentinel

pom.xml 添加

            <!-- SpringCloud Alibaba Sentinel -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>

        <!-- SpringCloud Alibaba Sentinel Gateway -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
        </dependency>

        <!-- Sentinel Datasource Nacos -->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>

自定义谓词

predicates:
    - Token=12345
  • 定义配置类,用于承载配置参数
import lombok.Data;

@Data
public class TokenConfig {
    private String Token;
}
  • 定义路由谓词工厂,类名固定格式
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.web.server.ServerWebExchange;

import java.util.Collections;
import java.util.List;
import java.util.function.Predicate;

@Component
public class TokenRoutePredicateFactory extends AbstractRoutePredicateFactory<TokenConfig> {

    public TokenRoutePredicateFactory()
    {
        super(TokenConfig.class);
    }

    /*
    将yml配置中的Token值存入TokenConfig类
     */
    @Override
    public List<String> shortcutFieldOrder() {
        return Collections.singletonList("token");
    }
    /*
    具体判断逻辑,返回true/false
     */
    @Override
    public Predicate<ServerWebExchange> apply(TokenConfig config) {
        return exchange -> {
            //获取yml中配置的Token
            var token = config.getToken();
            //获取请求的request
            var request = exchange.getRequest();
            return true;
        };

    }
}

自定义过滤器

filters:    - RequestLog=user, dsqda
  • 自定义网关过滤工厂
import org.springframework.cloud.gateway.filter.GatewayFilter;import org.springframework.cloud.gateway.filter.factory.AbstractNameValueGatewayFilterFactory;import org.springframework.stereotype.Component;@Componentpublic class RequestLogGatewayFilterFactory  extends AbstractNameValueGatewayFilterFactory {    @Override    public GatewayFilter apply(NameValueConfig config) {        return (exchange,chain)->{                //yml中filter配置的名称和值              config.getName();              config.getValue();              //请求              var request = exchange.getRequest();              return chain.filter(exchange);        };    }}

自定义全局过滤器

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Component
public class CustomeGlobalFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        return chain.filter(exchange);
    }
    //数值越小越靠前
    @Override
    public int getOrder() {
        return 0;
    }
}

跨域

  • 增加配置类
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
import org.springframework.web.util.pattern.PathPatternParser;

@Configuration
public class CorsConfig {

    @Bean
    public CorsWebFilter corsWebFilter(){
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedMethod("*");
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
        source.registerCorsConfiguration("/**",config);
        return  new CorsWebFilter(source);

    }

}
0

Deprecated: strtolower(): Passing null to parameter #1 ($string) of type string is deprecated in /www/wwwroot/biji.moyuke.net/var/Widget/Archive.php on line 1032

评论

博主关闭了所有页面的评论