前言
看过之前SBC系列的小伙伴应该都可以搭建一个高可用、分布式的微服务了。 目前的结构图应该如下所示:
各个微服务之间都不存在单点,并且都注册于 Eureka
,基于此进行服务的注册于发现,再通过 Ribbon
进行服务调用,并具有客户端负载功能。
一切看起来都比较美好,但这里却忘了一个重要的细节:
当我们需要对外提供服务时怎么处理?
这当然也能实现,无非就是将我们具体的微服务地址加端口暴露出去即可。
那又如何来实现负载呢?
简单!可以通过 Nginx F5
之类的工具进行负载。
但是如果系统庞大,服务拆分的足够多那又有谁来维护这些路由关系呢?
当然这是运维的活,不过这时候运维可能就要发飙了!
并且还有一系列的问题:
- 服务调用之间的一些鉴权、签名校验怎么做?
- 由于服务端地址较多,客户端请求难以维护。
针对于这一些问题 SpringCloud
全家桶自然也有对应的解决方案: Zuul
。
当我们系统整合 Zuul 网关之后架构图应该如下所示:
我们在所有的请求进来之前抽出一层网关应用,将服务提供的所有细节都进行了包装,这样所有的客户端都是和网关进行交互,简化了客户端开发。
同时具有如下功能:
- Zuul 注册于
Eureka
并集成了Ribbon
所以自然也是可以从注册中心获取到服务列表进行客户端负载。
- 功能丰富的路由功能,解放运维。
- 具有过滤器,所以鉴权、验签都可以集成。
基于此我们来看看之前的架构中如何集成 Zuul
。
集成 Zuul
为此我新建了一个项目 sbc-gateway-zuul
就是一个基础的 SpringBoot
结构。其中加入了 Zuul 的依赖:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zuul</artifactId> </dependency>
由于需要将网关也注册到 Eureka
中,所以自然也需要:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency>
紧接着配置一些项目基本信息:
# 项目配置 spring.application.name=sbc-gateway-zuul server.context-path=/ server.port=8383 # eureka地址 eureka.client.serviceUrl.defaultZone=http://node1:8888/eureka/ eureka.instance.prefer-ip-address=true
在启动类中加入开启 Zuul
的注解,一个网关应用就算是搭好了。
@SpringBootApplication //开启zuul代理 @EnableZuulProxy public class SbcGateWayZuulApplication { }
启动 Eureka
和网关看到已经注册成功那就大功告成了:
服务路由
路由是网关的核心功能之一,可以使系统有一个统一的对外接口,下面来看看具体的应用。
传统路由
传统路由非常简单,和 Nginx
类似,由开发、运维人员来维护请求地址和对应服务的映射关系,类似于:
zuul.routes.user-service.path=/user-service/** zuul.routes.user-sercice.url=http://localhost:8080/
这样当我们访问 http://localhost:8383/user-service/getUserInfo/1
网关就会自动给我们路由到 http://localhost:8080/getUserInfo/1
上。
可见只要我们维护好这个映射关系即可自由的配置路由信息(user-sercice 可自定义
),但是很明显这种方式不管是对运维还是开发都不友好。由于实际这种方式用的不多就再过多展开。