上一篇文章中,讲了Zuul 转发,动态路由,负载均衡,等等一些Zuul 的特性,这个一篇文章,讲Zuul Filter 使用,关于网关的作用,这里就不再次赘述了,重点是zuul的Filter ,我们可以实现安全控制,比如,只有请求参数中有token和密码的客户端才能访问服务端的资源。那么如何来实现Filter了?

Spring Cloud Zuul

zuul 执行流程

Zuul大部分功能都是通过过滤器来实现的。Zuul中定义了四种标准过滤器类型,这些过滤器类型对应于请求的典型生命周期。

PRE:这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中选择请求的微服务、记录调试信息等。

ROUTING:这种过滤器将请求路由到微服务。这种过滤器用于构建发送给微服务的请求,并使用Apache HttpClient或Netfilx Ribbon请求微服务。

OST:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等。

ERROR:在其他阶段发生错误时执行该过滤器。

除了默认的过滤器类型,Zuul还允许我们创建自定义的过滤器类型。例如,我们可以定制一种STATIC类型的过滤器,直接在Zuul中生成响应,而不将请求转发到后端的微服务。

准备工作

我们先拿之前两篇文章,构建的两个微服务代码为基础,进行下面的操作

建议先阅读以下两篇文章

Spring Cloud(四) 服务提供者 Eureka + 服务消费者 Feign
Spring Cloud(三) 服务提供者 Eureka + 服务消费者(rest + Ribbon)

http://www.ymq.io/2017/12/06/spring-cloud-feign/

http://www.ymq.io/2017/12/05/spring-cloud-ribbon-rest/

Eureka Service

导入第三篇文章中的项目:作为服务注册中心

spring-cloud-eureka-service

Eureka Provider

导入第三篇文章中的项目:作为服务的提供者

spring-cloud-eureka-provider-1
spring-cloud-eureka-provider-2
spring-cloud-eureka-provider-3

简单使用

新建项目 spring-cloud-zuul-filter

添加依赖

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

开启服务注册

在程序的启动类 ZuulFilterApplication 通过 @EnableZuulProxy 开启 Zuul 服务网关

package io.ymq.example.zuul.filter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.context.annotation.Bean;
@EnableZuulProxy
@SpringBootApplication
public class ZuulFilterApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulFilterApplication.class, args);
}
}

添加配置

配置文件 application.yml

spring:
application:
name: zuul-service-filter
server:
port: 9000
zuul:
routes:
api:
path: /**
serviceId: eureka-provider
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/

TokenFilter

ZuulFilter 是Zuul中核心组件,通过继承该抽象类,覆写几个关键方法达到自定义调度请求的作用

TokenFilter 过滤器

package io.ymq.example.zuul.filter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletRequest;
/**
* 描述: 过滤器 token
*
* @author yanpenglei
* @create 2017-12-11 14:38
**/
public class TokenFilter extends ZuulFilter {
private final Logger LOGGER = LoggerFactory.getLogger(TokenFilter.class);
@Override
public String filterType() {
return "pre"; // 可以在请求被路由之前调用
}
@Override
public int filterOrder() {
return 0; // filter执行顺序,通过数字指定 ,优先级为0,数字越大,优先级越低
}
@Override
public boolean shouldFilter() {
return true;// 是否执行该过滤器,此处为true,说明需要过滤
}
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
LOGGER.info("--->>> TokenFilter {},{}", request.getMethod(), request.getRequestURL().toString());
String token = request.getParameter("token");// 获取请求的参数
if (StringUtils.isNotBlank(token)) {
ctx.setSendZuulResponse(true); //对请求进行路由
ctx.setResponseStatusCode(200);
ctx.set("isSuccess", true);
return null;
} else {
ctx.setSendZuulResponse(false); //不对其进行路由
ctx.setResponseStatusCode(400);
ctx.setResponseBody("token is empty");
ctx.set("isSuccess", false);
return null;
}
}
}

PasswordFilter

ZuulFilter 是Zuul中核心组件,通过继承该抽象类,覆写几个关键方法达到自定义调度请求的作用

PasswordFilter 过滤器

package io.ymq.example.zuul.filter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletRequest;
/**
* 描述: 过滤器 Password
*
* @author yanpenglei
* @create 2017-12-11 15:40
**/
public class PasswordFilter extends ZuulFilter {
private final Logger LOGGER = LoggerFactory.getLogger(TokenFilter.class);
@Override
public String filterType() {
return "post"; // 请求处理完成后执行的filter
}
@Override
public int filterOrder() {
return 1; // 优先级为0,数字越大,优先级越低
}
@Override
public boolean shouldFilter() {
RequestContext ctx = RequestContext.getCurrentContext();
return (boolean) ctx.get("isSuccess");
// 判断上一个过滤器结果为true,否则就不走下面过滤器,直接跳过后面的所有过滤器并返回 上一个过滤器不通过的结果。
}
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
LOGGER.info("--->>> PasswordFilter {},{}", request.getMethod(), request.getRequestURL().toString());
String username = request.getParameter("password");
if (null != username && username.equals("123456")) {
ctx.setSendZuulResponse(true);
ctx.setResponseStatusCode(200);
ctx.set("isSuccess", true);
return null;
} else {
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(400);
ctx.setResponseBody("The password cannot be empty");
ctx.set("isSuccess", false);
return null;
}
}
}

开启过滤器

在程序的启动类 ZuulFilterApplication 添加 Bean

@Bean
public TokenFilter tokenFilter() {
return new TokenFilter();
}
@Bean
public PasswordFilter PasswordFilter() {
return new PasswordFilter();
}

filterType

filterType:返回一个字符串代表过滤器的类型,在zuul中定义了四种不同生命周期的过滤器类型,具体如下:

  • pre:路由之前
  • routing:路由之时
  • post: 路由之后
  • error:发送错误调用
  • filterOrder:过滤的顺序
  • shouldFilter:这里可以写逻辑判断,是否要过滤,本文true,永远过滤。
  • run:过滤器的具体逻辑。可用很复杂,包括查sql,nosql去判断该请求到底有没有权限访问。

测试服务

依次启动项目:

spring-cloud-eureka-service
spring-cloud-eureka-provider-1
spring-cloud-eureka-provider-2
spring-cloud-eureka-provider-3
spring-cloud-zuul-filter

启动该工程后,访问服务注册中心,查看服务是否都已注册成功:http://localhost:8761/

查看 eureka 监控,看服务是否都注册成功

token 测试

访问:http://127.0.0.1:8761/

步骤一 提示 token is empty

访问:http://127.0.0.1:9000/

步骤二 加上token ?token=token-uuid ,已经验证通过了,提示 The password cannot be empty

password 测试

![The password cannot be empty][3]

加上token 和 password &password=123456 ,已经验证通过

访问:http://127.0.0.1:9000/?token=token-uuid&password=123456

F5 刷新,每次都验证通过,并且负载均衡

Spring Cloud(七)服务网关 Zuul Filter 使用的更多相关文章

  1. Spring Cloud Gateway 服务网关快速上手

    Spring Cloud Gateway 服务网关 API 主流网关有NGINX.ZUUL.Spring Cloud Gateway.Linkerd等:Spring Cloud Gateway构建于 ...

  2. 二十一、springcloud(七)服务网关zuul

    1.简介 Eureka用于服务的注册于发现,Feign支持服务的调用以及均衡负载,Hystrix处理服务的熔断防止故障扩散,Spring Cloud Config服务集群配置中心,在微服务架构中,后端 ...

  3. Spring Cloud (13) 服务网关-路由配置

    传统路由配置 所谓传统路由配置方式就是在不依赖于服务发现机制情况下,通过在配置文件中具体制定每个路由表达式与服务实例的映射关系来实现API网关对外部请求的路由.没有Eureka服务治理框架帮助的时候, ...

  4. Spring Cloud (12) 服务网关-基础

    通过前几篇介绍,已经可以构建一个简单的微服务架构了,如下图: 通过eureka实现服务注册中心以及服务注册发现,通过ribbon或feign实现服务的消费以及负载均衡,通过spring cloud c ...

  5. Spring Cloud Gateway服务网关

    原文:https://www.cnblogs.com/ityouknow/p/10141740.html Spring 官方最终还是按捺不住推出了自己的网关组件:Spring Cloud Gatewa ...

  6. spring cloud:服务网关 Spring Cloud GateWay 入门

    Spring 官方最终还是按捺不住推出了自己的网关组件:Spring Cloud Gateway ,相比之前我们使用的 Zuul(1.x) 它有哪些优势呢?Zuul(1.x) 基于 Servlet,使 ...

  7. Spring Cloud (14) 服务网关-过滤器

    Spring Cloud Zuul作为网关所具备的最基本的功能:路由,还具备另外一个核心的功能:过滤器. 过滤器 通过Spring Cloud Zuul实现的路由功能,我们的微服务可以通过统一的API ...

  8. Spring Cloud 之 服务网关

    在微服务架构体系中,使用API 服务网关后的系统架构图如下: API服务网关的主要作用如下: 服务访问的统一入口 服务访问的负载均衡功能 服务访问的路由功能 在SpringCloud中,基于Netfl ...

  9. Spring Cloud 微服务:Eureka+Zuul+Ribbon+Hystrix+SpringConfig实现流程图

    相信现在已经有很多小伙伴已经或者准备使用springcloud微服务了,接下来为大家搭建一个微服务框架,后期可以自己进行扩展.会提供一个小案例: 服务提供者和服务消费者 ,消费者会调用提供者的服务,新 ...

随机推荐

  1. jmeter 调用python的方法三种 (还没试)

    参考文章1: Jmeter 运行 Python 代码进行 AK/SK 认证 (使用 OS Process Sampler) 思路是:jmeter调用shell,用shell执行py 参考文章2: Jm ...

  2. windows 下OPENSSL 生成秘钥和公钥的方法

    1. 生成原始 RSA私钥文件 private_key.pem openssl genrsa -out private_key.pem 1024 2. 将原始 RSA私钥转换为 pkcs8格式 ope ...

  3. haproxy报错解决

    .有一次访问出现 错误 http://192.168.0.200:10080 haproxy service unavailable no server is avaible to handle th ...

  4. python函数,定义,参数,返回值

    python中可以将某些具备一定功能的代码写成一个函数,通过函数可以在一定程度上减少代码的冗余,节约书写代码的时间.因为有一些代码实现的功能我们可能会在很多地方用到. 1.函数的声明与定义 通过def ...

  5. Linux nginx 会话保持(session)

    nginx 会话保持(session)有2种算法,一种是自带IP HASH 算法,一种是基于第三方模块sticky模块来实现会话保持 1)ip_hash 简单易用,但是有如下缺点 后端服务器宕机后,s ...

  6. webdriervAPI(警告框处理)

    from  selenium  import  webdriver driver  =  webdriver.Chorme() driver.get("http://www.baidu.co ...

  7. Ubuntu搭建Spring源码环境常见问题

    在一心想要学习Spring框架源码时,我们会遇到很多麻烦的问题.开始本文前,你只需要拥有一个装好IDEA的Ubuntu系统就可以愉快启程了.如果还没有IDEA,可以参考在Ubuntu上安装Intell ...

  8. 《剑指offer》Q13-18 (牛客10.13)

    目录 Q13 调整数组顺序使奇数位于偶数前 Q14 链表中倒数第k个结点 Q15 反转链表 Q16 合并两个有序链表 Q17 树的子结构 Q18 二叉树的镜像 Q13 调整数组顺序使奇数位于偶数前 输 ...

  9. Spring-Boot的第三方类库的依赖版本调整方法

    springboot方式构建的工程,是dependencyManagement方式进行依赖包的版本管理, spring中有默认的版本,可以修改ext参数来调整版本 如下SpringBoot-2.2.x ...

  10. 【并行计算-CUDA开发】 NVIDIA Jetson TX1

    概述 NVIDIA Jetson TX1是计算机视觉系统的SoM(system-on-module)解决方案.它组合了最新的NVIDIAMaxwell GPU架构,其具有ARM Cortex-A57 ...