前言
经过前几章节的介绍,对于
Spring Cloud Netflix
下的核心组件已经了解了一大半。这些组件基本涵盖了微服务架构中最为基础的几个核心。利用这些组件已经可以搭建一个简单的微服务架构系统了。例如通过Eureka
实现高可用的服务注册中心以及实现微服务的注册与发现;Ribbon
与Fegin
实现了服务间负载均衡的接口调用;同时为了使系统服务更为健壮,对依赖的服务调用使用了Hystrix
经行包装,做了熔断机制,避免因为个别服务异常而引起整个系统无法使用。
那么,外部的应用如何来访问内部各种各样的微服务呢?在微服务架构中,后端服务往往不直接开放给调用端,而是通过一个API网关根据请求的url,路由到相应的服务。当添加API网关后,在第三方调用端和服务提供方之间就创建了一面墙,这面墙直接与调用方通信进行权限控制,然后将请求均衡分发给后台服务端。
为什么要使用微服务网关
如果让客户端直接访问各个微服务,会存在一下问题:
- 客户端多次请求不同的微服务,增加客户端的复杂性。
- 存在跨域请求,在一定场景下处理相对复杂。
- 认证复杂,每个服务需要独立认证。
- 难以重构,随着项目扩大,可能需要重新规划微服务,如果客户端直接与微服务相连,那么客户端也需要改造。
- 某些微服务可能使用了防火墙/浏览器不友好的协议,直接访问会有困难。
以上问题可借住网关解决。微服务网关是 客户端与服务器端之前的中间层,所有的外部请求都会先经过服务网关,再发往各个微服务。
在Spring Cloud体系中, Spring Cloud Zuul就是提供负载均衡、反向代理、权限认证的一个API gateway。
网关的选择
现在市场上有很多的网关可供选择:
- Spring Cloud Zuul:本身基于Netflix开源的微服务网关,可以和
Eureka
,Ribbon
,Hystrix
等组件配合使用。 - Kong : 基于
OpenResty
的 API 网关服务和网关服务管理层。 - Spring Cloud Gateway:是由spring官方基于
Spring5.0
,Spring Boot2.0
,Project Reactor
等技术开发的网关,提供了一个构建在Spring Ecosystem
之上的API网关,旨在提供一种简单而有效的途径来发送API,并向他们提供交叉关注点,例如:安全性,监控/指标和弹性。目的是为了替换Spring Cloud Netfilx Zuul的
。
在Spring cloud体系中,一般上选择 Zuul
或者 Gateway
。当然,也可以综合自己的业务复杂性,自研一套或者改在一套符合自身业务发展的api网关的,最简单做法是做个聚合api服务,通过SpringBoot 构建对外的 api 接口,实现统一鉴权、参数校验、权限控制等功能,说白了就是一个rest服务。
Zuul介绍和使用
Zuul
是Netflix
开源的微服务网关,它可以和Eureka
、Ribbon
、Hystirx
等组件配合使用,Zuul
的核心是一系列的过滤器。
这些过滤器可以完成以下功能:
- 身份认证与安全:识别每个资源的验证要求,并拒绝哪些与要求不符的请求。
- 审查与监控:在边缘位置追踪有意义的数据和统计结果,从而带来精确地生产视图。
- 动态路由:动态的将请求路由到不同的后端集群。
- 压力测试:逐渐增加指向集群的流量,以了解性能。
- 负载分配:为每一种负载类型分配对应容量,并弃用超过限定值的请求。
- 静态响应处理:在边缘位置直接建立部分响应,从而避免其转发到内部集群。
- 多区域弹性:跨越 AWS Region 进行请求路由,旨在实现 ELB 使用的多样化,以及让系统的边缘更贴近系统的使用者。
Spring Cloud
对 Zuul
进行了整合与增强。目前,Zuul 使用的默认HTTP客户端是 Apache HTTP Client
,也可以使用 RestClient
或者 okhttp3.OkHttpClient
。若要使用 RestClient
,可以设置 ribbon.restclient.enable=true
;想要使用 okhttp3.OkHttpClient
,可以设置 ribbon.okhttp.enable=true
。
快速入门
前提: 在第二章节中我们已经写好了注册中心Eureka
和服务的提供者Client
,将它们启动,并访问。
- 新建一个工程
Zuul
pom
文件修改,引入zuul
<!-- zuul 依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<!-- eureka client 依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
- 修改启动类
Application.java
,通过@EnableDiscoveryClient
注册为Eureka
客户端应用,以获得服务发现的能力。同时@EnableZuulProxy
注解开启Zuul
的 API 网关服务功能。
@SpringBootApplication
@EnableDiscoveryClient
@EnableZuulProxy
//路由访问规则:http://xxx:xxx/service-id/...
//http://localhost:9000/client/msg
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
- 编写配置文件
application.yml
spring:
application:
name: gateway
eureka:
client:
service-url:
defautZone: http://localhost:8761/eureka/
server:
port: 9000
zuul:
routes:
# 将 url 进行改造
client: /c/**
- 启动 zuul 后查看 Eureka 界面,启动了两个client,端口分别是
8081
、8082
测试:
未通过网关直接访问http://localhost:8081/msg?name=zuul
,返回hello~ zuul! welcome spring cloud.8081
,访问端口同样成功。
通过网关访问http://localhost:9000/client/msg?name=zuul
,可正常返回。返回端口轮训为8081、8082,说明有分发请求的功能,即负载均衡
。
试试改造后的访问方式,http://localhost:9000/c/msg?name=zuul
,效果一样,url看上去更精简。
小结
到此Zuul
的基本使用我们就介绍完了。关于Zuul
更多的配置,动态路由,动态过滤器,后面在来介绍。