• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • SpringCloud2.x Greenwich版本搭建:(七) Gateway網關

    標簽: springboot  微服務  springcloud  java

    1.Gateway是什么?

    Spring Cloud Gateway 是 Spring Cloud 的一個全新項目,該項目是基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技術開發的網關,它旨在為微服務架構提供一種簡單有效的統一的 API 路由管理方式。

    SpringCloud Gateway是基于WebFlux框架實現的,而WebFlux框架底層則使用了高性能的Reactor模式通信框架Netty。

    Spring Cloud Gateway 作為 Spring Cloud 生態系統中的網關,目標是替代 Netflix Zuul,其不僅提供統一的路由方式,并且基于 Filter 鏈的方式提供了網關基本的功能,例如:安全,監控/指標,和限流。

     

    Zuul是阻塞的,Gateway是非阻塞的,這么說是不嚴謹的,準確的講Zuul1.x是阻塞的,而在2.x的版本中,Zuul也是基于Netty,也是非阻塞的,如果一定要說性能,其實這個真沒多大差距。

     

    2.創建springcloud-getway子項目

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.1.5.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.itlinli</groupId>
        <artifactId>springcloud-geteway</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>springcloud-geteway</name>
        <description>Demo project for Spring Boot</description>
    
        <properties>
            <java.version>1.8</java.version>
            <spring-cloud.version>Greenwich.SR1</spring-cloud.version>
        </properties>
    
        <dependencies>
            <!--這里不添加父依賴了,因為spring cloud gateway是基于webflux的,不要導入spring-boot-start-web-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-gateway</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>${spring-cloud.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>
    

    Spring Cloud Gateway 網關路由有兩種配置方式:

    • 在配置文件 yml 中配置

    • 通過@Bean自定義 RouteLocator,在啟動主類 Application 中配置

    3.使用配置文件配置

    server:
      port: 8250
    spring:
      application:
        name: geteway
      cloud:
        gateway:
          discovery:
            locator:
              #開啟路由轉發
              enabled: false   #為true是時候http://localhost:8250/consumer-hystrix/hello/lisi 也可以訪問,開啟了2個路由。
              # 服務名小寫開啟
              lowerCaseServiceId: true
          routes:
            # 路由ID(一個路由配置一個ID)
            - id : consumer-hystrix
              # 通過注冊中心來查找服務名稱(lb代表從注冊中心獲取服務,并且負載均衡)
              uri: lb://consumer-hystrix
              predicates:
               - Path=/gateway/**  # 匹配到的以/gateway開頭的路徑都轉發到gateway的服務,相當于訪問 lb://consumer-hystrix/**
              filters:
                - StripPrefix=1     # 去掉匹配到的路徑的第一段
    
    eureka:
      client:
        service-url:
          defaultZone: http://localhost:8800/eureka/
    

    我這里采用之前項目中的消費者進行調用測試。

    4.啟動類

    @SpringBootApplication
    @EnableEurekaClient
    public class SpringcloudGetewayApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(SpringcloudGetewayApplication.class, args);
        }
    
    }

     

    5.啟動測試

    6.配置限流

           <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
            </dependency>

    7.修改配置文件

    server:
      port: 8250
    spring:
      redis:
        host: 192.168.221.150
        port: 6379
      application:
        name: geteway
      cloud:
        gateway:
          discovery:
            locator:
              #開啟路由轉發
              enabled: false   #為true是時候http://localhost:8250/consumer-hystrix/hello/lisi 也可以訪問,開啟了2個路由。
              # 服務名小寫開啟
              lowerCaseServiceId: true
          routes:
            # 路由ID(一個路由配置一個ID)
            - id : consumer-hystrix
              # 通過注冊中心來查找服務名稱(lb代表從注冊中心獲取服務,并且負載均衡)
              uri: lb://consumer-hystrix
              predicates:
               - Path=/gateway/**  # 匹配到的以/gateway開頭的路徑都轉發到gateway的服務,相當于訪問 lb://consumer-hystrix/**
              filters:
                - StripPrefix=1         # 去掉匹配到的路徑的第一段
                - name: RequestRateLimiter      #必須為filters名稱
                  args:
                    redis-rate-limiter.replenishRate: 1  #允許用戶每多少秒處理多少個請求
                    redis-rate-limiter.burstCapacity: 3  #令牌桶的容量,允許在一秒鐘內完成的最大請求數
                    key-resolver: "#{@ipKeyResolver}"    #使用ip限流,可以使用其他的接口限流等
    eureka:
      client:
        service-url:
          defaultZone: http://localhost:8800/eureka/
    
    
    

    8.添加限流配置類

    package com.itlinli.config;
    
    import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Primary;
    import reactor.core.publisher.Mono;
    
    @Configuration
    public class RateLimitConfig {
        @Bean
        KeyResolver userKeyResolver() {
            return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
        }
    
        @Primary
        @Bean
        KeyResolver ipKeyResolver() {
            return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName());
        }
    
        @Bean
        KeyResolver apiKeyResolver() {
            return exchange -> Mono.just(exchange.getRequest().getPath().value());
        }
    }

    9.啟動服務測試1秒內請求超過3次

    10.getway整合sentinel實現限流

            <dependency>
                <groupId>com.alibaba.csp</groupId>
                <artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
                <version>1.7.1</version>
            </dependency>
    
    
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
                <version>2.1.2.RELEASE</version>
            </dependency>
    
    
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
                <version>2.1.2.RELEASE</version>
            </dependency>

    11.配置文件

    server:
      port: 8250
    spring:
      main:
        allow-bean-definition-overriding: true
      redis:
        host: 192.168.221.150
        port: 6379
      application:
        name: geteway
      cloud:
        sentinel:
          filter:
            enabled: false
        gateway:
          discovery:
            locator:
              #開啟路由轉發
              enabled: false   #為true是時候http://localhost:8250/consumer-hystrix/hello/lisi 也可以訪問,開啟了2個路由。
              # 服務名小寫開啟
              lowerCaseServiceId: true
          routes:
            # 路由ID(一個路由配置一個ID)
            - id : consumer-hystrix
              # 通過注冊中心來查找服務名稱(lb代表從注冊中心獲取服務,并且負載均衡)
              uri: lb://consumer-hystrix
              predicates:
               - Path=/gateway/**  # 匹配到的以/gateway開頭的路徑都轉發到gateway的服務,相當于訪問 lb://consumer-hystrix/**
              filters:
                - StripPrefix=1         # 去掉匹配到的路徑的第一段
               # - name: RequestRateLimiter      #必須為filters名稱
                #  args:
                 #   redis-rate-limiter.replenishRate: 1  #允許用戶每多少秒處理多少個請求
                  #  redis-rate-limiter.burstCapacity: 3  #令牌桶的容量,允許在一秒鐘內完成的最大請求數
                   # key-resolver: "#{@ipKeyResolver}"    #使用ip限流,可以使用其他的接口限流等
    eureka:
      client:
        service-url:
          defaultZone: http://localhost:8800/eureka/
    
    
    

    12.添加配置文件

    package com.itlinli.config;
    
    import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule;
    import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayRuleManager;
    import com.alibaba.csp.sentinel.adapter.gateway.sc.SentinelGatewayFilter;
    import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.BlockRequestHandler;
    import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.GatewayCallbackManager;
    import com.alibaba.csp.sentinel.adapter.gateway.sc.exception.SentinelGatewayBlockExceptionHandler;
    import org.springframework.beans.factory.ObjectProvider;
    import org.springframework.cloud.gateway.filter.GlobalFilter;
    import org.springframework.cloud.gateway.filter.factory.RequestRateLimiterGatewayFilterFactory;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.Ordered;
    import org.springframework.core.annotation.Order;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.MediaType;
    import org.springframework.http.codec.ServerCodecConfigurer;
    import org.springframework.web.reactive.function.BodyInserters;
    import org.springframework.web.reactive.function.server.ServerResponse;
    import org.springframework.web.reactive.result.view.ViewResolver;
    import org.springframework.web.server.ServerWebExchange;
    import reactor.core.publisher.Mono;
    
    import javax.annotation.PostConstruct;
    import java.util.*;
    
    @Configuration
    public class GatewayConfiguration {
        private final List<ViewResolver> viewResolvers;
        private final ServerCodecConfigurer serverCodecConfigurer;
    
        public GatewayConfiguration(ObjectProvider<List<ViewResolver>> viewResolversProvider,
                                    ServerCodecConfigurer serverCodecConfigurer) {
            this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
            this.serverCodecConfigurer = serverCodecConfigurer;
        }
    
        @Bean
        @Order(Ordered.HIGHEST_PRECEDENCE)
        public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {
            // Register the block exception handler for Spring Cloud Gateway.
            return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);
        }
    
        @Bean
        @Order(Ordered.HIGHEST_PRECEDENCE)
        public GlobalFilter sentinelGatewayFilter() {
            return new SentinelGatewayFilter();
        }
    
        @PostConstruct
        public void doInit() {
            initGatewayRules();
            initBlockHandler();
        }
    
        /**
         * 配置限流規則
         */
    
        private void initGatewayRules() {
            Set<GatewayFlowRule> rules = new HashSet<>();
            rules.add(new GatewayFlowRule("consumer-hystrix") //consumer-hystrix對應配置文件中的路由ID
                    .setCount(3) // 限流閾值
                    .setIntervalSec(1) // 統計時間窗口,單位是秒,默認是 1 秒
            );
            GatewayRuleManager.loadRules(rules);
        }
    
        /**
         * 自定義限流異常處理器
         */
        private void initBlockHandler() {
            BlockRequestHandler blockRequestHandler = new BlockRequestHandler() {
                @Override
                public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) {
                    Map<String, String> result = new HashMap<>();
                    result.put("code", String.valueOf(HttpStatus.TOO_MANY_REQUESTS.value()));
                    result.put("message","限制請求次數!");
                    return ServerResponse.status(HttpStatus.TOO_MANY_REQUESTS)
                            .contentType(MediaType.APPLICATION_JSON_UTF8)
                            .body(BodyInserters.fromObject(result));
                }
            };
    
            // 加載自定義限流異常處理器
            GatewayCallbackManager.setBlockHandler(blockRequestHandler);
        }
    
    }
    

    13.啟動測試

    1秒請求超過3次

    版權聲明:本文為qq_41085151原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/qq_41085151/article/details/108096444

    智能推薦

    SpringCloud入門(八):網關Gateway 之 服務注冊與發現(Greenwich.SR2)

    簡介 在實際的工作中,服務的相互調用都是依賴于服務中心提供的入口來使用,服務中心往往注冊了很多服務,如果每個服務都需要單獨配置的話,非常麻煩。Spring Cloud Gateway 提供了一種默認轉發的能力,只要將 Spring Cloud Gateway 注冊到服務中心,Spring Cloud Gateway 默認就會代理服務中心的所有服務 代碼實現 新建一個Module,命名為micros...

    SpringCloud入門(十):網關Gateway 之 限流(Greenwich.SR2)

    簡介 限流:在高并發系統中,往往需要在系統中限流,一方面是為了防止大量請求使服務器過載,導致服務的不可用,另一方面是為了防止網絡攻擊。 一般開發高并發系統常見的限流有:限制總并發數(比如數據庫連接池、線程池)、限制瞬時并發數(如 nginx 的 limit_conn 模塊,用來限制瞬時并發連接數)、限制時間窗口內的平均速率(如 Guava 的 RateLimiter、nginx 的 limit_r...

    SpringCloud2.x(七)統一管理微服務配置——Spring Cloud Config

    一、為什么要統一管理微服務配置 對于傳統的單體應用,通常使用配置文件管理所有配置。比如Spring Boot開發的單體應用,配置內容可以放在application.yml文件,需要切換環境的話可以設置多個Profile并在啟動應用時指定spring.pfofiles.active={profile}。 然而,在微服務架構中,配置管理一般有以下需求 集中管理配置:一個使用微服務架構的應用系統可能會包...

    springCloud2.x版本集成elasticJob curator不兼容問題demo

    springCloud2.x版本集成elasticJob curator不兼容問題demo 背景 elasticJob集成步驟 沖突原因(curator-framework/curator-client/curator-recipes) 版本沖突錯誤代碼: 排查問題原因 解決辦法: 結束 背景 最近公司需要我集成elasticjob到現有項目,編寫demo過程都很順利,但是集成到項目時發現了一些問...

    SpringCloud2.x(二) 搭建完整Demo-搭建權限認證模塊、Eureka注冊中心

    SpringCloud2.x(二) 搭建完整Demo-搭建權限認證模塊 1.搭建權限認證模塊 2.搭建Eureka注冊中心(服務注冊發現,加密配置,搭建集群) ------------------------------------------------------------------------------------------------------------------------...

    猜你喜歡

    SpringCloud第七章(服務網關GateWay)

    目錄 1:什么是GateWay 2:網關的作用 3:GateWay特點 3.1:路由功能 3.2:斷言 3.3:過濾器 1:什么是GateWay Spring Cloud Gateway 是 Spring Cloud 新推出的網關框架,之前是 Netflix Zuul1,Gateway比 Zuul 2 更早的使用 Netty 實現異步 IO,從而實現了一個簡單、比 Zuul 1.x 更高...

    微服務實戰系列(七)-網關springcloud gateway

    1. 場景描述 springcloud剛推出的時候用的是netflix全家桶,路由用的zuul,但是據說zull1.0在大數據量訪問的時候存在較大性能問題,2.0就沒集成到springcloud中了,springcloud推出了自己的路由-springcloud gateway,親兒子,目前官網主推。 netfelix的zull路由: 2. 解決方案 2.1 新建springboot項目 在spr...

    HTML中常用操作關于:頁面跳轉,空格

    1.頁面跳轉 2.空格的代替符...

    freemarker + ItextRender 根據模板生成PDF文件

    1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...

    電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!

    Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...

    精品国产乱码久久久久久蜜桃不卡