Spring Cloud 学习记录(四)Zuul
Zuul是Netflix的一个子项目,Spring Cloud 将Zuul进行了进一步的实现与封装,将其整合到Spring-Netflix项目中,为微服务集群提供代理、过滤、路由等功能。
为什么微服务需要网关?
添加网关,可以将集群的服务都隐藏到网关之后,而对客户端来说,无须关心集群的内部结构,只需关系网关的配置的信息;对于Spring Cloud集群来说,不必过多暴露服务,提升了集群的安全性。
Zuul功能
Zuul将外部的请求过程划分为不同的阶段,每个阶段都提供了一系列 过滤器,这些过滤器可以帮我们实现以下功能:
-
身份验证和安全性:对需要身份认证的资源进行过滤,拒绝处理不符合身份认证的请求
-
观察和监控:跟踪重要的数据,为我们展示准确的请求状况
-
动态路由:将请求动态路由到不同的服务集群
-
负载分配:设置每种请求的处理能力,删除那些超出限制的请求
-
静态响应处理:提供一些静态的过滤器,直接响应一些请求,而不将它们转发到集群内部
-
路由的多样化:除了可以将请求路由到Spring Cloud集群外,还可以将请求路由到其他服务。
Web项目整合Zuul
1.使用sts创建springboot项目,first-router 作为网关
选择zuul和web左右依赖:
pom.mxl内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.panku</groupId>
<artifactId>first-router</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>first-router</name>
<description>zuul</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.17.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Edgware.SR5</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.yml
server:
port: 8081
zuul:
routes:
books:
url: http://localhost:8090
入口类,内容如下:
package com.panku;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@SpringBootApplication
@EnableZuulProxy
public class FirstRouterApplication {
public static void main(String[] args) {
SpringApplication.run(FirstRouterApplication.class, args);
}
}
再创建一个服务提供方的springboot web项目,具体代码如下:
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.panku</groupId>
<artifactId>book-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>book-server</name>
<description>zuul</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.17.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.yml
server:
port: 8090
入口类:
package com.panku;
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;
@SpringBootApplication
@RestController
public class BookServerApplication {
@RequestMapping("/hello/{name}")
public String hello(@PathVariable("name")String name) {
return "hello,"+name;
}
public static void main(String[] args) {
SpringApplication.run(BookServerApplication.class, args);
}
}
过滤器运行机制
上面项目中,我们使用了@EnableZuulProxy注解。开启该注解后,在Spring容器初始化时,会将zuul相关初始化,其中包含一个Spring Boot的Bean:ServletRegistrationBean,该类主要用于注册servlet。Zuul提供了一个ZuulServlet类,在Servlet的Service方法中,执行各种Zuul过滤器。
ZuulServlet的service方法接收到请求后,会执行pre阶段的过滤器,再执行routing阶段的过滤器,最后执行post阶段的过滤器。其中routing阶段的过滤器会将请求转发到“源服务”,源服务可以是第三方的Web服务,也可以是Spring Cloud的集群服务。在执行pre和routing阶段的过滤器时,如果出现异常,则会执行error过滤器。整个过程的HTTP请求、HTTP响应、状态等数据,都会被封装到一个RequestContext对象中。
Spring Cloud中使用Zuul
原来的springcloud结构
加入Zuul后的spring cloud结构
demo:
创建:
- zuul-eureka-server 作为服务注册中心
- zuul-book-service 作为服务提供者
- zuul-sale-service 作为服务调用者
- zuul-gateway 作为微服务网关
核心片段代码:
zuul-gateway的配置:
spring:
application:
name: zuul-gateway
server:
port: 8081
eureka:
instance:
hostname: localhost
client:
service-url:
default-zone: http://locahost:8761/eureka
zuul:
routes:
sale:
path: /sale/**
service-id: zuul-sale-service
demo结构图:
未完待续====