微服务项目搭建:Nacos以及GateWay配置

Nacos

为什么要在Nacos进行配置?

方便管理,不用重启项目就可以更改配置。如果微服务的实例多了,里面的配置可以方便统一管理。

配置三要素

搭建完成Nacos服务发现中心,下边搭建Nacos为配置中心,其目的就是通过Nacos去管理项目的所有配置。

先将项目中的配置文件分分类:

1、每个项目特有的配置

是指该配置只在有些项目中需要配置,或者该配置在每个项目中配置的值不同。

比如:spring.application.name每个项目都需要配置但值不一样,以及有些项目需要连接数据库而有些项目不需要,有些项目需要配置消息队列而有些项目不需要。

2、项目所公用的配置

是指在若干项目中配置内容相同的配置。比如:redis的配置,很多项目用的同一套redis服务所以配置也一样。swagger的配置,log的配置等等

另外还需要知道nacos如何去定位一个具体的配置文件,即:namespace、group、dataid.

1、通过namespace、group找到具体的环境和具体的项目。

2、通过dataid找到具体的配置文件,dataid有三部分组成

比如:content-service-dev.yaml配置文件 由(content-service)-(dev). (yaml)三部分组成

content-service:第一部分,它是在application.yaml中配置的应用名,即spring.application.name的值。

dev:第二部分,它是环境名,通过spring.profiles.active指定,

Yaml: 第三部分,它是配置文件 的后缀,目前nacos支持properties、yaml等格式类型,本项目选择yaml格式类型。

所以,如果我们要配置content-service工程的配置文件:

在开发环境中配置content-service-dev.yaml

在测试环境中配置content-service-test.yaml

在生产环境中配置content-service-prod.yaml

我们启动项目中传入spring.profiles.active的参数决定引用哪个环境的配置文件,例如:传入spring.profiles.active=dev表示使用dev环境的配置文件即content-service-dev.yaml。

3.配置优先级

如果本地的配置和nacos的配置文件有冲突,那么,以谁的为主?

应用场景:该工程在开发环境启动一个实例,又由于开发需要,在启动一个实例,需要更改端口,但是只是开发需要,去改nacos不合理,这时候就适合在本地改动配置。

到目前为止已将所有微服务的配置统一在nacos进行配置,用到的配置文件有本地的配置文件 bootstrap.yaml和nacos上的配置文件,SpringBoot读取配置文件 的顺序如下:

引入配置文件的形式有:

1、以项目应用名方式引入

2、以扩展配置文件方式引入

3、以共享配置文件 方式引入

4、本地配置文件

1,2,3都在nacos。4在本地

各配置文件 的优先级:项目应用名配置文件 > 扩展配置文件 > 共享配置文件 > 本地配置文件。

有时候我们在测试程序时直接在本地加一个配置进行测试,比如下边的例子:

我们想启动两个内容管理微服务,此时需要在本地指定不同的端口,通过VM Options参数,在IDEA配置启动参数。

通过-D指定参数名和参数值,参数名即在bootstrap.yml中配置的server.port。

启动ContentApplication2,发现端口仍然是63040,这说明本地的配置没有生效。

这时我们想让本地最优先,可以在nacos配置文件 中配置如下即可实现。

再次启动ContentApplication2,端口为63041。

配置本地优先:

yaml 复制代码
#配置本地优先
spring:
 cloud:
  config:
    override-none: true

之后再创建实例的时候,可以通过添加参数的方式去配置端口等。

如何灵活的切换配置文件?

传参:

spring.profiles.active=test还是dev还是prod等

实例

特有配置
yaml 复制代码
spring:
  application:
    name: content-api #服务名称
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://192.168.101.65:3306/xcplus_content?serverTimezone=UTC&userUnicode=true&useSSL=false&
    username: root
    password: mysql
  cloud:
    nacos:
      server-addr: 192.168.101.65:8848
      discovery:
        namespace: devNeu
        group: xuecheng-plus-project

这里在配置的时候,服务名称,server-addr和group,namespace都不能配到ncaos里,因为如果配置走,本地将无法发现nacos里的服务。

所以

yaml 复制代码
  cloud:
    nacos:
      server-addr: 192.168.101.65:8848
      discovery:
        namespace: devNeu
        group: xuecheng-plus-project
   和
    application:
    name: content-api #服务名称
​

不能配置到nacos的配置文件里。

需要拼装配置文件的例如content-api-dev.yaml里的东西在本地都不能删除。

本地配置的时候不要忘了配置config

注意区分profiles下的active的dev和自己的namespace里的

要注意区分服务注册发现和服务配置文件的信息。

yaml 复制代码
spring:
  application:
    name: content-api #服务名称
#  datasource:
#    driver-class-name: com.mysql.cj.jdbc.Driver
#    url: jdbc:mysql://192.168.101.65:3306/xcplus_content?serverTimezone=UTC&userUnicode=true&useSSL=false&
#    username: root
#    password: mysql
  cloud:
    nacos:
      server-addr: 192.168.101.65:8848
      discovery: #服务注册发现的相关配置
        namespace: devNeu
        group: xuecheng-plus-project
      config: #配置文件的相关信息
        namespace: devNeu #我的命名空间,无论是配置也好,服务也好,都在我的命名空间下
        group: xuecheng-plus-project
        file-extension: yaml
        refresh-enabled: true
  profiles:
    active: dev #环境名,拼接配置文件用的

注意对应配置文件的依赖

如果想用注册,就加discovery,如果想用配置中心,就加config

xml 复制代码
<!--        上报服务nacos-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
​
<!--        nacos配置依赖-->
<!--        微服务里有一个配置的客户端,去nacos定时的拉取配置-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>

结果:

ini 复制代码
2023-10-21 14:11:44,739 DEBUG [com.alibaba.nacos.client.Worker.longPolling.fixed-192.168.101.65_8848-devNeu][NacosRestTemplate.java:476] - HTTP method: POST, url: http://192.168.101.65:8848/nacos/v1/cs/configs/listener, body: {Listening-Configs=content-api-dev.yaml•xuecheng-plus-project•b1560ddf63798a362c47f567fa2516e2•devNeu•content-api.yaml•xuecheng-plus-project••devNeu•content-api•xuecheng-plus-project••devNeu•, tenant=devNeu}
2023-10-21 14:11:44,739 DEBUG [com.alibaba.nacos.client.Worker.longPolling.fixed-192.168.101.65_8848-devNeu][NacosRestTemplate.java:494] - Execute via interceptors :[com.alibaba.nacos.client.config.impl.ConfigHttpClientManager$LimiterHttpClientRequestInterceptor@403264c2]
2023-10-21 14:11:44,759 DEBUG [com.alibaba.nacos.client.Worker.longPolling.fixed-192.168.101.65_8848-devNeu][NacosRestTemplate.java:476] - HTTP method: POST, url: http://192.168.101.65:8848/nacos/v1/cs/configs/listener, body: {Listening-Configs=content-api-dev.yaml•xuecheng-plus-project•b1560ddf63798a362c47f567fa2516e2•devNeu•content-api.yaml•xuecheng-plus-project••devNeu•content-api•xuecheng-plus-project••devNeu•, tenant=devNeu}

从nacos里拿配置

接口层本身是不需要配置数据库的,但是他依赖着service层的代码,当打包启动的时候,就将service的mapper,service等代码全部依赖到接口层工程,接口层本身是不需要数据库连接的。

所以,在service层里配置数据库,在接口层去引用service工程的

service模块下的test里的bootstrap.yml里配置:

yaml 复制代码
spring:
  application:
    name: content-service #服务名称
  #  datasource:
  #    driver-class-name: com.mysql.cj.jdbc.Driver
  #    url: jdbc:mysql://192.168.101.65:3306/xcplus_content?serverTimezone=UTC&userUnicode=true&useSSL=false&
  #    username: root
  #    password: mysql
  cloud:
    nacos:
      server-addr: 192.168.101.65:8848
      config: #配置文件的相关信息
        namespace: devNeu #我的命名空间,无论是配置也好,服务也好,都在我的命名空间下
        group: xuecheng-plus-project
        file-extension: yaml
        refresh-enabled: true
  profiles:
    active: dev #环境名,拼接配置文件用的
#  datasource:
#    driver-class-name: com.mysql.cj.jdbc.Driver
#    url: jdbc:mysql://192.168.101.65:3306/xcplus_content?serverTimezone=UTC&userUnicode=true&useSSL=false&
#    username: root
#    password: mysql
​
# 日志文件配置路径
logging:
  config: classpath:log4j2-dev.xml
​

我们的接口工程里不需要直接配置数据库,而是去引用service的。

api工程没有数据库连接,api的nacos文件里也没有。

yaml 复制代码
#nacos配置里也注释掉datasource
server:
  servlet:
    context-path: /content
  port: 63040
# spring:
#   datasource:
#     driver-class-name: com.mysql.cj.jdbc.Driver
#     url: jdbc:mysql://192.168.101.65:3306/xcplus_content?serverTimezone=UTC&userUnicode=true&useSSL=false&
#     username: root
#     password: mysql

api工程里用扩展引用

yaml 复制代码
#发送请求的时候,自带/content内容,这个服务里就不用再写了
#server:
#  servlet:
#    context-path: /content
#  port: 63040
#微服务配置
spring:
  application:
    name: content-api #服务名称
#  datasource:
#    driver-class-name: com.mysql.cj.jdbc.Driver
#    url: jdbc:mysql://192.168.101.65:3306/xcplus_content?serverTimezone=UTC&userUnicode=true&useSSL=false&
#    username: root
#    password: mysql
  cloud:
    nacos:
      server-addr: 192.168.101.65:8848
      discovery: #服务注册的相关配置
        namespace: devNeu
        group: xuecheng-plus-project
      config: #配置文件的相关信息
        namespace: devNeu #我的命名空间,无论是配置也好,服务也好,都在我的命名空间下
        group: xuecheng-plus-project
        file-extension: yaml
        refresh-enabled: true
        extension-configs:
          - data-id: content-service-${spring.profiles.active}.yaml
            group: xuecheng-plus-project
            refresh: true
​
  profiles:
    active: dev #环境名,拼接配置文件用的
# 日志文件配置路径
logging:
  config: classpath:log4j2-dev.xml
​
swagger:
  title: "学成在线内容管理系统"
  description: "学成在线内容管理系统接口文档"
  base-package: com.xuecheng.content
  version: 1.0.0
  enabled: true
​
​

里的部分

yaml 复制代码
        extension-configs:
          - data-id: content-service-${spring.profiles.active}.yaml
            group: xuecheng-plus-project
            refresh: true
​
  profiles:
    active: dev #环境名,拼接配置文件用的

service的nacos里的配置:

yaml 复制代码
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://192.168.101.65:3306/xcplus_content?serverTimezone=UTC&userUnicode=true&useSSL=false&
    username: root
    password: mysql

api接口工程重启,如果能正常查询数据库,则证明配置成功。

当一个服务想要依赖另一个服务里的配置的时候,可以考虑用extension-configs:

公用配置

logging,swagger等。

公用配置,group可以当成项目名字或者分类。

yaml 复制代码
#logging
# 日志文件配置路径
logging:
  config: classpath:log4j2-dev.xml
yaml 复制代码
swagger:
  title: "学成在线项目结构文档"
  description: "学成在线内容管理系统接口文档"
  base-package: com.xuecheng
  version: 1.0.0
  enabled: true
​

都配置到nacos里的新建公共分组xuecheng-plus-common里

本地配置:

yaml 复制代码
#发送请求的时候,自带/content内容,这个服务里就不用再写了
#server:
#  servlet:
#    context-path: /content
#  port: 63040
#微服务配置
spring:
  application:
    name: content-api #服务名称
#  datasource:
#    driver-class-name: com.mysql.cj.jdbc.Driver
#    url: jdbc:mysql://192.168.101.65:3306/xcplus_content?serverTimezone=UTC&userUnicode=true&useSSL=false&
#    username: root
#    password: mysql
  cloud:
    nacos:
      server-addr: 192.168.101.65:8848
      discovery: #服务注册的相关配置
        namespace: devNeu
        group: xuecheng-plus-project
      config: #配置文件的相关信息
        namespace: devNeu #我的命名空间,无论是配置也好,服务也好,都在我的命名空间下
        group: xuecheng-plus-project
        file-extension: yaml
        refresh-enabled: true
        extension-configs:
          - data-id: content-service-${spring.profiles.active}.yaml
            group: xuecheng-plus-project
            refresh: true
        shared-configs: #共享文件,nacos里
          - data-id: swagger-${spring.profiles.active}.yaml
            group: xuecheng-plus-common
            refresh: true
          - data-id: logging-${spring.profiles.active}.yaml
            group: xuecheng-plus-common
            refresh: true
​
  profiles:
    active: dev #环境名,拼接配置文件用的

新增:

yaml 复制代码
shared-configs:
          - data-id: swagger-${spring.profiles.active}.yaml
            group: xuecheng-plus-common
            refresh: true
          - data-id: logging-${spring.profiles.active}.yaml
            group: xuecheng-plus-common
            refresh: true

网关配置

pom文件:

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
​
    <parent>
        <groupId>com.xuecheng</groupId>
        <artifactId>xuecheng-plus-parent</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <relativePath>../xuecheng-plus-parent</relativePath>
    </parent>
    <artifactId>xuecheng-plus-gateway</artifactId>
​
    <dependencies>
​
        <!--网关-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
​
        <!--服务发现中心-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!-- 排除 Spring Boot 依赖的日志包冲突 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
​
        <!-- Spring Boot 集成 log4j2 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
        </dependency>
​
​
    </dependencies>
​
    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
​
</project>
​

本地:

yml配置:

yaml 复制代码
#微服务配置
spring:
  application:
    name: gateway
  cloud:
    nacos:
      server-addr: 192.168.101.65:8848
      discovery:
        namespace: devNeu
        group: xuecheng-plus-project
      config:
        namespace: devNeu
        group: xuecheng-plus-project
        file-extension: yaml
        refresh-enabled: true
        shared-configs:
          - data-id: logging-${spring.profiles.active}.yaml
            group: xuecheng-plus-common
            refresh: true
  profiles:
    active: dev
​

nacos中:

gateway-dev.yaml

  • Path=/content/** # 这个是按照路径匹配,只要以/content/开头就符合要求,都会路由到id值(例如content-api)的微服务。
yaml 复制代码
server:
  port: 63010 # 网关端口
spring:
  cloud:
    gateway:
#      filter:
#        strip-prefix:
#          enabled: true
      routes: # 网关路由配置
        - id: content-api # 路由id,自定义,只要唯一即可
          # uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址
          uri: lb://content-api # 路由的目标地址 lb就是负载均衡,后面跟服务名称
          predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
            - Path=/content/** # 这个是按照路径匹配,只要以/content/开头就符合要求,都会路由到id值的微服务。
#          filters:
#            - StripPrefix=1
        - id: system-api
          # uri: http://127.0.0.1:8081
          uri: lb://system-api
          predicates:
            - Path=/system/**
#          filters:
#            - StripPrefix=1
        - id: media-api
          # uri: http://127.0.0.1:8081
          uri: lb://media-api
          predicates:
            - Path=/media/**
#          filters:
#            - StripPrefix=1
        - id: search-service
          # uri: http://127.0.0.1:8081
          uri: lb://search
          predicates:
            - Path=/search/**
#          filters:
#            - StripPrefix=1
        - id: auth-service
          # uri: http://127.0.0.1:8081
          uri: lb://auth-service
          predicates:
            - Path=/auth/**
#          filters:
#            - StripPrefix=1
        - id: checkcode
          # uri: http://127.0.0.1:8081
          uri: lb://checkcode
          predicates:
            - Path=/checkcode/**
#          filters:
#            - StripPrefix=1
        - id: learning-api
          # uri: http://127.0.0.1:8081
          uri: lb://learning-api
          predicates:
            - Path=/learning/**
#          filters:
#            - StripPrefix=1
        - id: orders-api
          # uri: http://127.0.0.1:8081
          uri: lb://orders-api
          predicates:
            - Path=/orders/**
#          filters:
#            - StripPrefix=1

503报错: 服务不可用。

服务不是立即启动完毕,nacos就可以发现服务,需要等30s以上,有一个窗口期。

相关推荐
wowocpp1 小时前
spring boot Controller 和 RestController 的区别
java·spring boot·后端
后青春期的诗go1 小时前
基于Rust语言的Rocket框架和Sqlx库开发WebAPI项目记录(二)
开发语言·后端·rust·rocket框架
freellf1 小时前
go语言学习进阶
后端·学习·golang
全栈派森3 小时前
云存储最佳实践
后端·python·程序人生·flask
CircleMouse3 小时前
基于 RedisTemplate 的分页缓存设计
java·开发语言·后端·spring·缓存
獨枭4 小时前
使用 163 邮箱实现 Spring Boot 邮箱验证码登录
java·spring boot·后端
维基框架4 小时前
Spring Boot 封装 MinIO 工具
java·spring boot·后端
秋野酱4 小时前
基于javaweb的SpringBoot酒店管理系统设计与实现(源码+文档+部署讲解)
java·spring boot·后端
☞无能盖世♛逞何英雄☜5 小时前
Flask框架搭建
后端·python·flask
进击的雷神5 小时前
Perl语言深度考查:从文本处理到正则表达式的全面掌握
开发语言·后端·scala