在前面的篇章都是一个服务消费者去调用一个服务提供者,但事实上我们的系统基本不会那么简单,如果真的是那么简单的业务架构我们也没必要用Spring Cloud,直接部署一个Spring Boot应用就够了。所以当我们的服务消费者有很多个,比如说在一个电商系统里,会员中心是一个微服务,商品详情又是一个微服务,订单又是一个微服务,支付又是一个等等,在这么多的微服务中,每个系统都需要自己的url,这种情况我们需要一个组件来集中管理和分发这些请求,把不同url转发给不同的微服务去处理。Zuul就可以很好地完成这件事,但是Zuul可以做的远不止是路由功能。先看一下官方对Zuul的简介:

Routing is an integral part of a microservice architecture. For example, / may be mapped to your web application, /api/users is mapped to the user service and /api/shop is mapped to the shop service. Zuul is a JVM-based router and server-side load balancer from Netflix.

Netflix uses Zuul for the following:

  • Authentication
  • Insights
  • Stress Testing
  • Canary Testing
  • Dynamic Routing
  • Service Migration
  • Load Shedding
  • Security
  • Static Response handling
  • Active/Active traffic management

Zuul’s rule engine lets rules and filters be written in essentially any JVM language, with built-in support for Java and Groovy.

内容来源:https://cloud.spring.io/spring-cloud-netflix/reference/html/#router-and-filter-zuul

Zuul提供的功能有很多,这里限于篇幅先介绍路由和过滤功能。

一、路由

1.1、创建新的module

新建一个新的module,名称为zuul,选择Eureka Discovery Client和Zuul两个依赖,如下:

<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>

1.2、修改配置文件

在application.properties中添加以下配置

server.port=8033
spring.application.name=server-zuul eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ zuul.routes.api-ribbon.service-id=consumer-ribbon
zuul.routes.api-ribbon.path=/api-ribbon/* zuul.routes.api-feign.service-id=consumer-feign
zuul.routes.api-feign.path=/api-feign/*

另外在启动类加上@EnableEurekaClient和@EnableZuulProxy注解

解释一下上面的zuul的配置,zuul配置路由时zuul.routes.XXX.service-id指定的是XXX服务的服务名,这里指定的是消费者的应用名,比如我们的两个服务消费者的应用名分别是consumer-ribbon和consumer-feign,而zuul.routes.XXX.path指定是映射路径,配置之后的请求地址就可以直接是zuul的地址+端口+url。举个例子,比如zuul的主机是localhost,端口是8033,那么当我们所有url为localhost:8033/api-ribbon/的请求就会被映射到consumer-ribbon服务,所有url为localhost:8033/api-feign/的请求就会被映射到consumer-feign。

1.3、启动&测试

依次启动注册中心、服务提供者、ribbon消费者、feign消费者和zuul,访问http://localhost:8033/api-ribbon/index?uid=ribbon,可以看到返回了

服务8770的消息:用户ribbon调用了此服务

访问http://localhost:8033/api-feign/index?uid=ribbon也能看到同样的信息,这说明我们的路由功能已经生效了。

二、过滤

我们可以对某些请求进行一些过滤的工作,比如对分发给ribbon这个服务的请求都进行参数校验,要求所有这个服务的请求都要带上token。

在zuul的module新建一个CustomFilter继承ZuulFilter

@Component
public class CustomFilter extends ZuulFilter { private Logger logger = LoggerFactory.getLogger(getClass()); @Override
public String filterType() {
return "pre";
} @Override
public int filterOrder() {
return 0;
} @Override
public boolean shouldFilter() {
return true;
} @Override
public Object run() throws ZuulException {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
logger.info("request uri:" + request.getRequestURI());
String uri = request.getRequestURI();
String token = request.getParameter("token");
if (uri.startsWith("/api-ribbon") && StringUtils.isEmpty(token)) {
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(401);
ctx.setResponseBody("Token must not be empty.");
}
return null;
}
}

需要重写的这四个方法:

  • filterType:返回过滤的类型,允许的有四个值:

    1. pre:路由前
    2. routing:路由时
    3. post:路由后
    4. error:发送错误调用
  • filterOrder:过滤顺序。这个方法返回一个整型数值,其实表示的是过滤的优先级,当有多个过滤器存在时,数字越大,优先级越高。

  • shouldFilter:返回一个布尔类型的值,它和run方法一起使用,返回true时会执行run方法,否则不执行。可以把这个方法理解问某种过滤规则的开关。

  • run:该方法是核心方法,过滤的具体规则在这个方法实现。虽然该方法要求返回一个对象,但是现在的实现往往会忽略,直接返回null就可以了。

上面的代码就是先获取路由前的请求uri和请求参数token的值,如果请求的是ribbon服务,就需要token参数,否则不需要。

依次启动注册中心、服务提供者、ribbon消费者、feign消费者和zuul,然后当访问http://localhost:8033/api-ribbon/index?uid=ribbon时会返回

Token must not be empty.

再访问http://localhost:8033/api-feign/index?uid=ribbon即会返回

服务8770的消息:用户ribbon调用了此服务

这说明我们的过滤器已经生效了

三、总结

以上就是Zuul的简单介绍,更多功能可以自行探索。下一篇介绍配置中心。

源码已经上传到github:https://github.com/spareyaya/spring-cloud-demo/tree/master/chapter5

Spring Cloud系列(五):服务网关Zuul的更多相关文章

  1. Spring Cloud(十):服务网关zuul(转)

    前面的文章我们介绍了,Eureka用于服务的注册于发现,Feign支持服务的调用以及均衡负载,Hystrix处理服务的熔断防止故障扩散,Spring Cloud Config服务集群配置中心,似乎一个 ...

  2. SpringCloud学习笔记(20)----Spring Cloud Netflix之服务网关Zuul的各种姿势

    1. 禁用过滤器 # zuul.<SimpleClassName>.<filterType>.disable=true # 例如禁用 自定义的过滤器 zuul.MyFilter ...

  3. SpringCloud学习笔记(18)----Spring Cloud Netflix之服务网关Zuul原理

    1. Zuul的工作机制 Zuul提供了一个框架,可以对过滤器进行动态的加载,编译,运行.过滤器之间没有直接的相互通信,他们是通过一个RequestContext的静态类来进行数据传递的.Requet ...

  4. SpringCloud学习笔记(17)----Spring Cloud Netflix之服务网关Zuul的使用

    1. 什么时候Zuul? Zuul是一个基于jvm路由和服务端的负载均衡器,在云平台上提供动态路由,监控,弹性,安全等边缘服务的框架. 路由功能:相当于nginx的反向代理 比如: / 可能需要映射到 ...

  5. SpringCloud学习笔记(19)----Spring Cloud Netflix之服务网关Zuul自定义过滤器

    zuul不仅只是路由,还可以自定义过滤器来实现服务验证. 实现案例:自定义过滤器,检验头部是否带有token,如果token=wangx,则通过校验,若不存在或不为wangx则返回提示token错误. ...

  6. spring cloud 系列第6篇 —— zuul 服务网关 (F版本)

    源码Gitub地址:https://github.com/heibaiying/spring-samples-for-all 一.zuul简介 1.1 API 网关 api 网关是整个微服务系统的门面 ...

  7. Spring Cloud 系列之 Netflix Zuul 服务网关

    什么是 Zuul Zuul 是从设备和网站到应用程序后端的所有请求的前门.作为边缘服务应用程序,Zuul 旨在实现动态路由,监视,弹性和安全性.Zuul 包含了对请求的路由和过滤两个最主要的功能. Z ...

  8. Spring Cloud实战之初级入门(六)— 服务网关zuul

    目录 1.环境介绍 2.api网关服务 2.1 创建工程 2.3 api网关中使用token机制 2.4 测试 2.5 小结 3.一点点重要的事情 1.环境介绍 好了,不知不觉中我们已经来到了最后一篇 ...

  9. Spring Cloud(十):服务网关 Zuul(路由)【Finchley 版】

    Spring Cloud(十):服务网关 Zuul(路由)[Finchley 版]  发表于 2018-04-23 |  更新于 2018-05-09 |  通过之前几篇 Spring Cloud 中 ...

  10. Spring Cloud(十一):服务网关 Zuul(过滤器)【Finchley 版】

    Spring Cloud(十一):服务网关 Zuul(过滤器)[Finchley 版]  发表于 2018-04-23 |  更新于 2018-05-07 |  在上篇文章中我们了解了 Spring ...

随机推荐

  1. 【译】android的审计和hacking工具

    原文:Best Android Tools For Security Audit and Hacking android系统占移动市场份额的80%且有恶意软件,这是一个问题.Hacker会对手机恶意操 ...

  2. ZOJ3261并查集逆向处理

    题意:       给你一些点,还有一些边,每个点上都有一个权值,然后有一些询问,分为两种, query a 询问与a直接或者间接想连的点中最大权值的是那个点,输出那个点,如果那个点的权值小于等于a的 ...

  3. Listview滑动时不加载数据,停下来时加载数据,让App更优

    http://blog.csdn.net/yy1300326388/article/details/45153813

  4. Day003 变量、常量、作用域

    变量 变量:就是可以变化的量 Java是一种强类型语言,每个变量都必须声明其类型. Java变量是程序中最基本的存储单元,其要素包括变量名,变量类型和作用域 变量的定义 数据类型 变量名 = 值:可以 ...

  5. java.lang.ClassNotFoundException: org.apache.jsp.index_jsp

    问题描述 Tomcat启动报错 java.lang.ClassNotFoundException: org.apache.jsp.index_jsp 问题原因 因为tomcat在启动过程中jsp和se ...

  6. 一、unittest介绍与基础使用

    一.unittest为单元测试框架,系统标准库 import unittest

  7. Python JWT 介绍

    Python JWT 介绍 目录 Python JWT 介绍 1. JWT 介绍 2. JWT 创建 token 2.1 JWT 生成原理 2.2 JWT 校验 token 原理 3. 代码实现 4. ...

  8. MSSQL·查看数据库编码格式

    阅文时长 | 0.67分钟 字数统计 | 837.6字符 主要内容 | 1.引言&背景 2.声明与参考资料 『MSSQL·查看数据库编码格式』 编写人 | SCscHero 编写时间 | 20 ...

  9. [笔记] 《c++ primer》书店程序 Chapter7

    Sales_data.h 1 #ifndef SALES_DATA_H 2 #define SALES_DATA_H 3 4 #include "Version_test.h" 5 ...

  10. 【转载】Windows 10系统默认将画面显示比例调整至125%或150%,最高分辨率已经达到3840×2160(4K)这一级别。

    高分屏打开软件界面模糊?不会设置太浪费 2017-08-31 19:37 抹又重彩 现在有好多朋友都喜欢并买了高分屏笔记本电脑.高分屏笔记本就是配有高分辨率屏幕的笔记本.为了给用户带来更好的视觉体验, ...