Spring cloud实践之道六(网关Zuul)

为什么需要网关

根据前面的内容,我们已经能做到下面的内容:

  1. Eureka进行服务的注册和发现
  2. Ribbon进行负载均衡
  3. 通过Feign,RestTemplate进行服务的调用
  4. Hystrix进行服务降级,隔离故障
  5. Spring Cloud Config进行集群配置
  6. Spring Cloud Bus进行配置的刷新

下面我们要考虑一下这问题:

  1. 外部应用如何来访问服务
  2. 外部应用如何进行服务访问的权限控制
  3. 如何将请求均衡分发给后台服务

解决方案:
Spring Cloud Zuul路由是微服务架构的不可或缺的一部分,提供动态路由,监控,弹性,安全等的边缘服务。

Spring cloud实践之道六(网关Zuul)_第1张图片
网关框架图

演示用项目源码

网关路由

  1. 在pom.xml文件中增加依赖
        
            org.springframework.cloud
            spring-cloud-starter-zuul
        
        
            org.springframework.cloud
            spring-cloud-starter-eureka
        
  1. 增加注解
@SpringBootApplication
@EnableZuulProxy
@EnableDiscoveryClient
public class ZuulApplication {
    public static void main(String[] args) {
        new SpringApplicationBuilder(ZuulApplication.class).web(true).run(args);
    }
}
  1. 配置文件中进行路由的定义
#这里的配置表示,访问/a/** 直接重定向到服务eurekaClient/**
zuul.routes.a.path=/a/**
zuul.routes.a.serviceId=eurekaClient

服务过滤

  1. 书写一个过滤类,继承ZuulFilter
public class AccessFilter extends ZuulFilter {

    private static Logger log = LoggerFactory.getLogger(AccessFilter.class);

    /**
     * 返回一个字符串代表过滤器的类型,在zuul中定义了四种不同生命周期的过滤器类型
     * 
     * pre:可以在请求被路由之前调用
     * routing:在路由请求时候被调用
     * post:在routing和error过滤器之后被调用
     * error:处理请求时发生错误时被调用
     */
    @Override
    public String filterType() {
        return "pre";
    }

    /**
     * 通过int值来定义过滤器的执行顺序
     */
    @Override
    public int filterOrder() {
        return 0;
    }

    /**
     * 返回一个boolean类型来判断该过滤器是否要执行,所以通过此函数可实现过滤器的开关。
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }

    /**
     * 过滤器的具体逻辑。需要注意,这里我们通过ctx.setSendZuulResponse(false)令zuul过滤该请求,不对其进行路由,
     * 然后通过ctx.setResponseStatusCode(401)设置了其返回的错误码,当然我们也可以进一步优化我们的返回,
     * 比如,通过ctx.setResponseBody(body)对返回body内容进行编辑等。
     */
    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        log.info(String.format("%s request to %s", request.getMethod(), request
                .getRequestURL().toString()));
        Object accessToken = request.getParameter("accessToken");
        if (accessToken == null) {
            log.warn("access token is empty");
            ctx.setSendZuulResponse(false);
            ctx.setResponseStatusCode(401);
            return null;
        }
        log.info("access token ok");
        return null;
    }
}
  1. 这个过滤器需要装载
    //  装载过滤器
    @Bean
    public AccessFilter accessFilter() {
        return new AccessFilter();
    }
  1. 所有的请求加上accessToken才能正常访问

下图为filterType的生命周期示意图


Spring cloud实践之道六(网关Zuul)_第2张图片
filterType生命周期介绍

你可能感兴趣的:(Spring cloud实践之道六(网关Zuul))