大数据(8p)SparkStreaming精准一次消费Kafka

最全真实大数据简历模版(二)【大数据-3年经验】金融_大数据 简历,2024年最新阿里P7级别面试经验总结 为了提高产品服务质量,满足客户的个性化需求,给客户针对性推荐有价值的产品信息,现需将每位客户的需求更加细化、精准化,通过收集用户的信息与浏览行为习惯,为每个用户打上标签构建专属用户画像,针对性匹配金融产品,帮助客户发现真正有帮助,有价值的信息,节省客户的浏览时间,快速了解类似产品和资讯的速度,缩短成交周期。5.通过构建匹配、统计、挖掘模型,把用户的学历、职业、商圈、消费能力、商品偏好、房产、车产等用户属性与标签进行合并,最终产生的用户标签数据,保存到Hbase中; 阅读详情

1、数据容错语义

encn说明
at most once数据最多一条数据可能会丢,但不会重复
at least one数据至少一条数据绝不会丢,但可能重复
exactly once数据有且只有一条数据不会丢,也不会重复

2、SparkStreaming消费Kafka

建议 Executor数量 = 主题下的分区数

2.1、Scala代码,设置自动提交消费者偏移量

如下代码所示:enable.auto.commit设置为true
自动提交消费者偏移量 会有 数据丢失的风险(可以自行模拟出错)

import org.apache.kafka.clients.consumer.ConsumerRecord
import org.apache.kafka.common.serialization.StringDeserializer
import org.apache.spark.SparkConf
import org.apache.spark.streaming.dstream.InputDStream
import org.apache.spark.streaming.kafka010.ConsumerStrategies.Subscribe
import org.apache.spark.streaming.kafka010.KafkaUtils
import org.apache.spark.streaming.kafka010.LocationStrategies.PreferConsistent
import org.apache.spark.streaming.{Seconds, StreamingContext}

object Hello {
  def main(args: Array[String]): Unit = {
    // 创建StreamingContext对象
    val c3: SparkConf = new SparkConf().setAppName("a3").setMaster("local[*]")
      // 下面这个设置用来解决序列化异常
      .set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
    val ssc = new StreamingContext(c3, Seconds(9))
    // Kafka消费者配置
    val kafkaConsumerConfig: Map[String, Object] = Map[String, Object](
      // Kafka服务器
      "bootstrap.servers" -> "hadoop100:9092,hadoop101:9092,hadoop102:9092",
      // 反序列化类:字符串序列化器
      "key.deserializer" -> classOf[StringDeserializer],
      "value.deserializer" -> classOf[StringDeserializer],
      // 消费者组
      "group.id" -> "g0",
      // 从最新处开始消费
      "auto.offset.reset" -> "latest",
      // 自动提交消费者偏移量
      "enable.auto.commit" -> (true: java.lang.Boolean)
    )
    // 创建消费Kafka的Dstream
    val kafkaDStream: InputDStream[ConsumerRecord[String, String]] =
      KafkaUtils.createDirectStream[String, String](
        ssc = ssc,
        // locationStrategy(位置策略):在Executor上,如何来调度 给定的主题分区的消费者
        // PreferConsistent:一致地在所有Executors中分布分区
        locationStrategy = PreferConsistent,
        // consumerStrategy(消费策略)
        consumerStrategy = Subscribe[String, String](
          // Subscribe(订阅)参数:1、订阅的主题;2、Kafka消费者配置
          topics = Set("t0"), kafkaConsumerConfig)
      )
    // SparkStreaming输出:打印
    kafkaDStream.print()
    // 启动任务和等待终止
    ssc.start()
    ssc.awaitTermination()
  }
}

2.2、创建主题并生产数据进行测试

kafka-topics.sh \
--zookeeper hadoop100:2181/kafka \
--create \
--replication-factor 1 \
--partitions 1 \
--topic t0
kafka-producer-perf-test.sh --topic t0 \
--record-size 1024 \
--producer-props bootstrap.servers=hadoop100:9092 \
--throughput -1 \
--num-records 400

3、 消费者偏移量的存储

为了规避数据丢失的风险,我们要关闭自动提交偏移量(enable.auto.commit设为false),并且 把消费者偏移量存储起来,下面介绍两种主流方法:

3.1、存Kafka的主题

  • Kafka带有提交偏移量的API,可将偏移量存储在一个特殊的Kafka主题中。
    但这个容错语义是at least one,且Kafka不是事务性的,故障出现后会数据可能会重复。
    如要实现at least one,要求SparkStreaming输出形式是幂等的。
  • 幂等(idempotent、idempotence):
    在编程中一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。
  • 幂等函数:可以使用相同参数重复执行,并能获得相同结果的函数。
    例如setTrue()就是一个幂等函数。
  • SparkStreaming有哪些输出是幂等的?
    println不是幂等性的,因为我们看到了重复打印
    数据按Key写Redis是幂等性的,重复写结果相同
    数据按RowKey写HBase是幂等性的,重复写结果相同
ds.foreachRDD { rdd =>
  // 1、获取偏移量(如果有)
  val offsetRanges = rdd.asInstanceOf[HasOffsetRanges].offsetRanges
  // 2、处理数据并输出结果

  // 3、输出结果成功后,异步提交偏移量
  ds.asInstanceOf[CanCommitOffsets].commitAsync(offsetRanges)
}
import org.apache.kafka.clients.consumer.ConsumerRecord
import org.apache.kafka.common.serialization.StringDeserializer
import org.apache.spark.streaming.dstream.InputDStream
import org.apache.spark.streaming.{Seconds, StreamingContext}
import org.apache.spark.streaming.kafka010.{
  CanCommitOffsets, ConsumerStrategies, HasOffsetRanges, KafkaUtils, LocationStrategies, OffsetRange}

object Hello {
  def main(args: Array[String]): Unit = {
    val streamingContext = new StreamingContext("local[2]", "a0", Seconds(9))
    // Kafka消费者的配置
    val kafkaParams = Map[String, Object](
      "bootstrap.servers" -> "hadoop100:9092,hadoop101:9092,hadoop102:9092",
      "key.deserializer" -> classOf[StringDeserializer],
      "value.deserializer" -> classOf[StringDeserializer],
      "group.id" -> "g0",
      "auto.offset.reset" -> "latest",
      "enable.auto.commit" -> "false"
    )
    // 创建消费Kafka的Dstream
    val ds0: InputDStream[ConsumerRecord[String, String]] =
      KafkaUtils.createDirectStream[String, String](
        streamingContext,
        LocationStrategies.PreferConsistent,
        ConsumerStrategies.Subscribe[String, String](Array("t0"), kafkaParams)
      )
    // 数据处理(此处不处理)
    val ds1 = ds0
    // SparkStreaming输出及提交偏移量
    ds1.foreachRDD { rdd =>
      // 1、获取Kafka消费者偏移量(如果有)
      val offsetRanges: Array[OffsetRange] = rdd.asInstanceOf[HasOffsetRanges].offsetRanges
      // 2、输出结果(此处为打印,别的输出方式有:写Redis、写HBase…)
      rdd.foreach(println)
      // 3、手动提交offset
      ds1.asInstanceOf[CanCommitOffsets].commitAsync(offsetRanges)
    }
    // 启动任务和等待终止
    streamingContext.start()
    streamingContext.awaitTermination()
  }
}

3.2、存数据库

例如,要将SparkStreaming结果输出到MySQL,那么可以把偏移量也存储在MySQL,并利用MySQL的事务来确保exactly once,伪代码如下:

// 根据主题和分区从数据库获取消费者偏移量
val fromOffsets = selectOffsetsFromYourDatabase.map { resultSet =>
  new TopicPartition(resultSet.string("topic"), resultSet.int("partition")) -> resultSet.long("offset")
}.toMap

val stream = KafkaUtils.createDirectStream[String, String](
  streamingContext,
  PreferConsistent,
  Assign[String, String](fromOffsets.keys.toList, kafkaParams, fromOffsets)
)

stream.foreachRDD { rdd =>
  // 1、获取偏移量(如果有)
  val offsetRanges = rdd.asInstanceOf[HasOffsetRanges].offsetRanges
  // 2、计算结果
  val results = yourCalculation(rdd)

  // 3.1、开始事务

  // 3.2、更新输出结果
  // 3.3、更新消费者偏移量

  // 3.4、结束事务
}

4、参考

基于Hadoop+Spark的信用卡欺诈检测系统:从零搭建实时风控平台 大数据技术在金融风控领域的应用日益广泛,其核心原理是通过分布式计算框架处理海量交易数据。Hadoop生态系统中的HDFS提供可靠的数据存储,而Spark框架则实现了高效的批处理和实时计算能力。这种技术组合的价值在于能够构建精准的欺诈检测模型,同时满足金融业务对实时性的严格要求。在信用卡交易场景中,系统通过特征工程提取交易金额、时间、商户类型等关键指标,利用随机森林等机器学习算法识别异常模式。Spark Streaming与Kafka的集成实现了毫秒级的风险判断,将可疑交易实时预警。这种离线数仓与实时流处理相 阅读详情

相关推荐

大数据Hadoop运维应用实践——大数据平台架构_kafka入门与实践

本文介绍了大数据平台中Kafka分布式消息队列的原理、架构与集群部署实践。首先详细解析了Kafka的核心概念、特性和适用场景,包括其高吞吐、持久化存储、分布式等优势,以及与其他主流消息中间件的对比。随后,文章提供了三节点Kafka集群的完整部署方案,涵盖ZooKeeper集群配置、Kafka参数优化、systemd服务集成等关键步骤。最后给出了Kafka基础命令操作示例,帮助读者快速掌握集群管理技能。生产环境推荐采用Kafka 3.9.2 + ZooKeeper 3.9.5 + OpenJDK17的组合

提供C#相关开发 、云计算、运维测试、网络安全相关技术分享与服务,有意向可联系。 146

Spark3.x-实战之mysql方式实现kafka精准一次性消费

Spark3.x-实战之mysql方式实现kafka精准一次性消费

S1124654的博客 795

大数据企业面试真题汇总三

1)Map方法之后Reduce方法之前这段处理过程叫Shuffle2)Map方法之后,数据首先进入到分区方法,把数据标记好分区,然后把数据发送到环形缓冲区;环形缓冲区默认大小100m,环形缓冲区达到80%时,进行溢写;溢写前 对数据进行排序,排序按照对key的索引进行字典顺序排序,排序的手段快排;溢写产生大量溢写文件,需要对溢写文件进行归并排序;对溢写的文件也可以进行Com biner操作,前提是汇总操作,求平均值不行。最后将文件按照分区存储到磁盘,等待Reduce端拉取。

悦分享 1497

Kafka Consumer如何实现精确一次消费数据

文章目录简介kafka消费机制精确一次消费实现总结 简介 kafka消费机制 精确一次消费实现 总结

qq_18581221的博客 2万+

学习笔记( 11 ) - 解决:finalshell连接虚拟机(ubuntu)超时,主机ping不通虚拟机,主机没有VMnet8网卡, Connection refused: connect

解决:finalshell连接虚拟机(ubuntu)超时,主机ping不通虚拟机,主机没有VMnet8网卡, Connection refused: connect

烟溪彭于晏的博客 2万+

得物APP破解

本文介绍了得物App(版本4.74.5)的逆向破解过程,重点分析了绕过强制更新、抓包技巧以及破解newSign参数的详细方法。首先通过断网再联网的方式绕过强制更新,然后使用SocksDroid进行抓包分析,发现首页推荐接口需要newSign参数。通过反编译定位到RequestUtils.c方法,利用Frida进行Hook验证,最终解析出newSign的生成逻辑:将请求参数加入固定字段后排序拼接,再进行MD5加密生成签名。文中提供了完整的Hook脚本和签名算法分析,仅供学习移动安全技术参考。

m0_74653634的博客 3473

Spark消费Kafka如何实现精准一次性消费?

1.定义 精确一次消费(Exactly-once) 是指消息一定会被处理且只会被处理一次。不多不少就一次处理。 如果达不到精确一次消费,可能会达到另外两种情况: 至少一次消费(at least once),主要是保证数据不会丢失,但有可能存在数据重复问题。 最多一次消费 (at most once),主要是保证数据不会重复,但有可能存在数据丢失问题。 如果同时解决了数据丢失和数据重复的问题,那么就实现了精确一次消费的语义了。 2. 问题如何产生 数据何时会丢失: 比如实时计算任务进行计算.

鄙人王道长的博客 3978

智能优化算法-北方苍鹰优化算法(NGO)(附源码)

北方苍鹰优化算法 (Northern Goshawk Optimizer, NGO) 是一种基于群体智能的元启发式优化算法,它模拟了北方苍鹰(Northern Goshawk)的捕食行为、领地行为以及社交互动,用于解决复杂的优化问题。总之,NGO作为一种新颖的优化算法,在处理复杂优化问题方面展现出了潜力。随着进一步的研究和应用,NGO有望成为解决实际问题的有效工具。

w971656545的博客 1360

SparkStreaming 整合 Kafka 实现精准一次消费

简介 Kafka数据写入的过程 ACK机制 数据消费语义 实现 At Least Once ( 至少消费一次): 可以保证 数据不丢失, 但有可能存在数据重复问题。 比如将ack级别设置成-1, 这样生产者发送完消息后,只有等到分区的leader和ISR队列中所有follower的全部落盘成功后才会返回ack, 生产者才会去发送下一条数据。这样可以保证生产者到消费者之间数据不会丢失. 但是可能生产者因为网络延时没有收到ack而实际上消费者已经接收到了消息, 然后又发送了一条消息, 这样就会导致数据重复的问

BurukeYou 3984

鱼眼双目测距实战:从OpenCV标定到SGBM匹配的完整流程解析

本文详细解析了鱼眼双目测距的完整流程,从OpenCV标定到SGBM匹配,涵盖标定、校正、匹配和测距四个关键阶段。通过实战经验分享,帮助开发者解决鱼眼镜头强畸变带来的测距挑战,提升测距精度至5%以内。特别适合机器人导航、自动驾驶和VR领域的开发者参考。

weixin_27298377的博客 122

Python爬虫实战:爬取携程旅游平台数据,我拆解了动态反爬+Cookie续命(附完整可运行代码)

反爬类型表现形式应对思路sign参数返回403/空数据逆向JS还原加密逻辑Cookie时效登录后1小时Cookie失效定时刷新Cookie/保存登录态行为检测爬取过快触发验证码模拟真人延时/随机点击IP封禁单IP爬取超50条数据被封付费代理池/降低请求频率爬取携程旅游平台数据的核心,不是“简单的HTTP请求”,而是“理解平台的反爬逻辑并合规适配”——从sign参数破解到Cookie维护,再到行为模拟,每一步都是对HTTP协议、前端加密、用户行为的深度理解。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1713

(33)保证数据的精准一次性消费

2.5.1 定义 ➢ 精确一次消费(Exactly-once) 是指消息一定会被处理且只会被处理一次。不多不少就一次处理。 如果达不到精确一次消费,可能会达到另外两种情况: ➢ 至少一次消费(at least once) 主要是保证数据不会丢失,但有可能存在数据重复问题。 ➢ 最多一次消费 (at most once) 主要是保证数据不会重复,但有可能存在数据丢失问题。 2.5.2 问题如何产生 ➢ 数据何时会丢失 比如实时计算任务进行计算,到数据结

song_quan_的博客 437

QGIS之七建筑面由DSM和DEM获取高度并可视化

QGIS建筑面由DSM和DEM获取高度并可视化

yilvyangguang520的博客 3510

SparkStreaming实时数仓——首单分析(上)[ 精准一次性消费之手动维护+幂等性,一个流一个topic情况 ]

文章目录一、需求分析及实现思路1.1 需求分析:当日新增付费用户首单分析1.2 整体实时计算框架流程1.3 具体业务流程图二、实时采集mysql数据2.1 canal实时采集mysql数据2.1.1 什么是canal2.1.2 canal使用场景①原始场景:阿里otter中间件的一部分②常见场景1:更新缓存服务器③常见场景2④常见场景32.1.3 canal的工作原理mysql的主从复制原理canal工作原理2.1.4 mysql的binlog①什么是binlog②开启bin

平平无奇小码农~ 3439

【图像超分】论文复现:经典超分 | SAN的Pytorch源码复现,跑通源码,适配高版本的python/pytorch/cuda,使用EDSR-PyTorch进行训练和测试

本文介绍了单幅图像超分辨率重建方法SAN(二阶注意网络)的代码实现。文章详细说明了在高版本Python/Pytorch环境下适配SAN源码的方法,并提供了修改后的完整代码和预训练模型下载链接。 主要亮点包括: 将SAN模型实现整合到EDSR-Pytorch框架中,解决了高版本环境下的兼容性问题 提供了完整的数据集准备指南(DIV2K训练集和5个测试集) 给出了详细的测试命令,涵盖x2、x3、x4不同放大倍率 公开了预训练模型和可视化结果的下载资源 提供了修改后的适配高版本环境的代码。

主要更新底层视觉(去噪、超分等)相关的科研内容,形式为【论文精读】+【论文复现】 1412

AI辅助Android开发:从传统到智能化的技术演进

AI辅助开发的核心在于利用算法模型自动化或优化传统任务。在Android开发中,AI可应用于需求分析、设计、编码、测试和维护各阶段。需求分析:AI工具如基于NLP的模型(例如GPT系列)可解析用户需求文档,自动生成用户故事和原型设计。假设产品需求为“开发一个航班查询应用”,AI能提取关键词,输出UML图或伪代码。代码生成:使用AI代码助手(如GitHub Copilot),工程师输入自然语言描述,AI生成Java/Kotlin代码片段。

郑伟强dev的专栏 137

大数据学长面试之vivo面试题

大数据学长面试之vivo面试题

m0_46914845的博客 951

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

sparkStreaming消费kafka-1.0.1方式:direct方式(存储offset到zookeeper)

版本声明: kafka:1.0.1 spark:2.1.0 注意:在使用过程中可能会出现servlet版本不兼容的问题,因此在导入maven的pom文件的时候,需要做适当的排除操作 1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/P...

362

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

Kafka+SparkStreaming的精准一次性消费

Kafka+SparkStreaming的精准一次性消费语义Kafka自身的精准一次性ackat least once+幂等性 = exactly oncekafka事务SparkStreaming exactly onceSpark Streaming如何保证exactly once扩展:Storm\Spark Streaming\Flink的消费语义 Kafka自身的精准一次性 ack at least once+幂等性 = exactly once kafka事务 SparkStreaming exa

u010737756的博客 2193

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

SparkStreaming

对象的checkpoint()设置路径,可以实现在指定路径周期性的记录ss的一些元数据和状态信息,再通过对象的getorCreate()获得这些checkpoint信息StreamingContext,自动加载之前保存的 Checkpoint。1.消息队列的集成,如kafka,可以使用 Kafka 的 Offset 来记录已消费的消息的偏移量,并定期提交偏移量到 Kafka 的特殊主题中。在出现故障后,可以使用提交的偏移量来恢复消费过程,并确保不会重复消费数据。2.做完维护业务数据操作后,提交偏移量。

February13的博客 3682

大数据热门技术Spark+机器学习+贝叶斯算法第9季

本套教程版权归张老师所有本套大数据热门技术Spark+机器学习+贝叶斯算法系列课程,历经5年沉淀,调研企业上百家,通过上万学员汇总,保留较为完整的知识体系的同时,让每个模块看起来小而精,碎而不散。在本课程中基于大量案例实战,深度剖析和讲解Spark2.4原理和新特性,且会包含完全从企业真实业务需求中抽取出的案例实战。内容涵盖Spark核心编程、Spark SQL和Spark Streaming、Spark内核以及源码剖析、推荐系统、Kafka消费机制、Spark机器学习、朴素贝叶斯算法、企业级实战案例等。通过理论和实际的紧密结合,可以使学员对大数据Spark技术栈有充分的认识和理解,在项目实战中对Spark和流式处理应用的场景、以及大数据开发有更深刻的认识;并且通过对流处理原理的学习和与批处理架构的对比,可以对大数据处理架构有更全面的了解,为日后成长为架构师打下基础。本套教程可以让学员熟练掌握Spark技术栈,提升自己的职场竞争力,实现更好的升职或者跳槽,或者从J2EE等传统软件开发工程师转型为Spark大数据开发工程师,或是对于正在从事Hadoop大数据开发的朋友可以拓宽自己的技术能力栈,提升自己的价值。本套大数据热门技术Spark+机器学习+贝叶斯算法共计13季,本套为第9季。

spark streaming消费kafka数据手动管理偏移量offset到zookeeper,保证精准消费一次

Spark Streaming消费kafka数据手动管理偏移量offset到zookeeper,保证精准一致消费,最终的处理结果保存在mysql中。 spark的版本是2.1 kafka的版本是0.8 代码: /** * @author lhq * @date 2020/10/10 10:35 * @version 1.0 */ import java.sql.{Connection, DriverManager, PreparedStatement} import kafka.com

weixin_43806056的博客 726

Kafka和下游系统SparkStreaming如何保证Exactly-Once

1、Kafka如何保证数据不丢失和数据重复 kafka分为生产者和消费者,所以kafka保证数据不丢失需要从以下三个方面保证: 1.1、生产者角度: 1.1.1、什么是ISR 光是依靠多副本机制能保证Kafka的高可用性,但是能保证数据不丢失吗?不行 因为如果leader宕机,但是leader的数据还没同步到follower上去,此时即使选举了follower作为新的leader,但是刚才的数据已经丢失了。 ISR是:跟leader 保持同步的follower 集合,当 ISR 中的 follower

Lucky_LML的博客 874

Spark streaming知识

目录 一.SparkStreaming有哪几种方式消费kafka中的数据,他们之间的区别是什么? 二.Spark Streaming窗口函数的原理 三.spark streaming 容错原理 4.背压机制 5.Spark Streaming 如何实现精确一次消费 一.SparkStreaming有哪几种方式消费kafka中的数据,他们之间的区别是什么? 1.基于Receiver的方式 这种方式使用Receiver来获取数据.Receiver是使用kafka的高层次Consumer.

敲代码的彭于晏 536

基于redis的控制sparkStreaming 对接kafka 精确一次消费数据的解决方案

demo程序使用"KafkaUtils.createDirectStream"创建Kafka输入流,此API内部使用了Kafka客户端低阶API,不支持offset自动提交(提交到zookeeper)。 "KafkaUtils.createDirectStream"官方文档: http://spark.apache.org/docs/2.2.0/streaming-kafka-0-8-integr...

sghuu的博客 1773

Spark Streaming

目录1 简介2 实例3 架构与抽象4 转化操作5 输出操作6 输入源7 24/7不间断运行 1 简介 许多应用需要即时处理收到的数据,例如用来实时追踪页面访问统计的应用、训练机器学习模型的应用,还有自动检测异常的应用。Spark Streaming 是Spark为这些应用而设计的模型。Spark Streaming使用离散化流作为抽象表示,叫做DStream。DStream可以从各种输入源创建,比如Flume、Kafka或者HDFS。创建出来的DStream支持两种操作,一种是转化操作(transforma

BGoodHabit的博客 1771
上一篇: 大数据(3g)HIVE开窗函数应用场景(不定更)
下一篇: Python工程师Java之路(q)Properties
小基基o_O
博客等级 码龄9年 4413粉丝 467原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小基基o_O

您的鼓励是我创作的巨大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值