Spring Boot集成ShardingSphere实现读写分离 | Spring Cloud 43

news2024/11/23 19:07:03

一、读写分离

1.1 背景

面对日益增加的系统访问量,数据库的吞吐量面临着巨大瓶颈。 对于同一时刻有大量并发读操作和较少写操作类型的应用系统来说,将数据库拆分为主库和从库,主库负责处理事务性的增删改操作,从库负责处理查询操作,能够有效的避免由数据更新导致的行锁,使得整个系统的查询性能得到极大的改善。

通过一主多从的配置方式,可以将查询请求均匀的分散到多个数据副本,能够进一步的提升系统的处理能力。 使用多主多从的方式,不但能够提升系统的吞吐量,还能够提升系统的可用性,可以达到在任何一个数据库宕机,甚至磁盘物理损坏的情况下仍然不影响系统的正常运行。

与将数据根据分片键打散至各个数据节点的水平分片不同,读写分离则是根据 SQL 语义的分析,将读操作和写操作分别路由至主库与从库。

在这里插入图片描述
读写分离的数据节点中的数据内容是一致的,而水平分片的每个数据节点的数据内容却并不相同。将水平分片和读写分离联合使用,能够更加有效的提升系统性能。

1.2 挑战

读写分离虽然可以提升系统的吞吐量和可用性,但同时也带来了数据不一致的问题。 这包括多个主库之间的数据一致性,以及主库与从库之间的数据一致性的问题。 并且,读写分离也带来了与数据分片同样的问题,它同样会使得应用开发和运维人员对数据库的操作和运维变得更加复杂。 下图展现了将数据分片与读写分离一同使用时,应用程序与数据库集群之间的复杂拓扑关系。
在这里插入图片描述

1.3 应用场景

许多系统通过采用主从数据库架构的配置来提高整个系统的吞吐量,但是主从的配置也给业务的使用带来了一定的复杂性。接入 ShardingSphere,可以利用读写分离功能管理主从数据库,实现透明化的读写分离功能,让用户像使用一个数据库一样使用主从架构的数据库。

1.4 核心概念

1.4.1 主库

添加、更新以及删除数据操作所使用的数据库,目前仅支持单主库。(可支持单主库多表数据分片)

1.4.2 从库

查询数据操作所使用的数据库,可支持多从库。

1.4.3 主从同步

将主库的数据异步的同步到从库的操作。 由于主从同步的异步性,从库与主库的数据会短时间内不一致。

1.4.4 负载均衡策略

通过负载均衡策略将查询请求疏导至不同从库。

1.5 使用限制

  • 不处理主库和从库的数据同步(数据同步需自行实现)
  • 不处理主库和从库的数据同步延迟导致的数据不一致
  • 不支持主库多写
  • 不处理主从库间的事务一致性。主从模型中,事务中的数据读写均用主库。

二、Mysql主从数据库同步

针对 1.5章节 提到的使用限制,自行实现主库和从库的数据同步,配置详情请见往期章节:Mysql8 数据库安装及主从配置 | Spring Cloud 2

三、读写分离示例示例

3.1 读写分开总体结构

3.1.1 主库数据源write_ds1

数据库地址数据源名称真实表名逻辑表名称业务描述
192.168.0.35write_ds1t_goods_0t_goods商品表-分表
192.168.0.35write_ds1t_goods_1t_goods商品表-分表

3.1.2 从库数据源read_ds1

数据库地址数据源名称真实表名逻辑表名称业务描述
192.168.0.45read_ds1t_goods_0t_goods商品表-分表
192.168.0.45read_ds1t_goods_1t_goods商品表-分表

3.1.3 从库数据源read_ds2

数据库地址数据源名称真实表名逻辑表名称业务描述
192.168.0.46read_ds2t_goods_0t_goods商品表-分表
192.168.0.46read_ds1t_goods_1t_goods商品表-分表

3.1.1 逻辑商品表 t_goods

-- ----------------------------
-- Table structure for t_goods_0
-- ----------------------------
DROP TABLE IF EXISTS `t_goods_0`;
CREATE TABLE `t_goods_0`  (
  `goods_id` bigint NOT NULL,
  `goods_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '商品名称',
  `main_class` bigint NULL DEFAULT NULL COMMENT '商品大类数据字典',
  `sub_class` bigint NULL DEFAULT NULL COMMENT '商品小类数据字典',
  PRIMARY KEY (`goods_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for t_goods_1
-- ----------------------------
DROP TABLE IF EXISTS `t_goods_1`;
CREATE TABLE `t_goods_1`  (
  `goods_id` bigint NOT NULL,
  `goods_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '商品名称',
  `main_class` bigint NULL DEFAULT NULL COMMENT '商品大类数据字典',
  `sub_class` bigint NULL DEFAULT NULL COMMENT '商品小类数据字典',
  PRIMARY KEY (`goods_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

3.2 项目结构

3.2.1 项目总体结构

在这里插入图片描述

3.2.2 Maven 依赖

shading-sphere/shading-readwrite/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">
    <parent>
        <artifactId>shading-sphere</artifactId>
        <groupId>com.gm</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>shading-readwrite</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
            <version>5.2.1</version>

        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.3.1</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.5.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.3</version>
        </dependency>


        <dependency>
            <groupId>org.yaml</groupId>
            <artifactId>snakeyaml</artifactId>
            <version>1.33</version>
        </dependency>

    </dependencies>

</project>
  • shardingsphere-jdbc-core-spring-boot-starter使用版本5.2.1

  • JDBCORM 框架选用mybatis-plus

3.2.3 配置文件

server:
  port: 8844

spring:
  application:
    name: @artifactId@
  shardingsphere:
    # 数据源配置
    datasource:
      names: write_ds1,read_ds1,read_ds2
      write_ds1:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://192.168.0.35:3306/db1?useUnicode=true&characterEncoding=UTF-8&rewriteBatchedStatements=true&allowMultiQueries=true&serverTimezone=Asia/Shanghai
        username: root
        password: '1qaz@WSX'
      read_ds1:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://192.168.0.45:3306/db1?useUnicode=true&characterEncoding=UTF-8&rewriteBatchedStatements=true&allowMultiQueries=true&serverTimezone=Asia/Shanghai
        username: root
        password: '1qaz@WSX'
      read_ds2:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://192.168.0.46:3306/db1?useUnicode=true&characterEncoding=UTF-8&rewriteBatchedStatements=true&allowMultiQueries=true&serverTimezone=Asia/Shanghai
        username: root
        password: '1qaz@WSX'
    # 定义规则
    rules:
      sharding:
        # 数据分片规则配置
        tables:
          # 指定某个表的分片配置,逻辑表名
          t_goods:
            # 这个配置是告诉sharding有多少个库和多少个表及所在实际的数据库节点,由数据源名 + 表名组成(参考 Inline 语法规则)
            actual-data-nodes: readwrite_ds.t_goods_$->{0..1} # 此处使用下方定义的读写分离数据源
            # 配置表分片策略
            table-strategy:
              # 用于单分片键的标准分片场景
              standard:
                # 分片列名称
                sharding-column: main_class
                # 分片算法名称
                sharding-algorithm-name: t_goods_table_inline
            # 分布式序列策略
            key-generate-strategy:
              # 自增列名称,缺省表示不使用自增主键生成器
              column: goods_id
              # 分布式序列算法名称
              key-generator-name: snowflake
        # 分片算法配置
        sharding-algorithms:
          # 分片算法名称
          t_goods_table_inline:
            # 分片算法类型
            type: INLINE
            # 分片算法属性配置
            props:
              algorithm-expression: t_goods_${main_class % 2}
        # 分布式序列算法配置(如果是自动生成的,在插入数据的sql中就不要传id,null也不行,直接插入字段中就不要有主键的字段)
        keyGenerators:
          # 分布式序列算法名称
          snowflake:
            # 分布式序列算法类型
            type: SNOWFLAKE
      readwrite-splitting:
        dataSources:
          readwrite_ds: # 此处定义的数据源名称在上分分表中使用
            staticStrategy:
              writeDataSourceName: write_ds1
              readDataSourceNames:
                - read_ds1
                - read_ds2
            # dynamicStrategy:
            loadBalancerName: myBalancer
        load-balancers:
          myBalancer:
            type: RANDOM
            props:
              transactionalReadQueryStrategy: PRIMARY
    props:
      sql-show: true #显示sql

mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

配置简要说明:

商品逻辑表t_goods

  • 按照商品大类取模分片算法进行分表
  • 使用RANDOM算法进行读写分离配置

读写分离规则中定义的数据源名称readwrite_ds,在逻辑表t_goods的数据分片规则中得用应用(actual-data-nodes属性)

ShardingSphere-JDBC读写分离实现包括:静态读写分离动态读写分离两种方式,示例采用静态读写分离

关于动态读写分离使用配置,请见官网:
https://shardingsphere.apache.org/document/5.2.1/cn/user-manual/shardingsphere-jdbc/yaml-config/rules/ha/
https://shardingsphere.apache.org/document/5.2.1/cn/user-manual/shardingsphere-jdbc/spring-boot-starter/rules/ha/

ShardingSphere内置提供了多种负载均衡算法,请见官网:
https://shardingsphere.apache.org/document/5.2.1/cn/user-manual/common-config/builtin-algorithm/load-balance/

3.2.4 实体定义

com/gm/shading/readwrite/entity/Goods.java

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

@Data
@TableName("t_goods")
public class Goods {

    @TableId(type = IdType.ASSIGN_ID)
    private Long goodsId;

    private String goodsName;

    private Long mainClass;

    private Long subClass;

}

3.2.5 定义mapper

com/gm/shading/readwrite/mapper/GoodsMapper.java

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.gm.shading.readwrite.entity.Goods;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface GoodsMapper extends BaseMapper<Goods> {
    void save(Goods goods);
}

src/main/resources/mapper/GoodsMapper.xml

<?xml version="1.0" encoding="UTF-8"?>

<!--
  ~ Copyright (c) 2020 mttsmart4cloud Authors. All Rights Reserved.
  ~
  ~ Licensed under the Apache License, Version 2.0 (the "License");
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~     http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  -->

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.gm.shading.readwrite.mapper.GoodsMapper">
    <insert id="save" parameterType="com.gm.shading.readwrite.entity.Goods">
        insert into t_goods (goods_name, main_class, sub_class)
        values (#{goodsName}, #{mainClass}, #{subClass})
    </insert>
</mapper>

3.2.6 单元测试

src/test/java/com/gm/shading/readwrite/ShadingReadWriteApplicationTests.java

package com.gm.shading.readwrite;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gm.shading.readwrite.entity.Goods;
import com.gm.shading.readwrite.mapper.GoodsMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
import java.util.Random;

@SpringBootTest
public class ShadingReadWriteApplicationTests {

    @Autowired
    GoodsMapper goodsMapper;

    // 分布式队列不生效,使用数据库递增
    @Test
    void addGoods() throws InterruptedException {
        for (int i = 1; i <= 10; i++) {
            Goods goods = new Goods();

            Random random = new Random();
            int mainClass = random.nextInt(100) + 1;
            int subClass = random.nextInt(100) + 1;
            goods.setMainClass((long) mainClass);
            goods.setSubClass((long) subClass);
            goods.setGoodsName("商品" + i);
            goodsMapper.insert(goods);
        }

        Thread.sleep(2000);
        for (int i = 1; i <= 10; i++) {
            QueryWrapper<Goods> queryWrapper = new QueryWrapper<>();
            List<Goods> list = goodsMapper.selectList(queryWrapper.orderByAsc("goods_id"));
            for (Goods goods : list) {
                System.out.println(goods.toString());
            }
        }
    }

    // 分布式队列生效,使用雪花算法生成ID
    @Test
    void addGoods2() throws InterruptedException {
        for (int i = 1; i <= 10; i++) {
            Goods goods = new Goods();

            Random random = new Random();
            int mainClass = random.nextInt(100) + 1;
            int subClass = random.nextInt(100) + 1;
            goods.setMainClass((long) mainClass);
            goods.setSubClass((long) subClass);
            goods.setGoodsName("商品" + i);
            goodsMapper.save(goods);
        }

        Thread.sleep(2000);
        for (int i = 1; i <= 10; i++) {
            QueryWrapper<Goods> queryWrapper = new QueryWrapper<>();
            List<Goods> list = goodsMapper.selectList(queryWrapper.orderByAsc("goods_id"));
            for (Goods goods : list) {
                System.out.println(goods.toString());
            }
        }
    }
}

3.2.7 数据分片及读写分离效果

在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/508680.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

NetApp 利用适用于混合云的实时解决方案解决芯片设计方面的数据管理挑战

电子设计自动化 (EDA) 成本持续增加&#xff0c;而周期时间缩短。这些都为 EDA 设计带来了前所未有的挑战&#xff0c;对现代高性能工作流的需求变得从未如此巨大。 联想凌拓芯片设计行业存储解决方案及最佳实践 联想凌拓芯片行业数据存储与管理解决方案&#xff0c;针对EDA…

驱动设计的思想:面向对象/分层/分离(以LED操作为例)

1. 面向对象 字符设备驱动程序抽象出一个file_operations结构体&#xff1b; 对于LED&#xff0c;写的程序针对硬件部分抽象出led_operations结构体。 2. 分层 上下分层&#xff0c;之前写的LED驱动程序就分为2层&#xff1a; ① 上层实现硬件无关的操作&#xff0c;比如注册…

一文搞懂——MySQL索引事务JDBC

目录 一、索引 1.1 索引是什么&#xff1f; 1.2 怎样创建索引&#xff1f; 1.3 索引使用的数据结构是什么&#xff1f; 1.4 索引相关的概念 1.5 索引失效的原因 二、事务 2.1 事务是什么&#xff1f; 2.2 为什么要使用事务&#xff1f; 2.3 事务的使用 2.4 事务的特性…

黑马头条(学习笔记)

​ 目录 一. 项目概述 二、项目初始化 移动端 REM 适配&#xff1a; 关于 PostCSS 配置文件&#xff1a; Autoprefixer 插件的配置 &#xff1a; postcss-pxtorem 插件的配置&#xff1a; 关于字体图标: 配置路由&#xff1a; 封装请求模块: 三&#xff1a;登录注册&…

ChatGPT有话说:虚拟现实 VS 增强现实

以下内容均为ChatGPT根据用户引导和提示作出的阐述和说明。 一、引言 虚拟现实和增强现实是当前最受瞩目的创新技术。虚拟现实是指利用计算机生成的虚拟环境&#xff0c;用户可以通过佩戴VR头戴式显示器等设备完全沉浸在其中&#xff0c;感受到身临其境的感觉。而增强现实则是…

三分钟上手安全渗透系统Kali Linux

kali linux系统集成了常用的安全渗透工具&#xff0c;省去了安装工具的时间&#xff0c;做安全相关的工作是非常推荐使用的。 安装Kalii Linux 安装系统 一般使用虚拟机进行安装&#xff0c;Kali Linux基于Debian内核&#xff0c;虚拟机的操作系统选择Debian 7.x 64 选择系统…

【JAVA】用Java实现简易图书管理系统

【JAVA】用Java实现简易图书管理系统 1. 设计背景和系统功能和设计方法1.1设计背景1.2系统功能1.3设计方法 2. 设计思路3. 设计模块和代码实现3.1 Book类的实现3.2 BookList类的实现(书架)3.3 User类的实现&#xff08;用户类&#xff09;3.3.1 AdminUser&#xff08;管理员类&…

家用洗地机好用吗?值得推荐的家用洗地机

谁说家务苦差事&#xff1f;现在有了洗地机&#xff0c;家庭清洁变得更加简单、快捷、干净&#xff0c;让您轻松应对家庭日常清洁的要求。洗地机采用先进的技术&#xff0c;自动感应地面脏污&#xff0c;智能调节出水量和吸力&#xff0c;不仅能够保持地面清洁&#xff0c;更能…

深入理解MapReduce:使用Java编写MapReduce程序【上进小菜猪】

&#x1f4ec;&#x1f4ec;我是上进小菜猪&#xff0c;沈工大软件工程专业&#xff0c;爱好敲代码&#xff0c;持续输出干货。 MapReduce是一种用于处理大规模数据集的并行编程模型。由于其高效性和可扩展性&#xff0c;MapReduce已成为许多大型互联网公司处理大数据的首选方…

隐语v0.8.2版本更新,首次发布TEEU

隐语v0.8.2版本更新&#x1f31f; 应用层 机器学习&#xff1a; - MPC 纵向 LR &#xff08;SSRegression&#xff09;新增 Policy SGD 优化器和 Early Stopping 支持&#xff0c;减少调参成本&#xff0c;加快收敛速度&#xff1b; - WOE 分箱进行了若干优化&#xff0c;性…

HR SaaS市场竞争火热,肯耐珂萨缘何持续领跑? |爱分析调研

摘要&#xff1a; 中国人力资源数字化市场规模快速增长&#xff0c;各路厂商云集&#xff0c;呈现百花齐放的态势。作为人力资源管理一体化云解决方案的龙头服务商&#xff0c;肯耐珂萨坚定执行价值导向的差异化竞争策略&#xff0c;15年引领行业创新&#xff0c;依托行业领先方…

linux下的Qt打包常见原因分析和雷区,获取一键式打包脚本(能避免各种问题)

目录 一. 大致如下常见问题&#xff1a; &#xff08;1&#xff09;找不到程序所依赖的Qt库 version Qt_5 not found (required by &#xff08;2&#xff09;Could not Load the Qt platform plugin "xcb" in "" even though it was found &#xff0…

64/32位Linux系统的地址空间布局对比分析

Ubuntu从17.10开始不再官方支持32位(i386)架构&#xff08;严格的说是从18.04开始的&#xff0c;因为17.10不支持32位的PC版&#xff0c;但是支持32位的SERVER版&#xff0c;但是偶数稳定版确实是从18.04开始的)&#xff0c;只支持64位(amd64)架构&#xff0c;这是因为随着时间…

为什么ChatGPT用强化学习而非监督学习?

为什么ChatGPT非得用强化学习&#xff0c;而不直接用监督学习&#xff1f;原因不是那么显而易见。在上周发布的《John Schulman&#xff1a;通往TruthGPT之路》一文中&#xff0c;OpenAI联合创始人、ChatGPT主要负责人John Schulman分享了OpenAI在人类反馈的强化学习&#xff0…

去阿里面试,面试前20分钟突然要求候选人展示过去的工作方案,候选人拒绝后,竟被取消面试!...

离职时&#xff0c;你会把自己的工作成果拷贝下来留档吗&#xff1f; 一位网友说&#xff1a; 面试阿里&#xff0c;面试前20分钟&#xff0c;面试官突然要求他展示过去的工作成果&#xff0c;因为之前是用公司电脑&#xff0c;离职时把电脑交上去了&#xff0c;没有任何留档&a…

AE(自动编码器)与VAE(变分自动编码器)的区别和联系?

他们各自的概念看以下链接就可以了&#xff1a;https://blog.csdn.net/weixin_43135178/category_11543123.html 这里主要谈一下他们的区别&#xff1f; 先说结论&#xff1a; VAE是AE的升级版&#xff0c;VAE也可以被看作是一种特殊的AEAE主要用于数据的压缩与还原&#xff0…

redisson中的分布式锁解读

概述 Redisson是一个在Redis的基础上实现的Java驻内存数据网格&#xff08;In-Memory Data Grid&#xff09;。它不仅 提供了一系列的分布式的Java常用对象&#xff0c;还提供了许多分布式服务。其中包括(BitSet, Set, Multimap, SortedSet, Map, List, Queue, BlockingQueue,…

【电机应用控制】——FOC基础理论针对无刷电机360°无死角磁场矢量控制

目录 前言 一、FOC简介 1、概述 2、框图详解 二、FOC控制核心—坐标变换 1、CLARKE变换 2、PARK变换&反变换 三、FOC闭环回路 四、SVPWM解析 总结 前言 声明&#xff1a;学习笔记来自正点原子B站教程&#xff0c;根据自己理解进行精简总结&#xff0c;仅供学习…

『python爬虫』16. 多线程与多进程(保姆级图文)

目录 多线程1. 什么是多线程&#xff1f;2. 串行模式3. 多线程3.1 多线程方法写法3.2 多线程方法带参数3.3 多线程类写法 多进程1. 什么是多进程 欢迎关注 『python爬虫』 专栏&#xff0c;持续更新中 欢迎关注 『python爬虫』 专栏&#xff0c;持续更新中 多线程 1. 什么是多…

优化Docker Compose日志输出,加速容器化应用的轻松部署

摘要&#xff1a; 在使用 Docker Compose 部署容器化应用程序时&#xff0c;优化日志输出对于提升效率和管理便利性至关重要。本文将介绍如何优化 Docker Compose 日志输出&#xff0c;以加速容器化应用的轻松部署过程。 优化操作 当我们使用 Docker Compose 部署容器化应用程…