消息队列

一文了解消息队列MQ(超详细+干货满满) 阅读详情
  • 如何保证消息不丢失?
  • 如何处理重复消息?
  • 如何保证消息的有效性?
  • 如何处理消息堆积?

什么是消息队列

消息队列就是进程之间或者线程之间用来通信的一个队列组件,也就是我们常说的消息中间件,但是它的存在并不仅仅只是为了解决通信的问题。

为什么需要消息队列

因为互联网的快速发展,业务不断扩展,导致由以前的单体架构升级到现在的微服务架构,很多服务之间相互调用依赖,所以我们需要消息队列来进行服务之间的解耦、控制资源合理使用以及缓冲流量洪峰等等。

前面刚说过,消息队列的存才并不仅仅为了解决通信的问题,更重要的,它主要是用来实现异步处理、服务解耦、流量控制。

异步处理

随着业务的不断扩展,你会发现请求链路越来越长,请求链长了,响应速度也就慢了,所以需要用消息队列实现异步处理,从而减少处理请求的等待时间,让服务异步并发处理,提升系统的总体性能。

在这里插入图片描述

服务解耦

看上面的例子,订单服务下游还有短信服务和积分服务,如果现在还要加营销服务和数据分析服务,甚至更多的服务,为了迎合下游服务的改动,订单服务需要经常修改,这订单服务项目组也太难受了吧!
所以就需要使用消息队列来进行对服务之间关系的解耦,订单服务把相关信息放到消息队列里面,下游的服务谁需要谁就订阅订单服务主题,这样订单服务项目组就会轻松很多了啦!

在这里插入图片描述

流量控制

在并发量级很大的情况下,比如秒杀活动爆发式的流量打入后台,后台很可能会顶不住,所以就需要一个中间件,先将请求全部放入消息队列,然后后台尽自己最大的能力去处理消息队列中的请求,等待超时的请求可以直接返回错误。这种就属于生产者生产过快的情况。

有一些请求不需要实时响应,但是业务复杂度很高,逻辑流程链很长,如果实时处理需要耗费很多时间。那么就可以将请求放入消息队列,然后后台服务根据自己的节奏对消息队列中的请求进行处理。何种就属于消费者消费过慢的情况。

上面这两种情况,消息队列都可以在其中发挥很好的缓冲作用。

在这里插入图片描述

消息队列的两种模型

队列模型

生产者向队列中发送消息,一个队列可以有多个生产者生产的消息,也可以有多个消费者,但是每个消费者之间存在竞争关系,每一条消息只能由一个消费者消费。
在这里插入图片描述

发布/订阅模型

如果想让一条消息被多个消费者消费,该怎么办呢?那么发布/订阅模式派上用场了,该模型是将一个消息发布到主题(topic)中,所有订阅了这个主题的消费者都可以消费这个主题的消息。
在这里插入图片描述
注:这里所说的一条消息被多个消费者消费,有一个前提,这多个消费者不属于同一个消费组,同一个消息只能由同一个消费组中的某一个消费者去消费,这里说的多个消费者消费同一个消息,是因为可以有多个消费组都订阅了这个主题,消费组的概念,下面会讲到。

比如说QQ,发布/订阅模型就相当于我跟你都加入了同一个群聊,这个群里还有很多人,我在群里发一条消息,群里的所有人都可以看到这条消息。而队列模型就相当于我跟你私聊,我给你发了一条消息,只有你看得到,其他人是看不到的。

如果我用一个QQ给多个人私聊发同样的消息也可以实现一条消息被多个消费者接受,也就是用队列模型实现一个消息被多个消费者消费。可以让多个队列全量存储相同的信息,也就是数据的冗余可以实现一条消息被多个消费者消费。像我们常用的RabbitMQ就是使用队列模型,通过交换机(Exchange)来把消息发送给多个队列,从而以队列模型实现一条消息被多个消费者消费。

如果QQ群里面只有我们两个人,我给你发消息,只有你一个人接收的到,这种情况发布/订阅模型不就跟队列模型一样了。

小结

队列模型一条消息只能被一个消费者消费,发布/订阅模型一条消息可以被多个消费者消费。当然队列模型也可以通过把信息全量存储在多个队列中的方式来实现一条消息被多个消费者消费,但是会存在数据的冗余。

发布/订阅模型是兼容队列模型的,也就是只有一个消费者的情况下发布/订阅模型跟队列模型是一样的。

RabbitMQ采用队列模型,RocketMQ和Kafka采用的是发布/订阅模型。

生产者消费者模型

发送消息方叫做生产者(Producer),接收并消费消息方叫做消费者(Consumer),消息队列服务端是Broker。消息从Producer发送至Broker,Broker将消息存储在本地,然后Consumer从Broker中获取消息或者Broker把消息推送给Consumer,然后由Consumer消费消息。

在这里插入图片描述
为了提高并发度,发布/订阅模型还会存在队列和分区的概念,消息就是发送到一个主题(topic)下的某个队列或者某个分区的,RocketMQ中叫做队列,Kafka中叫做分区。

比如一个主题下面有5个队列,那么这个主题的并发度就是5,也就是同时可以有5个消费者并行消费该主题下的消息。一般可以采用轮询或者key hash取余的策略把同一个主题下的消息分配到不同的队列中。

消费者还有组的概念,也就是消费组(Consumer Group),所有的消费者都是属于某个消费组的,同一条消息会发送给订阅了这个主题的多个消费组。比如现在有两个消费组,Group 1和Group 2,他们都订阅了主题Topic a,此时有一条消息发送到了topic a,那么Group 1和Group 2都可以接收到这条消息。这条消息是写入Topic a中的某个队列的,消费组中会有一个消费者去消费这条消息。

每个消费组都会有自己的一个消费点(offset)来表示消费到的位置,在消费点之前的消息说明这个消息已经被同一个消费组下其他消费者消费过了,如果这个offset是队列级别的,每个消费组都会维护订阅的Topic下的每个队列的offset。来看张图吧!

在这里插入图片描述

如何保证消息不丢失

对于常见的消息队列,一般只要配置得当,是不会丢失消息的。先看看这个关系图:
在这里插入图片描述
一共有生产消息、存储消息、消费消息三个阶段,下面就以这三个阶段入手看看如何保证消息不丢失。

生产消息

生产者发送消息至Borker,需要对Broket的响应进行处理,不管是同步发送消息还是异步发送消息,都需要做好try-catch对Broket的响应做出妥善的处理,如果Broket返回写入消息失败等其他错误信息,生产者需要重新发送消息至Broket,如果多次发送失败则需要报警并且记录日志。这样可以保证消息在生产阶段不会丢失。

存储消息

存储消息阶段需要等待消息写入磁盘(消息刷盘)之后再给生产者做出相应。因为如果消息仅仅写入了内存就给生产者相应的话,这个时候如果断电导致机器停了,那么消息也就没了,但是生产者缺以为消息已经存储成功了。

如果Borket是集群部署,有多副本机制,那么消息不仅仅要写入当前Broket,还需要写入副本机器中,那么必须等待消息写入两台机器之后再给生产者做出相应,这样就可以保证消息在存储阶段不丢失了。

如果两台机器都挂了呢?那就加!三台!四台!五台!如果整个机房地震了,全挂呢咋办!先关心一下人有没有事好伐!这种情况,异地部署吧!没招!不要杠精说整个地球地震了咋办!

消费消息

消费者拿到消息之后,等他真正执行完逻辑之后,也就是处理完消息之后,再给Borket做出响应,如果在消费者刚拿到消息就做相应的话,消费者宕机了,那这消息就没了!这样就可以保证消息再消费阶段不会丢失了。

小结

保证消息不丢失,需要三方共同配合:

生产者需要做好对Borket相应的处理,异常处理、错误重试、报警机制、日志记录。

Broket需要把握好相应的时机,在单机情况下等待消息刷盘之后再做相应,集群部署多副本情况下,保证消息发送至两个以及以上副本的时候再做相应。

消费者需要真正处理完消息之后(完成所有业务逻辑处理)在给Broket进行相应。

注:以上这些操作,虽然是保证了消息的可靠性,保证了消息不丢失,但是程序性能会降低很多。

如何处理重复消息

上一个问题已经说过,为了保证消息不丢失,在生产消息阶段生产者需要等待Broket的响应,如果在Briket做出相应的时候,网络出现问题,导致生产者没有收到相应,那么生产者会再次重复发送,这样Broket中就会有两条重复的消息了!

再看消费消息阶段,如果一个消费者已经处理完了消息,业务逻辑已经处理完,事物也提交了,准备更新Consumer offset了,就在这时消费者挂了,也就是更新Consumer offset还没更新成功,所以此时另一个消费者还是会拿到刚才那条消息再重复执行一次,这就造成了消息重复消费!

从正常的业务流程来看,消息重复好像是不可避免的,因为我们总不能为了解决消息重复的问题又导致消息丢失的问题吧!那么我们换个角度去思考这个问题。既然我们不能避免消息的重复,那么我们就对因为消息重复带来的业务上面的影响进行处理,关键点就在于幂等。

什么叫做幂等
学过数学的都知道,这是一个数学的概念。但是在代码的角度来思考,何为幂等,其实我们可以这样简单理解,幂等就是使用同样的参数多次调用同一个接口和一次调用同一个接口执行结果是一样的、举个例子:

执行一条SQL语句:update table money = 100 where id = 1 and money = 50;
对于这条SQL语句,不管执行多少次,money的值都是100,这个就叫做幂等。

几个常用的实现幂等的套路

我们现在要做的,就是对业务逻辑进行改造处理,实现幂等,从而保证就算消息重复了也不会影响最终的结果。怎么做呢?常见的套路主要有以下这些:

  • 提交结果的时候,做一个前置的判断,就比如上面的money=50。
    加一个version,利用版本号机制,对比消息中的版本号和数据库中的版本号是否相等。
  • 使用数据库的约束列,比如唯一键。
  • 记录关键的key,比如保存订单处理数据的时候,如果有重复消息,就先判断一下这个ID的订单是否已经被处理过了,如果没有被处理过再进行后面的业务逻辑。

方法绝不仅仅只有这些,如何实现还是要看业务的具体细节,根据业务逻辑而定。

如何保证消息的有序性

有序性分为全局有序和部分有序。

全局有序

必须只有一个生产者往Topic中发送消息,并且Topic中只有一个队列(分区),消费者必须单线程消费这个队列(分区)中的消息,这样消息就是全局有序的,但是一般我们不需要全局有序。
在这里插入图片描述

部分有序

绝大多数时候我们都是使用部分有序,将Topic内部划分成我们指定数量的队列(分区),然后通过特定的策略将消息发送给指定的队列,然后每个队列对应一个单线程的消费者去消费队列中的信息,这样既可以实现消息的部分有序,还可以通过Topic中队列的数量提高并发处理消息的效率。
在这里插入图片描述
注:这里的生产者也可以是一个,只要根据特定策略将同类消息发送到指定队列即可。

如何处理消息堆积

消息堆积往往是因为生产者的生产能力和消费者的消费能力不匹配造成的,有可能是因为消费者消费消息出现错误反复重试导致,也有可能是消费者消费能力太弱导致。要解决消息堆积的问题,首先要确定消费慢的原因,如果是因为消费错误导致反复重试,那么就先解决代码中的bug。如果是因为消费者消费能力太弱,就对消息处理的业务逻辑代码进行优化,如果优化之后还是消费慢,那么就进行扩容,也就是增加Topic中队列的数量和消费者的数量。

注:增加一个消费者就必须增加一个队列,否则消费者是没有东西消费的,在同一个Topic中,一个队列只会分配给一个消费者。

【基础篇-消息队列】——为什么需要消息队列 本文探讨了消息队列的核心作用与应用场景。文章重点分析了消息队列的三大典型应用:1)异步处理,以秒杀系统为例说明如何提升响应速度;2)流量控制,介绍令牌桶等削峰填谷方法保护系统;3)服务解耦,通过订单系统案例说明如何降低模块间耦合度。同时也指出消息队列可能带来的延迟增加、系统复杂度提升等问题。文章强调架构设计需要权衡利弊,根据业务特点选择合适方案。 阅读详情

相关推荐

POSIX 消息队列

一、什么是 POSIX 消息队列?POSIX 消息队列 是一种用于进程间通信(IPC)的技术,它允许不同进程之间通过发送和接收消息来进行通信。POSIX 消息队列是基于 POSIX 标准的一部分,旨在提供跨平台的兼容性和一致性。通俗解释想象一下,你和你的朋友在不同的房间里,你们需要传递信息给对方。传统的做法可能是大喊大叫,但这种方式不太可靠。更好的方法是使用一个小盒子(消息队列),你们可以把信息写在纸上,放进这个盒子里。当你有信息要传递给你的朋友时,你可以把纸条放进盒子;

奋斗在路上的博客 1102

消息队列详解

文章目录1、什么是 MQ 1、什么是 MQ MQ 全称 Message Queue,也就是我们所说的消息队列。消息队列就是在消息的传输过程中保存消息的容器,多用于分布式系统之间进行通信。 RabbitMQ是流行的消息队列服务软件,是开源的AMQP(高级消息队列协议)实现。支持多种客户端,如:Java、Python、C、PHP、Ruby、JavaScript等,用于在分布式系统中存储转发消息,可以实现异步处理、流量削峰、系统解耦,在易用性、扩展性、高可用等方面表现优异。 RabbitMQ是程序员的必备技能,

悦.L的博客 2万+

RobotStudio码垛机器人创建过程

首先导入一个IRB2600机器人,移动夹具的本地坐标原点,使原点位置为顶面中心(与法兰盘连接的部位)。对齐夹爪Smart组件的本地坐标和机器人末端法兰盘的坐标...

个人博客 1万+

为什么需要使用消息队列

MQ简介 消息队列(MQ)是一种应用程序对应用程序的通信方法,应用程序通过队列进行通信,而不是通过直接调用彼此来通信,队列的使用除去了接收和发送应用程序同时执行的要求。是进行通信的中间件产品。(换言之:MQ负责两个系统之间传递消息,这两个系统可以是异构的,处于不同硬件、不同操作系统、用不同语言编写,只需要简单的调用几个MQ的API,就可以互相通讯,你不必考虑底层系统和网络的复杂性。MQ能够应付多种...

q89563848的博客 1982

动态数据脱敏技术分析

在当前国内信息安全热潮中,数据脱敏作为数据安全的重要一环得到了业界的认可与重视。早在2012年,数据脱敏首次作为一个单独的魔力象限由Gartner发布,Gartner在2014年又提出了:按照数据使用场景,将数据脱敏分为静态数据脱敏(Static data masking-SDM )与动态数据脱敏(Dynamic data masking-DDM )。 可能有人望文生义,认为动态数据脱敏一定比静态数据脱敏高级。非也非也,静态or动态,取决于脱敏的使用场景,主要是以使用场景为由来选择合适的数据脱敏的模式。 本

美创科技的博客 4666

随机森林模型及案例(Python)

1 集成模型简介 集成学习模型使用一系列弱学习器(也称为基础模型或基模型)进行学习,并将各个弱学习器的结果进行整合,从而获得比单个学习器更好的学习效果。 集成学习模型的常见算法有Bagging算法和Boosting算法两种。 Bagging算法的典型机器学习模型为随机森林模型,而Boosting算法的典型机器学习模型则为AdaBoost、GBDT、XGBoost和LightGBM模型。 1.1 Bagging算法简介 Bagging算法的原理类似投票,每个弱学习器都有一票,最终根据所有弱学习器的投

qq_42433311的博客 4万+

ucosiii 消息队列

我想要验证的是,当没生产一个消息,队列中都会有一个最高优先级的任务就绪,消息会不会被低优先级的任务拿走。(因为cli_Msg是模拟邮箱,只有一个消息的空间,监控他的空间大小意义不大)。然后我把所有xxxxPend函数获取消息后,把消息的内容修改为”is null“,运行后:disp.t1_str出现"is null x",这是我们不想要的结果。所以,还是老老实实地用申请堆上的空间,来存放发送的消息吧,发送前申请空间,xxxxPend周就立刻释放掉空间,而不是使用全局变量。:消息对列,被读走,就没了。

qq_62775800的博客 2258

别再为EPI形变头疼了!FSL的topup+eddy实战保姆级教程(含AP/PA数据采集要点)

本文详细介绍了如何使用FSL的topup和eddy工具解决EPI形变问题,包括数据采集要点、参数设置和实战操作步骤。通过AP/PA双编码数据和精确的形变场估计,有效矫正MRI图像中的几何畸变,提升弥散数据质量。特别适合需要处理高场强MRI数据的研究人员和技术人员。

weixin_28725949的博客 399

POSIX消息队列与System V消息队列

是一个结构体,用于描述当消息队列中有新消息时,如何通知进程。:通知方法,取值如下:SIGEV_NONE:不发送任何通知。:发送一个信号事件发生时,将sigev_signo指定的信号发送给指定的进程;:事件发生时,内核会(在此进程内)以sigev_notify_attributes为线程属性创建一个线程,并让其执行sigev_notify_function,并以sigev_value为其参数:当为时,指定要发送的信号。:通知时传递的数据,类型为。:当为时,指定的线程函数。:当为。

v13111329954的博客 1970

【系统分析师】2009年真题:综合知识-答案及详解

在某银行业务的用例模型中,“取款”用例需要等到“存款”用例执行之后才能执行,两个用例之间的关系属于(1);“取款”和“存款”两个用例中都需 要执行查询余额的功能,将查询余额提取成独立的用例,那么“取款”和“存款” 用例与“查询余额”用例之间的关系属于(2)。(1)A. 关联关系 B. 扩展关系 C. 使用关系 D. 依赖关系 (2)A. 扩展关系 B. 使用关系 C. 依赖关系 D. 继承关系【参考答案】D、A雇员类含有计算报酬的行为,利用面向对象的(3),可以使得其派生类专职 雇员类和兼职雇员类计算报酬的

数据知道的博客 1万+

18、Excel VBA编程:自定义函数创建与代码调试全攻略

本文详细介绍了Excel VBA中自定义函数的创建方法,以获取单元格注释为例演示了完整开发流程,并深入讲解了代码调试的重要性与核心工具。内容涵盖三种主要错误类型及其应对策略,系统介绍了调试工具栏、断点、逐行执行、Locals窗口、Immediate窗口等实用功能。通过综合案例展示了如何运用调试技术解决实际问题,并总结了提前规划、逐步测试、日志记录等最佳实践,帮助读者提升VBA编程效率与代码质量。

life6的博客 100

什么是消息队列?

消息队列MQ的主要作用:异步处理,应用解耦,流量削锋和消息通讯

大道至简,持之以恒! 5105

YOLOv26详解 | 一文带你从代码角度深入理解ultralytics最新作品yolov26的创新 | 训练、推理、验证、导出 (附网络结构图PPT可用,全网最全)

YOLOv26带来多项创新:1)采用双检测头机制(One-to-Many和One-to-One)实现端到端无NMS推理;2)移除DFL简化边界框回归;3)引入ProgLoss+STAL优化小目标检测;4)使用MuSGD优化器提升训练稳定性。网络结构方面,SPPF模块增加shortcut连接,并在C3k2中引入PSABlock注意力机制。该版本更注重实际部署,简化了推理流程,提升硬件兼容性。教程涵盖模型训练、验证、推理及导出全流程,支持多种格式转换如ONNX、TensorRT等,适合工业应用场景。

Snu77的博客 4061

【消息队列】认识消息队列

生产者消费者模型固然很好,要如何实现呢?此时消息队列就是对生产者消费者模型思想的其中一种实现方式! > 消息队列(Message Queue)是一种在分布式系统中用于组件间通信的技术。它允许应用程序通过发送和接收消息来进行异步通信。逐渐成为解决系统间通信、解耦和负载均衡的重要工具。 概念不好理解很正常,随着你往下看,便能拨开云雾见光明了。 既然叫做消息队列,首先必须得理解什么是消息队列,在数据结构阶段的学习中,肯定学到了一种数据结构叫做队列,队列是一种先进先出的结构,那什么是消息呢?就拿我们常用的通讯

程序猿教你打篮球的博客 6918

QCC304x系列开发教程(基础篇)之2.1-QCC3040之开发环境搭建

一、安装MDE 1.解压qualcomm_mde.win.2.4_installer_2.4.1.4压缩包,安装MDE_WIN_2.4.1.4_x64.exe,路径自定义 点击NEXT, 安装完成后,点击Finish. 完成安装后,桌面生成快捷方式

心跳包的博客 6076

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

消息队列和分布式消息队列

存储消息的队列。存储:存数据消息:某种数据结构。比如字符串,对象,二进制数据,JSON等等队列:先进先出的数据结构。

诨号无敌鸭的博客 1647

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

【MQ01】什么是消息队列?用哪个消息队列?

什么是消息队列?用哪个消息队列?来了来了,消息队列系列总算来咯。对于搜索引擎相关的知识大家消化的怎么样呀?其实对于搜索引擎来说,我们学习的内容还是挺全面的,也算是比较深入了。而对于消息队列来说,我不准备写得太深入,因为对于这个东西,实战并不算多,主要的原因咱们在今天这篇文章结束的时候再详细的来说吧。先来说概念,到底啥是消息队列?那么多种消息队列工具,或者叫消息队列中间件,我们应该选择哪个呢?我将以...

硬核项目经理 1236

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Linux——消息队列

消息队列是一种用于在应用程序之间传递和存储数据的通信机制。它允许应用程序将消息发送到队列中,然后由另一个应用程序从队列中接收和处理这些消息。消息队列可以有效地实现异步通信、解耦应用程序之间的依赖关系,以及实现消息的持久化和顺序处理。常见的消息队列系统包括RabbitMQ、Kafka、ActiveMQ等。消息队列在现代分布式系统和微服务架构中被广泛应用。

m0_74774362的博客 1373

到底什么是消息队列?Java中如何实现消息队列?

网上查了一些资料,感觉都是概念性的很空泛的东西,可是不知道到底是什么东西,如何在Java中实现并使用…… 在此请教各位前辈到底什么是消息队列?Java中如何实现消息队列? 来个个人通俗的解释吧。 消息队列,顾名思义 首先是个队列。 队列的操作有入队和出队 也就是你有一个程序在产生内容然后入队(生产者) 另一个程序读取内容,内容出队(消费者) 这是最最基本的概念。

Golden_lion的博客 1万+

System V消息队列与POSIX消息队列

函数的的oflag类似有 O_RDONLY、O_RDWR, O_WRONLY,除此之外还有 O_CREAT、O_EXCL(如果 O_CREAT 指定,但 name 不存在,就返回错误),O_NONBLOCK(以非阻塞方式打开消息队列,在正常情况下 mq_receive和mq_send 函数会阻塞的地方,使用该标志打开的消息队列会返回 EAGAIN 错误)。通过设置用int mq_notify(),当消息队列从空变为非空 时,已注册的进程将收到一个信号或触发一个回调函数,以异步地通知该进程。

xu_hao430621的博客 1058

什么是消息队列

1、异步处理:一旦生产者发送完消息,便可以立即转向其他任务,而消费者则可以在任何时候开始处理消息。这样一来,生产者和消费者之间就不会发生阻塞。2、削峰填谷:消息队列允许我们先将用户请求存储起来,然后消费者(或说实际执行任务的应用)可以根据自身的处理能力和需求,逐步从队列中取出并处理请求。

cui_hao_nan的博客 986

Linux中消息队列

【代码】Linux中消息队列。

weixin_51034082的博客 838

消息队列-简单介绍Java消息队列,什么是消息队列,作用以及常见消息队列

天天说队列, 项目请求数据不能及时处理时,就一言不合通过队列啊, 心中那个是妈卖批,那么到底什么队列呢,队列有到底运用于哪些运用场景呢; 先说说应用场景吧, 不知道有啥作用,看多了含义,原理什么的还是头疼; 消息队列应用场景 1.比如你的服务器一秒能处理100个订单,但秒杀活动1秒进来1000个订单,持续10秒,在后端能力无法增加的情况下,你可以用消息队列将总共10000个请求压在队列里,后...

香烟达人的博客 2804
上一篇: UDP解决丢包问题总结
下一篇: linux查看服务器负载和资源占用情况,以及性能监控
GoodLinGL
博客等级 码龄6年 120粉丝 47原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值