使用Nacos实现网关动态路由

背景

网关作为一个主要的外部流量入口,其重启的次数当然是越少越好,所以不能有时候为了修改一个路由就重启整个网关服务,这样的话网关就不是一个高可用的网关。当然,有时候要新增或修改代码层面的自定义的过滤器时还是要重启网关的,所以我们能做的就是尽可能减少不必要的重启。这里就可以引入阿里巴巴开源的 Nacos 了。

什么是 Nacos?

Naocs 是阿里巴巴开源的一款微服务组件,它提供注册中心和配置中心来供我们使用。并且 Nacos 同时支持 AP 模式和 CP 模式来供我们选择使用。具体可以查看官方文档来进一步了解。

安装 Nacos

本地的话我这边建议直接用 Docker 来安装Nacos,省心省力。按照官方提供的方法,我们可以直接下载官方提供的 docker-compose 文件来启动 Nacos。

# 克隆项目
git clone https://github.com/nacos-group/nacos-docker.git
## 进入项目目录 然后启动
cd nacos-docker
docker-compose -f example/standalone-mysql-5.7.yaml up

我这边是启动了一个使用 MySQL 5.7 的单机 Nacos,如果你想使用其他的数据库或者启动集群的话可以参照一下官方文档

待启动完成后,就可以用浏览器打开 http://localhost:8848/nacos 进入 Nacos的管理台了。默认的登陆账号密码都是 nacos

image-20210508221303506

网关使用 Nacos

我这边 Spring Cloud 使用的版本号是 2020.0.2

Nacos 创建配置

在开始配置网关项目前,我们先在 Nacos 里创建一个配置,等下网关启动的时候就用这个配置。

server:
  port: 8989

spring:
  cloud:
    gateway:
      routes:
        - id: route-demo
          uri: https://baidu.com
          predicates:
            - Path=/**

在上面配置中,我们定义了项目启动端口为 8989,然后创建了一个路由,这个路由接收所有请求,然后转发到百度。

image-20210508222500763

依赖配置

因为 Nacos 是阿里巴巴开源的,所以这里要用到 spring-cloud-alibaba-dependencies 这个依赖,在 Spring Cloud Gateway 项目里面添加如下依赖:

<dependencies>
  <dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
  </dependency>
</dependencies>

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>com.alibaba.cloud</groupId>
      <artifactId>spring-cloud-alibaba-dependencies</artifactId>
      <version>2021.1</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

配置文件

导入依赖后,我们在 resources 文件夹下创建一个 bootstrap.yml 文件,然后在里面填入 Nacos 配置中心的相关的信息

spring:
  cloud:
    nacos:
      server-addr: localhost:8848
      config:
        prefix: gateway
        file-extension: yml

上面配置中,server-addr 配置了本地 Nacos 的地址,prefix 配置了刚才配置文件的前缀,file-extension 配置了刚才 Nacos 上创建的文件扩展名。

在 Nacos Spring Cloud 中,dataId 的完整格式如下:

${prefix}-${spring.profiles.active}.${file-extension}
  • prefix 默认为 spring.application.name 的值,也可以通过配置项 spring.cloud.nacos.config.prefix来配置。
  • spring.profiles.active 即为当前环境对应的 profile,详情可以参考 Spring Boot文档注意:当 spring.profiles.active 为空时,对应的连接符 - 也将不存在,dataId 的拼接格式变成 ${prefix}.${file-extension}
  • file-exetension 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置。目前只支持 propertiesyaml 类型。

启动网关项目

配置完成后,如果你和我用的 Spring Cloud 版本一样是 2020.0.2 版的话,你启动项目后会发现,欸??怎么启动端口还是默认的 8080 呢?

发生这种情况是因为项目没有读取 bootstrap.yml 文件,这是因为 Spring Cloud 从数字版开始,把 bootstrap 默认为关闭状态,此时如果要使用 bootstrap 的话就要导入以下依赖就可以了

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>

导入依赖后再次启动网关,发现启动端口变成了我们刚在 Nacos 上配置的 8989 了,这时你打开浏览器访问 http://localhost:8989 就会跳转到百度首页了。

动态路由

其实到这一步,动态路由的工作基本上已经完成了,现在你可以在 Nacos 找到刚才配置 gateway.yml,然后点击右边的编辑按钮,修改一下配置的路由。比如我这边把它改成知乎的地址。

image-20210508224219917

配置完后点击下面的发布,此时你不用任何操作,不用重启网关项目,直接再次访问 http://localhost:8989 ,就会发现现在会跳转到知乎了。这样就实现了动态路由了。