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

相关文章
相关标签/搜索