SpringCloud 妹子圖之路由網關鑑權熔斷

點擊▲關注 “爪哇筆記”   給公衆號標星置頂

更多精彩 第一時間直達

前言

妹子圖架構發佈以後,不少小夥伴在後臺問路由網關、鑑權、限流怎麼搞得?這不熱乎乎的教程馬上就出來了。

架構

架構基本這麼一個組合,如果是個人開發或者小團隊項目,其實各個組件服務完全可以單機部署,因爲集羣費銀子也沒必要。

基礎組件

  • 路由網關:GateWay

  • 註冊中心:Nacos

  • 負載均衡:Ribbon

  • 熔斷器:Hystrix

配置

網關 pom.xml 引入:

<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>
         <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
</dependencies>

注意 Gateway 默認使用的是 webflux,不要引入 web,否則啓動會報錯。

啓動配置 bootstrap.yml,請自行安裝 Nacos

server:
  port: 8080

spring:
  application:
    name: tools-gateway
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848
      discovery:
        server-addr: 127.0.0.1:8848
    gateway:
      routes:
      - id: sys
        uri: lb://tools-sys
        predicates:
        - Path=/api/sys/**
        filters:
        - StripPrefix=2
        - name: Hystrix
          args:
            name: fallback
            fallbackUri: forward:/fallback # 熔斷回調
      - id: weChat
        uri: lb://tools-meizi
        predicates:
        - Path=/api/meizi/**
        filters:
        - StripPrefix=2
    # 跨域請求
    filter:
      remove-hop-by-hop:
        headers:
        - trailer
        - te
        - keep-alive
        - transfer-encoding
        - upgrade
        - proxy-authenticate
        - connection
        - proxy-authorization
        - x-application-context
        - access-control-allow-credentials
        - access-control-allow-headers
        - access-control-allow-methods
        - access-control-allow-origin
        - access-control-max-age
        - vary
      globalcors:
        corsConfigurations:
          '[/**]':
            allowCredentials: true
            allowedHeaders: '*'
            allowedMethods: '*'
            allowedOrigins: '*'
            maxAge: 3628800

# 熔斷
hystrix:
  command:
    default:
      circuitBreaker:
        enabled: true
        errorThresholdPercentage: 50
        forceClosed: false
        forceOpen: false
        requestVolumeThreshold: 4
        sleepWindowInMilliseconds: 10000
      execution:
        isolation:
          semaphore:
            maxConcurrentRequests: 2
          strategy: SEMAPHORE
          thread:
            timeoutInMilliseconds: 3000
      metrics:
        healthSnapshot:
          intervalInMilliseconds: 500
        rollingPercentile:
          bucketSize: 100
          enabled: true
          numBuckets: 6
          timeInMilliseconds: 60000
        rollingStats:
          numBuckets: 10
          timeInMilliseconds: 5000
      requestCache:
        enabled: false
      requestLog:
        enabled: false
  shareSecurityContext: true
  threadpool:
    default:
      coreSize: 1
      maxQueueSize: 200
      queueSizeRejectionThreshold: 2

鑑權

/**
 * 鑑權
 * @Author 小柒2012
 * @Date 2020/6/12
 */
@Configuration
public class AuthFilter implements GlobalFilter, Ordered {

    private static final Logger logger = LoggerFactory.getLogger(AuthFilter.class);

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String token = exchange.getRequest().getHeaders().getFirst("token");
        String path = exchange.getRequest().getPath().toString();
        /**
         * 排除
         */
        if(patterns.contains(path)){
            return chain.filter(exchange);
        }
        /**
         * 判斷 token 是否爲空
         */
        if (StringUtils.isBlank(token)) {
            logger.info( "token is empty..." );
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }else{
            /**
             * 驗證真僞
             */
            CheckResult checkResult = JwtUtils.validateJWT(token);
            if (!checkResult.isSuccess()) {
                logger.info( "token is error..." );
                exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
                return exchange.getResponse().setComplete();
            }
        }
        return chain.filter(exchange);
    }

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

    private  static List<String> patterns =
            Arrays.asList(new String[] {"/api/sys/login","/error","/api/sys/v2/api-docs"});
}

熔斷

一般是指軟件系統中,由於某些原因使得服務出現了過載現象,爲防止造成整個系統故障,從而採用的一種保護措施,所以很多地方把熔斷亦稱爲過載保護。

適用場景

防止應用程序直接調用那些很可能會調用失敗的遠程服務或共享資源。

服務降級

當服務器壓力劇增的情況下,根據當前業務情況及流量對一些服務和頁面有策略的降級,以此釋放服務器資源以保證核心任務的正常運行。

核心配置:

spring:
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    gateway:
      routes:
      - id: sys
        uri: lb://tools-meizi
        predicates:
        - Path=/api/meizi/**
        filters:
        - StripPrefix=2
        - name: Hystrix
          args:
            name: fallback
            fallbackUri: forward:/fallback # 熔斷回調

主要參數:

# 熔斷
hystrix:
  command:
    default:
      circuitBreaker:
        enabled: true
        errorThresholdPercentage: 50
        forceClosed: false
        forceOpen: false
        requestVolumeThreshold: 4
        sleepWindowInMilliseconds: 10000
      execution:
        isolation:
          semaphore:
            maxConcurrentRequests: 2
          strategy: SEMAPHORE
          thread:
            timeoutInMilliseconds: 3000
      metrics:
        healthSnapshot:
          intervalInMilliseconds: 500
        rollingPercentile:
          bucketSize: 100
          enabled: true
          numBuckets: 6
          timeInMilliseconds: 60000
        rollingStats:
          numBuckets: 10
          timeInMilliseconds: 5000
      requestCache:
        enabled: false
      requestLog:
        enabled: false
  shareSecurityContext: true
  threadpool:
    default:
      coreSize: 1
      maxQueueSize: 200
      queueSizeRejectionThreshold: 2

核心代碼 DefaultHystrixController

/**
 * 降級處理
 */
@RestController
public class DefaultHystrixController {

    @RequestMapping("/fallback")
    public Map<String,String> fallback(){
        Map<String,String> map = new HashMap<>(8);
        map.put("code","fail");
        map.put("msg","服務異常");
        return map;
    }
}

小結

以上基本能滿足項目的常用需求,如果想更加靈活的使用,建議使用 Alibaba Sentinel,阿里巴巴團隊開源的一款熔斷限流神器,配合控制檯更加靈活實用。


▲掃一掃回覆【妹子圖】獲取源碼

你點的每個在看,我都認真當成了喜歡

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章