1.为什么使用微服务网关
经过前面的学习,微服务架构已经初具雏形,但还有一些问题-不同的微服务一般会有不同的网络地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求。
如果让客户端直接与各个微服务通信,会有以下的问题
1.客户端会多次请求不同的微服务,增加了客户端的复杂性
2.存在跨域请求,在一定的场景下处理相对复杂
3.认证复杂,每个服务都需要单独认证
4.难以重构,随着迭代,可能需要重新划分微服务
5.某些微服务可能使用了防火墙/浏览器不友好的协议,直接访问有困难
以上的问题可以借助网关解决。微服务网关是介于客户端和服务器端之间的中间层,所有的外部请求都会经过微服务网关。
如图,微服务网关封装了应用程序的内部结构,客户端只需要和网关打交道就可以了,而无需直接调用特定服务的接口。这样开发得以简化。网关有以下优点
2.zuul简介
Zuul是Netflix开源的微服务网关,它可以和Eureka,Ribbon,Hystrix等组件配合使用。
Zuul的核心是一系列的过滤器,这些过滤器可以完成以下功能
@身份认证与安全:识别每个资源的验证要求,并拒绝那些与要求不服的请求
@审查与监控:在边缘位置追踪有意义的数据和统计结果,从而带来精准的生产视图
@动态路由:动态的将请求路由到不同的后端集群
@压力测试:逐渐增加指向集群的流量,以了解性能
@静态响应处理:在边缘位置直接建立部分响应,从而避免其转发到内部集群
@多区域弹性:跨域AWS Region进行请求路由,旨在实现ELB使用的多样化,以及让系统的边缘更贴近系统的使用者
3.编写Zuul微服务网关
1.添加依赖
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.itmuch.cloud</groupId>
<artifactId>microservice-gateway-zuul</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>microservice-gateway-zuul</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</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>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Camden.SR4</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>
在启动类上添加注解@EnableZuulProxy,声明一个Zuul代理。该代理使用Ribbon来定位注册在Eureka Server中的微服务;
同时,该代理还整合了Hystrix,从而是吸纳了容错,所有经过Zuul的请求都会在Hystrix命令中执行
package com.itmuch.cloud.microservicegatewayzuul;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
/**
* @EnableZuulProxy在启动类上添加@EnableZuulProxy,声明一个Zuul代理。该代理使用Ribbon来定位注册Eureka Server中的微服务
* 同时,该代理还整合了Hystrix,从而实现了容错,所有经过Zuul的请求都会在Hystrix命令中执行
*/
@SpringBootApplication
@EnableZuulProxy
public class MicroserviceGatewayZuulApplication {
public static void main(String[] args) {
SpringApplication.run(MicroserviceGatewayZuulApplication.class, args);
}
}
我们打开spring-cloud-starter-zuul的源码发现
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
可以发现zuul中已经整合了节点,hystrix,ribbon
编写配置文件
server:
port: 8040
spring:
application:
name: microservice-gateway-zuul
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/,http://localhost:8763/eureka/
Zuul的路由端点
当@EnableZuulProxy与SpringBootActuator配合使用,Zuul会暴露一个路由管理端点/routes。借助这个端点,可以方便,直观的查看以及Zuul的路由
/routes端点的使用非常简单,使用GET方法访问该端点,即可返回ZUUL当前映射的路由列表;
使用POST方法访问该端点就会强制刷新Zuul当前映射的路由列表(尽管路由列表会自动刷新,Spring Cloud依然提供了强制立即刷新的方式)
由于spring-cloud-starter-zuul已经包含了spring-boot-starter-actuator,因此之前的代码已经具备路由的能力
我们访问http://localhost:8040/routes
路由配置详解
1.自定义指定微服务的访问路径
配置zuul.routes.指定微服务的serviceId