Spring Cloud中的API网关服务Zuul

到目前为止,咱们Spring Cloud中的内容已经介绍了不少了,Ribbon、Hystrix、Feign这些知识点你们都耳熟能详了,咱们在前文也提到过微服务就是把一个大的项目拆分红不少小的独立模块,而后经过服务治理让这些独立的模块配合工做等。那么你们来想这样两个问题:1.若是个人微服务中有不少个独立服务都要对外提供服务,那么对于开发人员或者运维人员来讲,他要如何去管理这些接口?特别是当项目很是大很是庞杂的状况下要如何管理?2.权限管理也是一个老生常谈的问题,在微服务中,一个独立的系统被拆分红不少个独立的模块,为了确保安全,我难道须要在每个模块上都添加上相同的鉴权代码来确保系统不被非法访问?若是是这样的话,那么工做量就太大了,并且维护也很是不方便。 html

为了解决上面提到的问题,咱们引入了API网关的概念,API网关是一个更为智能的应用服务器,它有点相似于咱们微服务架构系统的门面,全部的外部访问都要先通过API网关,而后API网关来实现请求路由、负载均衡、权限验证等功能。Spring Cloud中提供的Spring Cloud Zuul实现了API网关的功能,本文咱们就先来看看Spring Cloud Zuul的一个基本使用。java


本文是Spring Cloud系列的第十九篇文章,了解前十八篇文章内容有助于更好的理解本文: spring

1.使用Spring Cloud搭建服务注册中心
2.使用Spring Cloud搭建高可用服务注册中心
3.Spring Cloud中服务的发现与消费
4.Eureka中的核心概念
5.什么是客户端负载均衡
6.Spring RestTemplate中几种常见的请求方式
7.RestTemplate的逆袭之路,从发送请求到负载均衡
8.Spring Cloud中负载均衡器概览
9.Spring Cloud中的负载均衡策略
10.Spring Cloud中的断路器Hystrix
11.Spring Cloud自定义Hystrix请求命令
12.Spring Cloud中Hystrix的服务降级与异常处理
13.Spring Cloud中Hystrix的请求缓存
14.Spring Cloud中Hystrix的请求合并
15.Spring Cloud中Hystrix仪表盘与Turbine集群监控
16.Spring Cloud中声明式服务调用Feign
17.Spring Cloud中Feign的继承特性
18.Spring Cloud中Feign配置详解api


构建网关

网关的构建咱们经过下面三个步骤来实现。缓存

1.建立Spring Boot工程并添加依赖

首先咱们建立一个普通的Spring Boot工程名为api-gateway,而后添加相关依赖,这里咱们主要添加两个依赖spring-cloud-starter-zuul和spring-cloud-starter-eureka,spring-cloud-starter-zuul依赖中则包含了ribbon、hystrix、actuator等,以下:安全

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.7.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    <spring-cloud.version>Dalston.SR3</spring-cloud.version>
</properties>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <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>
</dependencies>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

2.添加注解

而后在入口类上添加@EnableZuulProxy注解表示开启Zuul的API网关服务功能,以下:服务器

@SpringBootApplication
@EnableZuulProxy
public class ApiGatewayApplication {

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

3.配置路由规则

application.properties文件中的配置能够分为两部分,一部分是Zuul应用的基础信息,还有一部分则是路由规则,以下:架构

# 基础信息配置
spring.application.name=api-gateway
server.port=2006
# 路由规则配置
zuul.routes.api-a.path=/api-a/**
zuul.routes.api-a.serviceId=feign-consumer

# API网关也将做为一个服务注册到eureka-server上
eureka.client.service-url.defaultZone=http://localhost:1111/eureka/

咱们在这里配置了路由规则全部符合/api-a/**的请求都将被转发到feign-consumer服务上,至于feign-consumer服务的地址究竟是什么则由eureka-server去分析,咱们这里只须要写上服务名便可。以上面的配置为例,若是我请求http://localhost:2006/api-a/h...接口则至关于请求http://localhost:2005/hello1(我这里feign-consumer的地址为http://localhost:2005),咱们在路由规则中配置的api-a是路由的名字,能够任意定义,可是一组path和serviceId映射关系的路由名要相同。 app

OK,作好这些以后,咱们依次启动咱们的eureka-server、provider和feign-consumer,而后访问以下地址http://localhost:2006/api-a/h...,访问结果以下: 负载均衡

图片描述

看到这个效果说明咱们的API网关服务已经构建成功了,咱们发送的符合路由规则的请求自动被转发到相应的服务上去处理了。

请求过滤

构建好了网关,接下来咱们就来看看如何利用网关来实现一个简单的权限验证。这里就涉及到了Spring Cloud Zuul中的另一个核心功能:请求过滤。请求过滤有点相似于Java中Filter过滤器,先将全部的请求拦截下来,而后根据现场状况作出不一样的处理,这里咱们就来看看Zuul中的过滤器要如何使用。很简单,两个步骤:

1.定义过滤器

首先咱们定义一个过滤器继承自ZuulFilter,以下:

public class PermisFilter extends ZuulFilter {
    @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();
        String login = request.getParameter("login");
        if (login == null) {
            ctx.setSendZuulResponse(false);
            ctx.setResponseStatusCode(401);
            ctx.addZuulResponseHeader("content-type","text/html;charset=utf-8");
            ctx.setResponseBody("非法访问");
        }
        return null;
    }
}

关于这个类我说以下几点:

1.filterType方法的返回值为过滤器的类型,过滤器的类型决定了过滤器在哪一个生命周期执行,pre表示在路由以前执行过滤器,其余可选值还有post、error、route和static,固然也能够自定义。
2.filterOrder方法表示过滤器的执行顺序,当过滤器不少时,这个方法会有意义。
3.shouldFilter方法用来判断过滤器是否执行,true表示执行,false表示不执行,在实际开发中,咱们能够根据当前请求地址来决定要不要对该地址进行过滤,这里我直接返回true。
4.run方法则表示过滤的具体逻辑,假设请求地址中携带了login参数的话,则认为是合法请求,不然就是非法请求,若是是非法请求的话,首先设置ctx.setSendZuulResponse(false);表示不对该请求进行路由,而后设置响应码和响应值。这个run方法的返回值在当前版本(Dalston.SR3)中暂时没有任何意义,能够返回任意值。

2.配置过滤器Bean

而后在入口类中配置相关的Bean便可,以下:

@Bean
PermisFilter permisFilter() {
    return new PermisFilter();
}

此时,若是咱们访问http://localhost:2006/api-a/h...,结果以下:

图片描述

若是给请求地址加上login参数,则结果以下:

图片描述

总结

到这里小伙伴们应该已经见识到Spring Cloud Zuul的强大之处了吧,API网关做为系统的的统一入口,将微服务中的内部细节都屏蔽掉了,并且可以自动的维护服务实例,实现负载均衡的路由转发,同时,它提供的过滤器为全部的微服务提供统一的权限校验机制,使得服务自身只须要关注业务逻辑便可。

Zuul的入门知识咱们就先介绍到这里,小伙伴们有问题欢迎留言讨论。

更多JavaEE资料请关注公众号:

图片描述

相关文章
相关标签/搜索