微服务看门神-Zuul
Zuul网关和基本应用场景
构建微服务时,常见的问题是为系统的客户端应用程序提供唯一的网关。
事实上,您的服务被拆分为小型微服务应用程序,这些应用程序应该对用户不可见,否则可能会导致大量的开发/维护工作。还有一些情况,整个生态系统网络流量可能会通过一个可能影响群集性能的点。
为了解决这个问题,Netflix(微服务的一个主要采用者)创建并开源了它的Zuul,Zuul是Netflix的基于JVM的路由器和服务器端负载均衡器。后来Spring在Pivotal下已经在其Spring Cloud中对其进行了调整,使我们能够通过简单的步骤轻松有效地使用zuul。
Zuul是一种边缘服务,它支持对多个服务请求的代理。它为您的生态系统提供统一的“前门”,允许任何浏览器,移动应用程序或其他用户界面使用来自多个主机的服务。您可以将Zuul与其他Netflix堆栈组件(如Hystrix)集成以实现容错,使用Eureka进行服务发现,或者使用它来管理整个系统中的路由规则,过滤器和负载平衡。
最重要的是,Spring框架通过Spring boot/cloud很好地适应了所有这些组件。
路由器和过滤器
路由是微服务架构不可或缺的一部分。例如,/
可以映射到您的Web应用程序,/api/users
映射到用户服务并/api/shop
映射到商店服务。
Netflix使用Zuul进行以下操作:
认证
洞察
压力测试
金丝雀测试
动态路由
服务迁移
负载脱落
安全
静态响应处理
主动/主动流量管理
Zuul的规则引擎允许规则和过滤器基本上以任何JVM语言编写,内置支持Java和Groovy。
Zuul组件
Zuul主要有四种类型的过滤器,使我们能够在任何特定事务的请求处理的不同时间线中拦截流量。我们可以为特定的url模式添加任意数量的过滤器。
前置过滤器 - 在路由请求之前调用。
后置过滤器 - 在路由请求后调用。
路由过滤器 - 用于路由请求。
错误过滤器 - 在处理请求时发生错误时调用。
使用不同的过滤器在Zuul内部请求处理流程
过滤器关键概念
关键词 | 备注 |
---|---|
类型Type | 定义在路由过程中,过滤器被应用的阶段 |
执行顺序Execution Order | 在同一个Type中,定义过滤器执行的顺序 |
条件Criteria | 过滤器被执行必须满足的条件 |
动作Action | 如果条件满足,过滤器中将被执行的动作 |
标准过滤器类型
PRE
在请求被路由到源服务器前要执行的过滤器
适用业务场景:
认证
选路由
请求日志
ROUTING
处理将请求发送到源服务器的过滤器
POST
在响应从源服务器返回时要被执行的过滤器
对响应增加HTTP 头
收集统计和度量
将响应以流的方式发送回客户端
ERROR
上述阶段中出现错误要执行的过滤器
过滤器样例
public class PreFilter extends ZuulFilter {
// 过滤器类型
@Override
public String filterType() {
return "pre";
}
// 过滤器顺序
@Override
public int filterOrder() {
return 1;
}
// 是否加入过滤器流程中
@Override
public boolean shouldFilter() {
return true;
}
// 过滤器运行代码
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
System.out.println("Request Method : " + request.getMethod() + " Request URL : " + request.getRequestURL().toString());
return null;
}
}
netflix zuul实例概述
现在让我们通过使用Zuul创建一个简单而有意义的生态系统来尝试一下。我们将创建下面的组件来演示整个事物:
学生微服务 - 基于spring boot启动的微服务,它只是暴露单个URL以启用一些搜索功能。为简单起见,我们将返回硬编码值,但在现实世界中,我们可以让此服务连接数据库以获取数据。
Zuul网关服务
它基于spring boot启动,它将基本上拦截学生服务的所有流量并应用一系列请求过滤器然后路由到底层服务,并在响应服务时再次,它将应用一些响应过滤。由于它是一个网关,我们可以使用过滤器有效地采取许多有趣和有用的操作。
网关服务的一些共同责任是 -
在网关层应用微服务身份验证和安全性以保护实际服务
我们可以通过使一些日志记录在边缘获取有意义的数据和统计数据来实现微服务洞察和监控进入生态系统的所有流量,从而为我们提供准确的生产视图。
动态路由可以根据需要将请求路由到不同的后端群集。
我们可以通过逐渐增加到新集群的流量来进行运行时压力测试,以便在许多情况下衡量性能,例如集群有新的H / W和网络设置,或者部署了新版本的生产代码。
我们可以进行动态负载,即为每种类型的请求分配容量,并删除超出限制的请求。
我们可以应用静态响应处理,即直接在边缘构建一些响应,而不是将它们转发到内部集群进行处理。
技术栈和运行环境
Java 1.8和IntelliJIDEA作为开发环境
Spring cloud Zuul作为网关代理提供商
Spring boot作为应用程序框架
Spring Rest用于将微服务暴露为REST
Maven作为构建工具
创建学生微服务
按照以下步骤开发学生微服务,稍后将通过zuul代理访问的几个REST端点。稍后我们将研究zuul部分,现在让我们先创建学生服务。
创建Spring Boot项目
创建一个Spring boot项目从spring初始化网站,依赖于Web。
将项目解压缩并导入到IDEA中。在此步骤中,使用命令执行maven构建,mvn clean install
以便正确下载所有maven依赖项。
添加几个REST端点
我们现在只需向此服务添加一些REST端点,以便稍后测试网关。为此,我们需要通过添加注释添加一个REST控制器@RestController
。为简单起见,我们将添加一个模型类Student
。
完成所有更改后,该类将如下所示。
package com.example.springboostudentservice; import java.util.Date;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; @RestController
@SpringBootApplication
public class SpringBootStudentServiceApplication
{
@RequestMapping(value = "/echoStudentName/{name}")
public String echoStudentName(@PathVariable(name = "name") String name)
{
return "hello <strong style=\"color: red;\">" + name + " </strong> Responsed on : " + new Date();
} @RequestMapping(value = "/getStudentDetails/{name}")
public Student getStudentDetails(@PathVariable(name = "name") String name)
{
return new Student(name, "Pune", "MCA");
} public static void main(String[] args)
{
SpringApplication.run(SpringBootStudentServiceApplication.class, args);
}
} class Student
{
String name;
String address;
String cls; public Student(String name, String address, String cls) {
super();
this.name = name;
this.address = address;
this.cls = cls;
} public String getName() {
return name;
} public String getAddress() {
return address;
} public String getCls() {
return cls;
}
}
应用程序配置
spring:
application:
name: student
server:
port: 8090
这里我们按属性给这个服务命名,spring.application.name=student
我们也定义了默认端口server.port=8090
。我们需要覆盖默认端口,因为我们将在localhost中运行不同微服务的多个实例。
验证学生服务
最后使用命令执行maven构建,mvn clean install
并通过运行命令将此项目作为spring boot应用程序启动java -jar target\spring-boot-zuulgatway-student-service-0.0.1-SNAPSHOT.jar
。现在,一旦服务器启动,转到浏览器并测试端点是否正常工作。
http://localhost:8090/echoStudentName/james
http://localhost:8090/getStudentDetails/james
创建学校微服务
创建过程和学生微服务一样,但是由于服务之间的功能和差异性,我们需要对接口进行简单的修改
添加几个REST断点
我们现在只需向此服务添加一些REST端点,为此,我们需要通过添加注释添加一个REST控制器@RestController
。为简单起见,我们将添加一个模型类School
。
完成所有更改后,该类将如下所示。
@SpringBootApplication
@RestController
public class SpringBootZuulgatewaySchoolServiceApplication {
@RequestMapping(value = "/echoSchoolName/{name}")
public String echoSchoolName(@PathVariable(name = "name") String name)
{
return "hello <strong style=\"color: green;\">" + name + " </strong> Responsed on : " + new Date();
}
@RequestMapping(value = "/getSchoolDetails/{name}")
public School getSchoolDetails(@PathVariable(name = "name") String name)
{
return new School(name, "China", "ZheJiang");
}
public static void main(String[] args) {
SpringApplication.run(SpringBootZuulgatewaySchoolServiceApplication.class, args);
}
}
class School
{
String name;
String address;
String cls;
public School(String name, String address, String cls) {
super();
this.name = name;
this.address = address;
this.cls = cls;
}
public String getName() {
return name;
}
public String getAddress() {
return address;
}
public String getCls() {
return cls;
}
}
应用程序配置
现在打开application.properties
文件并添加这些条目。
spring:
application:
name: school
server:
port: 8100
这里我们按属性给这个服务命名,spring.application.name=school我们也定义了默认端口
server.port=8100`。我们需要覆盖默认端口,因为我们将在localhost中运行不同微服务的多个实例。
验证学校服务
最后使用命令执行maven构建,mvn clean install
并通过运行命令将此项目作为spring boot应用程序启动java -jar target\spring-boot-zuulgatway-school-service-0.0.1-SNAPSHOT.jar
。现在,一旦服务器启动,转到浏览器并测试端点是否正常工作。
http://localhost:8100/echoSchoolName/学军中学
http://localhost:8100/getSchoolDetails/学军中学
现在我们将使用Zuul创建实际的网关服务。
创建Zuul网关服务
这将是一个基于Spring boot的微服务,但它有一个特殊的功能。它将使用zuul创建一个代表学生服务的API网关。稍后我们可以添加任意数量的微服务,如学生服务,学校服务并能够创建一个强大的微服务生态系统。
创建String Boot项目
从spring初始化网站创建一个具有Zuul
依赖关系的Spring boot项目。
将项目作为现有maven项目解压缩并导入IDEA。在此步骤中,使用命令执行maven构建,mvn clean install
以便正确下载所有maven依赖项。
启用Zuul服务
现在@EnableZuulProxy
在src
文件夹中的Spring启动应用程序类中添加注释。使用此批注,此工件将像Zuul服务代理一样运行,并将启用API网关层的所有功能,如前所述。然后我们将添加一些过滤器和路由配置。
import com.example.zuuldemo.filters.ErrorFilter;
import com.example.zuuldemo.filters.PostFilter;
import com.example.zuuldemo.filters.PreFilter;
import com.example.zuuldemo.filters.RouteFilter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
@EnableZuulProxy
public class ZuuldemoApplication {
public static void main(String[] args) {
SpringApplication.run(ZuuldemoApplication.class, args);
}
@Bean
public PreFilter preFilter() {
return new PreFilter();
}
@Bean
public PostFilter postFilter() {
return new PostFilter();
}
@Bean
public ErrorFilter errorFilter() {
return new ErrorFilter();
}
@Bean
public RouteFilter routeFilter() {
return new RouteFilter();
}
}
Zuul应用配置
打开application.yml并在下面添加条目
zuul:
routes:
student:
url: http://localhost:8090
school:
url: http://localhost:8100
server:
port: 8080
这里zuul.routes.student.url
将路由所有流量以请求/student
到实际的学生服务服务器。zuul.routes.school.url
将路由所有流量以请求/school
到实际的学校服务服务器 server.port
- 需要覆盖默认端口,因为我们将在localhost中运行不同微服务的多个实例。
添加Zuul过滤器
正如我们已经描述了zuul组件,我们将添加一些过滤器,Zuul支持4种类型的过滤器,即pre
,post
,route
和error
。在这里,我们将创建每种类型的过滤器。
要编写过滤器,我们基本上需要执行以下步骤:
需要扩展
com.netflix.zuul.ZuulFilter
需要重写
filterType
,filterOrder
,shouldFilter
和run
方法。这里的filterType
方法只能返回四个String中的任何一个 -pre/post/route/error
。降低此值后,过滤器将像特定过滤器一样运行。run
method是根据我们的要求放置滤波器逻辑的地方。此外,我们可以根据需要添加任意数量的任何特定过滤器,这种情况
filterOrder
将用于确定该过滤器执行阶段该文件管理器的顺序。
前置过滤器代码 - 我们将添加以下预过滤器。目前,过滤器除了println
用于测试目的之外什么都不做。但实际上那些功能足以完成前面提到的许多重要方面。
package com.example.springbootzuulgateway.filters;
import javax.servlet.http.HttpServletRequest;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
public class PreFilter extends ZuulFilter {
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 1;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
System.out.println("Request Method : " + request.getMethod() + " Request URL : " + request.getRequestURL().toString());
return null;
}
}
后置过滤器
package com.example.springbootzuulgateway.filters; import com.netflix.zuul.ZuulFilter; public class PostFilter extends ZuulFilter { @Override
public String filterType() {
return "post";
} @Override
public int filterOrder() {
return 1;
} @Override
public boolean shouldFilter() {
return true;
} @Override
public Object run() {
System.out.println("Inside Response Filter"); return null;
} }
路由过滤器
package com.example.springbootzuulgateway.filters; import com.netflix.zuul.ZuulFilter; public class RouteFilter extends ZuulFilter { @Override
public String filterType() {
return "route";
} @Override
public int filterOrder() {
return 1;
} @Override
public boolean shouldFilter() {
return true;
} @Override
public Object run() {
System.out.println("Inside Route Filter"); return null;
} }
错误过滤器
package com.example.springbootzuulgateway.filters; import com.netflix.zuul.ZuulFilter; public class ErrorFilter extends ZuulFilter { @Override
public String filterType() {
return "error";
} @Override
public int filterOrder() {
return 1;
} @Override
public boolean shouldFilter() {
return true;
} @Override
public Object run() {
System.out.println("Inside Route Filter"); return null;
} }
5.5。注册zuul过滤器
创建要自动注册和启用的这些过滤器的bean定义。
@Bean
public PreFilter preFilter() {
return new PreFilter();
}
@Bean
public PostFilter postFilter() {
return new PostFilter();
}
@Bean
public ErrorFilter errorFilter() {
return new ErrorFilter();
}
@Bean
public RouteFilter routeFilter() {
return new RouteFilter();
}
Netflix zuul示例演示
所以我们启用了Zuul,添加了所需的配置并开发了过滤器。所以我们可以做基本的测试来理解整个事情。
使用命令执行maven构建,mvn clean install
并通过运行命令将此项目作为spring boot应用程序启动java -jar target\spring-boot-zuulgateway-0.0.1-SNAPSHOT.jar
。
现在,一旦服务器启动,转到浏览器并通过访问学生服务名称和学校服务来测试端点是否正常工作,即/student
和/school
。
http://localhost:8080/student/echoStudentName/james
http://localhost:8080/school/echoSchoolName/学军学校
总结
这就是netflix zuul过滤器示例。我建议你自己做,通过代理添加一些更多的底层服务和路由请求,应用不同类型的过滤器并在过滤器中添加真正的逻辑。
链接: https://pan.baidu.com/s/1zpUBTCDNVHO4s8TAIOxKVA 提取码: 8v7w
请在评论部分将您的问题提交给我。
快乐学习!!
微服务看门神-Zuul的更多相关文章
- springcloud微服务实战:Eureka+Zuul+Feign/Ribbon+Hystrix Turbine+SpringConfig+sleuth+zipkin
相信现在已经有很多小伙伴已经或者准备使用springcloud微服务了,接下来为大家搭建一个微服务框架,后期可以自己进行扩展.会提供一个小案例: 服务提供者和服务消费者 ,消费者会调用提供者的服务,新 ...
- springcloud微服务实战:Eureka+Zuul+Ribbon+Hystrix+SpringConfig
原文地址:http://blog.csdn.net/yp090416/article/details/78017552 springcloud微服务实战:Eureka+Zuul+Ribbon+Hyst ...
- 微服务:Eureka+Zuul+Ribbon+Feign+Hystrix构建微服务架构
原文地址:http://blog.csdn.net/qq_18675693/article/details/53282031 本案例将打架一个微服务框架,参考来源官方参考文档 微服务:是什么?网上有一 ...
- 【微服务】之六:轻松搞定SpringCloud微服务-API网关zuul
通过前面几篇文章的介绍,我们可以轻松搭建起来微服务体系中比较重要的几个基础构建服务.那么,在本篇博文中,我们重点讲解一下,如何将所有微服务的API同意对外暴露,这个就设计API网关的概念. 本系列教程 ...
- SpringCloud的微服务网关:zuul(实践)
Zuul的主要功能是路由和过滤器.路由功能是微服务的一部分,比如/api/user映射到user服务,/api/shop映射到shop服务.zuul实现了负载均衡. zuul有以下功能: Authen ...
- SpringCloud的微服务网关:zuul(理论)
参考链接:https://springcloud.cc/spring-cloud-dalston.html 一.概念与定义 1.为什么要引入API网关 后期维护:路由规则和服务实例列表困难 系统架构: ...
- 从Uber微服务看最佳实践如何炼成?
导读:Uber成长非常迅速,工程师团队快速扩充,据说Uber有2000名工程师,8000个代码仓库,部署了1000多个微服务.微服务架构是Uber应对技术团队快速增长,功能快速上线很出色的解决方案.本 ...
- SpringCloud微服务(05):Zuul组件,实现路由网关控制
本文源码:GitHub·点这里 || GitEE·点这里 一.Zuul组件简介 1.基础概念 Zuul 网关主要提供动态路由,监控,弹性,安全管控等功能.在分布式的微服务系统中,系统被拆为了多个微服务 ...
- springCloud搭建微服务集群+Zuul服务器端负载均衡
概述 最近研究了一下springCloud的微服务集群,主要用到了SpringCloud的服务发现和服务器端负载均衡,所有的项目都是用的springboot,可以和springCloud无缝对接. 技 ...
随机推荐
- renren-fast后端源码参考-配置和对应工具
1. renren-fast后端源码参考-配置和对应工具 1.1. 前言 renren-fast是个开源的前后端分离快速开放平台,没有自己框架的同学可以直接使用它的,而我打算浏览一遍它的代码,提取一些 ...
- vue中的插槽
匿名插槽 // comp1 <div> <slot></slot> </div> // parent <comp>hello</com ...
- echarts自定义悬浮框的显示
最近在使用echarts的地图功能 ,业务需求是显示前五的具体信息,并且轮流显示,首先解决轮流显示的问题 var counta = 0; //播放所在下标 var mTime = setInterva ...
- FreePascal - Typhon如何添加不能识别单元?
Typhon 32位 6.9 问题:想使用LSUtils单元,这个单元在Lazarus里面,直接引入就可以使用,而且单元头注释明显写明是CodeTyphon工程的一部分,那么正常在Typhon只要引入 ...
- 【python】一篇文章里的词频统计
一.环境 1.python3.6 2.windows系统 3.安装第三方模块 pip install wordcloud #词云展示库 pip install jieba #结巴分词 pip inst ...
- OCR6:Custom Traineddata
参考:https://groups.google.com/forum/#!msg/tesseract-ocr/MSYezIbckvs/kO1VoNKMDMQJ V4版本代码示例 : import py ...
- 洛谷P4556 雨天的尾巴(线段树合并)
洛谷P4556 雨天的尾巴 题目链接 题解: 因为一个点可能存放多种物品,直接开二维数组进行统计时间.空间复杂度都不能承受.因为每一个点所拥有的物品只与其子树中的点有关,所以可以考虑对每一个点来建立一 ...
- 项目Alpha冲刺随笔集合
班级:软件工程1916|W 作业:项目Alpha冲刺 团队名称:SkyReach 目标:完成项目Alpha版本 项目Github地址 评审表 团队博客汇总 队员学号 队员姓名 个人博客地址 备注 22 ...
- 记CSP2019
给出题人倒杯茶好吧,出题人给你倒一杯卡布奇诺.给出题人倒一杯卡布奇诺! 开始你的炫技秀,搞CCF.漂亮! 六道题你能秒我?你能秒杀我?!你今天能六道题把李某秒了,我!当!场!就把这个电脑屏幕吃掉!! ...
- hive表分区相关操作
Hive 表分区 Hive表的分区就是一个目录,分区字段不和表的字段重复 创建分区表: create table tb_partition(id string, name string) PARTIT ...