网关服务zuul

网关服务zuul
路由 + 过滤 = zuul ,核心就是一系列过滤器

一、作用

网关服务zuul
前置过滤器:限流、权限过滤
后置过滤器:统计、日志

1、限流: 由于zuul充当的是api网关的角色,所以限流在很适合在上面实现,时机是请求被转发到服务之前调用,放在最前面的前置过滤器上;限流也应该放在权限拦截之前;作为限流保护防止网络攻击;如下是一种谷歌限流实现:
网关服务zuul
按照一定速率往令牌桶放置令牌,当令牌桶满了就丢掉;请求来了都要从令牌桶获取令牌,获取不到将会被拒绝,获取到了才能进行正常的转发到对应服务。

二、服务网关的要素

稳定性、高可用、高并发、性能、安全、拓展性

三、环境配置和运行

1、pom文件

    <dependencies>
   		 <!-- 需要eureka中获取服务,所以引入eureka客户端-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

2、yml文件

spring:
  application:
    name: gateway
server:
  port: 9001

eureka:
  client:
  	# eureka服务端地址
    service-url:
      defaultZone: http://localhost:8761/eureka
zuul:
  routes:
    # 配置eureka注册中心中的order服务路由到myOrder上
    order: /myOrder/**
    # 设置为不过滤 cookie Authorization Set-Cookie,经过zuul的路由将会携带过来这些东西
    sensitiveHeaders:
  #过滤拦截下面地址,可以使用**代表任意
  ignored-patterns: /**/order/test
  # 全部服务都可以传递ccookie,不设置敏感头
  sensitive-headers:

3、application

@SpringBootApplication
//@EnableDiscoveryClient  不需要注册也可以获取到服务
@EnableZuulProxy //开启zuul路由服务代理
public class GatewayApplication {

    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }

}

4、zuul自定义前置过滤器

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.apache.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;

@Component
public class MyPreFilter 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 context = RequestContext.getCurrentContext();
        HttpServletRequest request = context.getRequest();
        String token = request.getParameter("token");
        if (StringUtils.isBlank(token)){
            //设置不通过zuul过滤
            context.setSendZuulResponse(false);
            //返回没有权限401状态码
            context.setResponseStatusCode(HttpStatus.SC_UNAUTHORIZED);
        }

        return null;
    }
}

网关服务zuul
端口后第一个order是服务名称,也可在zuul中配置映射别的服务名称;
如果地址栏不包含token就会被拦截,这里就是一个简易的拦截;原理是所有的请求都将经过zuul路由,那合并在所有服务中写拦截器呢,直接在zuul上实现就可以啦。

5、自定义zuul post过滤

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;


@Component
public class MyPostFilter 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 context = RequestContext.getCurrentContext();
        HttpServletResponse response = context.getResponse();
        //在返回头中写入信息
        response.setHeader("ok","你还好么,兄弟132");
        return null;
    }
}

6、基于谷歌限流令牌桶实现限流

import com.google.common.util.concurrent.RateLimiter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.exception.ZuulException;
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;

@Component
public class RateLimtFilter extends ZuulFilter {
    private RateLimiter RATE_LIMIT =RateLimiter.create(100);

    @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(!RATE_LIMIT.tryAcquire()){
            throw new RuntimeException("现在人流量大,请稍后操作.....");
        }
        return null;
    }
}

未分类
匿名

发表评论

匿名网友