当前位置: 首页 > 编程日记 > 正文

日均350000亿接入量,腾讯TubeMQ性能超过Kafka

640?wx_fmt=png

整理 | 夕颜
出品 | AI科技大本营(ID:rgznai100)
【导读】近日,腾讯开源动作不断,相继开源了分布式消息中间件TubeMQ,基于最主流的 OpenJDK8开发的Tencent Kona JDK,分布式HTAP数据库 TBase,企业级容器平台TKEStack,以及高性能图计算框架Plato。短短一周之内,腾讯开源了五大重点项目。其中,TubeMQ是腾讯大数据平台部门应用的核心组件,据悉,在目前日均接入35万亿条数据背景下,部门每年都会针对它制定KPI指标,来保证系统能稳定运行,并且持续改进以提高性能,降低成本。
TubeMQ究竟有什么不一般的地方,今天我们就来详细了解一下。


TubeMQ是什么?

TubeMQ技术博客已经对TubeMQ进行了详细的技术解读,这里我们再来回顾一下。
TubeMQ是腾讯大数据在2013年开始研发的分布式消息中间件系统(MQ),专注服务大数据场景下海量数据的高性能存储和传输。经过近7年上万亿的海量数据沉淀,较之于众多的开源MQ组件,TubeMQ在海量实践(稳定性+性能)和低成本方面有一定的优势。
目前,TubeMQ已经在腾讯内部多个重要业务部门成功落地,如微信支付、社交广告、腾讯游戏、腾讯视频、微视等。
640?wx_fmt=png
注:近期,腾讯开源了TubeMQ的相关代码及设计。项目推出后得到了广泛关注和对比讨论,在GitHub上已经获得了1.5k个Star。
GitHub:
https://github.com/Tencent/TubeMQ

TubeMQ VS Kafka性能对比测试总结

作为一款国产框架,自然而然会有人与 Kafka 做比较。在GitHub上,腾讯也相应对两者进行了性能对比。
GitHub地址:
https://github.com/Tencent/TubeMQ/blob/master/docs/tubemq_perf_test_vs_Kafka_cn.md#top
介绍中提到,TubeMQ系统架构的思想就是源于Apache Kafka,而在实现上,则完全采取自适应的方式,结合实战做了很多优化及研发工作,如分区管理、分配机制和全新节点通讯流程,自主开发高性能的底层RPC通讯模块等。这些实现使得TubeMQ在保证实时性和一致性的前提下,具有很好的健壮性及更高的吞吐能力。结合目前主流消息中间件使用情况,以Kafka为参照做性能对比测试,对比常规应用场景下两套系统性能。
从TubeMQ架构图可以很清晰的看到,作为分布式的消息中间件系统,Broker单节点的性能情况直接影响到集群总体的性能表现,即相同的节点数下Broker节点性能越高则TubeMQ的总体性能越强。
下表是TubeMQ与Kafka性能数据对比方案,在数据1份写入2份并行消费的场景下,从机型、关键配置、系统数据的对比中可以很清晰地看到TubeMQ的性能情况:
640?wx_fmt=png
总的来说:Kafka按照顺序写顺序块读的模式实现,单实例下性能数据很强,但随着实例数增多,它的性能就呈现不稳定下降状态;TubeMQ采用顺序写 + 随机读的模式,即使在最大限制下系统仍可以做到长期稳定的1G以上的入流量,同时,结合服务端过滤,过滤消费非常顺畅。
具体的数据分析来看:

1、单Topic单实例配置下,TubeMQ吞吐量要远低于Kafka;单Topic多实例配置下,TubeMQ在4个实例时吞吐量追上Kafka对应5个分区配置,同时TubeMQ的吞吐量随实例数增加而增加,Kafka出现不升反降的情况;TubeMQ可以在系统运行中通过调整各项参数来动态的控制吞吐量的提升;

2、多Topic多实例配置下,TubeMQ吞吐量维持在一个非常稳定的范围,且资源消耗,包括文件句柄、网络连接句柄数等非常的低;Kafka吞吐量随Topic数增多呈现明显的下降趋势,且资源消耗急剧增大;在SATA盘存储条件下,随着机型的配置提升,TubeMQ吞吐量可以直接压到磁盘瓶颈,而Kafka呈现不稳定状态;在CG1机型SSD盘情况下,Kafka的吞吐量要好于TubeMQ;

3、在过滤消费时,TubeMQ可以极大地降低服务端的网络出流量,同时还会因过滤消费消耗的资源少于全量消费,反过来促进TubeMQ吞吐量提升;kafka无服务端过滤,出流量与全量消费一致,流量无明显的节约;

4、资源消耗方面各有差异:TubeMQ由于采用顺序写随机读,CPU消耗很大,Kafka采用顺序写块读,CPU消耗很小,但其他资源,如文件句柄、网络连接等消耗非常的大。在实际的SAAS模式下的运营环境里,Kafka会因为zookeeper依赖出现系统瓶颈,会因生产、消费、Broker众多,受限制的地方会更多,比如文件句柄、网络连接数等,资源消耗会更大。

具体的场景测试及结论可参考GitHub:
https://github.com/Tencent/TubeMQ/blob/master/docs/tubemq_perf_test_vs_Kafka_cn.md#top

TubeMQ相比Kafka的系统特点:

1、纯Java实现语言:
TubeMQ采用纯Java语言开发,便于开发人员快速熟悉项目及问题处理。

2、引入Master协调节点:
相比Kafka依赖于Zookeeper完成元数据的管理和实现HA保障不同,TubeMQ系统采用的是自管理的元数据仲裁机制方式进行,Master节点通过采用内嵌数据库BDB完成集群内元数据的存储、更新以及HA热切功能,负责TubeMQ集群的运行管控和配置管理操作,对外提供接口等;通过Master节点,TubeMQ集群里的Broker配置设置、变更及查询实现了完整的自动化闭环管理,减轻了系统维护的复杂度。

3、服务器侧消费负载均衡:
TubeMQ采用的是服务侧负载均衡的方案,而不是客户端侧操作,提升系统的管控能力同时简化客户端实现,更便于均衡算法升级。

4、系统行级锁操作:
对于Broker消息读写中存在中间状态的并发操作采用行级锁,避免重复问题

5、Offset管理调整:
Offset由各个Broker独自管理,ZK只作数据持久化存储用(最初考虑完全去掉ZK依赖,考虑到后续的功能扩展就暂时保留)。

6、消息读取机制的改进:
相比于Kafka的顺序块读,TubeMQ采用的是消息随机读取模式,同时为了降低消息时延又增加了内存缓存读写,对于带SSD设备的机器,增加消息滞后转SSD消费的处理,解决消费严重滞后时吞吐量下降以及SSD磁盘容量小、刷盘次数有限的问题,使其满足业务快速生产消费的需求。

7、消费者行为管控:
支持通过策略实时动态地控制系统接入的消费者行为,包括系统负载高时对特定业务的限流、暂停消费,动态调整数据拉取的频率等。

8、服务分级管控:
针对系统运维、业务特点、机器负载状态的不同需求,系统支持运维通过策略来动态控制不同消费者的消费行为,比如是否有权限消费、消费时延分级保证、消费限流控制,以及数据拉取频率控制等。

9、系统安全管控:
根据业务不同的数据服务需要,以及系统运维安全的考虑,TubeMQ系统增加了TLS传输层加密管道,生产和消费服务的认证、授权,以及针对分布式访问控制的访问令牌管理,满足业务和系统运维在系统安全方面的需求。

10、资源利用率提升改进:
相比于Kafka,TubeMQ采用连接复用模式,减少连接资源消耗;通过逻辑分区构造,减少系统对文件句柄数的占用,通过服务器端过滤模式,减少网络带宽资源使用率;通过剥离对Zookeeper的使用,减少Zookeeper的强依赖及瓶颈限制。

11、客户端改进:
基于业务使用上的便利性以,我们简化了客户端逻辑,使其做到最小的功能集合,我们采用基于响应消息的接收质量统计算法来自动剔出坏的Broker节点,基于首次使用时作连接尝试来避免大数据量发送时发送受阻(具体内容见后面章节介绍)。

与当前主流MQ横向对比分析

下表是TubeMQ与主流MQ做的一个整体情况对比,便于大家快速粗略了解TubeMQ与其他的MQ之间的差异。需要注意的是,相比其他MQ,基于成本和异步复制仍有丢数据的考虑,TubeMQ没有纳入多副本实现。
同时,腾讯也表示,相关高可靠的业务应用通过另一套实时多副本MQ来提供相应服务,并有计划融合进TubeMQ接下来的版本中。如下是相关特性比较:

比较项
TubeMQ
Kafka
Pulsar
数据时延
非常低,10毫秒级
比较低,250毫秒级
非常低,10毫秒级
请求TPS
高,单机14W+/s
一般,单机10W+/s
一般,单机10W+/s (大压力下不稳定)
过滤消费
支持服务端过滤
客户端过滤,不支持服务端过滤
客户端过滤,不支持服务端过滤
数据副本同步策略
无,通过RAID10磁盘备份+低时延消费解决
多机异步备份
多机异步备份(高性能场景)
数据可靠性
一般,单机故障未消费的数据存在丢失风险
一般,主机故障未同步的数据存在丢失风险
一般,主机故障未同步的数据存在丢失风险
单机磁盘IO 100%时对外服务能力
高,特定机型下可以通过SSD转存储消费功能,维持约700M写入及超过1G的消费流量
低,滞后会读写受阻,甚至会停写
低,滞后会读写受阻,甚至会停写
系统稳定性
高,已线上运营7年,每天25万亿的数据量,已做到单集群400台Broker的线上运营规模
一般,性能随Topic数增多出现不稳定情况,没有超大数据运营规模场景
一般,高压下存在性能下降、服务受阻等情况
跨集群管控能力
有,实施中
配置可管理性
高,热备存储,中心化管理,API或页面操作
一般,基于zk配置管理,API或页面操作
一般,基于zk配置管理,API或页面操作
易用性
一般,只提供Java和C++的Lib,数据上报支持tcp、udp、http
高,有很多配套插件使用
高,有很多配套插件使用


TubeMQ集群架构

经过多年演变,TubeMQ集群分为如下5个部分:
640?wx_fmt=png

  • 负责对外交互和运维操作的Portal部分,包括API和Web两块,API对接集群之外的管理系统,Web是在API基础上对日常运维功能做的页面封装;
  • 负责集群控制的Control部分,该部分由1个或多个Master节点组成,Master HA通过Master节点间心跳保活、实时热备切换完成(这是大家使用TubeMQ的Lib时需要填写对应集群所有Master节点地址的原因),主Master负责管理整个集群的状态、资源调度、权限检查、元数据查询等;
  • 负责实际数据存储的Store部分,该部分由相互之间独立的Broker节点组成,每个Broker节点对本节点内的Topic集合进行管理,包括Topic的增、删、改、查,Topic内的消息存储、消费、老化、分区扩容、数据消费的offset记录等,集群对外能力,包括Topic数目、吞吐量、容量等,通过水平扩展Broker节点来完成;
  • 负责数据生产和消费的Client部分,该部分我们以Lib形式对外提供,大家用得最多的是消费端,相比之前,消费端现支持Push、Pull两种数据拉取模式,数据消费行为支持顺序和过滤消费两种。对于Pull消费模式,支持业务通过客户端重置精确offset以支持业务extractly-once消费,同时,消费端新推出跨集群切换免重启的BidConsumer客户端;
  • 负责offset存储的zk部分,该部分功能已弱化到仅做offset的持久化存储,考虑到接下来的多节点副本功能该模块暂时保留。


Broker文件存储方案

以磁盘为数据持久化媒介的系统都面临各种因磁盘问题导致的系统性能问题,TubeMQ系统也不例外,性能提升很大程度上是在解决消息数据如何读写及存储的问题,在这个方面TubeMQ进行了比较多的改进:
TubeMQ的磁盘存储方案类似Kafka,但又不尽相同,如下图示,存储实例由一个索引文件和一个数据文件组成,每个Topic可以分配1个或者多个存储实例,每个Topic单独维护管理存储实例的相关机制,包括老化周期,partition个数,是否可读可写等:
640?wx_fmt=png
在文件存储基础上,我们针对每个存储实例又额外增加了一个单独的内存缓存块,即在原有写磁盘基础上增加一块内存,隔离硬盘的慢速影响,数据先刷到内存,然后由内存控制块批量地将数据刷到磁盘文件:
640?wx_fmt=png
针对除了由磁盘存储外还带SSD硬件的服务器,我们又做了一层SSD存储,在磁盘IO飙升时候将滞后消费读进行转移,避免读写集中在SATA盘上,不过该方案有别于外界系统先将数据存SSD,然后再将数据由SSD转到磁盘的通常做法:
按照我们的分析,正常情况下磁盘的顺序读写性能已足够满足数据持久化的需求,磁盘IO到100%时的性能下降主要是由于滞后消费引起,滞后的比例越大影响越大;SSD相比磁盘,虽然读写速度近似内存但写入次数有限,像MQ这种每天大量写的系统很有可能因为SSD突然变得不可写带来系统风险。
基于这些考虑,我们采用了动态的SSD转存储消费方案:正常情况下数据走磁盘读写消费;数据挤压情况出现,并且持续的状态触发运维设置的阀值时,滞后的数据消费将被转移到SSD上进行;数据挤压情况解除后,SSD停用数据继续走磁盘进行读写:
640?wx_fmt=png
目前我们仍在探索新的存储方案,后续版本中我们会将实践后的内容分享到大家。

TubeMQ客户端的演进

业务与TubeMQ接触得最多的是消费侧,怎样更适应业务特点、更方便业务使用我们在这块做了比较多的改进:

  • 数据拉取模式支持Push、Pull:
Push客户端:TubeMQ最初消费端版本只提供Push模式的消费,这种模式能比较快速地消费数据,减轻服务端压力,但同时也带来一个问题,业务使用的时候因为无法控制拉取频率,从而容易形成数据积压数据处理不过来。
带消费中止/继续的Push客户端:在收到业务反馈能否控制Push拉取动作的需求后,我们增加了resumeConsume()/pauseConsume()函数对,让业务可以模拟水位线控制机制,状态比较繁忙时调用pauseConsume()函数来中止Lib后台的数据拉取,在状态恢复后,再调用resumeConsume()通知Lib后台继续拉取数据。
Pull客户端:我们后来版本里增加了Pull客户端,该客户端有别于Push客户端,是由业务而非Lib主动的拉取消息并对数据处理的结果进行成功与否的确认,将数据处理的主动权留给业务。这样处理后,虽然服务端压力有所提升,但业务消费时积压情况可大大缓解。

  • 数据消费行为支持顺序和过滤消费:


在TubeMQ设计初我们考虑是不同业务使用不同的Topic,实际运营中我们发现不少业务实际上是通过代理模式上报的数据,数据通过Topic下的文件ID或者表ID属性来区分,业务为了消费自己的一份数据是需要全量消费该Topic下的所有数据。我们通过tid字段支持指定属性的过滤消费模式,将数据过滤放到服务端来做,减少出流量以及客户端的数据处理压力。

  • 支持业务extractly-once消费:

为了解决业务处理数据时需要精确回档的需求,在客户端版本里提供了通过客户端重置精确offset功能,业务重启系统时,只需通过客户端提供待回拨时间点的消费上下文,TubeMQ即可按照指定的精确位置接续消费。该特性目前已在Flink这类实时计算框架使用,依托Flink基于checkpoint机制进行extractly-once数据处理。

TubeMQ捐赠Apache软件基金会

值得注意的是,腾讯已将TubeMQ捐献给全球最大的开源基金会Apache软件基金会,走上了社区开放治理之路。
640?wx_fmt=png
(腾讯开源路线图)

近年来,腾讯在开源上的步伐不断加快。截至11月,腾讯自主开源项目已达89个,Star数超过26万,重点关注领域包括 IaaS、容器与云原生、数据库、大数据与 AI、中间件、IoT/边缘计算、小程序生态等。在不断贡献优质项目之余,腾讯也积极贡献开源社区,除了加入Apache基金会、Linux基金会、LFAI 基金会、OpenStack基金会、MariaDB基金会多个顶尖开源基金会的白金会员外,腾讯众多业务团队和技术人员也积极参与到开源贡献中,已广泛参与数十个社区和项目的建设。

(*本文为AI科技大本营整理文章,转载信联系1092722531


精彩推荐



开幕倒计时16天|2019 中国大数据技术大会(BDTC)即将震撼来袭!豪华主席阵容及百位技术专家齐聚,15 场精选专题技术和行业论坛,超强干货+技术剖析+行业实践立体解读。6.6 折票限时特惠(立减1400元),学生票仅 599 元!

640?wx_fmt=jpeg

推荐阅读

相关文章:

iOS应用版本更新(自动提醒用户)

在#import "AppDelegate.h" 文件中的application:(UIApplication )application didFinishLaunchingWithOptions:(NSDictionary )launchOptions 方法中调用检测结果 获得发布版本的Version 比较当前版本与新上线版本做比较 UIAlertView代理方法

Bash Shell脚本编程-变量知识

Shell:GUI CLI提供交互式接口:提高效率命令行展开:~ ,{}命令别名:alias命令历史:historyGlobbing:*,?,[],[^]命令补全:$PATH指定的目录下路径补全…

FFmpeg中可执行文件ffplay用法汇总

从https://ffbinaries.com/downloads 下载最新的4.1版本的windows 64位FFplay。目前linux下的只有3.2版本的。FFplay是一个由FFmpeg和SDL库组成的简单媒体播放器,它主要用作各种FFmpeg API的测试。 通过执行以下命令将FFplay信息重定位到ffplay_help.txt文件中便于…

用Go重构C语言系统,这个抗住春晚红包的百度转发引擎承接了万亿流量

整理 | 夕颜出品 | AI科技大本营(ID:rgznai100)11 月 20 日,百度的万亿流量转发引擎 BFE 登上了 GitHub Trending Top 3,今日 Star 已突破 270。事实上,这个曾经抗住 2019 年春晚抢红包的转发引擎早已于 2019 年夏在 G…

Swift3.0带来的变化汇总系列一——字符串与基本运算符中的变化

var string "Hello-Swift" //获取某个下标后一个下标对应的字符 char"e" //swift2.2 //var char string[startIndex.successor()] //swift3.0 var char string[string.index(after: startIndex)] //获取某个下标前一个下标对应的字符 char2 "t&qu…

vc+如何添加右键弹出菜单

2019独角兽企业重金招聘Python工程师标准>>> 一、创建新工程 二、编辑菜单资源 1、添加菜单 按“CtrlR”,双击“Menu”图标2、于菜单编辑器内编辑菜单四、添加代码(红色部分) void CCMenuView::OnUpdateShow(CCmdUI* pCmdU…

EMNLP 2019 | 大规模利用单语数据提升神经机器翻译

BDTC大会官网:https://t.csdnimg.cn/q4TY作者 | 吴郦军、夏应策来源 | 微软研究院AI头条(ID:MSRAsia)编者按:目前,目标语言端的无标注单语数据已被广泛应用于在机器翻译任务中。然而,目标语言端的无标注数据…

swift 3.0 json解析、字典转模型三种方案

swift3.0发布有一段时间了,发现很多朋友在swift3.0json解析上上遇到很多问题,我这边为大家提三种常见的json方案。 1.第一种是自带的字典转模型,自带的需要实现系统的setValue方法,然后自己还要实现dictToModel方法即可解析&…

海思3559A上编译GDB源码操作步骤及简单使用

1. 从http://ftp.gnu.org/gnu/gdb/ 下载最新稳定版8.3,即gdb-8.3.tar.gz,解压缩; 2. 在gdb-8.3目录下,创建一个build.sh脚本文件,内容如下: ./configure \--prefix"$PWD/install" \--targetaar…

Hibernate之继承映射

Hibernate的继承映射可以理解为两个持久化类之间的继承关系 例如老师和人之间的关系 持久化类 Person类 public class Person { private Integer id; privvate String name; private String sex; public Person (){} // 无参构造器 p…

AutoML未来可期,工程师的明天何去何从?

人工智能和机器学习建模专业技术人才紧缺,即使是高水平的人工智能专家,在大数据智能分析机器学习建模时,主要依靠人工经验,建模过程费时费力,缺少有效方法。为了解决这一突出问题,国内外出现了一种用机器学…

海思3559A上编译Valgrind源码操作步骤

注:按照以下步骤可以在海思板子上正常编译valgrind源码并生成valgrind可执行文件,但可能还不能在海思板子上正常使用。 1. 从http://valgrind.org/downloads/?srcwww.discoversdk.com 下载Valgrind 3.15.0即valgrind-3.15.0.tar.bz2; 2. 在valgrind-3…

Swift之SDWebImage第三方框架

在学习Swift过程中,最害怕的使用了OC的第三方框架 好不容易配置成功了,却出现了意外的Bug [UIImageView setImageWithURL:]: unrecognized selector sent to instance解决办法 第一次配置的时候,因为百度了教程,所以一次性成功…

文件分区格式化及挂载

创建一个5G的分区,文件系统为ext2,卷标为DATA,块大小为1024,预留管理空间为磁盘分区的8%;挂载至/backup目录,要求使用卷标进行挂载,且在挂载时启动此文件系统上的acl功能;在虚拟机创…

iOS开发swift版异步加载网络图片(带缓存和缺省图片)

iOS开发之swift版异步加载网络图片 与SDWebImage异步加载网络图片的功能相似,只是代码比较简单,功能没有SD的完善与强大,支持缺省添加图片,支持本地缓存。 异步加载图片的核心代码如下: func setZYHWebImage(url:NSStr…

2097352GB地图数据,AI技术酷炫渲染,《微软飞行模拟器》游戏即将上线

整理 | 若名出品 | AI科技大本营(ID:rgznai100)“只要是真实存在的地方,你都能抵达。”作为即将成为第一款将整个地球化作虚拟世界来供玩家玩的游戏,微软的《微软飞行模拟器》(Microsoft Flight Simulator)…

开源库nothings/stb的介绍及使用(图像方面)

GitHub上有个开源的stb库,Star数已过万,地址为https://github.com/nothings/stb,为何叫stb,是用的作者名字的缩写Sean T. Barrett。此库仅包含头文件,除stretchy_buffer.h外,其它所有文件以前缀stb开头&…

git stuff

git stuff trick git bash 无法标记复制解决办法 git bash窗口左上角图标点击,选择属性->选项->快速编辑模式 确定就ok了 Usual Commands 创建分支git branch branch-namegit push origin branch-name 删除分支git branch -r -d origin/branch-name 删除远程分支git push…

swift3.0之闭包

Swift 相比原先的 Objective-C 最重要的优点之一,就是对函数式编程提供了更好的支持。 Swift 提供了更多的语法和一些新特性来增强函数式编程的能力,本文就在这方面进行一些讨论。 Swift 概览 对编程语言有了一些经验的程序员,尤其是那些对多…

Linux下gdb attach的使用(调试已在运行的进程)

在Linux上,执行有多线程的程序时,当程序执行退出操作时有时会遇到卡死现象,如果程序模块多,代码量大,很难快速定位,此时可试试gdb attach方法。 测试代码main.cpp如下,这里为了使程序退出时产生…

一行Python代码能实现这么多丧心病狂的功能?(代码可复制)

最近看知乎上有一篇名为《一行 Python 能实现什么丧心病狂的功能?》(https://www.zhihu.com/question/37046157)的帖子,点进去发现一行Python代码可以做这么多丧心病狂的功能!整理了一下知乎上这篇文章的内容&#xff…

一步一步写算法(之图结构)

原文:一步一步写算法(之图结构) 【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 图是数据结构里面的重要一章。通过图,我们可以判断两个点之间是不是具有连通性…

FFmpeg中可执行文件ffprobe用法汇总

从https://ffbinaries.com/downloads 下载最新的4.1版本的Windows 64位FFprobe,FFprobe用于从多媒体流中获取相关信息或查看文件格式信息,并以可读的方式打印,FFprobe可以作为一个命令行程序单独使用。 通过执行以下命令将FFprobe信息重定位…

CocoaPods导入的库其头文件导入的方法

尽管CocoaPods使用十分方便,但其导入的第三方框架还是要经过几步操作,才能供项目使用; 第一步:导入库 1>-在终端进入项目的根目录; 2>-输入:touch Podfile,则项目文件夹会创建一个空的Podfile,这时,你可以将你想要导入的库写在里面.如: platform :ios, 6.0 pod RESid…

Google、微软、阿里、腾讯、百度这些大公司在GitHub上开源投入排名分析 | CSDN原力计划...

扫码参与CSDN“原力计划”作者 | 村中少年来源 | CSDN原力计划获奖作品现在有越来越多的公司都参与了开源,其背后有各自的目的所在,姑且不予讨论。本文是从多个方面分析各大公司在开源上的投入情况。由于全世界绝大多数的开源项目都有发布到Github上&…

jquery源码解析:each,makeArray,merge,grep,map详解

jQuery的工具方法,其实就是静态方法,源码里面就是通过extend方法,把这些工具方法添加给jQuery构造函数的。 jQuery.extend({ ...... each: function( obj, callback, args ) { //$.each(arr , function(i,value){}),第三个参数用于…

swift实现提示框第三方库:MBProgressHUD

GitHud的下载地址是:https://github.com/jdg/MBProgressHUD/ 下载完成后,将MBProgressHUD.h和MBProgressHUD.m拖入已经新建好的Swift项目。因为使用的swift语言,所以拖入项目的时候会提示是否新建一个桥接objective-c与swift的文件&#xff…

这段Python代码让程序员赚300W,公司已确认!网友:神操作!

Python到底还能给人多少惊喜?笔者最近看到了这两天关于Python最热门的话题,关于《地产大佬潘石屹学Python的原因》,结果被这个回答惊到了:来源:知乎 https://www.zhihu.com/question/355880221笔者翻了翻那些回答&…

FFmpeg中可执行文件ffmpeg用法汇总

从https://ffbinaries.com/downloads 下载最新的4.1版本的Windows 64位FFmpeg,FFmpeg是一个快速的音频/视频转换工具,FFmpeg可以作为一个命令行程序单独使用。 通过执行以下命令将FFmpeg信息重定位到ffmpeg_help.txt文件中便于查看,其内容如…

下载Ext JS 5.1 gpl版本的方法

先进入官网:http://www.sencha.com然后在导航的Products中选择Sencha Ext JS,会看到以下页面:这时候不要单击Download按钮,而是要单击导航中的DETAILS,页面切换后,就可在底部看到GPL版本的下载按钮了&#…