MQ学习笔记

一文了解消息队列MQ(超详细+干货满满) 阅读详情

之前写过关于ActiveMQ的学习笔记,然后面试时被问到MQ时依然不知道从哪开始说起,并且我发现即使写了ActiveMQ相关的学习笔记,然后并没什么卵用,依然忘的比较彻底.
然后我就意识到我的学习方法不太对,因为我对于MQ的认识只是停留在了很浅的一个层面,只是简单的认为它是一个存储消息的容器,需要用到的时候对MQ进行存取操作就行了.

然而如果我先从MQ开始入手学习,在学习ActiveMQ或者RabbitMQ时,我只需要记住他们的一些特点即可,这样会轻松很多并且更容易理解,所以这篇文章也是学习MQ的笔记.

参考链接关于MQ的几件小事

MQ(message queue)的概念:

消息的传输过程中的保存消息的容器.

MQ的优势:

1.解耦:
可以举个例子,例如当用户下单后,同时需要进行的步骤有在库存系统中将库存减一,客户系统中该用户的信息更新,订单系统需要生成一个订单等等,
假设没有MQ的话,需要分别调用库存系统,客户系统,订单系统中的方法,将数据作为参数传入,这就造成了比较强的依赖性,三个系统中也有大量的业务逻辑代码,**多个不相关系统因为需要同一个参数聚集到了一起,**只要出现一个问题就会导致其他系统都受影响.
而通过MQ则只需要1步,将消息发送到MQ中即可,这样的话大大降低了代码的耦合度,即使库存系统出现错误也不会影响到其他模块.

2.异步:
还是上面的例子,如果没有MQ,三个或者更多系统的业务代码会依次执行且需要等待处理结果,响应时间长,用户体验差.
而通过MQ则不需要等待,直接发送到MQ后即可返回给用户结果,而其它系统可以同时从MQ中获取数据消费,效率更高. 而且就算后续出了异常,用户也不知道,可以偷偷处理~~. 想必大家都遇到过下单成功后查询不到的问题吧哈哈.

3.扩展性
上边两个特点也能侧面展现出这个优势,当需要新增模块的时候,例如我添加物流系统,需要订单号,可以直接去MQ中获取即可,而不是将业务代码添加在源代码中.也可以理解为提高数据的可复用性

4.削峰
当访问量激增时,例如促销活动会导致并发量比较大,促销会生成大量的订单,此时会针对订单关联的系统和数据库造成访问压力,通过MQ可以将压力转移到MQ中,而MQ会根据自己的消费能力消费数据,保证了下游系统的稳定性,这样当我们在优化稳定性的时候可以优先针对上游(访问入口)和MQ(集群)进行优化.

消费者确认模式:

JMS提供的3中模式:

在这里插入图片描述

在这里插入图片描述
auto_acknowledge:
消费者接收到消息后自动确认。

client_acknowledge
client端确认模式,手动确认。

dups_ok_acknowledge
一条消息可以被多次消费,为了确保“一次且仅仅一次发送语义”。影响MQ性能。

缺点

从上面的总结可以看出来,通过MQ会导致整个系统对MQ的依赖性非常强,当MQ出现问题时会造成整个系统瘫痪,上面提到的削峰针对于下游系统稳定性高了,但是并发压力集中在了MQ上,因此当访问压力过大时可以通过集群保证MQ的稳定性.

数据一致性: 上面也提到过,例如用户下单后,返回下单成功通知,下游的库存系统在减1库存操作时出现异常,这样就出现数据不一致的问题,

STM32实现简单的智能电子相框 具体的代码案例和详细的代码实现超过5000字,无法在此篇文章中提供。但是,你可以参考STM32的官方文档和相应的图形库和多媒体库的文档,以获得更详细的实现细节和代码示例。对于硬件,我们可以选择使用STM32开发板,如STM32F4 Discovery。对于软件开发环境,我们将使用Keil MDK-ARM作为开发工具,并使用STM32CubeMX进行代码配置。在本文中,我们将使用STM32单片机实现一个简单的智能电子相框,包括显示照片、播放视频和音乐功能。接下来,我们将详细描述实现智能电子相框的步骤。 阅读详情

相关推荐

STM32 A/B分区OTA升级实战:从原理到避坑指南

本文详细解析STM32 A/B分区OTA升级的核心原理与实战实现,涵盖双分区设计、Bootloader开发、固件传输验证及常见问题解决方案。重点介绍通过A/B分区实现无缝升级与安全回滚的机制,帮助开发者规避典型陷阱,提升嵌入式系统远程更新的可靠性与效率。

qqq44的博客 1108

学习笔记-MQ

1、MQ基本概念 消息队列 优势: 应用解耦、提升容错和可维护性 异步提速、提高用户体验和系统吞吐量 削峰填谷、处理高并发 劣势: 可用性降低(如何保证高可用) 复杂度提高 常见MQ产品 RabbitMQ比价安全,所以金融行业常用。kafka多用于大数据。 2、RabbitMQ 6中模式 1.最简单的 2.work queue(队列)模式 3.publish/Subscribe发布订阅模式 exchange交互机是广播模式:fanout 4.routing路由模.

chenlu4ever的专栏 672

【TM1650】STM8S TM1650芯片控制程序

以下为.h文件: #ifndef __TM1650_I2C_H #define __TM1650_I2C_H #include "stm8s.h" #include "stm8s_gpio.h" #include "tim1.h" #include "usart2.h" #include <iostm8s103f3.h> #include <intrinsics....

cxw312864660的博客 1万+

MQ基础入门

1.什么是MQ MQ(Message Queue)消息队列,是基础数据结构中“先进先出”\color{red}{“先进先出”}“先进先出”的一种数据结构。指把要传输的数据(消息)放在队列中,用队列机制来实现消息传递——生产者产生消息并把消息放入队列,然后由消费者去处理。消费者可以到指定队列拉取消息,或者订阅相应的队列,由MQ服务端给其推送消息(详情请见https://baike.baidu.com/item/MQ/9062942?fr=aladdin添加链接描述)。 通俗来讲,本质还是个队列,只不过此队列中

小生不才的博客 4663

MTK PE+2.0介绍

  PE+2.0介绍:   1.      PE+2.0的状态机: 2.      升压波形协议及编码规则: PE+2.0软件设计:   在充电器类型为标充且底层电量SOC在1%—95%之间时,开始PE+2.0升压充电器的检测:首先将VBUSreset至5V,之后发送8.5的current pattern再获取此时VBUS电压和8.5V比较,若其与8.5的差值绝对值在0.5之...

raydom07的博客 1万+

自动驾驶必备:5分钟搞懂gPTP如何实现μs级时间同步(附开源代码)

本文深入解析了gPTP协议在自动驾驶系统中实现微秒级时间同步的核心机制与工程实践。针对多传感器融合与跨域协同的严苛需求,文章拆解了gPTP的频率同步、对等延迟测量与时间偏移校正三步流程,并提供了基于linuxptp和AVnu gPTP两大开源代码库的实战配置指南与性能评估方法,助力开发者构建高精度、高可靠的车载时间同步网络。

weixin_29211309的博客 167

乐优商城(二十四)——RabbitMQ及数据同步

目录 一、RabbitMQ 1.1 搜索与商品服务的问题 1.2 消息队列(MQ) 1.2.1 什么是消息队列 1.2.2 AMQP和JMS 1.2.3 常见MQ产品 1.2.4 RabbitMQ 1.3 下载和安装 1.3.1 下载 1.3.2 安装 二、五种消息模型 2.1 基本消息模型 2.1.1 生产者发送消息 2.1.2 管理工具中查看消息 2.1.3 消费...

lyj2018gyq的博客 3738

联邦学习中的差分隐私保护详解及python实现

随着数据隐私法规(如 GDPR、CCPA)日益严格,传统将数据集中到云端训练模型的方式面临合规与安全风险。联邦学习通过让各客户端保留本地数据,仅共享模型更新,缓解了数据流动带来的隐私风险。但模型更新仍可能泄露个体信息。为进一步保障隐私,可在本地更新中引入差分隐私(DP)机制,通过向梯度或模型更新中注入随机噪声,防止反向推断原始数据citeturn0search9。

闲人编程的博客 1920

MQ快速入门【详细】个人笔记 讲解通俗易懂

同步通讯——打电话异步通讯——发微信。

abfwaaf的博客 1587

PD3.0详解 第六章 协议层—数据消息之—VDM

PD3.0的VDM 很多对PD3.0协议了解不是很深入的同学可能对VDM有一些陌生,因为这个VDM是较为次要,只不过相对沟通电源的协议来讲VDM是次要,但从PD3.0协议的角度来说,这个也是非常重要的,是必须要非常明白的了解这个东西,所以今天大师匈就分享一下这部分的重要知识点。 VDM (vendor define message) VDM是什么意思呢,就是原厂定义的消息,比如PD快充芯片的原厂定义的一些自己独立的message。但是呢这部分也有规定的一些标准的字段。 另外我们要很清楚PD协议的数据分为几类

大师匈的博客 1万+

SAR成像专栏目录

为方便大家阅读,我做了一个专栏目录,蓝色字有超链接,可以直接打开。 本专栏默认读者已具备雷达系统的基本知识或者已阅读过雷达导论专栏中的文章。 1. 概述 SAR成像概述 星载SAR的各项指标解读(史上最全) SAR成像算法的实现途径与算力分析 2. SAR成像原理与SAR系统简介 雷达与分辨率 SAR成像原理与方法 SAR图像的形成和处理 SAR系统设计 3. 点目标仿真 点目标仿真(一)—— 数学模型 点目标仿真(二)—— Matlab仿真 4. 成像算法 更新中 雷达导论专

7461

黑马MQ-学习笔记

消息代理类似于小学做的做饭最短时间的题目 几个服务可以同时进行 在完成扣减余额和更新支付状态后 可以给消息队列发一个消息 这个流程就类似于炒菜是需要铁锅(同步) 而炒完菜就可以放入微波炉(异步)不需要我们自己去操作 而是交给消息代理。

2303_80864208的博客 971

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

【 mq】 mq学习笔记

用户请求瞬间流量被Redis的原子操作decrement承接,性能极高,防止数据库被击垮。判断结果立即返回给用户(成功/失败),用户体验好。RocketMQ 削峰与异步化抢购成功的请求被瞬间转换成消息存入RocketMQ,实现了流量削峰。主流程(抢购)和后续复杂流程(创建订单)解耦。订单消费者慢慢从MQ中取出消息,以数据库能承受的速率执行真正的创建订单、扣减数据库库存等操作。最终一致性通过Redis预扣库存和MQ重试机制,保证了库存数据和订单状态的最终一致性。

weixin_56738054的博客 858

IEM模型,地表粗糙度模拟

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

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Mq学习笔记

MQ学习笔记 进程间通信方式 在学习进程间通信的时候,对了解到进程间通信的方式,主要有 管道pipe:管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。管道的本质是一段缓冲区。 命名管道FIFO:有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信.命名管道的名字对应一个磁盘索引节点,有了这个名字任何进程有响应的权限都可以对他进行访问。 消息队列MessageQueue:消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。

qq_46665477的博客 280

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

黑马商城MQ高级学习笔记

1. 学习了发送者的可靠性,包括发送者重连机制和发送者确认机制。 2. 学习了MQ的可靠性,包括数据持久化和LazyQueue。 3. 学习了消费者的可靠性,包括消费者确认机制,失败重试机制,失败处理策略,业务幂等性。 4. 学习了延迟消息,包括通过死信交换机和DelayExchange插件两种实现方式。 5. 增加了用延迟消息处理超时订单的业务。

m0_73479109的博客 1647

MQ学习笔记整理

MQ学习笔记 一、为什么要使用MQ? 其实这里要讲的就是使用MQ的好处,MQ的的使用场景有很多,但是比较核心的有3个:解耦、异步、削峰 1. 解耦 例如:A系统要发送数据到B、C、D三个系统,通过接口调用发送。假如现在又添加了一个E系统,也要数据,A系统需要修改;B系统说我现在不需要这个数据了,A系统还是要修改。这种情况下,A系统的维护者肯定很崩溃。 其实这个调用是不需要直接同步调用接口的,如果...

拨开云雾看世界 4761

IBM MQ 学习笔记

MQ 介绍及安装 介绍 MQ,简单地说就是消息队列,应用程序把消息放进队列里,等待其他的应用程序或自己把它读走,用于进程间通信,并且可以像 socket 那样用于不同主机间的进程间通信。它有四个重要的概念: 队列管理器 用来管理队列。 队列 用来存放消息。 消息 就是要进行存储与传递的消息。 通道 队列管理器之间传递消息的管道。 安装 到这里下载 MQ for 64-bit

screensky的专栏 1万+

MQ-2学习笔记

1.工作原理 MQ-2型烟雾传感器属于二氧化锡半导体气敏材料,属于表面离子式N型半导体。处于200~300摄氏度时,二氧化锡吸附空气中的氧,形成氧的负离子吸附,使半导体中的电子密度减少,从而使其电阻值增加。当与烟雾接触时,如果晶粒间界处的势垒收到烟雾的调至而变化,就会引起表面导电率的变化。利用这一点就可以获得这种烟雾存在的信息,烟雾的浓度越大,导电率越大,输出电阻越低,则输出的模拟信号就越大。 浓度计算: 1、MQ-2的计算公式 阻值R与空气中被测气体的浓度C的计算关系式log R = mlog C

WANGXINGYUUUUU的博客 1万+

MQ消息学习笔记

MQ笔记整理 各个MQ之间的对比: 特性 ActiveMQ RabbitMQ RocketMQ Kafka 单机吞吐量 万级,比 RocketMQ、Kafka 低一个数量级 同 ActiveMQ 10 万级,支撑高吞吐 10 万级,高吞吐,一般配合大数据类的系统来进行实时数据计算、日志采集等场景 topic 数量对吞吐量的影响 topic 可以达到几百/几千的级别,吞吐量会有较小幅度的下降,这是 RocketMQ 的一大优势,在同等机器下,可以支撑大量的 topic topic 从几

weixin_44974020的博客 2236

mq学习笔记

mq使用场景优点 解耦 一个系统或者一个模块,调用了多个系统或者模块,互相之间的调用很复杂,维护起来很麻烦。但是其实这个调用是不需要直接同步调用接口的,如果用MQ给他异步化解耦,也是可以的,你就需要去考虑在你的项目里,是不是可以运用这个MQ去进行系统的解耦。在简历中体现出来这块东西,用MQ作解耦。 异步 削峰 mq缺点 系统可用性降低:系统引入的外部依赖越多,越容易挂掉,本来你就是A系统调用BCD三个系统的接口就好了,人ABCD四个系统好好的,没啥问题,你偏加个MQ进来,万一MQ挂了咋整?MQ挂了,整

weixin_43408277的博客 264
上一篇: JVM学习笔记---------堆内存模型
下一篇: 全文检索及lucene学习笔记
programmer_hard
博客等级 码龄8年 3粉丝 36原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值