Docker-compose编排MySQL+Nacos+Seata

本文详细介绍了如何使用Docker-compose部署MySQL、Nacos和Seata,涉及环境依赖、配置步骤及异常处理。在配置过程中,强调了应用配置文件的重要性,特别是MySQL、Seata与Nacos的连接设置,以及遇到的如endpoint为空、数据库连接异常、Nacos连接重试错误等问题的解决方案。

环境依赖

Nacos:v2.1.0

MySQL:8.0.21

Seata:1.5.0

nacos依赖MySql;

Seata依赖Nacos+Mysql

涉及到的点

deploy部署设置、depends_on执行顺序设置、自定义网段

完整配置

version: '3.9'
services:
  #mysql数据库脚本
  db:
    image: mysql:8.0.21
    container_name: mysql
    hostname: mysql-node1 
    restart: always
    ports:
      - 3306:3306
    volumes:
      - ./mysql/logs:/var/log/mysql
      - ./mysql/data:/var/lib/mysql
      - ./mysql/conf/my.cnf:/etc/my.cnf
      - ./mysql/init:/docker-entrypoint-initdb.d/
    environment:
      MYSQL_ROOT_PASSWORD: ltingzx
    healthcheck:
      test: [ "CMD", "mysqladmin" ,"ping", "-h", "localhost" ]
      interval: 5s
      timeout: 5s
      retries: 2
      start_period: 5s
    security_opt:
      - seccomp:unconfined
    networks:
      extnetwork:
        ipv4_address: 172.21.0.2 
  #nacos服务脚本
  nacos:
    image: nacos/nacos-server:v2.1.0
    container_name: nacos
    hostname: nacos-node1
    restart: always
    ports:
      - "8848:8848"
    volumes: #挂载目录
      - ./nacos/logs/:/home/nacos/logs
      - ./nacos/data/:/home/nacos/data
    environment:
      SPRING_DATASOURCE_PLATFORM: mysql #数据源平台 仅支持mysql或不保存empty
      MODE: standalone
      MYSQL_SERVICE_HOST: mysql
      MYSQL_SERVICE_DB_NAME: nacos
      MYSQL_SERVICE_PORT: 3306
      MYSQL_SERVICE_USER: root
      MYSQL_SERVICE_PASSWORD: ltingzx
      NACOS_APPLICATION_PORT: 8848
      JVM_XMS: 512m
      JVM_MMS: 256m
      JVM_XMN: 128m
      MYSQL_SERVICE_DB_PARAM: characterEncoding=utf8&connectTimeout=10000&socketTimeout=3000&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
    networks:
      extnetwork:
        ipv4_address: 172.21.0.3
    deploy:
      restart_policy:
        delay: 5s
        max_attempts: 10
    healthcheck:
      test: ["CMD-SHELL", "echo 'ruok' | curl -s telnet://localhost:8848 || exit 1"]
      interval: 3s
      timeout: 5s
      retries: 3
      start_period: 5s
    depends_on:
      db:
        #condition: service_started
        condition: service_healthy
        #condition: service_completed_successfully
  #seata服务脚本
  seata:
    image: seataio/seata-server:1.5.0
    container_name: seata-server
    restart: always
    ports:
      - "9200:9200"
      - "7091:7091"
    volumes:
      - ./seata-server/mysql-connector-java-8.0.25.jar:/seata-server/libs/mysql-connector-java-8.0.25.jar
      - ./seata-server/config/application.yml:/seata-server/resources/application.yml
      - ./seata-server/logs:/root/logs/seata
    environment:
      SEATA_IP: 121.40.236.43
      SEATA_PORT: 9200
    networks:
      extnetwork:
        ipv4_address: 172.21.0.4
    depends_on:
      nacos:
        condition: service_healthy
      db:
        condition: service_healthy
networks:
  extnetwork:
    name: extnetwork
    ipam:
      config:
        - subnet: 172.21.0.0/16

在Docker-compose.yml当前目录下创建MySQL、Nacos、Seata文件夹

mkdir -p ./mysql/data ./mysql/init ./mysql/conf

mkdir -p ./nacos/data ./nacos/init ./nacos/conf ./nacos/logs

mkdir -p ./seata-server/config

Mysql配置准备

1、上传nacos、seata依赖的sql文件

#### 然后将sql文件放在“./mysql/init”目录下即可----MySQL启动的时候就会直接在init文件夹下面加载初始化sql...

2、在Mysql/conf文件夹下面创建:my.cnf

Seata配置准备

在Seata的v1.4.3版本以上,合并了registry.conf和file.conf,只需要配置“ application.yml”即可。

如果找不到application.yml,可以在启动seata容器后从内部拷贝出来

docker cp seata-server:/seata-server/resources/application.yml 

 除此之外还需要准备seataServer.properties,需要在nacos中创建,用来替换原来的file.conf之类的配置。

Seata配置的注意事项

启动成功,但是未注册成功展示

        上面这个时启动失败的,但是没有报错(服务并没有注册到nacos中);下面这个是启动成功的,服务有注册到nacos中--但是此时依然会先报异常三的错误....等一会才会出现下面的信息---启动成功展示...

启动成功展示

 

异常解决

Seata相关异常

异常一: com.alibaba.nacos.api.exception.NacosException: endpoint is blank

Caused by: com.alibaba.nacos.api.exception.NacosException: endpoint is blank
        at com.alibaba.nacos.client.config.impl.ServerListManager.<init>(ServerListManager.java:183)
        at com.alibaba.nacos.client.config.http.ServerHttpAgent.<init>(ServerHttpAgent.java:274)
        at com.alibaba.nacos.client.config.NacosConfigService.<init>(NacosConfigService.java:88)
        ... 27 common frames omitted

原因:我配了./seata-server/config/application.yml:/seata-server/resources/application.yml 

而application.yml配置文件是错误的。

异常二:create connection SQLException, url: jdbc:mysql://127.0.0.1:3306/seata

10:07:06.730 ERROR --- [ctionPool-Create-83554804] com.alibaba.druid.pool.DruidDataSource   : create connection SQLException, url: jdbc:mysql://127.0.0.1:3306/seata?rewriteBatchedStatements=true, errorCode 0, state 08S01
==>
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
        at com.mysql.jdbc.Util.handleNewInstance(Util.java:389)
        at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1038)
        at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:338)

如上异常信息:create connection SQLException, url: jdbc:mysql://127.0.0.1:3306/seata?rewriteBatchedStatements=true, errorCode 0, state 08S01可以知,我们连接的是本地的127.0.0.1:3306的mysql,而在seata容器中并没有安装mysql,所以系统报错

原因是如下: 我们在environment配置中指定了STORE_MODE的模式是db,而我们在application.yml虽然配置了mysql信息,但是并没有成功读取,最终原因:“application.yml”配置错误

异常三:[NACOS HTTP-GET] The maximum number of tolerable server reconnection errors has been reached

09:06:26.451 ERROR --- [                     main] c.a.n.c.config.http.ServerHttpAgent      : [NACOS ConnectException httpGet] currentServerAddr:http://localhost:8848, err : Connection refused (Connection refused)
09:06:26.651 ERROR --- [                     main] c.a.n.c.config.http.ServerHttpAgent      : [NACOS ConnectException httpGet] currentServerAddr:http://localhost:8848, err : Connection refused (Connection refused)
09:06:26.851 ERROR --- [                     main] c.a.n.c.config.http.ServerHttpAgent      : [NACOS ConnectException httpGet] currentServerAddr:http://localhost:8848, err : Connection refused (Connection refused)
09:06:27.051 ERROR --- [                     main] c.a.n.c.config.http.ServerHttpAgent      : [NACOS ConnectException httpGet] currentServerAddr:http://localhost:8848, err : Connection refused (Connection refused)
09:06:27.053 ERROR --- [                     main] c.a.n.client.config.impl.ClientWorker    : [fixed-localhost_8848] [sub-server] get server config exception, dataId=metrics.enabled, group=SEATA_GROUP, tenant=
==>
java.net.ConnectException: [NACOS HTTP-GET] The maximum number of tolerable server reconnection errors has been reached
        at com.alibaba.nacos.client.config.http.ServerHttpAgent.httpGet(ServerHttpAgent.java:125)
        at com.alibaba.nacos.client.config.http.MetricsHttpAgent.httpGet(MetricsHttpAgent.java:51)
        at com.alibaba.nacos.client.config.impl.ClientWorker.getServerConfig(ClientWorker.java:200)
        at com.alibaba.nacos.client.config.NacosConfigService.getConfigInner(NacosConfigService.java:160)
        at com.alibaba.nacos.client.config.NacosConfigService.getConfig(NacosConfigService.java:100)
        at io.seata.config.nacos.NacosConfiguration.getLatestConfig(NacosConfiguration.java:109)
        at io.seata.config.AbstractConfiguration.getConfig(AbstractConfiguration.java:141)
        at io.seata.config.AbstractConfiguration.getConfig(AbstractConfiguration.java:132)
        at io.seata.config.AbstractConfiguration.getBoolean(AbstractConfiguration.java:111)
        at io.seata.config.AbstractConfiguration.getBoolean(AbstractConfiguration.java:117)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

 

由上知:[NACOS ConnectException httpGet] currentServerAddr:http://localhost:8848, err,可以看到nacos也是读取到的本地nacos,原因与上面的mysql异常一致。

以上异常1、2、3出现的最终原因是application.yml配置不正确;

 ---- 系统找不到application.yml文件,检查下配置路径。

 ---- 如果系统能找到application.yml,确保自所依赖的环境的IP、端口、密码都正确的情况下,那就检查下自己的配置格式;

 ---- 如果配置格式正确,那就检查下自己的缩进...

总之,application.yml文件错误...

Nacos相关异常

异常一:encrypted_data_key

---- 注意这是高版本和低版本不兼容的问题。

nacos:v2.1.0 此版本有encrypted_data_key, nacos:v2.1.0版本前没有

PreparedStatementCallback; bad SQL grammar [SELECT id,data_id,group_id,tenant_id,app_name,content,md5,gmt_modified,type,encrypted_data_key FROM config_info WHERE id > ? ORDER BY id ASC LIMIT ?,?]; nested exception is java.sql.SQLSyntaxErrorException: Unknown column 'encrypted_data_key' in 'field list'
........

Caused by: java.sql.SQLSyntaxErrorException: Unknown column 'encrypted_data_key' in 'field list'

原因:config_info查找的时候有 encrypted_data_key 实际上表里面没有,就会导致增加配置报错的问题

解决方法:修改config_info表结构。新增字段“encrypted_data_key”,类型为varchar 255即可。

-------注意:一定还要修改“his_config_info”

异常二:添加完encrypted_data_key后依然报错

2022-07-08 18:00:02+00:00 [Note] [Entrypoint]: /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/nacos-v2.1.0.sql
ERROR 1364 (HY000) at line 33: Field 'encrypted_data_key' doesn't have a default value

解决方法:取消encrypted_data_key为必填项即可。

在官方2.1.0版本的sql中,添加此字段的语句为:encrypted_data_key text NOT NULL COMMENT '秘钥';删除红字即可。

异常三:No DataSource set

Caused by: com.alibaba.nacos.api.exception.NacosException: Nacos Server did not start because dumpservice bean construction failure :
No DataSource set
at com.alibaba.nacos.config.server.service.dump.DumpService.dumpOperate(DumpService.java:225)
at com.alibaba.nacos.config.server.service.dump.ExternalDumpService.init(ExternalDumpService.java:52)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:363)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:307)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:136)
... 53 common frames omitted
Caused by: java.lang.IllegalStateException: No DataSource set
at org.springframework.util.Assert.state(Assert.java:73)
at org.springframework.jdbc.support.JdbcAccessor.obtainDataSource(JdbcAccessor.java:77)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:371)

原因:nacos启动的时候mysql还没有完全初始化完成。

导致未初始化完成原因一:nacos连接时间太短

修改nacos的mysql参数:connectTimeout,设置为10000即可。

如果此时还是要报错,那么通过查看mysql和nacos启动日志可以看到,mysql和nacos所在时区不一致....如下

--------实在不行就把MySQL和nacos分成两个docker-compose.yml即可

如果我们设置的docker-compose.yml文件版本为3.9的时候,可以采用如下方法:

----- 此方式可以见上一篇文章中的depends_on,指定依赖执行顺序即可

depends_on:
  db:
    condition: service_healthy
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值