什么是zuul?
Zuul是所有来自设备和网站的所有请求的大门。作为一个边缘服务应用程序,Zuul是用来支持动态路由、监视、弹性和安全性的。它还可以根据需要将请求路由到多个Amazon Auto伸缩组。
为什么要建立Zuul网关?
平台流量的数量和多样性有时会导致问题迅速产生而没有任何预警。我们需要一个系统,它允许我们快速改变行为以对这些情况作出反应。
Zuul使用了一系列不同类型的过滤器,使我们能够快速、灵活地将功能应用到我们的边缘服务中。这些过滤器帮助我们执行以下功能:
- 身份认证和安全性——识别每个资源的身份验证需求,并拒绝那些不满足它们的请求。
- 洞察力和监视——跟踪有意义的数据和统计数据,以便让我们对生产有一个准确的认识。
- 动态路由——根据需要动态地将请求路由到不同的后端集群。
- 压力测试——逐步增加集群的流量以评估性能。
- 负载脱落——为每种类型的请求分配容量,以及删除超过限制的请求。
- 静态响应处理——直接在边缘构建一些响应,而不是将它们转发到内部集群。
- 跨区域的弹性——跨AWS区域的路由请求,旨在实现ELB使用多样化并保证边缘位置与使用者尽可能接近。
第一个Zuul程序
我们将按照下面的架构来创建项目演示zuul的使用,“网关服务”和“服务提供者”都是简单的Spring Boot项目,“网关服务”通过把用户在浏览器端的请求转发到“服务提供者”来实现路由的功能。
由于Zuul程序一般都是在分布式集群环境下使用的,所以这次的入门演示demo就直接使用了Spring Cloud整合过的Netflix的Zuul,没有使用原生的Netflix下的Zuul,需要做底层研究的小伙伴可以去看Netflix托管在GitHub上的项目和文档,演示案例也是有的(嗯,好像挺对不起标题的,之前都是先讲解一个具体的工具类,再整合Spring Cloud来使用)。
创建一个简单java的maven项目zuul-provider,用于提供访问服务(图中蓝色的服务提供者),pom.xml中引入Spring Boot的依赖:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
接着创建启动类ProviderApp.class,为了方便,我把提供服务的Controller也一并整合到这个启动类里面:
package com.init.springCloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class ProviderApp {
public static void main(String[] args) {
SpringApplication.run(ProviderApp.class, args);
}
@RequestMapping(value = "/msg/{name}", method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public String getMessage(@PathVariable String name){
return "你好,"+name+"!";
}
}
服务提供者就搭建好了,启动zuul-provider项目,访问:http://localhost:8080/msg/spirit,可以看到服务提供者能正常提供服务:
接着创建一个简单java的maven项目zuul-router,作为网关服务,pom.xml中引入Spring Cloud整合的zuul依赖,由于zuul依赖底层使用了Apache提供的httpClient来做请求转发,我们再加入这个httpClient的依赖:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.5</version>
</dependency>
</dependencies>
在src/main/resources目录下新建application.yml文件,配置启动端口和zuul路由规则:
server:
port: 8081
zuul:
routes:
users:
path: /myusers/**
url: http://localhost:8080
zuul和routers都是指定的命名空间;
users是路由规则的名称(可以根据需要自己命名,切忌重名);
path是需要过滤服务对应的规则,如果省略path,那么就由路由规则的名称来取代;
url是转发路径。
更加详细的信息会在后面的博客中更新,这里主要是先做一个zuul入门程序的演示。
配置好了启动端口和zuul路由规则,接下来就是编写启动类RouterApp.class,并在启动类中使用注解@EnableZuulProxy来开启zuul服务代理:
package com.init.springCloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@SpringBootApplication
@EnableZuulProxy
public class RouterApp {
public static void main(String[] args) {
SpringApplication.run(RouterApp.class, args);
}
}
启动zuul-router项目,访问:http://localhost:8081/myusers/msg/spirit,可以看到zuul已经将我们的请求转发到了zuul-provider:
zuul中过滤器的运行机制
Zuul大部分功能都是通过过滤器来实现的。
标准过滤器
Zuul中定义了四种标准过滤器类型,这些过滤器类型对应于请求的典型生命周期。
- PRE:这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中选择请求的微服务、记录调试信息等。
- ROUTING:这种过滤器将请求路由到微服务。这种过滤器用于构建发送给微服务的请求,并使用Apache HttpClient或Netfilx Ribbon请求微服务。
- POST:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等。
- ERROR:在其他阶段发生错误时执行该过滤器。
内置特殊过滤器
- StaticResponseFilter:与CDN节点加速类似,StaticResponseFilter允许从Zuul本身生成响应,而不是将请求转发到源。
- SurgicalDebugFilter:SurgicalDebugFilter允许将特定请求路由到分隔的调试集群或主机。
除了上面两种类型的过滤器,我们还可以自定义过滤器,组合zuul提供的过滤器,实现我们的业务需求。
最后,大家有什么不懂的或者其他需要交流的内容,也可以进入我的QQ讨论群一起讨论:654331206
Spring Cloud系列:
Spring Cloud服务管理框架Eureka简单示例(三)