1 为什么需要服务网关
在分布式系统系统中,有商品、订单、用户、广告、支付等等一大批的服务,前端怎么调用呢?和每个服务一个个打交道?这显然是不可能的,这就需要有一个角色充当所有请求的入口,这个角色就是服务网关(API gateway)。
2 客户端直接与微服务通讯的问题
- 客户端会多次请求不同的微服务,增加了客户端的复杂性。
- 存在跨域请求,在一定场景下处理相对复杂。
- 认证复杂,每个服务都需要独立认证。
- 难以重构,随着项目的迭代,可能需要重新划分微服务。例如,可能将多个服务合并成一个或者将一个服务拆分成多个。如果客户端直接与微服务通讯,那么重构将会很难实施。
3 网关的优点
- 易于监控。可在微服务网关收集监控数据并将其推送到外部系统进行分析。
- 易于认证。可在微服务网关上进行认证。然后再将请求转发到后端的微服务,而无须在每个微服务中进行认证。
- 减少了客户端与各个微服务之间的交互次数。
为了解决上面这些问题,我们需要将权限控制这样的东西从我们的服务单元中抽离出去,而最适合这些逻辑的地方就是处于对外访问最前端的地方,我们需要一个更强大一些的均衡负载器,它就是本文将来介绍的:服务网关。
4 什么是网关?
服务网关是微服务架构中一个不可或缺的部分。通过服务网关统一向外系统提供REST API的过程中,除了具备服务路 由、均衡负载功能之外,它还具备了权限控制等功能。Spring Cloud Netflflix 中的 Zuul 就担任了这样的一个角色,为 微服务架构提供了前门保护的作用,同时将权限控制这些较重的非业务逻辑内容迁移到服务路由层面,使得服务集群主体能够具备更高的可复用性和可测试性。
5 使用zuul
5.1 新建zuul的module工程
5.2 新建pom文件
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
5.3 application.yml配置文件
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8888/eureka/
server:
port: 9000
spring:
application:
name: study-zuul
zuul:
routes:
#路由名称,随意命名
api-order:
path: /api-order/**
serviceId: study-user
api-user:
path: /api-user/**
serviceId: study-user
5.4 启动类
package com.study;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@SpringBootApplication
// 开启zuul功能
@EnableZuulProxy
@EnableEurekaClient
public class ZuulApp {
public static void main(String[] args) {
SpringApplication.run(ZuulApp.class, args);
}
}
5.5测试路由访问
直接访问该端口结果如下:
通过路由网关访问,和上面结果一样
5.6 配置统一前缀访问
zuul:
routes:
#路由名称,随意命名
api-order:
path: /api-order/**
serviceId: study-user
api-user:
path: /api-user/**
serviceId: study-user
#前缀访问
prefix: /study
添加统一前缀以后之前访问地址:http://localhost:9000/api-user/user/3
需要增加前缀才能访问,如下:
http://localhost:9000/study/api-user/user/3
5.7 忽略服务名serviceId访问
zuul:
routes:
#路由名称,随意命名
api-order:
path: /api-order/**
serviceId: study-user
api-user:
path: /api-user/**
serviceId: study-user
#忽略服务名serviceId访问
ignored-services: "*"
添加ignored-services: "*"以后,之前直接通过服务名访问的端口将无法直接访问,必须通过路由访问。
5.8 配url绑定映射
zuul:
routes:
testurl:
url: http://www.baidu.com
path: /testurl/**
添加以后只要访问http://地址/testurl/**的将直接跳转到http://www.baidu.com。
testurl可以自己设置名称。
5.9 配置URL映射负载