Kafka实战(Scala操作)
Kafka基础讲解部分
Kafka基础讲解部分
Kafka实战(Scala操作)
1、引入依赖
版本:
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spark.scala.version>2.12</spark.scala.version>
<spark.version>3.1.2</spark.version>
<spark.kafka.version>3.5.1</spark.kafka.version>
<kafka.version>2.8.0</kafka.version>
具体依赖:
<!-- spark-core -->
<dependency><groupId>org.apache.spark</groupId><artifactId>spark-core_${spark.scala.version}</artifactId><version>${spark.version}</version>
</dependency><!-- spark-sql -->
<dependency><groupId>org.apache.spark</groupId><artifactId>spark-sql_${spark.scala.version}</artifactId><version>${spark.version}</version>
</dependency><!-- kafka -->
<dependency><groupId>org.apache.kafka</groupId><artifactId>kafka-clients</artifactId><version>${kafka.version}</version>
</dependency>
2、创建生产者(Producer)
一:生产者相关配置讲解:
-
BATCH_SIZE_CONFIG = "batch.size"
:批处理数量,消息为batch.size
大小,生产者才会发送消息 -
LINGER_MS_CONFIG = "linger.ms"
:延迟时间,如果消息大小迟迟不为batch.size
大小,则可以在指定的时间linger.ms
后发送 -
RETRIES_CONFIG= "retry.count"
:重试次数,消息发送失败时,生产者可以再重试retry.count
次数 -
ACKS_CONFIG= "acks"
:ack机制,生产者需要等待aks
个副本成功写入消息后,才认为消息发送成功 -
acks一共有三个选项
- acks=0:生产者不需要等待来自服务器的任何确认。一旦消息被发送出去,生产者就认为消息已经成功发送。
- acks=1(默认值):生产者需要等待分区中的leader副本成功写入消息并返回确认后,才认为消息发送成功。
- acks=all 或 acks=-1:生产者需要等待ISR(In-Sync Replicas,同步副本集)中的所有副本都成功写入消息后,才认为消息发送成功。
-
KEY_SERIALIZER_CLASS_CONFIG
:键序列化 -
VALUE_SERIALIZER_CLASS_CONFIG
:值序列化
二:ProducerRecord讲解:
public ProducerRecord(String topic, Integer partition, Long timestamp, K key, V value) {this(topic, partition, timestamp, key, value, null);
}
基本讲解:Topic: 指定消息要发送到的目标主题(topic)的名称。Partition: 可选的分区号。如果未指定分区号,则Kafka会根据键(如果有的话)或者使用默认的分区策略来决定消息被发送到哪个分区。Timestamp: 可选的时间戳。指定消息的时间戳,通常用来记录消息的产生时间Key: 消息的键(optional)。在Kafka中,消息可以有一个可选的键,用于分区(partition)消息。键通常是一个字符串或者字节数组。Value: 消息的实际内容,可以是任何序列化的数据。
异步发送的普通生产者
在异步发送模式下,生产者调用send()
方法发送消息后,不会立即等待服务器的响应,而是继续执行后续操作。
import org.apache.kafka.clients.producer.{Callback, KafkaProducer, ProducerConfig, ProducerRecord, RecordMetadata}import java.util.Properties
import scala.util.Random// kafka生产者:将数据导入kafka中
object KafkaProducer {def main(args: Array[String]): Unit = {// 生产者相关配置val producerConf = new Properties()// 设置连接kafka(集群)配置【必配】producerConf.setProperty(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,"single:9092")// 批处理数量(每10条处理一次)producerConf.setProperty(ProducerConfig.BATCH_SIZE_CONFIG,"10")// 延迟时间:如果消息大小迟迟不为batch.size大小,则可以在指定的时间(50ms)后发送producerConf.setProperty(ProducerConfig.LINGER_MS_CONFIG,"50")// 消息发送失败时,生产者可以重试的次数producerConf.setProperty(ProducerConfig.RETRIES_CONFIG,"2")// ack机制:生产者需要等待1个副本成功写入消息后,才认为消息发送成功producerConf.setProperty(ProducerConfig.ACKS_CONFIG,"1")// 键值序列化producerConf.setProperty(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG,"org.apache.kafka.common.serialization.IntegerSerializer")producerConf.setProperty(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,"org.apache.kafka.common.serialization.StringSerializer")// 构造生产者producerval producer:KafkaProducer[Int,String] = new KafkaProducer(producerConf)// 发送消息val topic = "test02" // 指定主题(需存在)val rand = new Random()for(i<- 1 to 100000){// 封装待发送的消息val record: ProducerRecord[Int, String] = new ProducerRecord[Int, String](topic, 0, System.currentTimeMillis(), i, "test-"+i)// 向生产者发送记录producer.send(record)Thread.sleep(5+rand.nextInt(20))}// 强制将所有待发送的消息立即发送到 Kafka 集群,而不需要等待缓冲区填满或达到任何延迟阈值producer.flush()// 关闭并释放资源producer.close()}
}
异步发送的带回调函数生产者
在异步发送模式下,生产者调用send()
方法发送消息后,不会立即等待服务器的响应,而是继续执行后续操作,带回调函数生产者可以在控制台中看到发送成功或失败信息。
import org.apache.kafka.clients.producer.{Callback, KafkaProducer, ProducerConfig, ProducerRecord, RecordMetadata}import java.util.Properties
import scala.util.Randomimport java.util.Properties// kafka生产者:将数据导入kafka中
object KafkaProducer {def main(args: Array[String]): Unit = {// 生产者相关配置val producerConf = new Properties()// 设置连接kafka(集群)配置【必配】producerConf.setProperty(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,"single:9092")// 批处理数量(每10条处理一次)producerConf.setProperty(ProducerConfig.BATCH_SIZE_CONFIG,"10")// 延迟时间:如果消息大小迟迟不为batch.size大小,则可以在指定的时间(50ms)后发送producerConf.setProperty(ProducerConfig.LINGER_MS_CONFIG,"50")// 消息发送失败时,生产者可以重试的次数producerConf.setProperty(ProducerConfig.RETRIES_CONFIG,"2")// ack机制:生产者在发送消息后需要等待来自服务器的确认级别(服务器给出一次确认,才算写入成功)producerConf.setProperty(ProducerConfig.ACKS_CONFIG,"1")// 键值序列化producerConf.setProperty(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG,"org.apache.kafka.common.serialization.IntegerSerializer")producerConf.setProperty(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,"org.apache.kafka.common.serialization.StringSerializer")// 构造生产者producerval producer:KafkaProducer[Int,String] = new KafkaProducer(producerConf)// 发送消息val topic = "test02" // 指定主题(需存在)val rand = new Random()for(i<- 1 to 100000){// 封装待发送的消息val record: ProducerRecord[Int, String] = new ProducerRecord[Int, String](topic, 0, System.currentTimeMillis(), i, "test-"+i)// 用生产者发送记录producer.send(record,new Callback {override def onCompletion(metadata: RecordMetadata, exception: Exception): Unit = {if (exception == null){// 发送信息成功println("发送信息成功,topic:"+metadata.topic()+",partition:"+metadata.partition()+",offset:"+metadata.offset())}else{// 发送信息失败exception.printStackTrace()}}})Thread.sleep(5+rand.nextInt(20))}// 强制将所有待发送的消息立即发送到 Kafka 集群,而不需要等待缓冲区填满或达到任何延迟阈值producer.flush()// 关闭并释放资源producer.close()}
}
3、创建消费者(Consumer)
一:生产者相关配置讲解:
GROUP_ID_CONFIG
:消费者组的标识符,有还几个消费者共用这个组进行消费同一个主题消息GROUP_INSTANCE_ID_CONFIG
:消费者组中消费者实例的标识符,当前消费者自己在消费者组中的唯一标识MAX_POLL_RECORDS_CONFIG="records.count"
:控制每次从 Kafka 主题中拉取的最大记录数为records.count
MAX_POLL_INTERVAL_MS_CONFIG
:控制两次连续拉取消息之间的最大时间间隔,若消费者在此时间间隔内没有发送心跳,则会被认为死亡HEARTBEAT_INTERVAL_MS_CONFIG="time"
:控制消费者发送心跳的频率,每time
毫秒发一次心跳ENABLE_AUTO_COMMIT_CONFIG
:消费者自动提交偏移量(offset)给 KafkaAUTO_COMMIT_INTERVAL_MS_CONFIG="time"
:控制自动提交偏移量的频率,即time
毫秒提交一次偏移量PARTITION_ASSIGNMENT_STRATEGY_CONFIG="org.apache.kafka.clients.consumer.RoundRobinAssignor"
:轮询分区分配策略:将所有可用分区依次分配给消费者,以平衡负载AUTO_OFFSET_RESET_DOC="latest"
:偏移量策略:从分区的最新偏移量开始消费
二:消费者策略(读取数据方式)
Kafka为消费者提供了三种类型的订阅消费模式:subscribe(订阅模式)、SubscribePattern(正则订阅模式)、assign(指定模式)。
-
subscribe(订阅模式):
// 订阅单个主题(test02主题) consumer.subscribe(Collections.singletonList("test02"));
-
SubscribePattern(正则订阅模式):
// 使用正则表达式订阅主题 consumer.subscribe(Pattern.compile("topic-.*"));
-
assign(指定模式):
// 手动分配特定的分区给消费者(test02主题) TopicPartition partition0 = new TopicPartition("test02", 0); consumer.assign(Collections.singletonList(partition0));
package cha01import org.apache.kafka.clients.consumer.{ConsumerConfig, ConsumerRecords, KafkaConsumer}
import java.time.Duration
import java.util.{Collections, Properties}
import scala.collection.JavaConverters.iterableAsScalaIterableConverter// 消费者:用SparkStreaming来消费kafka中数据
object KafkaConsumer {def main(args: Array[String]): Unit = {// 消费者相关配置val props = new Properties()// 设置连接kafka(集群)配置【必配】props.setProperty(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG,"single:9092")// 消费者组的标识符props.setProperty(ConsumerConfig.GROUP_ID_CONFIG,"zhou-240801")// 消费者组中消费者实例的标识符(独享的)props.setProperty(ConsumerConfig.GROUP_INSTANCE_ID_CONFIG,"zhou")// 控制每次从 Kafka 主题中拉取的最大记录数props.setProperty(ConsumerConfig.MAX_POLL_RECORDS_CONFIG,"1000")// 控制两次连续拉取消息之间的最大时间间隔,若消费者在此时间间隔内没有发送心跳,则会被认为死亡props.setProperty(ConsumerConfig.MAX_POLL_INTERVAL_MS_CONFIG,"9000") // 9000毫秒(9秒)// 控制消费者发送心跳的频率,每1秒发一次心跳props.setProperty(ConsumerConfig.HEARTBEAT_INTERVAL_MS_CONFIG,"1000") // 心跳:1000毫秒(1秒)// 消费者组的最小会话超时时间props.setProperty("group.min.session.timeout.ms","15000") // 15000毫秒(15秒)// 消费者组的最大会话超时时间props.setProperty("group.max.session.timeout.ms","50000") // 50000毫秒(50秒)// 消费者的会话超时时间设置props.setProperty(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG,"20000") // 20000毫秒(20秒)// 消费者自动提交偏移量(offset)给 Kafkaprops.setProperty(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG,"true")// 控制自动提交偏移量的频率,即多久提交一次偏移量props.setProperty(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG,"500") //500毫秒// 轮询分区分配策略:将所有可用分区依次分配给消费者,以平衡负载props.setProperty(ConsumerConfig.PARTITION_ASSIGNMENT_STRATEGY_CONFIG,"org.apache.kafka.clients.consumer.RoundRobinAssignor")// 偏移量策略:从分区的最新偏移量开始消费props.setProperty(ConsumerConfig.AUTO_OFFSET_RESET_DOC,"latest")// 键值反序列化props.setProperty(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG,"org.apache.kafka.common.serialization.IntegerDeserializer") // 反序列化props.setProperty(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG,"org.apache.kafka.common.serialization.StringDeserializer") // 反序列化// 创建消费者val consumer = new KafkaConsumer[Int,String](props)// 订阅者模式val topic = "test02" // 主题consumer.subscribe(Collections.singletonList(topic))// 持续监听状态中while (true) {// 获取消息,每次获取消息的间隔为100msval records: ConsumerRecords[Int, String] = consumer.poll(Duration.ofMillis(100))for (record <- records.asScala) {println(s"topic:${record.topic()},key:${record.key()}, value:${record.value()}")}}}
}
相关文章:
Kafka实战(Scala操作)
Kafka基础讲解部分 Kafka基础讲解部分 Kafka实战(Scala操作) 1、引入依赖 版本: <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.report…...
Android Framework 之WMS详解
1.WMS说的就是 WindowManagerService:负责为Activity对应的窗口分配Surface,管理Surface的显示顺序以及位置尺寸,控制窗口动画 。 它是Android系统中为各个客户端即每个app来提供这样的服务的一个类。 在Android系统中在systemServer 进程和各…...
opencv-图像仿射变换
仿射变换设计图像位置角度的变化,是深度学习预处理中常用的功能。仿射变换就是对图像的平移缩放旋转翻转操作的组合 如下图,对图中点1,2,3与图二中三个点一一映射,仍然形成三角形,但形状已经发生改变,通过这两组三点求…...
算法的基本概念
一、算法的基本概念思维导图 二、什么是算法: 1.我们知道数据结构就是将我门现实的世界中的问题数据化,存入计算机中,并实现对数据结构的一些基本操作。 2.算法就是如何处理这些存入计算机中的信息,以求高效的解决实际问题。 3…...
124. Go Template应用实例:用代码生成代码
文章目录 生成器模式生成器代码生成 本文用生成器模式作为例子,来演示如何用代码生成代码。 生成器模式 熟悉 Java 开发的同学都知道,lombok 有一个著名的注解 Builder ,只要加在类上面,就可以自动生成 Builder 模式的代码。如下…...
【AI实践】阿里云方言文本转语音TTS
最近要做一些普通话和方言demo 找一个免费工具 免费在线文字转语音工具 | edge-tts 在线体验 (bingal.com) 还有一些方言在阿里云上找了下,基于官方demo改了一下 阿里云语音合成接口说明_智能语音交互(ISI)-阿里云帮助中心 (aliyun.com) 如何下载安装、使用语音…...
java 之 各类日期格式转换
一、前言 大家在开发过程中必不可少得和日期打交道,对接别的系统时,时间日期格式不一致,每次都要转换! 从 Java1 到 Java8 将近 20 年,再加上 Java8 的普及时间、各种历史 API 兼容过渡时间。我们很多时候需要在旧时间 API 与新时…...
Nvidia黄仁勋对话Meta扎克伯格:AI和下一代计算平台的未来 | SIGGRAPH 2024对谈回顾
在今年的SIGGRAPH图形大会上,Nvidia创始人兼CEO黄仁勋与Meta创始人马克扎克伯格进行了一场长达60分钟的对谈。这场对话不仅讨论了AI的未来发展和Meta的开源哲学,还发布了不少新产品,并深入探讨了下一代计算平台的可能性。 引言 人工智能的发…...
【JAVA设计模式】适配器模式——类适配器模式详解与案例分析
前言 在软件设计中,适配器模式(Adapter Pattern)是一种结构型设计模式,旨在使不兼容的接口能够协同工作。它通过引入一个适配器类,帮助两个接口之间进行适配,使得它们能够互相操作。本文将详细介绍适配器模…...
【Vue】全局组件和局部组件
一、全局组件 定义: 全局组件是在整个Vue应用中都可以使用的组件。它们被注册在Vue的根实例上,因此可以在任何子组件的模板中被引用,而无需在每个组件中重复注册。 注册方式: 全局组件通过Vue.component方法进行注册。这个方法接…...
react引入高德地图并初始化卫星地图
react引入高德地图并初始化卫星地图 1.安装依赖 yarn add react-amap amap/amap-jsapi-loader2.初始化地图 import AMapLoader from "amap/amap-jsapi-loader"; import { FC, useEffect, useRef, useState } from "react";const HomeRight () > {con…...
2024最简七步完成 将本地项目提交到github仓库方法
2024最简七步完成 将本地项目提交到github仓库方法 文章目录 2024最简七步完成 将本地项目提交到github仓库方法一、前言二、具体步骤1、github仓库创建2、将远程仓库拉取并合并(1)初始化本地仓库(2)本地仓库与Github仓库关联&…...
前端WebSocket入门,看这篇就够啦!!
在HTML5 的早期开发过程中,由于意识到现有的 HTTP 协议在实时通信方面的不足,开发者开始探索能够在 Web 环境下实现双向实时通信的新的通信协议,提出了 WebSocket 协议的概念。 一、什么是 WebSocket? WebSocket 是一种在单个 T…...
漏洞复现-F6-11泛微-E-Cology-SQL
本文来自无问社区,更多漏洞信息可前往查看http://www.wwlib.cn/index.php/artread/artid/15575.html 0x01 产品简介 泛微协同管理应用平台e-cology是一套企业级大型协同管理平台 0x02 漏洞概述 该漏洞是由于泛微e-cology未对用户的输入进行有效的过滤࿰…...
Turbo Boost 禁用
最近在做OAI NR的时候关闭CPU 睿频的时候出了一些问题,这里我把我找到的资料记录一下: 禁用 Turbo Boost 的过程可能会因不同的 BIOS/UEFI 和操作系统设置而有所不同。以下是一些可能的原因及解决方法: 可能的原因 BIOS/UEFI 设置问题: 你的…...
假期BUUCTF小练习3
文章目录 [极客大挑战 2019]BuyFlag[BJDCTF2020]Easy MD5[HCTF 2018]admin第一种方法 直接登录第二种方法 flack session伪造第三种方法Unicode欺骗 [MRCTF2020]你传你🐎呢[护网杯 2018]easy_tornadoSSTI注入 [ZJCTF 2019]NiZhuanSiWei [极客大挑战 2019]BuyFlag 一…...
【ubuntu系统】在虚拟机内安装Ubuntu
Ubuntu系统装机 描述新装机后的常规配置, 虚拟机使用vbox terminal 打不开 CTRL ALT F3 进入命令行模式(需要返回桌面时CTRL ALT F1)root用户登入cd /etc/default vi locale LANG“en_US” 改成 LANG“en_US.UTF-8”保存修改后&…...
Python初学者必须掌握的基础知识点
Python初学者必须掌握的基础知识点包括数据类型与变量、控制结构(条件语句和循环语句)、基本数据结构(列表、元组、字典、集合)、函数与模块、以及字符串处理等。以下是对这些基础知识点及其对应代码的详细介绍: 1. …...
ESP32是什么?
ESP32是一款由乐鑫信息科技(Espressif Systems)推出的高度集成的低功耗系统级芯片(SoC),它结合了双核处理器、无线通信、低功耗特性和丰富的外设,特别适用于各种物联网(IoT)应用。以…...
jemalloc分析内存
分析内存泄漏过程中, 由于tcmalloc不能长时间开启heap profile(会不停涨内存,导致内存爆掉).尝试换jemalloc. 交叉编译: git clone https://github.com/jemalloc/jemalloc.git./autogen.sh./configure --hostaarch64-…...
【QT】qss
目录 基本语法 设置全局样式 问题 分离样式代码 方案1 方案2 选择器 概况 子控件选择器 伪类选择器 盒子模型 修改控件样式示例 按钮 属性小结 复选框 属性小结 输入框 属性小结 列表框 属性小结 渐变色 示例: 菜单栏 设置菜单栏的背景…...
Java处理大数据的技巧
大数据处理是现代计算机科学中的一个重要领域,通过高效的算法和工具,我们可以从大量数据中提取有价值的信息。本文将介绍一些处理大数据的技巧和策略,并讨论如何通过Java与MySQL实现高效的大数据处理。 一、什么是大数据处理? 大…...
JavaScript基础——JavaScript常见语句(判断语句、循环语句、控制流语句)
JavaScript提供了丰富的语句来控制程序的执行流程,包括用于条件判断的if、switch和三元运算符,以及用于循环的for、while、do...while、for...in和for...of。此外,还有控制流语句如break、continue和return。 判断语句 if 语句 if 语句&…...
材质球向shader传值失败
unity中导入spine模型,当模型挂载SkeletonMecanim组件后,发现材质球向shader传值失败,改为SetPropertyBlock后可行。 //spine模型使用材质球传参数,当spine模型上挂载有SkeletonMecanim的情况下,会传值失败!!!!// for…...
【TDH社区版大事件】图分析、全文检索、小文件治理、数据开发工具通通都有!
星环科技大数据基础平台TDH社区版,在保留了商业版核心技术优势的基础上最大程度地降低了用户使用大数据技术的门槛与成本,具有更轻量、更简单、更易用等特性。 此次TDH社区开发版、社区版、社区订阅版均发布了新版本,带来新的产品组件和新的…...
【反序列化漏洞】serial靶机详解
一、安装靶机 首先创建新的虚拟机。 然后选择客户机版本为Ubuntu 64位。 然后选择使用现有磁盘,选择下载的vmdk磁盘文件即可。剩下的都是默认 二、信息收集 发现主机192.168.204.143 访问 扫描端口nmap -A 192.168.204.143 -p-,发现只有ssh:22和http:8…...
C#列表按照日期进行从大到小排序
C#列表按照日期进行从大到小排序...
rt-thread每个线程状态切换方法
线程状态 RT-Thread 中线程的状态定义在 rt_thread.h 头文件中,通常包括以下几种状态: RT_THREAD_INIT:线程初始化状态。RT_THREAD_READY:线程就绪状态。RT_THREAD_SUSPEND:线程挂起状态。RT_THREAD_RUNNING…...
visual studio跳转到上一个/下一个光标处的快捷键设置
vscode能通过Alt左右箭头跳转到上/下一个光标处,这对于“点进函数看源码,看完后跳转到原来位置”是非常方便的。 在Visual Studio中,有2种方法实现这样的功能。 第一种,直接点击这两个按钮:(缺点是每次要用…...
网络基础命令配置复习 (基础华为设备)
目录 一.前言 二.Telnet远程登陆 2.1telnet介绍 2.2telnet的配置 三.交换机基础配置 四.致谢 一.前言 网络基础不仅是IT从业者的必备知识,也是日常生活中使用网络的人们应该了解的内容。通过学习和掌握这些基础知识,你将能更好地理解和利用现…...
网站建设推广内容/百度关键词优化企业
“期权激励拿到手软” ——> 希望能弥补你看到基本工资后的脚软; “有活力的技术团队” ——> 团队平均工作经验<1年; “千亿市场的探索者” ——> 目前尚没看清具体市场在哪; “扁平化管理” ——> 公司还没招到HR࿱…...
怎么查网站的备案号/设计网站模板
SQL批处理是JDBC性能优化的重要武器,经本人研究总结,批处理的用法有三种。package lavasoft.jdbctest; import lavasoft.common.DBToolkit; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java…...
外贸公司网站素材/百度问问首页登录
这两天在看SpringCloud相关源码,发现里面使用了大量的设计模式,具体的有工厂方法模式,适配器设计模式,装饰设计模式等。 具体的体现是有这样一个接口:DataBuffer,与之对应的有个DataBufferFactory接口&…...
移动网站建设机构/seo网站推广软件排名
我想大家对QQ表情一定不会陌生,一个个小头像极大丰富了聊天的乐趣,使得聊天不再是简单的文字叙述,还能够配上喜、怒、哀、乐等表达人物心情的小图片。本文重点要介绍的内容就是如何在微信公众平台使用QQ表情,即在微信公众帐号开发…...
广州公司摇号申请网站/网络推广方法怎么样
作者:佚名出处:IT专家网论坛 2009-06-17 13:00List按对象进入的顺序保存对象,不做排序或编辑操作。Set对每个对象只接受一次,并使用自己内部的排序方法(通常,你只关心某个元素是否属于Set,而不关心它的顺序--否则应该使…...
郑州华久做网站/seo关键词排名优化销售
摘要: 背景 1个输入文件对应多个输出文件(不同分辨率,不同格式等),通过控制台的图形化界面,快速搭建常用视频处理流程。 优势 简单易用,视频上传完成自动触发转码任务。 功能强大,支…...