Spring Cloud 服务网关Zuul

Spring Cloud 服务网关Zuul

服务网关是分布式架构中不可缺少的组成部分,是外部网络和内部服务之间的屏障,例如权限控制之类的逻辑应该在这里实现,而不是放在每个服务单元。

Spring Cloud Netflix 中的Zuul正是提供该功能的组件:

1. 提供路由功能,可屏蔽内部服务细节,并可提供负载均衡

2. 通过服务网关中的过滤器,在各阶段过滤请求和相应,提供对外的权限控制。

3. 实现了断路器,不会因为具体微服务的故障而导致服务网关的阻塞,依然可以对外服务。

下来通过简单的例子体验一下Zuul提供的功能:

1. 首先需要一个eureka单元注册服务,一个client单元提供服务,之前已创建

2.新建Spring Cloud项目,命名zuul

3.添加依赖

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

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

4.增加主类

@EnableZuulProxy
@SpringCloudApplication
public class App 
{
    @Bean
    public AccessFilter accessFilter() {
        return new AccessFilter();
    }

    public static void main( String[] args )
    {
        new SpringApplicationBuilder(App.class).web(true).run(args);
    }
}

--- 添加EnableZuulProxy注解为开启Zuul网关代理

5.添加配置文件application.properties

server.port=8011
spring.application.name=zuul

#自定义映射
#zuul.routes.api-a.path=/client/**
#zuul.routes.api-a.serviceId=client
zuul.routes.api-a.path=/bing/**
zuul.routes.api-a.serviceId=http://cn.bing.com/

#默认映射 无需配置
#http://zuulhost:zuulport/serviceId/**  请求会被转发到serviceId对应的服务,需要注册到eureka

eureka.client.serviceUrl.defaultZone=http://localhost:8001/eureka/

---

6.增加过滤器类

public class AccessFilter extends ZuulFilter {

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

    /**
     pre:可以在请求被路由之前调用
     routing:在路由请求时候被调用
     post:在routing和error过滤器之后被调用
     error:处理请求时发生错误时被调用
     * @return
     */
    @Override
    public String filterType() {
        return "pre";
    }

    //过滤器执行顺序
    @Override
    public int filterOrder() {
        return 0;
    }

    //过滤器开关
    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();

        Object accessToken = request.getParameter("token");
        if(accessToken == null) {
            log.warn("access token is empty");
            ctx.setSendZuulResponse(false);
            ctx.setResponseStatusCode(401);
            ctx.setResponseBody(request.getMethod()+" "+request.getRequestURL().toString()+" no token");
            return null;
        }
        log.info("access token ok");
        return null;
    }

}

---继承ZuulFilter类

7. 依次启动eureka 、client、 zuul ,访问测试

1. 访问 http://localhost:8001/ 查看服务是否已注册

2. 访问 http://localhost:8011/bing/token=1 查看是否跳转到bing主页

3. 访问 http://localhost:8011/bing 查看过滤器是否工作

4. 访问 http://localhost:8011/client/info?token=1 查看zuul默认映射规则是否生效

参考:http://projects.spring.io/spring-cloud/spring-cloud.html

end

原文地址:https://www.cnblogs.com/luangeng/p/7289574.html