MySQL主从复制原理和使用

MySQL主从复制原理与实践:从配置到故障监控 上文《MySQL数据被误删怎么办?介绍了MySQL在故障或者误删数据后,可以通过备份+binlog的方式进行数据恢复。但是,当备份文件和binlog都丢失了呢?所以单节点是不可靠的,为了避免单节点故障带来的数据丢失以及MySQL服务的可用性,生产环境通常都是采用高可用或者集群模式。而在这背后则离不开主从复制技术,所以本文对主从复制的原理和操作展开介绍,从而全面了解这一技术。不管是备份恢复还是主从复制,其目的都是为了提高MySQL的可靠性、可用性等。 阅读详情

概述

实际生产的过程中为了实现数据库的高可用,不会只有一个数据库节点。至少会搭建主从复制的数据库架构,从库可以作为主库的数据备份,以免主数据库损坏的情况下丢失数据;当访问量增加的时候可以作为读节点承担部分流量等。下面就进行从零开始搭建MySQL的主从架构。

主从复制原理

以MySQL一主两从架构为为例,也就是一个master节点下有两个slave节点,在这套架构下,写操作统一交给master节点,读请求交给slave节点处理。

为了保证master节点和slave节点数据一致,在master节点写入数据后,会同时将数据复制到对应的slave节点。主从复制数据的过程中会用到三个线程,master节点上的binlog dump线程,slave节点的I\O线程和SQL线程。

主从复制的核心流程:

  1. 当master节点接收到一个写请求时,这个写请求可能是增删改操作,此时会把写请求的操作都记录到binlog日志中。
  2. master节点会把数据赋值给slave节点,如图中的两个slave节点。这个过程首先得要每个slave节点连接到master节点上,当slave节点连接到master节点上时,master节点会为每一个slave节点分别创建一个binlog dump线程,用于向每个slave节点发送binlog日志。
  3. 此时,binlog dump线程会读取master节点上的binlog日志,然后将binlog日志发送给slave节点上的I/O线程。
  4. slave几点上的I/O线程接收到binlog日之后,会将binlog日志先写入到本地的relaylog中,relaylog中就保存了master的binlog日志。
  5. 最后,slave节点上的SQL线程会读取relaylog中的biinlog日志,将其解析成具体的增删改操作,把这些在master节点上进行过的操作,重新在slave节点上也重做一遍,打到数据还原的效果,这样就可以保证master节点和slave节点的数据一致性了。

主从复制模式

MySQL的主从复制模式分为:全同步复制,异步复制,半同步复制,增强半同步复制。

  • 全同步复制

全同步复制,就是当主库执行完一个事物之后,要求所有的从库也都必须执行完该事务,才可以返回处理结果给客户端;因此虽然全同步复制数据一致性得到保证了,但是主库完成一个事物需要等待所有从库也完成,性能就比较低了。

  • 异步复制

异步复制,当主库提交事务后会通知binlog dump线程发送binlog日志给从库,一旦binlog dump线程将binlog日志发送给从库之后,不需要等到从库也同步完成事务,主库就会讲处理结果返回给客户端。

因为主库只管自己执行完事务,就可以将处理结果返回给客户端,而不用关系从库是否执行完事务,这就可能导致短暂的主从数据不一致的问题了,比如刚在主库插入的数据,如果马上在从库查询就可能查询不到。

当主库提交食物后,如果宕机挂掉了,此时可能binlog还没来得及同步给从库,这时候如果为了回复故障切换主从节点的话,就会出现数据丢失的问题,所以异步复制虽然性能高,但数据一致性上是比较弱的。

MySQL默认采用的是异步复制模式。

  • 半同步复制

半同步复制就是在同步复制和异步中做了折中选择,我们可以结合着MySQL官网来看下是半同步和主从复制的过程。

当主库提交事务后,至少还需要一个从库返回接收到binlog日志,并成功写入到relaylog的消息,这个的时候,主库才会讲处理结果返回给客户端。

相比前两种复制方式,半同步复制较好地兼顾了数据一致性以及性能损耗的问题。

同时,半同步复制也存在以下几个问题:

  1. 半同步复制的性能,相比异步复制而言有所下降,因为需要等到等待至少一个从库确认接收到binlog日志的响应,所以新能上是有所损耗的。
  2. 主库等待从库响应的最大时长我们是可以配置的,如果超过了我们配置的事件,半同步复制就会变成异步复制,那么,异步复制的问题同样也就出现了。
  3. 在MySQL5.7.2之前的版本中,半同步复制存在幻读问题。当主库成功提交事务并处于等待从库确认的过程中,这个时候,从库都还没来得及返回处理结果给客户端,但因为主库存储引擎内部已经提交事务了,所以,其他客户端是可以到主库中读到数据的。但是,如果下一秒主库宕机,下次请求过来只能读取从库,因为从库还没有从主库同步数据,所以从库中读取不到这条数据了,和上一次读取数据的结果相比,就造成了幻读的现象。

  • 增强半同步复制

增强半同步复制是MySQL5.7.2后的版本对半同步复制做的一个改进,原理几乎是一样的,主要是解决幻读的问题。

主库配置了参数rpl_semi_sync_master_wait_point=AFTER_SYNC后,主库在存储引擎提交事务前,必须先首都哦啊从库数据同步完成的确认信息后,才能提交事务,以此来解决幻读问题。

主从同步实战

  • 准备数据源

config/datasource.properties

# masters
spring.datasource.masters.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.masters.url=jdbc:mysql://192.168.1.111:3306/monomer_order?useUnicode=true&characterEncoding=utf8&useSSL=false&autoReconnect=true&zeroDateTimeBehavior=convertToNull
spring.datasource.masters.username=root
spring.datasource.masters.password=123456
​
# slaves
spring.datasource.slaves[0].driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.slaves[0].url=jdbc:mysql://192.168.1.112:3306/monomer_order?useUnicode=true&characterEncoding=utf8&useSSL=false&autoReconnect=true&zeroDateTimeBehavior=convertToNull
spring.datasource.slaves[0].username=root
spring.datasource.slaves[0].password=123456

  • 配置数据源
package com.xinxin.order.context.config;
​
import com.alibaba.druid.pool.DruidDataSourceFactory;
import lombok.Data;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.*;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.util.CollectionUtils;
​
import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
​
@Slf4j
@Data
@Configuration
@PropertySource("classpath:config/datasource.properties")
@ConfigurationProperties(prefix = "spring.datasource")
public class DataSourceConfig {
    /**
     * 主库数据源信息
     */
    private Map<String, String> masters;
    /**
     * 从库数据源信息
     */
    private List<Map<String, String>> slaves;
​
    @SneakyThrows
    @Bean
    public DataSource masterDataSource() {
        log.info("masters:{}", masters);
        if (CollectionUtils.isEmpty(masters)) {
            throw new Exception("主库数据源不能为空");
        }
        return DruidDataSourceFactory.createDataSource(masters);
    }
​
    @SneakyThrows
    @Bean
    public List<DataSource> slaveDataSources() {
        if (CollectionUtils.isEmpty(slaves)) {
            throw new Exception("从库数据源不能为空");
        }
        final ArrayList<DataSource> dataSources = new ArrayList<>();
        for (Map<String, String> slaveProperties : slaves) {
            log.info("slave:{}", slaveProperties);
            dataSources.add(DruidDataSourceFactory.createDataSource(slaveProperties));
        }
        return dataSources;
    }
​
    @Bean
    @Primary
    @DependsOn({"masterDataSource", "slaveDataSources"})
    public DataSource routingDataSource(@Qualifier("masterDataSource") DataSource masterDataSource,
                                        @Qualifier("slaveDataSources") List<DataSource> slaveDataSources) {
        final Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put(DataSourceContextHolder.MASTER, masterDataSource);
        for (int i = 0; i < slaveDataSources.size(); i++) {
            targetDataSources.put(DataSourceContextHolder.SLAVE + i, slaveDataSources.get(i));
        }
        final DataSourceRouter dataSourceRouter = new DataSourceRouter();
        dataSourceRouter.setTargetDataSources(targetDataSources);
        dataSourceRouter.setDefaultTargetDataSource(masterDataSource);
        return dataSourceRouter;
    }
​
    @Bean
    public DataSourceTransactionManager dataSourceTransactionManager(
            @Qualifier("routingDataSource") DataSource routingDataSource) {
        return new DataSourceTransactionManager(routingDataSource);
    }
}

  • 数据源上下文切换
package com.xinxin.order.context.config;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

@Slf4j
public class DataSourceContextHolder {
    public static final String MASTER = "master";
    public static final String SLAVE = "slave";

    private static ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();

    public static void setDatasourceType(String dataSourceType) {
        if (StringUtils.isBlank(dataSourceType)) {
            log.error("dataSourceType为空");
        }
        log.info("设置dataSource: {}", dataSourceType);
        CONTEXT_HOLDER.set(dataSourceType);
    }

    public static String getDataSourceType() {
        return CONTEXT_HOLDER.get() == null ? MASTER : CONTEXT_HOLDER.get();
    }

    public static void remove() {
        CONTEXT_HOLDER.remove();
    }
}

  • 数据源路由实现类
package com.xinxin.order.context.config;
​
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
​
@Slf4j
public class DataSourceRouter extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        log.info("当前数据源为: {}", DataSourceContextHolder.getDataSourceType());
        return DataSourceContextHolder.getDataSourceType();
    }
}

  • 数据源切换注解
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ReadOnly {
    String value() default DataSourceContextHolder.MASTER;
}

  • 动态数据源切换切面
package com.xinxin.order.aspect;

import com.xinxin.order.annotation.ReadOnly;
import com.xinxin.order.context.config.DataSourceContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

@Slf4j
@Aspect
@Component
public class DynamicDataSourceAspect implements Ordered {

    @Before(value = "execution(* *(..))&& @annotation(readOnly)")
    public void before(JoinPoint joinPoint, ReadOnly readOnly) {
        log.info(joinPoint.getSignature().getName() + "走从库");
        DataSourceContextHolder.setDatasourceType(DataSourceContextHolder.SLAVE);
    }

    @After(value = "execution(* *(..))&& @annotation(readOnly)")
    public void after(JoinPoint joinPoint, ReadOnly readOnly) {
        log.info(joinPoint.getSignature().getName() + "清除数据源");
        DataSourceContextHolder.remove();
    }

    @Override
    public int getOrder() {
        return 0;
    }
}

总结

项目整合读写分离主要是通过收到注入数据源,并通过拦截器设置当前线程的数据源类型,需要使用数据源的地方会通过数据源路由器读取当前线程的数据源类型后返回实际的数据源进行数据库的操作。

KIBANA可视化管理界面说明 更说明转自https://blog.youkuaiyun.com/IT_ZRS/article/details/125496588 1 主要结构功能 使用浏览器访问 ip:5601 默认端口,进入首页 Discover:日志管理视图 主要进行搜索和查询 Visualize:统计视图 构建可视化的图表 Dashboard:仪表视图 将构建的图表组合形成图表盘 Timelion:时间轴视图 随着时间流逝的数据 APM:性能管理视图 应用程序的性能管理系统 Canvas:大屏展示 阅读详情

相关推荐

恶意代码实验3:Word宏病毒实验

只要下次打开这个word文档,就会执行以上代码,并将自身复制到Normal.dot(word文档的公共模板)和当前文档的ThisDocument中,同时改变函数名(模板中为Document_Close,当前文档为Document_Open),此时所有的word文档打开和关闭时,都将运行以上的病毒代码,可以加入适当的恶意代码,影响word的正常使用,本例中只是简单的跳出一个提示框。回答不正确三次,即可自动跳出病毒程序,但那时已经出现几十个文档。1、打开的宏编辑器如图所示,即可编写病毒代码。

qq_63949327的博客 6507

【第七篇】MySQL主从复制原理详解【重点】

1.1 简介 小公司业务代码一般存于一个服务器上,而这个服务器有的时候可能会宕机,导致业务停顿,造成不必要的影响。这个时候就需要做高可用,比如两个ngix+两个tomcat+两个mysql实现高可用,避免单点问题。 主从复制: 指一台服务器充当主数据库服务器,另一台或多台服务器充当从数据库服务器,主服务器中的数据自动复制到从服务器之中。对于多级复制,数据库服务器即可充当主机,也可充当从机。MySQL主从复制的基础是主服务器对数据库修改记录二进制日志,从服务器通过主服务器的二进制日志自动执行更新。 1.

ᶻᶻᶻ 枕星河的博客 1656

通信系统原理[郭宇春]——模拟调制系统——课后习题答案

通信系统原理[郭宇春]——第三章课后习题答案,出错望指正!

尧呱呱的博客 3844

MySQL主从复制原理

1. 数据库主从概念、优点、用途 主从数据库是什么意思呢,主是主库的意思,从是从库的意思。数据库主库对外提供读写的操作,从库对外提供读的操作。数据库为什么需要主从架构呢? 高可用,实时灾备,用于故障切换。比如主库挂了,可以切从库。 读写分离,提供查询服务,减少主库压力,提升性能 备份数据,避免影响业务。 2. 数据库主从复制原理 主从复制原理,简言之,分三步曲进行: 主数据库有个 bin ...

牛奔的博客 7809

磁悬浮轴承控制策略设计及性能对比

摘要:针对高速磁悬浮转子控制问题,本文提出多方案对比分析。建立含陀螺效应的5自由度动力学模型,分析陀螺耦合、质量不平衡等关键挑战。对比四种控制策略:基础PID解耦、交叉反馈+自适应陷波、H∞鲁棒+前馈补偿、滑模控制+观测器,从实时性、鲁棒性等维度评估优劣。推荐采用交叉反馈+H∞+自适应陷波的混合方案,通过内环电流环与外环位置环协同,实现陀螺效应动态解耦和扰动抑制。实施步骤包括系统辨识、控制器设计、硬件部署等,需配合实验验证与参数整定。该方案综合性能最优,适用于高转速、强扰动场景。

技术工作者 1776

openEuler 22.03 LTS SP4离线安装UKUI桌面全攻略(附依赖包下载)

本文提供openEuler 22.03 LTS SP4系统离线安装UKUI桌面环境的完整实战指南。针对无网络环境,详细解析了利用dnf工具下载依赖包、配置离线软件源、处理依赖冲突及安装后优化的全流程,并附带了关键依赖包资源,帮助运维人员高效完成图形化部署。

c7d8e9的博客 483

MySQL 数据库主从复制的基本原理和步骤

详细介绍了MySQL主从复制的原理和基本流程,以及一些问题的处理方式。

终生学习践行者 4467

手把手教你用GEM-2多频电磁仪找地下管道(附真实数据图)

本文详细解析了使用GEM-2多频电磁仪精准定位地下管线的全流程,包括设备调试、频率选择、现场扫描技巧及数据解读。通过真实案例展示了如何应对复杂干扰环境,提升管线检测效率与准确性,特别适合市政工程和地下管线普查。

weixin_42565652的博客 402

如何使用MySQL进行主从复制

如何使用MySQL进行主从复制

han1725692339的博客 1万+

基于机器学习和辐射传输的地表温度模拟方法对比

对于不同的地表类型和不同的年份,经验方法是实用的,虽然整体精度不如物理方法,但具有计算速度快、对模型内部结构考虑较少等优点。尽管深度学习等回归的经验方法不需要考虑辐射传输和能量平衡的具体过程, 但在其输入参数的选择上也不能是无序和随机的,而是应选择有关相应物理过程的参数。经验方法在处理不同年份相同地表类型或表现相对较好, RMSE 约为 1.50K,但在不同地表类型且不同年份模拟结果较差, RMSE 约为 3.0K, 虽然精度不如物理方法,但它具有计算速度快,不需过多考虑模型内部结构的优点。

2301_77907355的博客 1023

荣耀Magic 6 dToF LiDAR Android阵营全球第一首发

40X30分辨率的BSI SPAD小面阵,帧率达到60帧,搭配多传感器融合算法, 可产生足够的稠密点云,为应用设备提供可靠的距离传感。在手机消费电子方案中,dToF LiDAR技术不仅提升了手机的功能和用户体验,还为手机厂商提供了差异化的竞争优势。随着技术的不断进步和市场的快速发展,我们可以期待未来dToF LiDAR技术将在手机领域发挥更大的作用,为用户带来更多创新和便捷的功能。增强现实(AR)体验:通过dToF LiDAR提供的高精度深度信息,手机可以更准确地放置虚拟物体在现实世界的表面上。

致力于lidar应用开发 19万+

MySQL主从复制-原理-实现

MySQL主从复制是一个异步的复制过程,底层是基于Mysql数据库自带的 二进制日志 功能。就是一台或多台MySQL数据库(slave,即从库)从另一台MySQL数据库(master,即主库)进行日志的复制,然后再解析日志并应用到自身,最终实现 从库 的数据和 主库 的数据保持一致。MySQL主从复制是MySQL数据库自带功能,无需借助第三方工具。

qq_45779998的博客 3687

4、教育数据挖掘:公共数据集与研究进展

本文综述了教育数据挖掘(EDM)领域的研究进展与公共数据集应用情况。从2013年至2020年,EDM在电子学习系统、大规模开放在线课程(MOOC)等方面快速发展,涵盖了多种研究任务、工具与方法。文章梳理了UCI、Mendeley、DataShop等平台的公开数据集,分析了其特点与局限性,并介绍了KDD Cup、Kaggle等竞赛中的教育数据集及其评价指标。同时,探讨了多模态、心理行为等特色数据集的应用场景。最后指出当前EDM面临的主要挑战是缺乏系统性数据集综述、数据预处理复杂及可重复性不足,呼吁加强数据共享

rgv2345678的博客 171

【MySQL】主从复制实现原理详解

目录 一、概要 1.1 mysql复制的优点 1.2 Mysql复制解决的问题 二、MySQL 主从复制的概念 三、MySQL 主从复制的主要用途 3.1 读写分离 3.2 数据实时备份,当系统中某个节点发生故障时,可以方便的故障切换(主从切换) 3.3 高可用(HA) 3.4 架构扩展 四、MySQL 主从形式一主一从 4.1 一主多从 4.2 多主一从 (从5.7开始...

小七的博客 1万+

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

MySql主从复制原理

1、什么是主从复制?概念 主从复制是用来建立一个和 主数据库完全一样的数据库环境称为从数据库;主数据库一般是准实时的业务数据库。2、主从复制作用我们来思考如果在企业网站中,后端MYSQL数据库只有一台时候,会有以下问题:1、单点故障服务不可用2、无法处理大量的并发数据请求3、数据丢失所以通过主从复制后,它的优点就很明显1、如果主节点出现故障,那么我们就直接将服务切到从节点,来保证服务立马可用。2、如果并发请求特别大的时候,我们可用进行读写分离操作,让主库负责写,从库负责读。

qq_37436172的博客 3638

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

MySQL主从复制的原理

MySQL主从复制原理

m0_68642284的博客 1122

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Redis与MySQL主从复制原理解析

主从复制是一种常用的数据冗余和负载均衡技术。无论是缓存系统Redis还是关系型数据库MySQL,都广泛应用了主从复制技术。MySQL的主从复制(Master-Slave Replication)是一种数据库同步技术,它允许将一个MySQL数据库服务器(称为主服务器或master)的数据复制到一个或多个MySQL数据库服务器(称为从服务器或slave)上。

2303_76892351的博客 1676

mysql的主从复制原理和配置

 1.mysql基于binlog的主从复制原理:      1. master将操作记录到二进制日志(binary log)中(这些记录叫做二进制日志事件,binary log events)   2. Slave通过I/O Thread异步将master的binary logevents拷贝到它的中继日志(relay log);   3. Slave执行relay日志中的事件,匹配自己...

King__Jack的博客 596

MySQL主从复制原理(原理+实操)

主从复制简介 在实际的生产中,为了解决Mysql的单点故障已经提高MySQL的整体服务性能,一般都会采用「主从复制」。 比如:在复杂的业务系统中,有一句sql执行后导致锁表,并且这条sql的的执行时间有比较长,那么此sql执行的期间导致服务不可用,这样就会严重影响用户的体验度。 主从复制中分为「主服务器(master)「和」从服务器(slave)」,「主服务器负责写,而从服务器负责读」,Mysql的主从复制的过程是一个「异步的过程」。 这样读写分离的过程能够是整体的服务性能提高,即使写操作时间比较长,也不影

qq_40907977的博客 5458

mysql之主从复制原理及实践

在现代数据库管理中,数据的高可用性和负载均衡是至关重要的。MySQL 的主从复制功能提供了一种有效的解决方案,可以通过将数据从一个主服务器复制到一个或多个从服务器,来实现数据的备份、读取负载分担和高可用性。的值替换为实际的主实例 IP 地址、端口号、同步用户及其密码,以及在主实例中通过。在 MySQL 控制台中,创建一个用于数据同步的专用用户,确保该用户具备。登录 MySQL 后,使用以下命令配置从实例连接到主实例。用户即可用于从实例的数据同步连接,接下来可以继续配置从实例。

qq_38917476的博客 2605

MySQL主从复制原理与延迟

MySQL主从复制是实现高可用数据库架构的关键技术,其原理是通过主库的Binlog Dump线程将数据变更发送到从库,从库的I/O线程写入relay log后由SQL线程重放。主从延迟的根本原因是主库多线程写入与从库单线程重放的性能差异,常见于大事务、DDL操作、网络瓶颈等场景。解决方案包括架构优化(分库分表、多级复制)、配置调优(并行复制、硬件升级)以及应用层适配(读写分离、事务拆分)。监控指标如Seconds_Behind_Master和复制位点对比可有效评估延迟情况。

m0_66884848的博客 984

MySQL主从复制原理是什么

MySQL 主从复制是一种非常灵活的高可用和扩展性方案,它通过将主库的更改记录同步到从库,实现了读写分离、数据备份和高可用性。虽然复制机制相对简单,但也需要仔细监控和维护以确保数据一致性和系统性能。

u012534547的博客 1251

MySQL主从复制原理及配置

1、什么是主从复制 2、主从复制原理 主从复制配置:1、主服务器数据库配置 2、从服务器数据库配置

m0_58784959的博客 671

mysql主从复制原理详解_深入研究MySQL(三)、主从复制原理及演示

一、主从复制概述这章来说说主从复制,对于主从复制,有很多知识,在以后分篇记录,所以在这里只说说简单的用法,用来入个门可以,先说啥是主从复制,主从复制就是将一台主机的数据复制到另一台或者多台主机上,复制过程中一台服务器充当主库(Master),就是源数据存放的主机,还有一台或者多台服务器充当从库(Slave),Mysql支持单向、双向、链式级联、异步复制,还有在5.5版本后的半同步复制等。...

weixin_39815031的博客 143
上一篇: 策略模式:【利于扩展,消除if的模式】
下一篇: Java实现常用的三种加密算法详解
Java技术那些事儿
博客等级 码龄5年 2306粉丝 2584原创
评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值