在微服务架构中,一个系统被拆成很多个小服务。作为客户端要如何去调用这么多的微服务呢?如果没有网关的存在,我们只能在客户端去记录每个微服务的地址,然后去分别调用。

这样的架构,会存在很多的问题
添加API网关之后,系统的架构图变成了如下所示:

上面的这些问题可以借用API网关来解决。
所谓的API网关,就是指系统的统一入口,它封装了应用程序的内部结构,为客户端提供统一服务,一些与业务本身无关的公共逻辑也可以在这里实现,比如认证、鉴权、监控、路由转发等。
在业界比较流行的网关中,有 Nginx+lua,Kong , Zuul 和Spring Cloud Gateway。
注意: SpringCloud alibaba技术栈中并没有提供给自己的网关,我们可以采用Spring Cloud Gateway来做网关。
Spring Cloud Gateway 是 Spring基于Spring5.0,Spring Boot 2.0和Project Reactor等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的API路由管理方式。它的目标是替代Netflix Zuul,其不仅提供统一的路由方式,并且基于Filter链的方式提供了网关基本的功能,例如: 安全,监控,限流。
优点:
本章代码已分享至Gitee: https://gitee.com/lengcz/springcloudalibaba01.git
创建api-gateway模块(springboot模块)
引入依赖gateway依赖(不需要webstarter依赖)
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-gatewayartifactId>
dependency>

server:
port: 7000
spring:
application:
name: api-gateway
cloud:
gateway:
routes: #路由数组,满足什么条件,转发到什么微服务
- id: product_route #当前路由发的标识,需要唯一,默认是UUID
uri: http://localhost:8081 #请求最终转发的地址
order: 1 #路由优先级 数值越小优先级越高
predicates: #断言
- Path=/product-serv/** #当请求路径满足Path指定的规则时,此路由信息才会正常转发
filters: #过滤器,在请求传递过程中,对请求做一些手脚
- StripPrefix=1 #在请求转发之前去掉一层路径,例如 localhost:7000/product-serv/product/1-->localhost:8081/product/1

在第二节中,我们在yml文件中配置了微服务的信息,写死了product微服务的ip和端口,那么当我们开启了多个product微服务做负载均衡怎么办?微服务的ip和端口变更怎么办?显然微服务的ip和端口不应该写死,从nacos服务注册中心获取微服务的地址和端口,就可以解决上述问题。如何操作呢?
显然我们需要在api-gateway模块进行改造
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
dependency>
@SpringBootApplication
@EnableDiscoveryClient //开启服务发现
public class ApiGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(ApiGatewayApplication.class,args);
}
}
server:
port: 7000
spring:
application:
name: api-gateway
cloud:
nacos:
discovery:
server-addr: localhost:8848 #将gateway注册到nacos
gateway:
discovery:
locator:
enabled: true # 让gateway从nacos获取服务信息
routes: #路由数组,满足什么条件,转发到什么微服务
- id: product_route #当前路由发的标识,需要唯一,默认是UUID
# uri: http://localhost:8081 #请求最终转发的地址
uri: lb://server-product #lb 指的是负载均衡,后面跟的是具体微服务的名称
order: 1 #路由优先级 数值越小优先级越高
predicates: #断言
- Path=/product-serv/** #当请求路径满足Path指定的规则时,此路由信息才会正常转发
filters: #过滤器,在请求传递过程中,对请求做一些手脚
- StripPrefix=1 #在请求转发之前去掉一层路径,例如 localhost:7000/product-serv/product/1-->localhost:8081/product/1



在前面的章节,我们需要自定义路由规则,但是gateway是有默认路由的。修改配置文件去掉路由规则,测试
server:
port: 7000
spring:
application:
name: api-gateway
cloud:
nacos:
discovery:
server-addr: localhost:8848 #将gateway注册到nacos
gateway:
discovery:
locator:
enabled: true # 让gateway从nacos获取服务信息

格式解释,其实默认规则也就相当于将Path中的前缀改成微服务的标识

