springcloud gateway 集成eureka

本文深入讲解Spring Cloud Gateway的特性,包括动态路由、断言与过滤器编写、限流、熔断及响应处理等。探讨了与Zuul的对比优势,提供了代码与配置文件两种路由规则设置方式,介绍了如何集成Eureka实现服务发现与负载均衡。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

gateway:  
springcloud子项目与spring无缝整合,上手简单,异步非阻塞,性能比zuul1好一点  
功能与zuul类似:权限认证,限流,路由分发,熔断,响应处理  
总结一下gateway的特性:
   1).动态路由
   2).易于编写的 Predicates(断言) 和 Filters(过滤器)
   3).限流
   4).集成 Eureka 默认路由
   5).集成 Hystrix 断路器
   6).路由超时

springcloud集成gateway代码地址 github: https://github.com/475cheng/gateway-demo-cheng

springboot接入gateway
1.引入pom.xml
```xml
<project>
<parent>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-parent</artifactId>
   <version>2.0.5.RELEASE</version>
</parent>
<dependencyManagement>
   <dependencies>
      <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-dependencies</artifactId>
         <version>Finchley.SR1</version>
         <type>pom</type>
         <scope>import</scope>
      </dependency>
   </dependencies>
</dependencyManagement>
<dependencies>
   <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-gateway</artifactId>
   </dependency>
   <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
   </dependency>
</dependencies>
</project>
```  

2.添加路由规则,有两种形式,代码或者配置文件  
   1).代码形式
```java
@Configuration
public class RouteLocatorBean {
    public static String httpUriA = "http://www.baidu.com";
    public static String httpUriB = "http://www.baidu.com/endpoint/endpointB";
    @Bean
    public RouteLocator myRoutes(RouteLocatorBuilder builder) {
        
        return builder.routes()
                .route(p -> p
                        .path("/getmessage")                              
                        .filters(f -> f.hystrix(config -> config            //404不会触发断路,服务停止才会触发forward
                                .setName("myCommandName")                   
                                .setFallbackUri("forward:/fallback")))    //1.对请求路径为/getmessage的,路由到httpUriB这个地址,如果这个地址服务挂掉,进行路由熔断,重定到这个地址/fallback
                        .uri(httpUriB))                               //uri这里可以是域名,它会自动将请求路径追加到域名后面
                .route(p -> p
                        .path("/endpointA")
                        .filters(f -> f.prefixPath("/endpoint"))
                        .uri(httpUriA))                               //2.对于请求路径为/endpointA的,对于请求路径包装,前缀添加/endpoint,最终访问路径为http://www.baidu.com/endpoint/endpointA
                .route(p -> p
                        .query("name", "shen")
                         .filters(f -> f.addRequestHeader("username","test"))
                        .uri(httpUriB))                               //3.对于请求中携带的参数为http://baidu.com?name=shen的,最终路由到httpUriB这个地址,并且在请求头中添加username=test
                .route(p -> p
                        .path("/fallback")                                  //4.如果gateway服务没有fallback端点,但是别的服务有fallback端点,可以这样配置
                        .uri("http://localhost:8888"))                      //那么上面熔断的路由都会请求带这个地址http://localhost:8888/fallback
                .build();
    }
}
```  

   2). 配置文件形式 以application.yml格式为例  

```application.yml
spring:
  cloud:
    gateway:
      enabled: true       //默认为true启动网关,如果项目中引用的jar包而不想启用网关,可以改为false
      routes:
      - id: path_route_hys
        uri: http://localhost:8888/endpoint/endpointB
        predicates:
        - Path=/getmessage  //特别注意:- Path =/getmessage 这样格式的话,gateway的所有配置都会失效
        filters:
        - name: Hystrix
          args:
            name: test_hystrix
            fallbackUri: forward:/fallback
      - id: path_route_pre
        uri: http://localhost:8888
        predicates:
        - Path=/endpointA
        filters:
        - PrefixPath=/endpoint
      - id: query_route
        uri: http://localhost:8888/endpoint/endpointB
        predicates:
        - Query=name, shen
        filters:
        - AddRequestHeader=username, test

hystrix:
  command:
    test_hystrix:              //这个地方是上面hystrix的name,timeout默认是1s,   default为全局配置默认
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 9000
```  

3.集成Eureka  
   1).pom添加
```pom.xml
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
接口用于重试
<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
</dependency>
```  

   2).以配置文件形式为例 yml格式为例
```yml
spring:    
  cloud:
    loadbalancer:
      retry:
        enabled: true   //开启失败重试
    gateway:
      discovery:
        locator:
          enabled: true             //当访问http://网关地址/服务名称(大写)/**地址会自动转发到http://服务名称(大写)/**地址,如果为false就不会自动转发
          lowerCaseServiceId: true //为true表示服务名称(小写)
      routes:
      - id: service-hi
        uri: lb://SERVICE-HI      //lb代表从注册中心获取服务,后面接的就是你需要转发到的服务名称 不能填uri只能是服务名称
        predicates:
        - Path=/demo/**
        filters:
        - name: Retry
          args:
            retries: 3              //在Eureka注册列表中有一个节点挂掉了,在短时间内,列表没有更新,还会调用挂掉的节点,可以通过失败重试调用其他节点
            statuses: BAD_GATEWAY
      
eureka:
  instance:
    prefer-ip-address: true
  client:
    service-url:
      defaultZone: http://123456@master:8761/eureka/
```  

4.gateway 自定义全局过滤器 (如:token过滤器)  

创建完全局过滤器,加上@Component注解就会生效  

```java
@Component
public class TokenFilter implements GlobalFilter, Ordered {

    Logger logger=LoggerFactory.getLogger( TokenFilter.class );
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String token = exchange.getRequest().getQueryParams().getFirst("token");
        if (token == null || token.isEmpty()) {
            logger.info( "token is empty..." );
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return -100;
    }
}
```  

5.gateway 自定义过滤器filter  
  
   1).创建自定义过滤器  

```java
public class RequestTimeGatewayFilterFactory extends AbstractGatewayFilterFactory<RequestTimeGatewayFilterFactory.Config> {    //泛型用静态内部类
    private static final Log log = LogFactory.getLog(GatewayFilter.class);
    private static final String REQUEST_TIME_BEGIN = "requestTimeBegin";
    private static final String KEY = "withParams";

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList(KEY);
    }

    public RequestTimeGatewayFilterFactory() {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, 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) {
                            StringBuilder sb = new StringBuilder(exchange.getRequest().getURI().getRawPath())
                                    .append(": ")
                                    .append(System.currentTimeMillis() - startTime)
                                    .append("ms");
                            if (config.isWithParams()) {
                                sb.append(" params:").append(exchange.getRequest().getQueryParams());
                            }
                            log.info(sb.toString());
                        }
                    })
            );
        };
    }
    public static class Config {
        private boolean withParams;
        public boolean isWithParams() {
            return withParams;
        }
        public void setWithParams(boolean withParams) {
            this.withParams = withParams;
        }

    }
}
```  
2).添加bean中  

```java
@Configuration
public class FilterBeanFactory {
    @Bean
    public RequestTimeGatewayFilterFactory elapsedGatewayFilterFactory() {
        return new RequestTimeGatewayFilterFactory();
    }
}
```  

3).引用自定义过滤器  

```yml
spring:
  cloud:
    gateway:
      routes:
      - id: add_request_header_route
        uri: http://localhost:8888/endpoint/endpointA
        filters:
        - RequestTime=true                //此处为因为自定义过滤器
```

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值