首页 文章 精选 留言 我的

精选列表

搜索[全基因组选择],共10000篇文章
优秀的个人博客,低调大师

得物视频编辑工具优化全指南

一、背景介绍 随着4G网络的推广和网络带宽的提升,视频成为互联网用户主要的消费载体,用户通过短视频来分享和浏览信息。由此视频的编辑功能越来越重要、越来越普遍。视频编辑的App也如雨后春笋般涌现。 为更好地推动得物App社区业务的发展,得物也自研符合得物需求的视频编辑工具。我们致力于打造一个“更快、更强”的视频编辑工具。 二、视频编辑工具介绍 为了让大家更好地了解得物App的视频编辑工具,我们先简单介绍一下视频编辑工具的主要功能。 下面是得物App视频编辑工具的主要功能: 视频编辑工具的重点如下: 视频编辑工具需要操作的资源: 文字:包括普通的文字、特殊的艺术字、花字等等; 图片:包括静态图,如JPEG/PNG等等,也包括HEIC/GIF等动态图; 视频:包括各种各样的视频(各种编码和封装格式),主流的格式一般是MP4的封装格式、H264视频编码格式、AAC音频编码格式等等; 音频:包括各种各样的音频(各种编码和封装格式),当然视频当然也是包含音频轨道的。 视频编辑工具主要的操作方式: 操作图片、视频帧:我们知道视频是一帧一帧的图片组成的,所以操作视频帧和操作图片是一样的道理,我们通过添加一些特效在图片和视频帧上面,实现一些有趣的效果来吸引用户。 操作音频:主流的操作音频方式如倍速、调整音量、变调等等,都是现今短视频的主要玩法。 视频编辑工具最终生成的是一个新的视频,这个视频将特定的资源应用一些特效生成一个新的视频。 下面的流程图可以很方便地让大家了解视频编辑的工作流程。为了方便,我们输入一个视频,加上一些特效,生成一个新的视频。 从上面的流程可以看出来,原始视频A.mp4经过解封装分离出音频轨道和视频轨道,对它们解码之后,对音频数据应用音频特效、对视频帧数据应用视频特效,然后编码封装合成一个新的视频。当然解码和编码都是有一个队列控制的,流程图上标注了,没有深入展开,大家了解即可。 经过上面的介绍,大家对视频编辑工具有了大概得了解,其实衡量一个视频编辑工具做得好不好,主要从下面这几个方面着手: 内存占用情况 导出视频的速度如何 导出视频的清晰度如何 下面从这三方面详细展开给大家阐述得物App的视频编辑工具优化的心路历程。 三、内存优化 性能是所有程序好不好的首要指标,一个工具即使功能再强大,但是一点就崩溃,或者用着用着内存暴涨、应用卡死,估计这个应用不能称为一个优秀的应用,下面我们具体谈一谈视频编辑工具的优化检测方案。 优化内存从良好的编码习惯开始,尤其对音视频这种对内存需求非常高的应用而言。例如一个1080 * 1920的视频,解码出来原始数据一帧图片大小也是1080 * 1920,占用内存是1080 * 1920 * (8 * 3 ) / 8 = 5.93 MB,一个视频帧就占用这么大,1秒一般有30帧,那得占用177.9MB,如果不加控制,那不管多高性能的手机也经不住这样的折腾。希望下面的内存检测和优化方案可以给你带来一些帮助。 3.1 合理设计队列 上面我们在介绍视频编辑流程的视频谈到了解码队列和编码队列的概念。其实队列这个概念在音视频中使用非常频繁,正是因为内存的限制,所以才引入队列这个控制方式。大家可能还有点懵,但是看完下面的流程图,我相信你一定会豁然开朗。 我们仅选取解码的部分来分析一下队列的重要应用。 在视频编辑工具中有几个重要的队列: 解码过程中: Video Packet Queue:视频解码之前Packet存放的队列,一般建议的队列大小是100 Audio Packet Queue:音频解码之前Packet存放的队列,一般建议的队列大小是150 Video Frame Queue:视频解码之后Frame存放的队列,一般建议的队列大小是3 Audio Frame Queue:音频解码之后Frame存放的队列,一般建议的队列大小是8 编码过程中: Encode Video Packet Queue:视频编码之后Packet存放的队列,一般建议的大小是100 Encode Audio Packet Queue:音频编码之后的Packet存放的队列,一般建议的大小是150 按照上面的方式设计队列的大小,可以在保证功能正常的情况下最大程度的降低内存占用,提升用户体验。 3.2 排查内存泄漏 Android上排查内存泄漏的方式有很多,这里介绍两种: Asan检测 Profile检测 Asan全称是AddressSanitizer是一种基于编译器的快速检测的工具,用于检测原生代码中的内存错误问题,Asan可以解决如下四种核心问题: 堆栈和堆缓冲区上溢、下溢 释放之后堆重新使用问题 超过范围的堆栈使用情况 重复释放、错误释放问题 Asan的使用方式建议参考google官方文档,这儿就不多作介绍了: https://github.com/google/sanitizers/wiki/AddressSanitizer 关于Profile的使用,如果需要检测Native内存使用情况,需要满足API>=29,大家在使用的时候需要非常注意。 下面是我们在demo中应用Asan抓取的堆栈: 20042-20042/? A/DEBUG: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 20042-20042/? A/DEBUG: Build fingerprint: 'samsung/t2qzcx/t2q:11/RP1A.200720.012/G9960ZCU2AUGE:user/release-keys' 20042-20042/? A/DEBUG: Revision: '13' 20042-20042/? A/DEBUG: ABI: 'arm64' 20042-20042/? A/DEBUG: Timestamp: 2021-09-17 00:32:31+0800 20042-20042/? A/DEBUG: pid: 19946, tid: 20011, name: AudioTrack >>> com.jeffmony.audioplayer <<< 20042-20042/? A/DEBUG: uid: 10350 20042-20042/? A/DEBUG: signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr -------- 2021-09-17 00:32:31.157 20042-20042/? A/DEBUG: Abort message: '================================================================= ==19946==ERROR: AddressSanitizer: heap-use-after-free on address 0x004ac1e41080 at pc 0x007157f69580 bp 0x00705c0bb350 sp 0x00705c0bab08 READ of size 1792 at 0x004ac1e41080 thread T32 (AudioTrack) #0 0x7157f6957c (/data/app/~~G094WKQQj7KZvdhvGYDLDA==/com.jeffmony.audioplayer-kcu1nmgzpBIQDRJDxCJDOQ==/lib/arm64/libclang_rt.asan-aarch64-android.so+0x9f57c) #1 0x706549c228 (/data/app/~~G094WKQQj7KZvdhvGYDLDA==/com.jeffmony.audioplayer-kcu1nmgzpBIQDRJDxCJDOQ==/lib/arm64/libltpaudio.so+0x14228) #2 0x706549bcd4 (/data/app/~~G094WKQQj7KZvdhvGYDLDA==/com.jeffmony.audioplayer-kcu1nmgzpBIQDRJDxCJDOQ==/lib/arm64/libltpaudio.so+0x13cd4) #3 0x70654994f0 (/data/app/~~G094WKQQj7KZvdhvGYDLDA==/com.jeffmony.audioplayer-kcu1nmgzpBIQDRJDxCJDOQ==/lib/arm64/libltpaudio.so+0x114f0) #4 0x70654a9cbc (/data/app/~~G094WKQQj7KZvdhvGYDLDA==/com.jeffmony.audioplayer-kcu1nmgzpBIQDRJDxCJDOQ==/lib/arm64/libltpaudio.so+0x21cbc) #5 0x70654a91d4 (/data/app/~~G094WKQQj7KZvdhvGYDLDA==/com.jeffmony.audioplayer-kcu1nmgzpBIQDRJDxCJDOQ==/lib/arm64/libltpaudio.so+0x211d4) #6 0x715af9d188 (/system/lib64/libwilhelm.so+0x1c188) #7 0x71570ea290 (/system/lib64/libaudioclient.so+0x8b290) #8 0x71570e9480 (/system/lib64/libaudioclient.so+0x8a480) #9 0x7156b664d4 (/system/lib64/libutils.so+0x154d4) #10 0x71593e9974 (/system/lib64/libandroid_runtime.so+0xa5974) #11 0x7156b65db0 (/system/lib64/libutils.so+0x14db0) #12 0x7156ace234 (/apex/com.android.runtime/lib64/bionic/libc.so+0xb6234) #13 0x7156a68e64 (/apex/com.android.runtime/lib64/bionic/libc.so+0x50e64) 0x004ac1e41080 is located 0 bytes inside of 1792-byte region [0x004ac1e41080,0x004ac1e41780) freed by thread T32 (AudioTrack) here: #0 0x7157f74c64 (/data/app/~~G094WKQQj7KZvdhvGYDLDA==/com.jeffmony.audioplayer-kcu1nmgzpBIQDRJDxCJDOQ==/lib/arm64/libclang_rt.asan-aarch64-android.so+0xaac64) #1 0x70654a6d2c (/data/app/~~G094WKQQj7KZvdhvGYDLDA==/com.jeffmony.audioplayer-kcu1nmgzpBIQDRJDxCJDOQ==/lib/arm64/libltpaudio.so+0x1ed2c) #2 0x70654a6af0 (/data/app/~~G094WKQQj7KZvdhvGYDLDA==/com.jeffmony.audioplayer-kcu1nmgzpBIQDRJDxCJDOQ==/lib/arm64/libltpaudio.so+0x1eaf0) #3 0x706549bf4c (/data/app/~~G094WKQQj7KZvdhvGYDLDA==/com.jeffmony.audioplayer-kcu1nmgzpBIQDRJDxCJDOQ==/lib/arm64/libltpaudio.so+0x13f4c) #4 0x706549bcd4 (/data/app/~~G094WKQQj7KZvdhvGYDLDA==/com.jeffmony.audioplayer-kcu1nmgzpBIQDRJDxCJDOQ==/lib/arm64/libltpaudio.so+0x13cd4) #5 0x70654994f0 (/data/app/~~G094WKQQj7KZvdhvGYDLDA==/com.jeffmony.audioplayer-kcu1nmgzpBIQDRJDxCJDOQ==/lib/arm64/libltpaudio.so+0x114f0) #6 0x70654a9cbc (/data/app/~~G094WKQQj7KZvdhvGYDLDA==/com.jeffmony.audioplayer-kcu1nmgzpBIQDRJDxCJDOQ==/lib/arm64/libltpaudio.so+0x21cbc) #7 0x70654a91d4 (/data/app/~~G094WKQQj7KZvdhvGYDLDA==/com.jeffmony.audioplayer-kcu1nmgzpBIQDRJDxCJDOQ==/lib/arm64/libltpaudio.so+0x211d4) #8 0x715af9d188 (/system/lib64/libwilhelm.so+0x1c188) #9 0x71570ea290 (/system/lib64/libaudioclient.so+0x8b290) 显示message是:heap-use-after-free on address 0x004ac1e41080 说明是使用了已经释放掉的内存了,再继续看,这个内存具体在什么地方被释放的?0x004ac1e41080 is located 0 bytes inside of 1792-byte region [0x004ac1e41080,0x004ac1e41780) Asan一个很大的优势就是可以追踪内存释放的路径,防止出现内存泄漏和野指针问题,特别是野指针,一旦出现特别难排查,简直是C++开发的噩梦,希望大家用好工具,同时培养良好的C++编码习惯。 3.3 优化线程 另一个影响内存的重要因素是线程,视频编辑工具涉及到的线程非常多,线程的使用得遵循一些基本的原则: 尽量少创建线程 尽量少使用pthread_mutex_t 本着功能隔绝原则使用线程 能同步就别异步 以编辑模块为例,这儿列一下我们使用到的所有线程: GL处理线程 视频解封装线程 视频中视频轨道解码线程 视频音频轨道解码线程 抽取缩略图线程 音频编码线程 视频编码线程 视频封装线程 如果插入了独立的音频文件,还需要添加两个额外的线程: 音乐文件播放线程 音乐文件解码线程 上面列出的是一个视频编辑工具能正常工作所必备的最少线程,如果你的视频编辑工具中多了什么线程,我们建议可以适当优化一下,毕竟少一个线程,可以少一分开销,而且少一分线程同步的工作。 我们在底层也按照Android的消息机制重写了一套C++层的消息分发SDK,这个我们后续会另外分享文章阐释我们定制的消息分发SDK,这儿点到为止。 四、提升导出视频的速度 我们使用视频编辑工具,最终是希望导出一个视频,如果这个导出的过程很慢,那肯定是无法忍受的,从上面的介绍我们已知视频的导出需要经过“解码——应用特效——编码”的过程,其中解码和编码这两个过程对速度的影响至关重要。因为解码和编码视频需要耗费大量的资源,目前主要有两种方式——“软解/编码”和“硬解/编码”。 如果你使用过FFmpeg或者其他使用CPU进行视频编解码的来处理视频的话,你可能已经遇到了处理速度慢的问题。这主要是因为软编码和软解码使用CPU进行运算,而CPU在处理视频上的速度远低于DSP芯片;简而言之“软解/编码”主要通过CPU来工作,通过CPU来主导大量的计算工作,是原始的处理方式,当然耗费的时间也比较长;“硬解/编码”是通过GPU来处理,GPU是专用的图形处理芯片,对视频的解码和编码有专门的优化,所以编码和解码的速度非常快。 Android上使用MediaCodec来实现“硬解/编码”,iOS上使用VideoToolBox来实现“硬解/编码”,这里着重介绍Android上编码解码的速度优化。 从上面的流程我们可以看出,编码在解码的后面,一个时长60s(30fps)的视频,需要解码1800帧,然后编码1800帧视频才能完整生成另外一个视频,这样串行的等待是耗时的主要原因。 这时候我们参考多线程方案,将一个60s的视频均分为两段,然后这两段视频同时进行解码操作,生成导出了两个30s的临时缓存视频文件,随后将这两个30s的视频合并为一个60s的B.mp4视频,最后删除临时缓存文件,这样我们只需要同时处理900帧的数据,理论上可以提升一倍的导出速度。 这就是并行导出,下面是得物App并行导出的基本流程。 首先我们要明确导出视频是需要消耗资源的,这个资源就是MediaCodec,最终是送入到GPU中处理,一个手机中的MediaCodec实例是有限的,正常情况下,一个手机可以提供的MediaCodec实例最多有16个,如果当前使用的MediaCodec实例超过16个,那么手机将无法正常工作。MediaCodec资源是手机中的所有App共同持有。所以并行分段的个数不是越多越好。 只有一段,需要两个MediaCodec(一个用来解码视频,一个用来编码视频),注意:音频的解码和编码可以不要用MediaCodec,毕竟音频的耗时少多了,不是瓶颈。 分成两段需要四个MediaCodec,分成三段需要六个MediaCodec,分成四段需要八个MediaCodec,以此类推。 下面是并行导出的测试结果: 两段并行速度提升50% ~ 70%,内存增加20%, 三段并行速度提升60% ~ 90%,内存增加80%;并行超过三段的话就无法明显提升速度了。我们比较建议并行两段,在一些性能很好的机型上并行三段。 如果有些同学对视频导出过程中文件操作还有疑问的,下面的示意图可以比较清楚地看出并行导出操作本地文件的过程: 并行导出的过程中,生成了两个临时文件 并行导出完成后,这两个临时文件合并为一个新的文件,两个临时生成的文件被删除了(节省用户宝贵的存储空间) 原始文件jeffmony_out.mp4并没有被删除/修改 Tips:目前我们在处理过程中生成的临时文件和最终的适配文件都会保存在/sdcard/Pictures/duapp/Compile/下,而在处理完成后的临时文件清理过程会触发在某些机型上的保护机制,建议后续调整到App的私有目录下。 当然还有其他的提升导出速度的建议,例如在视频帧特效处理的过程中,我们建议: 尽量采用FBO/EBO/ABO方式处理texture 纹理如果过大要进行压缩 严禁采用glFinish() 这些做法都是我们在视频编辑开发过程中的切实经验,希望能给大家带来一些帮助。 五、提升导出视频的清晰度 一个视频编辑功能是否足够优秀,其中的一个重要指标就是同等条件下导出的视频是否足够清楚,通常而言,衡量视频是否清晰的有两种方式: 主观标准:找一些用户观看不同的视频,根据用户的观感输出视频清晰度的对比结果,用户一般根据色彩、画面亮度、柔和度等来评估清晰度。 客观标准:利用算法计算视频画面质量分,目前比较推荐Netflix推出的开源库VMAF来计算视频帧的质量分。 实际上主观标准是比较准确的,但是可操作性比较差,特别是处理海量视频的时候,需要大量的人力,无法有效开展,因此日常工作中还是推荐客观标准进行海量计算,主观标准进行重点判断。具体的可以结合业务的重要程度来开展。 下面结合我们实际的工作给出具体提升视频清晰度的方式: 视频基础编码信息优化 Profile优化:Profile有三种Level,分别是Baseline、Main、High,其中Baseline Profile对应清晰度最低,Android 3.0之后的版本都支持的,Main Profile清晰度比Baseline Profile清晰度要好,但是从Android 7.0之后才支持,High Profile清晰度最高,也是从Android 7.0之后才支持。我们在设置Encoder Profile Level之前,需要判断一下当前是否支持。 Bitrate码率设置: 视频码率是视频数据传输时单位时间内传送的数据位数。单位是kbps,望文生义,码率越大,单位时间填充的数据就越多,视频质量就越高。但码率也不是设置的越大越好,超过必要限度,对视频画质的提升已不明显,建议采用合适的factor来调整码率。Bitrate = width * height * frameRate * factor,其中factor=0.15。 Bitrate Mode: 有三种通过的编码模式——VBR(可变码率)、CBR(固定码率)、ABR(平均码率),其中ABR是最好的方式,可以兼顾质量和视频大小。 B帧设置: 视频有I帧、P帧、B帧构成,其中I帧最大,P帧次之,B帧最小,我们在编码时尽量多设置B帧(在合理的范围内),并不会降低清晰度,但是可以大大降低视频的大小,这样我们就可以相应地调大码率,最终实现了提升清晰度的目标。 HEVC编码优化: 使用HEVC编码,可以保证在不增加文件大小的情况下,大大提升视频的清晰度。在相同的图像质量下,HEVC编码的视频比H.264编码的视频约减少40% 色彩调优 综合调整亮度、对比度、色温、饱和度、锐度等颜色参数,进而优化整体的视频画面,让视频画面看上去“更清晰”。 **超分算法 **: 采用ESRGAN算法,利用机器学习的优势对图片和视频进行去模糊、Resize、降噪、锐化等处理,重建图片,实现对图片的超分辨率处理。 特征提取:计算噪点 非线性映射:放大,模糊化噪点 图像重建:差分,平滑过度,去噪 下面是使用超分算法处理前后的对比图,可以很明显地看出右边的图更加清晰,少了很多噪点、图片更亮、过度更平滑。 如果大家想了解视频清晰度优化的技术细节,可以参考文章--视频清晰度优化指南 六、总结 本文开篇从介绍得物App的主要功能展开,提出了视频编辑工具优化的三个维度: 优化内存占用 提升视频导出速度 提升导出视频的清晰度 其中在“提升视频导出速度”时重点谈到了“并行导出”的技术方案,从最终的结果来看,视频导出速度的提升非常明显,同时也非常清楚地解释了“并行导出”过程中为什么生成临时文件?为什么有必要在导出完成之后删除临时文件?尽力给用户带来较好的体验。 最后在“提升导出视频的清晰度”中重点提到的超分算法应用效果提升明显,超分之后的视频帧相比原帧图更加清晰、噪点更少,而且细节部分更加真实。 后续我们还会结合AR特效输出更多有意义的技术分享,敬请期待。 *文 /JeffMony 关注得物技术,每周一三五晚18:30更新技术干货 要是觉得文章对你有帮助的话,欢迎评论转发点赞~

优秀的个人博客,低调大师

Hanami 2.0 发布,全栈 Ruby Web 框架

经过三年多的努力,Hanami 2.0 正式发布,随着这个版本的发布,Hanami 进入了框架成熟的新阶段,并为 Ruby 社区开启了新的篇章。 更好 Hanami 2.0 的核心是现在的 app/ 目录,在这里,你可以随心所欲地组织你的代码,同时还可以享受常见组件的合理默认值。随着你的应用程序的增长,你可以利用切片的优势,将你的代码分成若干域。 Hanami 2.0 提供了一个既简单又强大的框架: 新的应用程序核心提供了以容器和组件为中心的高级代码加载功能 代码自动加载帮助你以最小的代价工作 新的内置切片随着你的应用程序的增长而逐渐提供模块化。 一个始终存在的依赖关系混合器帮助你在你的应用程序的组件之间建立更清晰的联系 重新设计的 action 类与你的应用程序的业务逻辑无缝集成 带有 dotenv 集成的类型安全的应用程序设置,确保你的应用程序在每个环境中都有它所需要的东西。 新的供应商管理你的应用程序的关键组件和集成的生命周期 自上而下的模块化使您能够构建各种类型的应用程序,包括非 Web 应用程序 我们重写的入门指南可以帮助你开始使用上述所有内容 更快 Hanami 2.0 完全重写了 HTTP 路由引擎,基准显示它超过了几乎所有其他引擎。 当在开发中使用 Hanami 时,由于我们的智能代码加载,你的应用程序将立即启动和重新加载。无论你的应用程序有多大,你的控制台将在几毫秒内加载,你的测试将保持快速。 更多详情可查看:https://hanamirb.org/blog/2022/11/22/announcing-hanami-200/

优秀的个人博客,低调大师

微服务超全的设计选型参考

云栖号资讯:【点击查看更多行业资讯】在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来! 微服务架构模式的核心包含如下几部分: 微服务之间的 RPC 通信。Java Chassis 提供了非常高效的通信方式,并支持多协议扩展,比如最快的 REST 通信模式实现, 异步的二进制通信模式 HIGHWAY 。 分布式微服务实例和服务发现。结合 ServiceComb Service Center, 实现分布式、多集群服务发现能力,以及强大的微服务元数据管理能力。 配置外置,动态、集中的配置管理。能够使用 ServiceComb Kie, 华为云配置中心、 Nacos、 Apollo 等多种配置中心, 并且和 Spring Boot 配置管理能力完整融合。 分布式故障管理,服务容错、隔离、熔断。内置故障实例隔离、故障重试、耗时接口隔离等重要分布式故障处理能力。可选使用 Hystrix 的 容错、隔离、熔断能力, 只需要做简单的配置。 分布式日志追踪。提供 Open Tracing 支持。 此外还有性能监控,日志记录系统、健康检查等。Java Chassis 采用优雅的设计模式,实现了上述所有的核心部件的功能,并且使得这些功能 开箱即用。使用 Java Chassis , 开发者能够更加聚焦于业务功能开发,快速的构建商业可用的微服务应用。 Java Chassis 的软件工程实践 Java Chassis 在设计的时候, 不仅考虑了如何更好的使用微服务架构模式, 还把优秀的软件工程思想融合进来, 帮助开发者更好的管理信息 资产, 提升软件工程管理能力。 下图简单的描述 “以契约为中心” 的核心概念。 可以通过 Invocation 获取到 Java Chassis 的契约等源数据信息, 是 Java Chassis 的一个核心对象。 Java Chassis 的运行时架构 为了支持软件工程实践, Java Chassis 的运行时架构是一个哑铃结构, 两端分别是“编程模型” 和 “通信模型”, 中间是“运行模型”。 “编程模型” 面向开发者写服务接口的习惯, “通信模型” 面向微服务之间的高效编码和通信, “运行模型” 基于“契约”, 提供一种服务服务无关 的插拔机制,能够让开发者独立于业务实现开发治理功能,并且灵活的移除和增加功能,以及调整这些治理功能的处理顺序。 “运行模型” 的核心抽象接口是 Handler , 这个接口是一个异步的定义, Java Chassis 运行时模型采用纯异步的实现, 让整个系统运行非常 高效。 Java Chassis 微服务应用架构 有很多优秀的微服务应用架构实践。微服务应用架构应该充分考虑系统的弹性, 能够针对系统的性能瓶颈点进行扩容, 需要考虑应用系统内部微服务 拆分的灵活性, 为业务的变更做好及时调整。 下图展示了一个典型的应用架构。接入层采用一些网络基础设施,比如 DNS , 浮动 IP 等方便用户采用统一的 URL 访问系统, 或者采用 API 网关等 基础设施实现系统的能力开放。业务层包含应用网关, 进行一些认证鉴权、 审计等功能, 经过认证的请求被应用网关转发到微服务系统内部。 Java Chassis 微服务技术选型 Java 语言拥有庞大的技术体系和标准, 并且广泛的应用到业务的系统的各个方面。和 Java Chassis 有紧密关系的技术包括 JSP/Servlet 标准 和容器, Spring 和 Spring Boot 技术, 以及 Spring Boot 提供的 REST 开发框架 Spring MVC。 Java Chassis 和 JSP/Servlet 标准 Java Chassis 不依赖于 JSP/Servlet 标准, 可以基于 Vert.x 的 HTTP 实现, 提供非常轻量级和高效的 REST 服务, 在性能要求高的核心 业务场景, 使用这种轻量级的技术非常合适。这种场景下, 没有完整的实现 JSP/Servlet 相关接口, 比如 HttpServletRequest, HttpServletResponse 等。 servicecomb-samples ( https://github.com/apache/servicecomb-samples/tree/master/porter_lightweight ) 提供了一个完整的使用这种部署模式的例子。 Java Chassis 可以部署运行于 JSP/Servlet 容器里面, 在这个场景下, Java Chassis 的核心部件就是一个 Servlet , 在这个 Servlet 里面 实现了 Java Chassis 的核心 RPC 系统。采用 JSP/Servlet 容器运行 Java Chassis, 业务请求首先经过容器的 HTTP 实现, 然后经过 Filter, 进入 Java Chassis 的 RestServlet , 运行 Java Chassis 的运行时模型 (Handlers) , 进入业务接口处理。 Java Chassis 和 Spring、Spring Boot Java Chassis 目前依赖于 Spring, 但是从设计上是可以独立于 Spring 运行的。Spring 是被广泛使用的技术, 非常轻量级, 在 Java Chassis 中可以直接使用 Spring 相关的技术。Java Chassis 不依赖于 Spring Boot, 但是可以将 Java Chassis 运行于 Spring Boot 基础之上。 Spring Boot 2 开始也提供了多种运行环境支持, WebApplicationType.NONE, WebApplicationType.SERVLET, WebApplicationType.REACTIVE, Java Chassis 可以集成 NONE, SERVLET 两种模式。在 NONE 模式下集成 Java Chassis, 和 Spring Boot 自身的 REACTIVE 非常类似, 但是比 Spring Boot 的 REACTIVE 运行更加高效, 并且支持早期的 RestTemplate API 和 RPC API 来访问服务。 Spring MVC Java Chassis 继承了 Spring MVC 的接口设计, 提供了 Provider 和 Consumer 层面的 API 接口来定义 REST 接口和访问 REST 接口。但是需要 注意的是, 两个是完全不同的实现, 实现机制也不一样。Spring Boot 主要基于 Servlet, 实现了 MVC 模式, 不仅可以开发 REST 接口, 还可以 开发其他 HTTP 功能, 比如重定向, 返回 HTML 页面等, 还可以通过 @ExceptionHandler, @ControllerAdvice 等机制拦截 Servlet 请求,进行 异常处理。Java Chassis 只实现了 REST 服务定义和调用, 并且在异常处理机制和请求拦截机制上不一样。 Java Chassis 与 Spring Cloud Java Chassis 和 Spring Cloud 都实现了微服务架构模式, 相比而言, Java Chassis 是一个更加紧凑的实现, 开箱即用, 而 Spring Cloud 则是 相对松散的实现, 整合了大量的 Hystrix 组件。 微服务架构模式关注微服务内部和微服务之间的设计, 也关注微服务与微服务基础设施之间的关系。Java Chassis 微服务基础设施包括服务注册和发现, 服务配置管理, 灰度发布和契约管理等功能。Spring Cloud 可以使用 spring-cloud-huawei ( https://github.com/huaweicloud/spring-cloud-huawei ) 来使用 Java Chassis 相关的微服务基础设施。 【云栖号在线课堂】每天都有产品技术专家分享!课程地址:https://yqh.aliyun.com/zhibo 立即加入社群,与专家面对面,及时了解课程最新动态!【云栖号在线课堂 社群】https://c.tb.cn/F3.Z8gvnK 原文发布时间:2020-04-02本文作者:sandag本文来自:“51CTO”,了解相关信息可以关注“51CTO”

优秀的个人博客,低调大师

全栈工程师学习路线

某培训机构的课程表,不想去培训的,可以按照这个自学。 1 第一阶段JAVASCRIPT高级 ### 1 1 JavaScript高级 1 1 1 call、apply、bind、new等原理解析 1 1 2 原型链深入 1 1 3 闭包深入 1 1 4 执行上下文和作用域链 1 1 5 作用域链 1 2 ES6深入学习 1 2 1 常量 1 2 2 解构 1 2 3 模板字符串 1 2 4 展开操作符 1 2 5 解构操作符 1 2 6 箭头函数 1 2 7 数组新方法 1 2 8 类和继承 1 2 9 生成器 1 2 10 迭代器和集合 1 2 11 手写一个符合 Promise/A+规范的类库 1 3 V8内存管理 1 3 1 JavaScript中的垃圾收集 1 3 2 JavaScrpt中的内存管理 1 3 3 V8垃圾回收机制 1 3 4 引用记数 1 3 5 标记清除 1 3 6 标记整理和增量标记 2 第二阶段VUE.JS全家桶实战 2 1 基础篇 2 1 1 什么是VUE? 2 1 2 VUE的使用 2 1 3 VUE常见的指令 2 1 4 VUE的事件绑定和属性绑定 2 1 5 Vue中的计算属性 2 1 6 computed和watch的应用 2 1 7 表单中的数据绑定 2 1 8 VUE中的修饰符 2 1 9 自定义过滤器和指令 2 1 10 VUE实例上的方法 2 1 11 VUE中的生命周期 2 1 12 AXIOS应用 2 1 13 async 2 1 14 await 2 2 组件篇(模态框)和路由篇(权限控制) 2 2 1 什么是组件和组件的应用 2 2 2 组件的属性和校验 2 2 3 组件之间的通信 2 2 4 EventBus应用 2 2 5 组件slot用法 2 2 6 vue router的基础应用 2 2 7 编程式导航 2 2 8 路由的嵌套 2 2 9 路由守卫 2 2 10 路由元信息 2 3 vuex篇(商品收藏) 2 3 1 什么是vuex 2 3 2 vuex应用(state/getter/mutation/action) 2 3 3 vuex中的模块拆分 2 4 Vue全家桶项目 2 4 1 Vue-cli3.0项目搭建 2 4 2 服务器端构建koa+mongodb 2 4 3 MintUI和ElementUI组件实战 2 4 4 路由配置和动画 2 4 5 如何Mock后台数据 2 4 6 数据获取和axios应用拦截器 2 4 7 基于JWT的注册登录权限管理 2 4 8 公共组件封装 2 4 9 上拉刷新、下拉加载、图片懒加载 2 4 10 课程购买 2 4 11 微信和支付宝支付 2 4 12 使用vuex项目布署和上线 2 5 项目优化扩展篇和PWA原理 2 5 1 路由懒加载 2 5 2 页面与渲染 2 5 3 SSR之Nuxt 2 5 4 Vue骨架屏 2 5 5 Vue-devtools开发插件 2 5 6 手写自己的Vue组件库 2 5 7 组件的单元测试 2 5 8 Vue中的插件 2 5 9 PWA构建和配置 2 5 10 错误处理 2 5 11 中间件 2 5 12 路由 2 5 13 Skeleton 2 5 14 App Shell模型 2 5 15 手写一款MVVM框架 2 5 16 响应式开发的原理 3 第三阶段REACT全家桶实 ### 3 1 基础篇 3 1 1 模块化和组件化 3 1 2 React的属性 3 1 3 校验和参数传递 3 1 4 React的状态和双向数据绑定 3 1 5 React中的单向数据流 3 1 6 受控组件和非受控组件 3 1 7 React表单处理 3 2 进阶篇 3 2 1 create-react-app原理分析 3 2 2 JSX原理和虚拟DOM原理 3 2 3 setState原理实现 3 2 4 React中的事务处理 3 2 5 使用Immutablejs优化项目性能 3 2 6 React生命周期和动画原理 3 2 7 React错误处理和Hooks 3 2 8 React性能优化(react_perf、pureComponent) 3 2 9 React新的Context Api 3 2 10 fragments React中的高阶组件 3 2 11 React新一代的Fiber架构 3 2 12 手写一款React框架 3 3 路由和Redux篇 3 3 1 路由配置 3 3 2 路由懒加载 3 3 3 路由重定向 3 3 4 路由之权限管理 3 3 5 受保护的路由 3 3 6 手写一个完整的React-router4路由库 3 3 7 Redux核心概念 3 3 8 Action/Reducer/Store 3 3 9 Redux数据流 3 3 10 react-redux连接React组件 3 3 11 redux仓库 3 3 12 redux-logger 打印日志 3 3 13 redux-promise 中间件执行异步任务 3 3 14 redux-thunk 中间件执行异步任务 3 3 15 redux-saga 中间件执行副作用 3 3 16 手写Redux、react-redux、redux-logger、redux-promise、redux-thunk、redux-saga类库 3 4 SSR和mobx篇 3 4 1 客户端渲染VS服务端渲染 3 4 2 React中的服务端渲染 3 4 3 同构的原理和意义 3 4 4 SSR中使用路由 3 4 5 SSR中使用Redux 3 4 6 observable | computed | autorun | when | reaction 3 4 7 mobx实战 3 4 8 手写一个mobx类库 3 5 Ant-Design和AntDesignPro篇 3 5 1 Button、Modal、Loading、Notification、Message、List、Carousel等UI组件 3 5 2 布局组件、表单和复杂表格组件 3 5 3 手写Antdesign组件 3 5 4 让create-react-app可配的命令行工具roadhog 3 5 5 可插拔的企业级react应用框架umi 3 5 6 基于redux和redux-saga的数据流方案dva 3 5 7 开箱即用的中台前端/设计解决方案AntDesignPro 3 5 8 手写dva 4 第四阶段微信小程序&微信公众号&ReactNative ### 4 1 微信小程序 4 1 1 微信小程序 4 1 2 页面结构构建 4 1 3 页面样式定义 4 1 4 基础组件 4 1 5 后端开发接口 4 1 6 支付功能 4 1 7 小程序版珠峰课堂 4 2 微信公众号 4 2 1 微信API 4 2 2 消息中间件 4 2 3 微信公众号内的图片、音视频、图文、Ticket管理及三方接口调用 4 2 4 客户端 4 2 5 服务端 4 2 6 微信三方的请求转发交互 4 3 ReactNative 4 3 1 UIExplorer项目 4 3 2 css盒子模型和样式 4 3 3 css元素的浮动 4 3 4 flexbox布局 4 3 5 ReactNative长度单位 4 3 6 RN事件 4 3 7 React动画原理 4 3 8 实现一个Navigator 4 3 9 App架构之目录结构、路由和组件 4 3 10 App架构之网络和Container 4 3 11 App架构之命名空间 4 3 12 ReactNative第三方插件 4 3 13 珠峰课堂项目实战 5 第五阶段NODE.JS ### 5 1 Node.js核心模块 5 1 1 EventLoop和事件队列 5 1 2 process全局对象 5 1 3 events事件处理模块 5 1 4 commonjs原理解析 5 1 5 深入字符编码 5 1 6 Buffer对象 5 1 7 fs文件模块 5 1 8 压缩与解压缩 5 1 9 加密和签名算法 5 1 10 stream流的原理和应用 5 1 11 多进程与集群 5 1 12 tcp和http服务 5 1 13 多语言、防盗链、正向和反向代理服务器 5 2 express&koa 5 2 1 路由配置 5 2 2 处理参数 5 2 3 使用中间件 5 2 4 模板 5 2 5 静态文件服务器 5 2 6 重定向 5 2 7 cookie和session 5 2 8 手写express框架 5 2 9 手写koa框架 5 3 阿里企业级开发框架egg.js 5 3 1 内置对象 5 3 2 中间件 5 3 3 路由 5 3 4 控制器 5 3 5 服务 单元测试 5 3 6 应用部署 5 3 7 多进程模型和进程间通信 5 3 8 安全和国际化 5 4 单元测试&集群和负载均衡 5 4 1 测试用例和需求分析 5 4 2 单元测试框架mocha 5 4 3 爬虫利器 5 4 4 Puppeteer 实战 5 4 5 Jest+Enzyme实现React单元测试 5 4 6 cluster的工作原理和负载均衡算法 5 4 7 pm2使用 5 5 服务器布署 5 5 1 购买自己的域名 5 5 2 域名备案 5 5 3 购买服务器配置 5 5 4 服务器应用环境安装 5 5 5 配置服务器 5 5 6 项目远程部署 5 5 7 项目发布与更新 6 第六阶段前端工程化和性能优化 ### 6 1 webpack 6 1 1 webpack4实战 6 1 2 webpack4优化(dll、resolve、模块热替换、压缩、代码分割、可视化工具) 6 1 3 Webpack4源码分析 6 1 4 懒加载原理、热更新原理 6 1 5 编写自定义Loader(style-loader css-loader less-loader等) 6 1 6 编写自定义Plugin(html-webpack-plugin) 6 1 7 Webpack的事件机制tapable和AST抽象语法树 6 1 8 如何编写Babel插件 6 1 9 手写一款自己的Webpack 6 2 服务器布署 6 2 1 前端埋点上报 6 2 2 前端错误上报 6 2 3 前端性能上报 6 2 4 前端行为监控上报 6 2 5 前端恢复上线与A/B测试 6 2 6 网络缓存技术分析 6 3 前端性能优化 6 3 1 webpack 优化方案 6 3 2 浏览器缓存原理和最佳设置策略 6 3 3 CDN缓存优化 6 3 4 EventLoop异步更新 6 3 5 避免回流和重绘 6 3 6 节流与防抖 6 3 7 通过Performance监控性能 6 3 8 TCP网络调优 6 4 浏览器渲染原理 6 4 1 浏览器内核 6 4 2 DOM树 6 4 3 CSS规则树 6 4 4 渲染树 6 4 5 回流和重绘 6 5 网络安全 6 5 1 Web漏洞的分析与防御 6 5 2 XSS(跨站脚本攻击) 6 5 3 CSRF(跨站请求伪造) 6 5 4 防SQL注入 6 5 5 HTTPS加密 7 第七阶段计算机网络&服务器和运维 ### 7 1 七层网络协议 7 1 1 TCP/IP协议族的网络模型 7 1 2 IP协议以及简单路由机制 7 1 3 TCP连接的本质 7 1 4 TCP三次握手和四次挥手 7 1 5 TCP协议之滑动窗口和Nagle算法 7 1 6 HTTP、HTTPS和HTTP2的区别和联系 7 1 7 常用网络命令 7 1 8 网络调优实战 7 2 Linux 7 2 1 Linux与Windows的不同 7 2 2 Linux安装和虚拟机的使用 7 2 3 桥接、NAT、Host-Only等网络连接 7 2 4 快照、克隆、挂载点和分区 7 2 5 linux常用命令 文件处理、搜索、链接、帮助、解压与解压缩、用户和组 7 2 6 Shell编程 7 3 Nginx 7 3 1 nginx的安装和使用 7 3 2 模块和基本配置 7 3 3 正向反向代理等应用场景 7 3 4 CDN 7 3 5 浏览器缓存 7 3 6 跨域 7 3 7 防盗链 7 4 Docker 7 4 1 虚拟机 7 4 2 Linux容器 7 4 3 Docker核心概念 7 4 4 Docker架构 7 4 5 Docker镜像 7 4 6 Docker容器 7 4 7 Dockerfile 7 4 8 Docker数据盘 7 4 9 网络配置 7 4 10 docker-compose 8 第八阶段数据库 ### 8 1 Mongodb 8 1 1 Mongodb安装和使用 8 1 2 Mongodb的系统架构 8 1 3 Mongodb高级查询 8 1 4 Mongodb索引 8 1 5 Mongodb安全与权限 8 1 6 mongoose模块之Schema 8 1 7 mongoose模块之Model 8 2 Mysql 8 2 1 MYSQL安装与使用 8 2 2 MYSQL系统架构 8 2 3 数据处理之增删改查 8 2 4 数据类型和约束分页 8 2 5 索引和慢查询性能分析 8 2 6 数据库安全之防止SQL注入 8 2 7 数据库设计ER图设计 8 2 8 数据库事务 8 2 9 数据库设计之三大范式 8 2 10 基于角色的权限访问控制(Role-Based Access Control) 8 3 Redis 8 3 1 Redis安装和使用 8 3 2 5种数据结构及使用场景 8 3 3 API的理解和使用 8 3 4 Redis客户端 9 第九阶段项目实战 ### 9 1 Egg.js+AntDesignPro+MySQL 开发企业级CMS系 9 1 1 脚手架生成项目 9 1 2 配置后台代理 9 1 3 后台首页实现布局模版 9 1 4 封装顶部导航 9 1 5 左侧权限菜单导航 9 1 6 全部删除 9 1 7 搜索 9 1 8 为角色分配权限 9 1 9 为角色分配用户 9 1 10 文章分类 9 1 11 文章管理 9 1 12 广告轮播图 ### 9 2 React+Mongodb+websocket 开发多人聊天室 9 2 1 什么是实时通信 9 2 2 什么是Websocket 9 2 3 websocket和http的对比 9 2 4 使用socket.io实现聊天室 9 2 5 匿名聊天 9 2 6 有用户名的聊天和用户列表 9 2 7 用户私聊 9 2 8 划分不同的聊天房间 9 2 9 消息持久化 9 2 10 支持QQ表情 ### 9 3 cheerio+mysql+nodemailer 开发个性化新闻爬虫 9 3 1 用superagent+cheerio爬取网页内容 9 3 2 数据持久化到mysql数据库 9 3 3 用户个性化邮箱订阅标签 9 3 4 数据更新按兴趣分发推送邮件 9 3 5 用es实现全文检索 ### 9 4 React+Redux开发珠峰课堂使用canvas开发flappy bird 9 4 1 webpack环境搭建 9 4 2 底部页签导航 9 4 3 动画 9 4 4 redux改变课程分类 9 4 5 实现头部轮播图 9 4 6 课程列表列表 9 4 7 下拉刷新 9 4 8 上拉加载 9 4 9 记录滚动条位置 9 4 10 课程详情页面 9 4 11 用户注册和登录 9 4 12 受保护的我的课程页面 9 4 13 Redux开发插件 9 4 14 使用canvas开发flappy bird 画布和画图 background实现 实现大地 绘制管道 绘制小鸟 碰撞检测 场景管理 9 4 15 画布和画图 9 4 16 background实现 9 4 17 实现大地 9 4 18 绘制管道 9 4 19 绘制小鸟 9 4 20 碰撞检测 9 4 21 场景管理 ### 9 5 使用three.js开发微信小游戏跳一跳 9 5 1 基础信息属性配置 9 5 2 几何体创建以及相机镜头位置改变 9 5 3 更新相机坐标实现视觉动画 9 5 4 绑定事件实现jumper跳跃功能 9 5 5 回顾思路梳理逻辑 9 5 6 最终完成实现成功和失败的处理和重置操作 9 5 7 场景管理之场景 # 10 第九阶段前端设计模式 ### 10 1 创建型设计模式 10 1 1 工厂模式 10 1 2 建造者模式 10 1 3 原型模式 10 1 4 单例模式 10 2 结构型设计模式 10 2 1 外观模式 10 2 2 适配器模式 10 2 3 代理模式 10 2 4 装饰者模式 10 2 5 组合模式 10 3 行为型设计模式 10 3 1 观察者模式 10 3 2 状态模式 10 3 3 策略模式 10 3 4 命令模式 10 3 5 访问者模式 10 3 6 中介者模式 10 3 7 迭代器模式 11 第十阶段前端数据结构和算法 ### 11 1 算法的基础知识 11 1 1 输入、输出和数量级 11 1 2 计算能力的变革 11 1 3 CPU、寄存器和内存 11 1 4 二分查找 11 1 5 插入排序 11 1 6 冒泡排序 11 2 算法的衡量和优化 11 2 1 时间复杂度和空间复杂度 11 2 2 复杂度的本质 11 2 3 合并排序(分治策略) 11 2 4 递归函数复杂度分析(树状图) 11 2 5 递归表达式分析法 11 2 6 递归数学归纳法分析 11 2 7 主定理 *选学 11 3 排序算法 11 3 1 排序算法介绍 11 3 2 基于比较的排序算法 11 3 3 快速排序 11 3 4 快速排序复杂度和优化 11 3 5 合并排序的优化 11 3 6 计数排序 11 3 7 基数排序 11 3 8 桶排序 11 3 9 外部排序 11 4 递归 11 4 1 递归的基本概念 11 4 2 递归图形的绘制 11 4 3 递归和穷举问题 11 4 4 组合问题 11 4 5 递归空间优化 11 4 6 回溯算法 11 4 7 重复子问题优化 11 4 8 尾递归 11 4 9 搜索问题(8皇后) 11 4 10 深度优先搜索和广度优先搜索 11 5 数据结构 11 5 1 数组 11 5 2 双向链表 11 5 3 反转单向链表 11 5 4 堆 11 5 5 栈 11 5 6 队列

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册