SpringCloud Zuul 基础入门 - 《重新定义SpringCloud实战》读书笔记系列
Spring Cloud Zuul概述
随着微服务的流行,微服务架构将后端拆解为许多个单独的应用,可是这种方式在带来开发便捷的同时,也出现了新的问题:看起清晰的服务拆分,实则杂乱无章,有时候完成一个业务逻辑,需要到不用主机和不同端口上面调取接口,这是一件很痛苦的事情。于是一个面向服务治理、服务编排的组件出现了——微服务网关。由此,作为Netflix的早期服务化后端应用程序前门项目,Zuul应运而生。
Zuul是由Netflix孵化的一个致力于“网关”解决方案的开源组件。从2012年3月以来,其陆续发布了Zuul1.0与Zuul2.0版本,后经Pivotal公司发现并整合于Spring Cloud生态系统,即现在的Spring Cloud Zuul。在动态路由、监控、弹性、服务治理以及安全方面起着举足轻重的作用。
Zuul是设备和网站到后端应用程序所有请求的前门,为内部服务提供可配置的对外URL到服务的映射关系,基于JVM的后端路由器。其具备以下功能:
- 认证与鉴权
- 压力控制
- 金丝雀测试
- 动态路由
- 负载削减
- 静态响应处理
- 主动流量控制
其底层基于Servlet,本质组件是一系列Filter所构成的责任链。
Spring Cloud Zuul入门案例
这里采用的是书中提供的源码,github地址:https://github.com/SpringCloud/spring-cloud-code
这里实现了一个Zuul的Hello World的入门程序,用到的Spring Cloud组件是Eureka与Zuul,另外使用了一个普通服务作为zuul路由的下级服务,来模拟真实开发中的一次路由过程。
这里用到的是源码中的ch7-2,导入idea中如图:
1.创建Maven父级pom工程
在父工程里面配置好工程需要的父级以来,目的是为了方便管理与简化配置,pom文件如下:
<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>cn.springcloud.book</groupId>
<artifactId>ch7-2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>ch7-2-eureka-server</module>
<module>ch7-2-zuul-server</module>
<module>ch7-2-client-a</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
</parent>
<!-- 利用传递依赖,公共部分 -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- springboot web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<!-- 管理依赖 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!--注意: 这里必须要添加,否则各种依赖有问题 -->
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2. 创建Eureka组件工程
pom中引入Eureka Server依赖
<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>
<parent>
<groupId>cn.springcloud.book</groupId>
<artifactId>ch7-2</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>ch7-2-eureka-server</artifactId>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
启动类加上@EnableEurekaServer
注解
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
配置文件bootstrap.yml
server:
port: 8888
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
3. 创建Zuul Server组件工程
pom文件中引入zuul依赖:
<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>
<parent>
<groupId>cn.springcloud.book</groupId>
<artifactId>ch7-2</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>ch7-2-zuul-server</artifactId>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
启动类上加上相关注解
@SpringBootApplication
@EnableDiscoveryClient
@EnableZuulProxy
public class ZuulServerApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulServerApplication.class, args);
}
}
配置文件中设置eureka注册信息及zuul路由队则
spring:
application:
name: zuul-server
server:
port: 5555
eureka:
client:
serviceUrl:
defaultZone: http://${eureka.host:127.0.0.1}:${eureka.port:8888}/eureka/
instance:
prefer-ip-address: true
zuul:
routes:
client-a:
path: /client/**
serviceId: client-a
在上面的配置文件中,设置Zuul组件的端口为5555,指定注册中心,最后5行是本例的核心,它的意思是,将所有/client开头的URL映射到client-a这个服务中去。我们在请求的时候就可以不用请求实际的服务,转而请求这个5555端口的Zuul服务组件,/client即一次服务路由的规则。
4. 创建普通下游服务client-a
创建一个下游普通服务,来测试Zuul Server路由的路由功能。
pom:
<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>
<parent>
<groupId>cn.springcloud.book</groupId>
<artifactId>ch7-2</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>ch7-2-client-a</artifactId>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
启动类:
@SpringBootApplication
@EnableDiscoveryClient
public class ClientAApplication {
public static void main(String[] args) {
SpringApplication.run(ClientAApplication.class, args);
}
}
配置:
server:
port: 7070
spring:
application:
name: client-a
eureka:
client:
serviceUrl:
defaultZone: http://${eureka.host:127.0.0.1}:${eureka.port:8888}/eureka/
instance:
prefer-ip-address: true
测试接口:
@RestController
public class TestController {
@GetMapping("/add")
public Integer add(Integer a, Integer b){
return a + b;
}
}
在普通服务中做了一个很简单的get接口,接受两个参数a和b,返回和。
5. 效果展示
依次启动Eureka、Zuul、普通服务client-a,使用postman分两次调取接口。
直接调取接口:
经过Zuul网关调取接口:
由此可知当我们哎Zuul配置文件指定了路由规则后,当向Zuul Server发起请求的时候,它会去Eureka注册中心拉取服务列表,如果发现有指定的路由映射规则,就会按照规则路由到相应的服务接口上去。