目录
一、前言
二、文库·资源预览的演变(以PC端为例)
2.1、首先来看下老版本的“下载”
2.2、第一版“资源预览”的出现
2.3、“下载”升级到“文库”
2.4、“压缩包资源”要展示目录树
2.5、“压缩包”要展示子文件试读
2.6、“试读”不断迭代的原因
三、资源·解析方案(初版)
3.1、文档资源解析出图片和txt正文
3.2、文档资源解析出html
3.3、压缩包资源解压缩
3.4、压缩包资源解析子文件
四、资源·解析方案(演变过程)
4.1、线上试读预览异常反馈&分析排查:
4.2、转PDF插件替换评估&分析&方案
4.2.1 替换unoconv插件的必要性分析
4.2.2 选择一种替换unoconv转pdf的处理方案
4.3 选型方案分析&确定
4.3.1选型方案分析
4.4定制PDF转换服务&部署&运维
4.4.1研发定制
4.4.2 部署&可用性维护
4.5 部署服务器从阿里云迁移到华为云
4.6 解析服务内部优化措施
4.6.1 梳理oss存储流程&逻辑,精简处理流程,压缩存储成本,方案分析
4.6.2 优化解析内部交互流程,为后续版本的可扩展做准备
4.7 对解析上下链路节点,定制应急处理通道
五、资源·解析方案(趋势预估)
六、结言
一、前言
老用户都知道,CSDN下载站的资源预览成功经历了很多的版本迭代,也遇到了很多的波折,那本文尝试从一个后端研发的视角,来叙述一下,发生了哪些故事。
二、文库·资源预览的演变(以PC端为例)
CSDN主站的导航栏位,“下载”就排在第二位,说明是比较重要的一个业务线;
2.1、首先来看下老版本的“下载”
最开始的时候,“下载”详情页,只有一些基础信息、评论信息、和推荐信息的展示,这个时候还没有“资源试读”这个模块;
2.2、第一版“资源预览”的出现
老用户都很熟悉这个老版本“资源详情页”的样式,试读模块只有右上角一处“封面缩略图”作为试读入口,并且仅仅支持文档资源的图片试读(即:将pdf/doc/docx/ppt/pptx类型的资源,按照可试读的页数计算规则,为其生成对应页的可试读的图片);
2.3、“下载”升级到“文库”
( 引用详情页地址:https://download.csdn/download/v_july_v/4583815?spm=1003.2021.3001.6625.1)
和老版本详情页对比之下,很清晰可以看到,新版本的详情页中保留了“右上角”缩略图试读入口,也新增了“资源详情”栏位,在详情页直接展示资源的试读内容,如下图所示:
这个阶段,整个文库的前后端都有较大的变动,仅针对“资源试读”新增了html试读,并解析出txt正文信息过敏感词等等内部处理逻辑,此时给用户展示的试读内容:从图片试读,演变成“优先html试读,图片试读兜底”的处理思路;
2.4、“压缩包资源”要展示目录树
这次预览的升级主要是针对“压缩包”类型的文件('rar','zip' ,'tgz','gz','7z')这5类的压缩包资源,提供展示目录树结构的预览功能;
2.5、“压缩包”要展示子文件试读
(引用资源链接:https://download.csdn/download/wuxia2001/4071200?spm=1003.2021.3001.6625.10)
在压缩包的目录树预览出现一段时间以后,继续推出了,按照“定制的选举规则”,选举出适当的子文件给出预览展示;
至此,在对用户提供的预览展示效果上面,文库的迭代已经到了最新版本。
2.6、“试读”不断迭代的原因
- 为下载用户提供更多关于目标资源的信息,帮助用户甄选到合适资源;
- 迎合百度对站点&流量的调整策略,提升外部流量;
- 为了拓展对资源信息的提取&挖掘能力,为后续的发展做铺垫;
三、资源·解析方案(初版)
“解析服务”是独立于下载主站的服务,依靠rocketmq和http和主站服务们交互数据;
3.1、文档资源解析出图片和txt正文
处理大致流程:
- 收到一个文档资源解析请求,如果不是pdf,则通过unoconv将其转换成pdf文件;
- 拿到pdf文件的基础信息,如总页数,根据试读规则,计算可试读页数;
- 从pdf中提取可试读页的正文信息,保存到一个txt文件,并上传到oss,提取到的正文字符串需要过敏感词机审;
- 将pdf文件可试读页部分转换成图片,每一页试读页上传oss;
- 将收集到试读txt正文数据,敏感词机审结果,试读图片数据,走内部通道,持久化到对应的数据存储单元中;
3.2、文档资源解析出html
处理大致流程:
- 收到一个文档资源解析请求,如果不是pdf,则通过unoconv将其转换成pdf文件;
- 拿到pdf文件的基础信息,如总页数,根据试读规则,计算可试读页数;
- 从pdf中提取可试读页的正文信息,保存到一个txt文件,并上传到oss,提取到的正文字符串需要过敏感词机审;
- 将pdf文件可试读页部分转换成图片,每一页试读页上传oss;
- 将pdf文件可试读页部分转换成html静态资源,上传到oss(按照拆分规则存储到不同bucket中);
- 将收集到试读txt正文数据,敏感词机审结果,试读图片数据,html静态试读数据,走内部通道,持久化到对应的数据存储单元中;
3.3、压缩包资源解压缩
处理大致流程:
- 收到一个压缩包资源解析请求,从oss下载到服务器;
- 通过zipfile插件解压缩,并提取解压缩的目录层次信息,过敏感词机审,并最终上传到oss;
- 将收集到试读目录树信息,敏感词机审结果,走内部通道,持久化到对应的数据存储单元中;
3.4、压缩包资源解析子文件
处理大致流程:
- 文库后端核心服务有触发机制,遍历压缩包所有pdf/doc/docx/ppt/pptx类型的子文件,送去做子文件解析,解析流程和文档文件解析流程基本是一致的;
- 会把解析后拿到的数据,反馈到文库后端做数据存储,并根据既定的“子文件试读选举策略”,从需要解析和不需要解析的待选池子中,选举出一条试读子文件,送人审&审核通过后展示;
文档&压缩包解压缩&压缩包子文件解析解析有完整的示意图,本文不便全部贴出
给一个过时版本的逻辑示意图:(无敏感信息、线上业务逻辑已经优化变更)
以上为资源解析环节的流程,解析环节对接主站&审核&其他的对接流程比较复杂,与本文核心目标无关,不展开叙述。
四、资源·解析方案(演变过程)
随着时间的推移,线上多元化的资源进来验证,解析方案的可靠性也受到考验&挑战,推动着解析方案的不断调整&纠正完善,来适应不同阶段的解析考验;
4.1、线上试读预览异常反馈&分析排查:
1.中文转换乱码问题 | |
2.内容排版错乱问题 | |
预览乱的问题 | |
html排版问题 | |
html排版-css样式问题 |
通过对用同一资源,在不同解析阶段的解析结果的观察分析,得到了结论:
Unoconv是一个基于LibreOffice或OpenOffice的Python库,允许您将不同格式的文档转换为另一种格式。它可以处理各种类型的文档格式,如PDF、DOCX、HTML等,并且可以作为命令行工具使用。
以下是Unoconv和LibreOffice通常用于的场景:
- 文档格式转换
Unoconv允许用户在不同的应用程序之间进行快速文档转换,例如从Microsoft Word到PDF或ODT文件,也可以从PDF文档中提取文本或表格数据等等。这对于需要转换大量不同格式文件的个人和企业来说非常有用。
- 批量自动化处理
因为Unoconv可以被集成到其他独立的脚本或自动化流程中,所以它广泛用于数据分析、文件自动化和批量处理等领域,并能够让用户把重点放在有价值的任务上,而减少了手动操作时间和错误率。
- 字符集格式转换
某些特定程序可能不能打开含有不同字符集编码的文档,因此进行正确的字符集格式转换非常重要。Unoconv支持多种字符集的转换,如UTF-8、GBK等,并可对其执行自动化批处理。
需要注意的是,使用Unoconv和LibreOffice时,运行环境的配置、安装路径等均需正确设置。在Linux系统上使用Unoconv时,需要通过命令“sudo apt-get install uno-libs3 libreoffice”安装相关依赖库和软件包。
- 当使用转换pdf的插件:unoconv把目标文件转换成pdf时,生成的pdf已经产生了问题,后续的操作都是基于此异常pdf文件而生成异常的预览结果数据;
- 这种情况也做了进一步的分析:
- 是unoconv调用其依赖项libreoffice时,使用的字体缺失导致解析乱码,补充fonts字体库,可以解决乱码问题;
- 排序问题和样式问题无法得到有效的解决,但可以确定矛头集中到了「libreoffice」身上;
- 这种情况也做了进一步的分析:
- 并且发现unoconv插件,运行受其依赖的libreoffice的影响,同时解析多个大文件时,插件崩溃的概率比较大,从而导致解析失败;
4.2、转PDF插件替换评估&分析&方案
4.2.1 替换unoconv插件的必要性分析
(1)虽然从整个下载的总的解析体量上看,出现问题的数量级不多,但是隔段时间接可以收到用户的反馈,说明用户特别重视这种解析异常的问题;
(2)unoconv调用libreoffice抗压能力弱,经常会导致解析直接失败,这种情况被发现也0容忍的;
(3)unoconv转pdf,涉及到文档资源解析和压缩包子文件解析,涉及到2个重要解析环节,影响面比较大;
(4)libreoffice插件,网上有性能评估对比,可用性不高;
结论:
根据用户关注程度、插件稳定性、和解析能力的考虑,决定换掉:unoconv+libreoffice的转换模式。
4.2.2 选择一种替换unoconv转pdf的处理方案
- 方案选型·脑图
可行性分析:
方向A:需要琢磨一下,重新选型一个转pdf的工具,替换unoconv
a1、申请window机器,使用支持性最好的插件库。虽然linux和winodw机器一样的价格,但是涉及到更换运行环境,方案备用
a2、将现在linux(ubuntu:20.04)基础镜像类型,换成window版本的镜像。(此路不通,镜像是机遇宿主机内核的,无法打出来)
a3、重新起一个java服务,将转pdf这一块逻辑单独拎出来。(优先此方向)
方向B:细化转pdf这个操作,不同类型文件转pdf,单独处理,不再统一使用unoconv
b1、docx2pdf 强依赖:microsoftword软件,不支持linux且收费,弃用-
2、尝试:pywpsrpc pywpsrpc · PyPI 安装忒麻烦,弃用
WPS+pywpsrpc:虽然支持linux,但是强依赖WPS这个第三档软件,通过内部接口支持rpc调用。
* a.使用时,要求WPS软件启动。
* b.很灵活,目标pdf文件,需要手动将内容写入,并不能自动识别,转换,这不满足文库多文件类型灵活转PDF的场景。
实践&结论:
最终采用了:
方向A的a3号方案:重新起一个java服务,将转pdf这一块逻辑单独拎出来。(优先此方向)
4.3 选型方案分析&确定
4.3.1选型方案分析
既然要自己定制一个转pdf的服务,那肯定还是需要依赖第三方的插件的,只不过需要选择可控性高,性能好的才满足我们的需要,经过比对,还是选择了:
原因就是:
- 依赖体量小,容易扩展,可以快速移植部署;
- 处理速度快,可以实现1:n的解析场景,性能有保障;
- 转换效果理想,经过测试,在满足现有转换能力的基础上,可以解决线上出现的转换异常问题;
- 插件是jar开发的,便于快速研究调整和根据处理需求再包装,可以做一些定制化
结论:
方案符合业务场景需要,运维环境需要,扩展需要,可控性高的验证,决定执行;
4.4定制PDF转换服务&部署&运维
4.4.1研发定制
- 因为是定制的一个服务,且速度相对来说比较快,但也考虑到业务上对一个资源解析的最大时长的限制,设置了120s解析超时丢弃的策略,并且支持企微机器人告警通知;
- 为文档解析和压缩包子文件解析做了2套不同的通道,以后有特殊需求,留下来的扩展能力;
4.4.2 部署&可用性维护
4.4.2.1部署:
- 为了支持部署少量的定制PDF转换服务,就可以支持多个python解析容器的需要,启动参数可以设置稍大一些:
nohup java -jar -Xms15g -Xmx15g -XX:ErrorFile=/data1/java/jvm_pdf_error%p.log /******/*****jar --spring.profiles.active=env.* >> /dev/null 2>&1 &
至于是10G,15G,20G甚至更多,按需即可
如果pdf转换需求大,可以多找几台机器部署,做好python解析服务对接就可以了
4.4.2.2维护:
- 可以通过linux定时脚本,控制python解析容器和java-转pdf服务的一键按顺序启停,来达到缓解宿主机性能压力的问题
- 可以通过一些定制脚本,一键清理python解析服务所在docker容器的垃圾无用资源
(1)清理容器无用运行日志
#!/bin/sh # 1、一键清理所有容器服务日志 echo "======== 清理任务1:清理所有容器「服务日志」 ========" logs=$(find /dat**/docker/containers/ -name *-json.log) for log in $logs do echo "clean logs : $log" cat /dev/null > $log done echo "======== 清理任务1:✅ ========" echo " ⬇ ️" echo " ⬇ ️" # 2、一键清理所有Exited状态的容器 echo "======== 清理任务2:删除「已经关闭」的容器 ========" exit_cids=$(docker ps -qf status=exited) for ecid in $exit_cids do docker rm $ecid echo "clean exited container:$ecid" done echo "======== 清理任务2: ✅ ========" echo " ⬇ ️" echo " ⬇ ️" # 2、循环清理每个在运行容器中的core文件 echo "======== 清理任务3:清理「容器」中core缓存文件 ========" run_cids=$(docker ps -qf status=running) for rcid in $run_cids do echo "clearn container core cache files:$rcid" sudo docker exec -it $rcid /bin/bash -c "ls -lht|grep core**;rm -rf core**;" echo " ⬇ ️" done echo "清理完成" echo "======== 清理任务3:✅ ========"
(2)清理磁盘中因为dokcer容器运行产生的无用信息
#!/bin/sh echo "======== start clean docker containers logs ========" logs=$(find /data1/dock**/containers/ -name *-json.log) for log in $logs do echo "clean logs : $log" cat /dev/null > $log done echo "======== end clean docker containers logs ========"
4.5 部署服务器从阿里云迁移到华为云
公司基于成本&战略等因素考量,决定把全公司内部的服务器从阿里云迁移到华为云,文库涉及到的所有服务都迎合战略做迁移动作,包括:资源解析服务这块
4.6 解析服务内部优化措施
4.6.1 梳理oss存储流程&逻辑,精简处理流程,压缩存储成本,方案分析
4.6.2 优化解析内部交互流程,为后续版本的可扩展做准备
4.7 对解析上下链路节点,定制应急处理通道
-
为特别紧急程度的需求,定制了专属的解析通道,和正常解析通道相互隔离;
-
为客诉&特别情况下指定去处理的资源,定制了推送解析通道;
-
为解析结果推审核定制了高优先级推送通道;
- 定制单条&批处理的通道
五、资源·解析方案(趋势预估)
目前所有的解析动作都在后端处理,虽然能够拿到所有的解析细节,但是也会受到各种解析资源、服务器性能、网络稳定性等因素的影响,解析结果在满足用户对预览&运营对预览的最大化要求方面还有不足之处,现在提出了在前端预做预览的构想&测试,未来文库极有可能通过重整:上传-->解析-->审核-->展示 这条链路的交互细节,实现前端快速解析+后端安全存储的方式,来满足公司内外对资源解析的需求;
六、结言
以上就是至今为止,文库的资源解析这块的大概情况,很多细节不便展开赘述,诚然有很多不足,但我们也会在现有的条件下,做最大能力的优化调整,路漫漫其修远兮,吾将上下而求索,加油~
更多推荐
浅析一下文库·资源解析方案的演变历程
发布评论