Spring Cloud -Zuul

服務網關和zuul

一個角色來充當request的請求入口,處理非業務功能的場所(防刷,協議監控)java

要素:

  1. 穩定性,高可用
  2. 性能、併發性
  3. 安全性
  4. 擴展性

經常使用的網關方案

  1. Nginx+Lua(性能極高,事件驅動型,優化設計,擴展性,耦合低)
  2. Kong
  3. Tyknginx

    1. 全RestFul Api
    2. go開發
    3. 性能高
  4. Spring Cloud Zuulgit

    1. netflix 開發
    2. java技術棧
    3. 一代zuul不能和nginx比性能

項目改造應該合理利用原有的優點redis

特色:

路由+過濾器=Zuulspring

核心是一系列的過濾器apache

四種過濾器

  • 前置
  • 路由
  • 後置
  • error

image-20181018175625786

使用

導入依賴

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>

開啓註解@EnableZuulProxy

@EnableEurekaClient
@EnableZuulProxy

yml

spring:
  application:
    name: zuul
  cloud:
    config:
      discovery:
        service-id: CONFIG
        enabled: true
      profile: dev
server:
  port: 8085
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka
zuul:
  routes:
# /myProduct/product/list -> /product/list
#    aaa:
#      path: /myProduct/**
#      serviceId: PRODUCT
#簡潔寫法
    product: /myProduct/**
#    排除某些路由 set的寫法
  ignored-patterns:
    - /**/myProduct/product/list
 #用來查看配置
management:
  security:
    enabled: false

{{zuul}}/application/routes查看配置json

cookie和動態路由

Cookie

默認是不開啓cookie的

全局開啓api

zuul:
    sensitive-headers:

開啓方式:

zuul:
  routes:
# /myProduct/product/list -> /product/list
#    aaa:
#      path: /myProduct/**
#      serviceId: PRODUCT
#簡潔寫法
    product: /myProduct/**
  sensitive-headers:

image-20181019102234307

image-20181019102252196

image-20181019102134483

動態路由(cloud config +cloud bus)

image-20181019112548970

@Component
public class ZuulConfig {
    @Autowired
    @ConfigurationProperties("zuul")
    public ZuulProperties zuulProperties() {
        return new ZuulProperties();
    }
}

特色

  • 路由+過濾器=Zuul
  • 核心是一系列的過濾器

典型應用場景

  • 前置跨域

    • 鑑權
    • 過濾
  • 後置緩存

    • 統計
    • 日誌

Zuul的高可用

多個節點註冊到Eureka Server上

Nginx 和Zuul"混搭"

前置和後置過濾器

前置過濾

package com.zzjson.apigateway.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.apache.commons.lang.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_DECORATION_FILTER_ORDER;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;

/**
 * <p>****************************************************************************</p>
 * <p><b>Copyright © 2010-2018 rollBall team All Rights Reserved<b></p>
 * <ul style="margin:15px;">
 * <li>Description : com.zzjson.apigateway.filter</li>
 * <li>Version     : 1.0.0</li>
 * <li>Creation    : 2018年10月19日</li>
 * <li>@author     : zzy0_0</li>
 * </ul>
 * <p>****************************************************************************</p>
 */
@Component
public class TokenFilter extends ZuulFilter {

    @Override
    public String filterType() {
        return PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return PRE_DECORATION_FILTER_ORDER - 1;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() throws ZuulException {
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();
        String token = request.getParameter("token");
        if (StringUtils.isEmpty(token)) {
            //不經過
            requestContext.setSendZuulResponse(false);
            requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
        }
        return null;
    }
}

order 的值越小,優先級越高image-20181019161527446

後置過濾

package com.zzjson.apigateway.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletResponse;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.POST_TYPE;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SEND_RESPONSE_FILTER_ORDER;

/**
 * <p>****************************************************************************</p>
 * <p><b>Copyright © 2010-2018 rollBall team All Rights Reserved<b></p>
 * <ul style="margin:15px;">
 * <li>Description : com.zzjson.apigateway.filter</li>
 * <li>Version     : 1.0.0</li>
 * <li>Creation    : 2018年10月19日</li>
 * <li>@author     : zzy0_0</li>
 * </ul>
 * <p>****************************************************************************</p>
 */
@Component
public class AddResponseFilter extends ZuulFilter {

    @Override
    public String filterType() {
        return POST_TYPE;
    }

    @Override
    public int filterOrder() {
        return SEND_RESPONSE_FILTER_ORDER - 1;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() throws ZuulException {
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletResponse response = requestContext.getResponse();
        response.setHeader("surprise", "xx");
        return null;
    }
}

限流

限流保護,防止網絡攻擊

時機:請求被轉發以前調用

令牌桶限流

image-20181019162829140

package com.zzjson.apigateway.filter;

import com.google.common.util.concurrent.RateLimiter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.exception.ZuulException;
import com.zzjson.apigateway.exception.RateLimiterException;
import org.springframework.stereotype.Component;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVLET_DETECTION_FILTER_ORDER;

/**
 * <p>****************************************************************************</p>
 * <p><b>Copyright © 2010-2018 rollBall team All Rights Reserved<b></p>
 * <ul style="margin:15px;">
 * <li>Description :限流攔截器</li>
 * <li>Version     : 1.0.0</li>
 * <li>Creation    : 2018年10月19日</li>
 * <li>@author     : zzy0_0</li>
 * </ul>
 * <p>****************************************************************************</p>
 */
@Component
public class RateLimiterFilter extends ZuulFilter {
    private static final RateLimiter rateLimiter = RateLimiter.create(1);

    @Override
    public String filterType() {
        return PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return SERVLET_DETECTION_FILTER_ORDER - 1;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() throws ZuulException {
        //沒有取到令牌
        if (!rateLimiter.tryAcquire()) {
            throw new RateLimiterException();
        }
        return null;
    }
}

權限校驗

  1. /order/create 只能買家訪問
  2. /order/finish 只能賣家
  3. /product/list 均可以訪問

區分買家和賣家(返回的時候設置)

  • 買家:

    • cookie設置 openid=abc
  • 賣家:

    • cookie 設置token=uuid ,redis 設置 key=uuid,value=xyz

實現方式

  1. Zuul:在前置過濾器中實現相關的邏輯
  2. 分佈式Session Vs OAuth2

跨域解決

  1. 在被調用的類或者方法上加@CrossOrigin註解

    1. 容許cookie跨域image-20181022153138835
  2. Zuul裏面增長CrosFilter過濾器

    @Configuration
    public class CrosConfig {
        @Bean
        public CorsFilter corsFilter() {
            final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
            final CorsConfiguration config = new CorsConfiguration();
            //是否支持cookie跨域
            config.setAllowCredentials(true);
            //是否支持原始域 http://www.baidu.com
            config.setAllowedOrigins(Collections.singletonList("*"));
            config.setAllowedHeaders(Collections.singletonList("*"));
            config.setAllowedMethods(Collections.singletonList("*"));
            //設置緩存時間
            config.setMaxAge(300L);
            source.registerCorsConfiguration("/**", config);
            return new CorsFilter(source);
        }
    
    }

代碼地址: https://gitee.com/zzy0_0/api-gateway

相關文章
相關標籤/搜索