构建微服务时,常见的问题是为系统的客户端应用程序提供惟一的网关。java
事实上,您的服务被拆分为小型微服务应用程序,这些应用程序应该对用户不可见,不然可能会致使大量的开发/维护工做。还有一些状况,整个生态系统网络流量可能会经过一个可能影响群集性能的点。git
为了解决这个问题,Netflix(微服务的一个主要采用者)建立并开源了它的Zuul,Zuul是Netflix的基于JVM的路由器和服务器端负载均衡器。后来Spring在Pivotal下已经在其Spring Cloud中对其进行了调整,使咱们可以经过简单的步骤轻松有效地使用zuul。github
Zuul是一种边缘服务,它支持对多个服务请求的代理。它为您的生态系统提供统一的“前门”,容许任何浏览器,移动应用程序或其余用户界面使用来自多个主机的服务。您能够将Zuul与其余Netflix堆栈组件(如Hystrix)集成以实现容错,使用Eureka进行服务发现,或者使用它来管理整个系统中的路由规则,过滤器和负载平衡。web
最重要的是,Spring框架经过Spring boot/cloud很好地适应了全部这些组件。spring
路由是微服务架构不可或缺的一部分。例如,/
能够映射到您的Web应用程序,/api/users
映射到用户服务并/api/shop
映射到商店服务。数据库
Netflix使用Zuul进行如下操做:后端
认证api
洞察浏览器
压力测试安全
金丝雀测试
动态路由
服务迁移
负载脱落
安全
静态响应处理
主动/主动流量管理
Zuul的规则引擎容许规则和过滤器基本上以任何JVM语言编写,内置支持Java和Groovy。
Zuul主要有四种类型的过滤器,使咱们可以在任何特定事务的请求处理的不一样时间线中拦截流量。咱们能够为特定的url模式添加任意数量的过滤器。
前置过滤器 - 在路由请求以前调用。
后置过滤器 - 在路由请求后调用。
路由过滤器 - 用于路由请求。
错误过滤器 - 在处理请求时发生错误时调用。
使用不一样的过滤器在Zuul内部请求处理流程
关键词 | 备注 |
---|---|
类型Type | 定义在路由过程当中,过滤器被应用的阶段 |
执行顺序Execution Order | 在同一个Type中,定义过滤器执行的顺序 |
条件Criteria | 过滤器被执行必须知足的条件 |
动做Action | 若是条件知足,过滤器中将被执行的动做 |
PRE
在请求被路由到源服务器前要执行的过滤器
适用业务场景:
认证
选路由
请求日志
ROUTING
处理将请求发送到源服务器的过滤器
POST
在响应从源服务器返回时要被执行的过滤器
对响应增长HTTP 头
收集统计和度量
将响应以流的方式发送回客户端
ERROR
上述阶段中出现错误要执行的过滤器
public class PreFilter extends ZuulFilter {
// 过滤器类型
如今让咱们经过使用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初始化网站,依赖于Web。
将项目解压缩并导入到IDEA中。在此步骤中,使用命令执行maven构建,mvn clean install
以便正确下载全部maven依赖项。
咱们如今只需向此服务添加一些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;
spring
这里咱们按属性给这个服务命名,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控制器@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建立实际的网关服务。
这将是一个基于Spring boot的微服务,但它有一个特殊的功能。它将使用zuul建立一个表明学生服务的API网关。稍后咱们能够添加任意数量的微服务,如学生服务,学校服务并可以建立一个强大的微服务生态系统。
从spring初始化网站建立一个具备Zuul
依赖关系的Spring boot项目。
将项目做为现有maven项目解压缩并导入IDEA。在此步骤中,使用命令执行maven构建,mvn clean install
以便正确下载全部maven依赖项。
如今@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;
打开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支持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; } }
建立要自动注册和启用的这些过滤器的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();
}
使用命令执行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
请在评论部分将您的问题提交给我。
快乐学习!!