SpringCloud 妹子图之路由网关鉴权熔断

点击▲关注 “爪哇笔记”   给公众号标星置顶

更多精彩 第一时间直达SpringCloud 妹子图之路由网关鉴权熔断_第1张图片

前言

妹子图架构发布以后,不少小伙伴在后台问路由网关、鉴权、限流怎么搞得?这不热乎乎的教程马上就出来了。

架构

SpringCloud 妹子图之路由网关鉴权熔断_第2张图片

架构基本这么一个组合,如果是个人开发或者小团队项目,其实各个组件服务完全可以单机部署,因为集群费银子也没必要。

基础组件

  • 路由网关:GateWay

  • 注册中心:Nacos

  • 负载均衡:Ribbon

  • 熔断器:Hystrix

配置

网关 pom.xml 引入:


        
            org.springframework.cloud
            spring-cloud-starter-gateway
        
        
            org.springframework.cloud
            spring-cloud-starter-netflix-hystrix
        
         
            com.alibaba.cloud
            spring-cloud-starter-alibaba-nacos-discovery
        
        
            com.alibaba.cloud
            spring-cloud-starter-alibaba-nacos-config
        

注意 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 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 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 fallback(){
        Map map = new HashMap<>(8);
        map.put("code","fail");
        map.put("msg","服务异常");
        return map;
    }
}

小结

以上基本能满足项目的常用需求,如果想更加灵活的使用,建议使用 Alibaba Sentinel,阿里巴巴团队开源的一款熔断限流神器,配合控制台更加灵活实用。


▲扫一扫回复【妹子图】获取源码

你点的每个在看,我都认真当成了喜欢

你可能感兴趣的:(SpringCloud 妹子图之路由网关鉴权熔断)