admin管理员组

文章数量:1590711

目录

一、前言

二、文库·资源预览的演变(以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正文

处理大致流程:

  1. 收到一个文档资源解析请求,如果不是pdf,则通过unoconv将其转换成pdf文件;
  2. 拿到pdf文件的基础信息,如总页数,根据试读规则,计算可试读页数;
  3. 从pdf中提取可试读页的正文信息,保存到一个txt文件,并上传到oss,提取到的正文字符串需要过敏感词机审;
  4. 将pdf文件可试读页部分转换成图片,每一页试读页上传oss;
  5. 将收集到试读txt正文数据,敏感词机审结果,试读图片数据,走内部通道,持久化到对应的数据存储单元中;

3.2、文档资源解析出html

处理大致流程:

  1. 收到一个文档资源解析请求,如果不是pdf,则通过unoconv将其转换成pdf文件;
  2. 拿到pdf文件的基础信息,如总页数,根据试读规则,计算可试读页数;
  3. 从pdf中提取可试读页的正文信息,保存到一个txt文件,并上传到oss,提取到的正文字符串需要过敏感词机审;
  4. 将pdf文件可试读页部分转换成图片,每一页试读页上传oss;
  5. 将pdf文件可试读页部分转换成html静态资源,上传到oss(按照拆分规则存储到不同bucket中);
  6. 将收集到试读txt正文数据,敏感词机审结果,试读图片数据,html静态试读数据,走内部通道,持久化到对应的数据存储单元中;

3.3、压缩包资源解压缩

 处理大致流程:

  1. 收到一个压缩包资源解析请求,从oss下载到服务器;
  2. 通过zipfile插件解压缩,并提取解压缩的目录层次信息,过敏感词机审,并最终上传到oss;
  3. 将收集到试读目录树信息,敏感词机审结果,走内部通道,持久化到对应的数据存储单元中;

3.4、压缩包资源解析子文件

  处理大致流程:

  1. 文库后端核心服务有触发机制,遍历压缩包所有pdf/doc/docx/ppt/pptx类型的子文件,送去做子文件解析,解析流程和文档文件解析流程基本是一致的;
  2. 会把解析后拿到的数据,反馈到文库后端做数据存储,并根据既定的“子文件试读选举策略”,从需要解析和不需要解析的待选池子中,选举出一条试读子文件,送人审&审核通过后展示;

文档&压缩包解压缩&压缩包子文件解析解析有完整的示意图,本文不便全部贴出
给一个过时版本的逻辑示意图:(无敏感信息、线上业务逻辑已经优化变更

以上为资源解析环节的流程,解析环节对接主站&审核&其他的对接流程比较复杂,与本文核心目标无关,不展开叙述。

四、资源·解析方案(演变过程)

        随着时间的推移,线上多元化的资源进来验证,解析方案的可靠性也受到考验&挑战,推动着解析方案的不断调整&纠正完善,来适应不同阶段的解析考验;

4.1、线上试读预览异常反馈&分析排查:

1.中文转换乱码问题

2.内容排版错乱问题
预览乱的问题
html排版问题
html排版-css样式问题

        通过对用同一资源,在不同解析阶段的解析结果的观察分析,得到了结论:

Unoconv是一个基于LibreOffice或OpenOffice的Python库,允许您将不同格式的文档转换为另一种格式。它可以处理各种类型的文档格式,如PDF、DOCX、HTML等,并且可以作为命令行工具使用。

以下是Unoconv和LibreOffice通常用于的场景:

  1. 文档格式转换

Unoconv允许用户在不同的应用程序之间进行快速文档转换,例如从Microsoft Word到PDF或ODT文件,也可以从PDF文档中提取文本或表格数据等等。这对于需要转换大量不同格式文件的个人和企业来说非常有用。

  1. 批量自动化处理

因为Unoconv可以被集成到其他独立的脚本或自动化流程中,所以它广泛用于数据分析、文件自动化和批量处理等领域,并能够让用户把重点放在有价值的任务上,而减少了手动操作时间和错误率。

  1. 字符集格式转换

某些特定程序可能不能打开含有不同字符集编码的文档,因此进行正确的字符集格式转换非常重要。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 对解析上下链路节点,定制应急处理通道

  • 为特别紧急程度的需求,定制了专属的解析通道,和正常解析通道相互隔离;

  • 为客诉&特别情况下指定去处理的资源,定制了推送解析通道;

  • 为解析结果推审核定制了高优先级推送通道;

  • 定制单条&批处理的通道

 五、资源·解析方案(趋势预估)

          目前所有的解析动作都在后端处理,虽然能够拿到所有的解析细节,但是也会受到各种解析资源、服务器性能、网络稳定性等因素的影响,解析结果在满足用户对预览&运营对预览的最大化要求方面还有不足之处,现在提出了在前端预做预览的构想&测试,未来文库极有可能通过重整:上传-->解析-->审核-->展示  这条链路的交互细节,实现前端快速解析+后端安全存储的方式,来满足公司内外对资源解析的需求;

六、结言

       以上就是至今为止,文库的资源解析这块的大概情况,很多细节不便展开赘述,诚然有很多不足,但我们也会在现有的条件下,做最大能力的优化调整,路漫漫其修远兮,吾将上下而求索,加油~

本文标签: 文库历程方案资源