SpringCloud微服務實戰——搭建企業級開發框架(三十六):使用Spring Cloud Stream實現可靈活配置消息中間件的功能

  在以往消息隊列的使用中,我們通常使用集成消息中間件開源包來實現對應功能,而消息中間件的實現又有多種,比如目前比較主流的ActiveMQ、RocketMQ、RabbitMQ、Kafka,Stream等,這些消息中間件的實現都各有優劣。
  在進行框架設計的時候,我們考慮是否能夠和之前實現的短訊發送、分佈式存儲等功能一樣,抽象統一消息接口,屏蔽底層實現,在用到消息隊列時,使用統一的接口代碼,然後在根據自己業務需要選擇不同消息中間件時,只需要通過配置就可以實現靈活切換使用哪種消息中間件。Spring Cloud Stream已經實現了這樣的功能,下面我們在框架中集成並測試消息中間件的功能。

目前spring-cloud-stream官網顯示已支持以下消息中間件,我們使用RabbitMQ和Apache Kafka來集成測試:

一、集成RabbitMQ並測試消息收發

  RabbitMQ是使用Erlang語言實現的,這裡安裝需要安裝Erlang的依賴等,這裡為了快速安裝測試,所以使用Docker安裝單機版RabbitMQ。
1、拉取RabbitMQ的Docker鏡像,後綴帶management的是帶web管理界面的鏡像

docker pull rabbitmq:3.9.13-management

2、創建和啟動RabbitMQ容器

docker run -d\
 -e RABBITMQ_DEFAULT_USER=admin\
 -e RABBITMQ_DEFAULT_PASS=123456\
 --name rabbitmq\
 -p 15672:15672\
 -p 5672:5672\
 -v `pwd`/bigdata:/var/lib/rabbitmq\
 rabbitmq:3.9.13-management

3、查看RabbitMQ是否啟動

[root@localhost ~]# docker ps
CONTAINER ID        IMAGE                             COMMAND                  CREATED              STATUS                          PORTS                                                                                                                                                 NAMES
ff1922cc6b73        rabbitmq:3.9.13-management        "docker-entrypoint.s…"   About a minute ago   Up About a minute               4369/tcp, 5671/tcp, 0.0.0.0:5672->5672/tcp, :::5672->5672/tcp, 15671/tcp, 15691-15692/tcp, 25672/tcp, 0.0.0.0:15672->15672/tcp, :::15672->15672/tcp   rabbitmq

4、訪問管理控制台//172.16.20.225:15672 ,輸入設置的用戶名密碼 admin/123456登錄。如果管理台不能訪問,可以嘗試使用一下命令啟動:

docker exec -it rabbitmq rabbitmq-plugins enable rabbitmq_management


5、Nacos添加配置,我們以操作日誌和API日誌為示例,說明自定義輸入和輸出通道進行消息收發,operation-log為操作日誌,api-log為API日誌。注意,官網有文檔說明:使用multiple RabbitMQ binders 時需要排除RabbitAutoConfiguration,實際應用過程中,如果不排除,也不直接配置RabbitMQ的連接,那麼RabbitMQ健康檢查會默認去連接127.0.0.1:5672,導致後台一直報錯。

spring:
  autoconfigure:
    # 使用multiple RabbitMQ binders 時需要排除RabbitAutoConfiguration
    exclude: 
      - org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration
  cloud:
    stream:
      binders: 
        defaultRabbit: 
          type: rabbit
          environment: #配置rabbimq連接環境
            spring: 
              rabbitmq:
                host: 172.16.20.225
                username: admin
                password: 123456
                virtual-host: / 
      bindings: 
        output_operation_log:
          destination: operation-log  #exchange名稱,交換模式默認是topic
          content-type: application/json
          binder: defaultRabbit
        output_api_log:
          destination: api-log  #exchange名稱,交換模式默認是topic
          content-type: application/json
          binder: defaultRabbit
        input_operation_log: 
          destination: operation-log
          content-type: application/json
          binder: defaultRabbit
          group: ${spring.application.name}
          consumer:
            concurrency: 2 # 初始/最少/空閑時 消費者數量,默認1
        input_api_log: 
          destination: api-log
          content-type: application/json
          binder: defaultRabbit
          group: ${spring.application.name}
          consumer:
            concurrency: 2 # 初始/最少/空閑時 消費者數量,默認1

6、在gitegg-service-bigdata中添加spring-cloud-starter-stream-rabbit依賴,這裡注意,只需要在具體使用消息中間件的微服務上引入,不需要統一引入,並不是每個微服務都會用到消息中間件,況且可能不同的微服務使用不同的消息中間件。

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

7、自定義日誌輸出通道LogSink.java

/**
 * @author GitEgg
 */
public interface LogSink {

    String INPUT_OPERATION_LOG = "output_operation_log";

    String INPUT_API_LOG = "output_api_log";

    /**
     * 操作日誌自定義輸入通道
     * @return
     */
    @Input(INPUT_OPERATION_LOG)
    SubscribableChannel inputOperationLog();

    /**
     * API日誌自定義輸入通道
     * @return
     */
    @Input(INPUT_API_LOG)
    SubscribableChannel inputApiLog();
}

8、自定義日誌輸入通道LogSource.java

/**
 * 自定義Stream輸出通道
 * @author GitEgg
 */
public interface LogSource {

    String OUTPUT_OPERATION_LOG = "input_operation_log";

    String OUTPUT_API_LOG = "input_api_log";

    /**
     * 操作日誌自定義輸出通道
     * @return
     */
    @Output(OUTPUT_OPERATION_LOG)
    MessageChannel outputOperationLog();

    /**
     * API日誌自定義輸出通道
     * @return
     */
    @Output(OUTPUT_API_LOG)
    MessageChannel outputApiLog();

}

9、實現日誌推送接口的調用, @Scheduled(fixedRate = 3000)是為了測試推送消息,每隔3秒執行一次定時任務,注意:要使定時任務執行,還需要在Application啟動類添加@EnableScheduling註解。
ILogSendService.java

/**
 * @author GitEgg
 */
public interface ILogSendService {

    /**
     * 發送操作日誌消息
     * @return
     */
    void sendOperationLog();

    /**
     * 發送api日誌消息
     * @return
     */
    void sendApiLog();
}

LogSendImpl.java

/**
 * @author GitEgg
 */
@EnableBinding(value = { LogSource.class })
@Slf4j
@Component
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class LogSendImpl implements ILogSendService {

    private final LogSource logSource;

    @Scheduled(fixedRate = 3000)
    @Override
    public void sendOperationLog() {
        log.info("推送操作日誌-------開始------");
        logSource.outputOperationLog()
                .send(MessageBuilder.withPayload(UUID.randomUUID().toString()).build());
        log.info("推送操作日誌-------結束------");
    }

    @Scheduled(fixedRate = 3000)
    @Override
    public void sendApiLog() {
        log.info("推送API日誌-------開始------");
        logSource.outputApiLog()
                .send(MessageBuilder.withPayload(UUID.randomUUID().toString()).build());
        log.info("推送API日誌-------結束------");
    }
}

10、實現日誌消息接收接口

ILogReceiveService.java

/**
 * @author GitEgg
 */
public interface ILogReceiveService {

    /**
     * 接收到操作日誌消息
     * @param msg
     */
    <T> void receiveOperationLog(GenericMessage<T> msg);

    /**
     * 接收到API日誌消息
     * @param msg
     */
    <T> void receiveApiLog(GenericMessage<T> msg);
}

LogReceiveImpl.java

/**
 * @author GitEgg
 */
@Slf4j
@Component
@EnableBinding(value = { LogSink.class })
public class LogReceiveImpl implements ILogReceiveService {

    @StreamListener(LogSink.INPUT_OPERATION_LOG)
    @Override
    public synchronized <T> void receiveOperationLog(GenericMessage<T> msg) {
        log.info("接收到操作日誌: " + msg.getPayload());
    }

    @StreamListener(LogSink.INPUT_API_LOG)
    @Override
    public synchronized <T> void receiveApiLog(GenericMessage<T> msg) {
        log.info("接收到API日誌: " + msg.getPayload());
    }
}

10、啟動微服務,可以看到日誌打印推送和接收消息已經執行的情況
日誌接收和推送消息情況

二、集成Kafka測試消息收發並測試消息中間件切換

  使用Spring Cloud Stream的其中一項優勢就是方便切換消息中間件又不需要改動代碼,那麼下面我們測試在Nacos的Spring Cloud Stream配置中同時添加Kafka配置,並且API日誌繼續使用RabbitMQ,操作日誌使用Kafka,查看是否能夠同時運行。這裡先將配置測試放在前面方便對比,Kafka集群搭建放在後面說明。
1、Nacos添加Kafka配置,並且將operation_log的binder改為Kafka

spring:
  autoconfigure:
    # 使用multiple RabbitMQ binders 時需要排除RabbitAutoConfiguration
    exclude: 
      - org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration
  cloud:
    stream:
      binders: 
        defaultRabbit: 
          type: rabbit
          environment: #配置rabbimq連接環境
            spring: 
              rabbitmq:
                host: 172.16.20.225
                username: admin
                password: 123456
                virtual-host: / 
        kafka:
          type: kafka
          environment:
            spring:
              cloud:
                stream:
                  kafka:
                    binder:
                      brokers: 172.16.20.220:9092,172.16.20.221:9092,172.16.20.222:9092
                      zkNodes: 172.16.20.220:2181,172.16.20.221:2181,172.16.20.222:2181
                      # 自動創建Topic
                      auto-create-topics: true
      bindings: 
        output_operation_log:
          destination: operation-log  #exchange名稱,交換模式默認是topic
          content-type: application/json
          binder: kafka
        output_api_log:
          destination: api-log  #exchange名稱,交換模式默認是topic
          content-type: application/json
          binder: defaultRabbit
        input_operation_log: 
          destination: operation-log
          content-type: application/json
          binder: kafka
          group: ${spring.application.name}
          consumer:
            concurrency: 2 # 初始/最少/空閑時 消費者數量,默認1
        input_api_log: 
          destination: api-log
          content-type: application/json
          binder: defaultRabbit
          group: ${spring.application.name}
          consumer:
            concurrency: 2 # 初始/最少/空閑時 消費者數量,默認1

2、登錄Kafka服務器,切換到Kafka的bin目錄下啟動一個消費operation-log主題的消費者

./kafka-console-consumer.sh --bootstrap-server 172.16.20.221:9092 --topic operation-log

3、啟動微服務,查看RabbitMQ和Kafka的日誌推送和接收是否能夠正常運行

  • 微服務後台日誌顯示能夠正常推送和接收消息:
    服務後台日誌
  • Kafka服務器顯示收到了操作日誌消息
    Kafka服務器
三、Kafka集群搭建

1、環境準備:
  首先準備好三台CentOS系統的主機,設置ip為:172.16.20.220、172.16.20.221、172.16.20.222。
  Kafka會使用大量文件和網絡socket,Linux默認配置的File descriptors(文件描述符)不能夠滿足Kafka高吞吐量的要求,所以這裡需要調整(更多性能優化,請查看Kafka官方文檔):

vi /etc/security/limits.conf 
# 在最後加入,修改完成後,重啟系統生效。
*                soft    nofile          131072
*                hard   nofile          131072

  新建kafka的日誌目錄和zookeeper數據目錄,因為這兩項默認放在tmp目錄,而tmp目錄中內容會隨重啟而丟失,所以我們自定義以下目錄:

 mkdir /data/zookeeper
 mkdir /data/zookeeper/data
 mkdir /data/zookeeper/logs

 mkdir /data/kafka
 mkdir /data/kafka/data
 mkdir /data/kafka/logs

2、zookeeper.properties配置

vi /usr/local/kafka/config/zookeeper.properties

修改如下:

# 修改為自定義的zookeeper數據目錄
dataDir=/data/zookeeper/data

# 修改為自定義的zookeeper日誌目錄
dataLogDir=/data/zookeeper/logs

# 端口
clientPort=2181

# 注釋掉
#maxClientCnxns=0

# 設置連接參數,添加如下配置
# 為zk的基本時間單元,毫秒
tickTime=2000
# Leader-Follower初始通信時限 tickTime*10
initLimit=10
# Leader-Follower同步通信時限 tickTime*5
syncLimit=5

# 設置broker Id的服務地址,本機ip一定要用0.0.0.0代替
server.1=0.0.0.0:2888:3888
server.2=172.16.20.221:2888:3888
server.3=172.16.20.222:2888:3888

3、在各台服務器的zookeeper數據目錄/data/zookeeper/data添加myid文件,寫入服務broker.id屬性值
在data文件夾中新建myid文件,myid文件的內容為1(一句話創建:echo 1 > myid)

cd /data/zookeeper/data

vi myid

#添加內容:1 其他兩台主機分別配置 2和3
1

4、kafka配置,進入config目錄下,修改server.properties文件

vi /usr/local/kafka/config/server.properties
# 每台服務器的broker.id都不能相同
broker.id=1
# 是否可以刪除topic
delete.topic.enable=true
# topic 在當前broker上的分片個數,與broker保持一致
num.partitions=3
# 每個主機地址不一樣:
listeners=PLAINTEXT://172.16.20.220:9092
advertised.listeners=PLAINTEXT://172.16.20.220:9092
# 具體一些參數
log.dirs=/data/kafka/kafka-logs
# 設置zookeeper集群地址與端口如下:
zookeeper.connect=172.16.20.220:2181,172.16.20.221:2181,172.16.20.222:2181

5、Kafka啟動
kafka啟動時先啟動zookeeper,再啟動kafka;關閉時相反,先關閉kafka,再關閉zookeeper。

  • zookeeper啟動命令
./zookeeper-server-start.sh ../config/zookeeper.properties &

後台運行啟動命令:

nohup ./zookeeper-server-start.sh ../config/zookeeper.properties >/data/zookeeper/logs/zookeeper.log 2>1 &

或者

./zookeeper-server-start.sh -daemon ../config/zookeeper.properties &

查看集群狀態:

./zookeeper-server-start.sh status ../config/zookeeper.properties
  • kafka啟動命令
./kafka-server-start.sh ../config/server.properties &

後台運行啟動命令:

nohup bin/kafka-server-start.sh ../config/server.properties >/data/kafka/logs/kafka.log 2>1 &

或者

 ./kafka-server-start.sh -daemon ../config/server.properties &
  • 創建topic,最新版本已經不需要使用zookeeper參數創建。
./kafka-topics.sh --create --replication-factor 2 --partitions 1 --topic test --bootstrap-server 172.16.20.220:9092

參數解釋:
複製兩份
  –replication-factor 2
創建1個分區
  –partitions 1
topic 名稱
  –topic test

  • 查看已經存在的topic(三台設備都執行時可以看到)
./kafka-topics.sh --list --bootstrap-server 172.16.20.220:9092
  • 啟動生產者:
./kafka-console-producer.sh --broker-list 172.16.20.220:9092 --topic test
  • 啟動消費者:
./kafka-console-consumer.sh --bootstrap-server 172.16.20.221:9092 --topic test
./kafka-console-consumer.sh --bootstrap-server 172.16.20.222:9092 --topic test

添加參數 –from-beginning 從開始位置消費,不是從最新消息

./kafka-console-consumer.sh --bootstrap-server 172.16.20.221 --topic test --from-beginning
  • 測試:在生產者輸入test,可以在消費者的兩台服務器上看到同樣的字符test,說明Kafka服務器集群已搭建成功。
四、完整的Nacos配置
spring:
  jackson:
    time-zone: Asia/Shanghai
    date-format: yyyy-MM-dd HH:mm:ss
  servlet:
    multipart:
      max-file-size: 2048MB
      max-request-size: 2048MB
  security:
    oauth2:
      resourceserver:
        jwt:
          jwk-set-uri: '//127.0.0.1/gitegg-oauth/oauth/public_key'
  autoconfigure:
    # 動態數據源排除默認配置
    exclude: 
      - com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
      - org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration
  datasource: 
    druid:
      stat-view-servlet:
        enabled: true
        loginUsername: admin
        loginPassword: 123456
    dynamic:
      # 設置默認的數據源或者數據源組,默認值即為master
      primary: master
      # 設置嚴格模式,默認false不啟動. 啟動後在未匹配到指定數據源時候會拋出異常,不啟動則使用默認數據源.
      strict: false
      # 開啟seata代理,開啟後默認每個數據源都代理,如果某個不需要代理可單獨關閉
      seata: false
      #支持XA及AT模式,默認AT
      seata-mode: AT
      druid:
        initialSize: 1
        minIdle: 3
        maxActive: 20
        # 配置獲取連接等待超時的時間
        maxWait: 60000
        # 配置間隔多久才進行一次檢測,檢測需要關閉的空閑連接,單位是毫秒
        timeBetweenEvictionRunsMillis: 60000
        # 配置一個連接在池中最小生存的時間,單位是毫秒
        minEvictableIdleTimeMillis: 30000
        validationQuery: select 'x'
        testWhileIdle: true
        testOnBorrow: false
        testOnReturn: false
        # 打開PSCache,並且指定每個連接上PSCache的大小
        poolPreparedStatements: true
        maxPoolPreparedStatementPerConnectionSize: 20
        # 配置監控統計攔截的filters,去掉後監控界面sql無法統計,'wall'用於防火牆
        filters: config,stat,slf4j
        # 通過connectProperties屬性來打開mergeSql功能;慢SQL記錄
        connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000;
        # 合併多個DruidDataSource的監控數據
        useGlobalDataSourceStat: true
      datasource: 
        master: 
          url: jdbc:mysql://127.0.0.188/gitegg_cloud?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&serverTimezone=Asia/Shanghai
          username: root
          password: root
  cloud:
    sentinel:
      filter:
        enabled: true
      transport:
        port: 8719
        dashboard: 127.0.0.188:8086
      eager: true
      datasource:
        ds2:
          nacos:
            data-type: json
            server-addr: 127.0.0.188:8848
            dataId: ${spring.application.name}-sentinel
            groupId: DEFAULT_GROUP
            rule-type: flow
    gateway:
      discovery:
        locator:
          enabled: true
      routes:
        - id: gitegg-oauth
          uri: lb://gitegg-oauth
          predicates:
            - Path=/gitegg-oauth/**
          filters:
            - StripPrefix=1
        - id: gitegg-service-system
          uri: lb://gitegg-service-system
          predicates:
            - Path=/gitegg-service-system/**
          filters:
            - StripPrefix=1
        - id: gitegg-service-extension
          uri: lb://gitegg-service-extension
          predicates:
            - Path=/gitegg-service-extension/**
          filters:
            - StripPrefix=1
        - id: gitegg-service-base
          uri: lb://gitegg-service-base
          predicates:
            - Path=/gitegg-service-base/**
          filters:
            - StripPrefix=1
        - id: gitegg-code-generator
          uri: lb://gitegg-code-generator
          predicates:
            - Path=/gitegg-code-generator/**
          filters:
            - StripPrefix=1
      plugin: 
        config:
          # 是否開啟Gateway日誌插件
          enable: true
          # requestLog==true && responseLog==false時,只記錄請求參數日誌;responseLog==true時,記錄請求參數和返回參數。
          # 記錄入參 requestLog==false時,不記錄日誌
          requestLog: true
          # 生產環境,盡量只記錄入參,因為返回參數數據太大,且大多數情況是無意義的
          # 記錄出參
          responseLog: true
          # all: 所有日誌 configure:serviceId和pathList交集 serviceId: 只記錄serviceId配置列表 pathList:只記錄pathList配置列表
          logType: all
          serviceIdList:
           - "gitegg-oauth"
           - "gitegg-service-system"
          pathList:
           - "/gitegg-oauth/oauth/token"
           - "/gitegg-oauth/oauth/user/info"
    stream:
      binders: 
        defaultRabbit: 
          type: rabbit
          environment: #配置rabbimq連接環境
            spring: 
              rabbitmq:
                host: 127.0.0.225
                username: admin
                password: 123456
                virtual-host: / 
        kafka:
          type: kafka
          environment:
            spring:
              cloud:
                stream:
                  kafka:
                    binder:
                      brokers: 127.0.0.220:9092,127.0.0.221:9092,127.0.0.222:9092
                      zkNodes: 127.0.0.220:2181,127.0.0.221:2181,127.0.0.222:2181
                      # 自動創建Topic
                      auto-create-topics: true
      bindings: 
        output_operation_log:
          destination: operation-log  #exchange名稱,交換模式默認是topic
          content-type: application/json
          binder: kafka
        output_api_log:
          destination: api-log  #exchange名稱,交換模式默認是topic
          content-type: application/json
          binder: defaultRabbit
        input_operation_log: 
          destination: operation-log
          content-type: application/json
          binder: kafka
          group: ${spring.application.name}
          consumer:
            concurrency: 2 # 初始/最少/空閑時 消費者數量,默認1
        input_api_log: 
          destination: api-log
          content-type: application/json
          binder: defaultRabbit
          group: ${spring.application.name}
          consumer:
            concurrency: 2 # 初始/最少/空閑時 消費者數量,默認1
  redis:
    database: 1
    host: 127.0.0.188
    port: 6312
    password: 123456
    ssl: false
    timeout: 2000
  redisson: 
    config: |
      singleServerConfig:
        idleConnectionTimeout: 10000
        connectTimeout: 10000
        timeout: 3000
        retryAttempts: 3
        retryInterval: 1500
        password: 123456
        subscriptionsPerConnection: 5
        clientName: null
        address: "redis://127.0.0.188:6312"
        subscriptionConnectionMinimumIdleSize: 1
        subscriptionConnectionPoolSize: 50
        connectionMinimumIdleSize: 32
        connectionPoolSize: 64
        database: 0
        dnsMonitoringInterval: 5000
      threads: 0
      nettyThreads: 0
      codec: !<org.redisson.codec.JsonJacksonCodec> {}
      "transportMode":"NIO"
#業務系統相關初始化參數
system:
  #登錄密碼默認最大嘗試次數
  maxTryTimes: 5
  #不需要驗證碼登錄的最大次數
  maxNonCaptchaTimes: 2
  #註冊用戶默認密碼
  defaultPwd: 12345678
  #註冊用戶默認角色ID
  defaultRoleId: 4
  #註冊用戶默認組織機構ID
  defaultOrgId: 79
  #不需要數據權限過濾的角色key
  noDataFilterRole: DATA_NO_FILTER
  #AccessToken過期時間(秒)默認為2小時
  accessTokenExpiration: 60
  #RefreshToken過期時間(秒)默認為24小時
  refreshTokenExpiration: 300
logging:
  config: //${spring.cloud.nacos.discovery.server-addr}/nacos/v1/cs/configs?dataId=log4j2.xml&group=${spring.nacos.config.group}
  file:
    # 配置日誌的路徑,包含 spring.application.name  Linux:  /var/log/${spring.application.name}
    path: D:\\log4j2_nacos\\${spring.application.name}
feign:
  hystrix:
    enabled: false
  compression:
    # 配置響應 GZIP 壓縮
    response: 
      enabled: true
    # 配置請求 GZIP 壓縮
    request:
      enabled: true
      # 支持壓縮的mime types
      mime-types: text/xml,application/xml,application/json
      # 配置壓縮數據大小的最小閥值,默認 2048
      min-request-size: 2048
  client:
    config:
      default:
        connectTimeout: 8000
        readTimeout: 8000
        loggerLevel: FULL
#Ribbon配置
ribbon:
  #請求連接的超時時間
  ConnectTimeout: 50000
  #請求處理/響應的超時時間
  ReadTimeout: 50000
  #對所有操作請求都進行重試,如果沒有實現冪等的情況下是很危險的,所以這裡設置為false
  OkToRetryOnAllOperations: false
  #切換實例的重試次數
  MaxAutoRetriesNextServer: 5
  #當前實例的重試次數
  MaxAutoRetries: 5
  #負載均衡策略
  NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule
#Sentinel端點配置
management:
  endpoints:
    web:
      exposure:
        include: '*'
mybatis-plus:
  mapper-locations: classpath*:/com/gitegg/*/*/mapper/*Mapper.xml
  typeAliasesPackage: com.gitegg.*.*.entity
  global-config:
    #主鍵類型  0:"數據庫ID自增", 1:"用戶輸入ID",2:"全局唯一ID (數字類型唯一ID)", 3:"全局唯一ID UUID";
    id-type: 2
    #字段策略 0:"忽略判斷",1:"非 NULL 判斷"),2:"非空判斷"
    field-strategy: 2
    #駝峰下劃線轉換
    db-column-underline: true
    #刷新mapper 調試神器
    refresh-mapper: true
    #數據庫大寫下劃線轉換
    #capital-mode: true
    #邏輯刪除配置
    logic-delete-value: 1
    logic-not-delete-value: 0
  configuration:
    map-underscore-to-camel-case: true
    cache-enabled: false
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 多租戶配置
tenant:
  # 是否開啟租戶模式
  enable: true
  # 需要排除的多租戶的表
  exclusionTable:
    - "t_sys_district"
    - "t_sys_tenant"
    - "t_sys_role"
    - "t_sys_resource"
    - "t_sys_role_resource"
    - "oauth_client_details"
  # 租戶字段名稱
  column: tenant_id
# 數據權限
data-permission:
  # 註解方式默認關閉,否則影響性能
  annotation-enable: true
seata:
  enabled: false
  application-id: ${spring.application.name}
  tx-service-group: gitegg_seata_tx_group
  # 一定要是false
  enable-auto-data-source-proxy: false
  service:
    vgroup-mapping:
      #key與上面的gitegg_seata_tx_group的值對應
      gitegg_seata_tx_group: default
  config:
    type: nacos
    nacos:
      namespace:
      serverAddr: 127.0.0.188:8848
      group: SEATA_GROUP
      userName: "nacos"
      password: "nacos"
  registry:
    type: nacos
    nacos:
      #seata服務端(TC)在nacos中的應用名稱
      application: seata-server
      server-addr: 127.0.0.188:8848
      namespace:
      userName: "nacos"
      password: "nacos"
#驗證碼配置
captcha:
  #驗證碼的類型 sliding: 滑動驗證碼 image: 圖片驗證碼
  type: sliding
aj:
  captcha:
    #緩存local/redis...
    cache-type: redis
    #local緩存的閾值,達到這個值,清除緩存
    #cache-number=1000
    #local定時清除過期緩存(單位秒),設置為0代表不執行
    #timing-clear=180
    #驗證碼類型default兩種都實例化。
    type: default
    #漢字統一使用Unicode,保證程序通過@value讀取到是中文,在線轉換 //tool.chinaz.com/tools/unicode.aspx 中文轉Unicode
    #右下角水印文字(我的水印)
    water-mark: GitEgg
    #右下角水印字體(宋體)
    water-font: 宋體
    #點選文字驗證碼的文字字體(宋體)
    font-type: 宋體
    #校驗滑動拼圖允許誤差偏移量(默認5像素)
    slip-offset: 5
    #aes加密坐標開啟或者禁用(true|false)
    aes-status: true
    #滑動干擾項(0/1/2) 1.2.2版本新增
    interference-options: 2
    # 接口請求次數一分鐘限制是否開啟 true|false
    req-frequency-limit-enable: true
    # 驗證失敗5次,get接口鎖定
    req-get-lock-limit: 5
    # 驗證失敗後,鎖定時間間隔,s
    req-get-lock-seconds: 360
    # get接口一分鐘內請求數限制
    req-get-minute-limit: 30
    # check接口一分鐘內請求數限制
    req-check-minute-limit: 60
    # verify接口一分鐘內請求數限制
    req-verify-minute-limit: 60
#SMS短訊通用配置
sms:
  #手機號碼正則表達式,為空則不做驗證
  reg:
  #負載均衡類型 可選值: Random、RoundRobin、WeightRandom、WeightRoundRobin
  load-balancer-type: Random
  web:
    #啟用web端點
    enable: true
    #訪問路徑前綴
    base-path: /commons/sms
  verification-code:
    #驗證碼長度
    code-length: 6
    #為true則驗證失敗後刪除驗證碼
    delete-by-verify-fail: false
    #為true則驗證成功後刪除驗證碼
    delete-by-verify-succeed: true
    #重試間隔時間,單位秒
    retry-interval-time: 60
    #驗證碼有效期,單位秒
    expiration-time: 180
    #識別碼長度
    identification-code-length: 3
    #是否啟用識別碼
    use-identification-code: false
  redis:
    #驗證碼業務在保存到redis時的key的前綴
    key-prefix: VerificationCode
# 網關放行設置 1、whiteUrls不需要鑒權的公共url,白名單,配置白名單路徑 2、authUrls需要鑒權的公共url
oauth-list:
  staticFiles:
    - "/doc.html"
    - "/webjars/**"
    - "/favicon.ico"
    - "/swagger-resources/**"
  whiteUrls:
    - "/*/v2/api-docs"
    - "/gitegg-oauth/login/phone"
    - "/gitegg-oauth/login/qr"
    - "/gitegg-oauth/oauth/token"
    - "/gitegg-oauth/oauth/public_key"
    - "/gitegg-oauth/oauth/captcha/type"
    - "/gitegg-oauth/oauth/captcha"
    - "/gitegg-oauth/oauth/captcha/check"
    - "/gitegg-oauth/oauth/captcha/image"
    - "/gitegg-oauth/oauth/sms/captcha/send"
    - "/gitegg-service-base/dict/list/{dictCode}"
  authUrls:
    - "/gitegg-oauth/oauth/logout"
    - "/gitegg-oauth/oauth/user/info"
    - "/gitegg-service-extension/extension/upload/file"
    - "/gitegg-service-extension/extension/dfs/query/default"
源碼地址:

Gitee: //gitee.com/wmz1930/GitEgg

GitHub: //github.com/wmz1930/GitEgg