指导阅读
介绍

图书馆是用户在线共享文档的平台,用户可以从图书馆下载各种文档。自2009年11月平台上线以来,经过十几年的发展,文档数量和日下载量是一个非常庞大的数字。它是内容图书馆的核心资产,而文献下载服务是图书馆的一项基本服务。用户来图书馆的主要目的之一就是获取内容,所以下载服务的体验是最重要的,下载功能也是薅羊毛各类黑产的重要目标。
目前库是大型分布式单体架构,库的所有代码作为一个整体系统部署在一起。虽然库有多个应用和多个实例来实现分布式扩展,但从根本上来说,所有的代码都打包在一个程序中。文件下载功能是这个庞大单一架构的一部分。在图书馆十几年的发展历史中,这个庞大的单一架构和下载服务一直在发展壮大。02
面临的问题现象就业务和技术而言,当前图书馆下载服务面临着许多问题:体验来自贫穷顾客的许多抱怨:
每天都有很多用户反映文档下载失败,或者提示成功但是找不到文档,或者下载了但是内容不完整等等。为此,图书馆值班的客服和RD工作人员每天都要花费大量的精力处理下载的客户投诉,疲惫不堪。
事件
图书馆用户A:我刚买了一个文档,下载提示成功,但是文档没有下载。
图书馆乙:对于这次糟糕的经历,我感到非常抱歉...
RD图书馆:因为这个文档的作者设置了“不可下载”,这是一个历史遗留问题,所以我会修复它。
图书馆用户A:我下载的这个文件只有摘要,不完整。给我退款!
图书馆乙:好的,我马上联系RD...
RD图书馆:因为这是第三方文档,图书馆未能调用第三方服务,所以我们只能使用这里保存的摘要。
下载方式多,开发维护成本高:经过多年的发展,图书馆的下载方式已经多样化。PC、WAP、小程序、APP都有自己的下载接口,还有一些第三方合作相关的下载服务。比如用户可以从一些高校的内网下载图书馆的文档,也可以从图书馆下载第三方平台的文档。下载服务还有其他变种,如文件传输网盘、文件发送邮件附件等。这些下载服务大同小异,基本逻辑相似,也有自己的特殊逻辑。事件库产品:今天谈了一个新的内容合作伙伴,在他们的app上展示了我们的文档,应该是提供下载功能的。
RD图书馆:好的,我会开发一个下载界面。
图书馆产品:我们和XX大学合作,部分文献可以免费供他们使用。
RD图书馆:那我会单独给他们提供下载服务。
反黑产反作弊成本高:由于下载方式多种多样,图书馆历史上发展起来的各种反作弊逻辑也是五花八门,没有统一的策略。添加新的反作弊策略非常困难。互联网上出现了一些倒卖或下载文档的工具,我们很难定位他们是如何获取库内容的。
事件库产品:最近又发现了一个库下载工具,可以下载我们的文档。我们的下载服务需要接入XX反作弊平台。
RD图书馆:好的,我可能需要改变十几个界面...
针对这些下载的案例,虽然图书馆RD人员每天都进行整理归类,但实际效果并不明显,问题并没有得到彻底解决。因为各种下载案例都很复杂,很难描述。随着新项目上线,会出现新的问题,很难收敛。原因经过分析,这些问题有以下原因:[业务水平]图书馆的下载服务属于基础服务,业务场景相对固定。所有下载服务和下载方式的逻辑和步骤都是类似的。下载服务有安全检查、业务逻辑检查、获取下载地址、后期处理等流程。,可以计算最大公约数,抽象常用步骤。目前是面向接口的开发。在处理新需求时,很多情况下优先保证短、平、快上线,不选择长远方案。[架构级别]目前,下载服务和图书馆是相互耦合、相互影响的。而且下载的代码比较分散,基本都是面向接口的编程。没有统一的基础模块和通用规范,没有统一的异常处理机制和错误代码信息。[监控和操作级别]由于库的下载接口众多且分散,没有整体的日志收集机制,缺乏统一的监控、数据上报和操作工具。导致无法及时发现问题进行预警,往往在用户反馈后才发现问题。即使用户反馈问题,由于缺乏有效的操作工具,客服人员也无法自行定位问题,必须依靠研发的协助。
在定义下载服务的边界时,如何保证耦合性和内聚性之间的平衡非常重要。耦合和内聚这两个概念是相互关联的。如果一个架构具有高内聚、低耦合的特点,那么它就是稳定的。单体结构的问题是单体对于内部聚合和偶联是相反的。单体架构并不倾向于内聚,而是倾向于将改变后的代码组织在一起,衍生出各种不相关的代码逻辑并拼贴在一起。
回到我们具体的下载业务,如果下载服务中各个子模块的功能单一,那么凝聚力会更高,独立性也会更强。同样的服务,要做好自己业务范围内的功能,没必要面面俱到,否则很难维护。同时,下载服务与其他服务的联系越少,服务间的耦合度越低,相对独立性越强。这是我们对下载微服务转型的基本指导思想。基于这样的想法,我们重新思考图书馆业务,让这种新的微服务架构能够实现我们下载业务所需要的功能和特性。我们设计实现了一个下载式微服务系统,独立部署和上线,与其他业务隔离。同时,库的所有下载接口都包含在这个框架中,主要集中在以下几个方面:
1.抽象下载过程并定义一般下载步骤。将来让RD人员按照这个框架的规范开发下载服务。
2.抽象下载行为。对于每个下载过程,都有详细的数据记录,包括下载现场数据、下载过程和下载结果。为监控和操作工具提供基础数据。
3.开发组件化的功能模块,便于复用和统一修改升级。
4.制定统一的异常处理机制,规范错误码,自动收集下载日志,优化提示文案。
5.制作配套的运营分析工具,方便客服人员定位问题,增加下载数据的实时监控。
综上所述,图书馆RD、PM、QA联合推出下载服务优化项目,解决长期存在的下载问题。04
方案实现要把传统的面向接口的开发系统改造成独立的微服务系统,我们重点做两件事。首先是定义微服务调用的协议和规则,独立在线部署下载系统,使微服务可以垂直划分,这是微服务化的基础。第二件事是基于我们的下载业务,开发一个符合业务需求,适合业务发展的下载技术框架。4.1微服务基金会在单片应用中,模块之间的调用是通过本机编程语言的方法或函数来实现的。而一个基于微服务的分布式应用,是分布部署在多台机器上,通过网络通信互相调用服务。库下载服务借助公司常用的BNS实现流量调度和负载均衡。BNS服务全称:百度命名服务,即名称服务,用于满足通用资源定位、模块间ip白名单授权验证、负载均衡以及其他任何依赖于这些信息的开发和运维需求。我们将所有下载服务的在线机器添加到我们创建的BNS中。如果客户端或者其他内部业务想要访问下载服务,都将通过这个BNS进行访问,并且支持就近访问相应的机房,避免了远程网络通信带来的额外开销。远程访问和重试机制依赖于内部RAL客户端。RAL支持各种交互式协议和数据打包格式。它具有高性能、低成本的特点,能与BNS完美配合。调用方使用RAL与下载服务进行交互,不需要关注数据格式处理和协议交互的过程,是一种简单可靠的方式。部署云平台也是非常成熟可靠的解决方案。实现与图书馆主业隔离,开发和上线互不影响。
4.2业务框架基于图书馆业务的思维,在新的图书馆下载微服务系统中,我们开发了一个适合图书馆业务场景,符合长期发展变化的下载服务框架。该框架做了以下五个部分:抽象的下载过程,标准化的下载过程
首先,我们抽象了下载过程。抽象就是简化业务,对下载行为进行总结和过滤,去掉不必要的步骤或冗余信息,分析其本质。经过分析,该库的下载业务逻辑通常是固定的,下载过程可分为下载行为初始化、安全检查、权限检查、主要业务操作和后期操作。
其中,下载行为初始化操作会提前采集该下载行为的基础数据,即不包含隐私数据的用户信息、当前下载场景信息、下载对象信息等。,它将用于下面的链接和编写下载日志。第二步是安检。这一步会限制频率,防止部分IP或账号短时间下载,会有一些拦截检查和防作弊检查。第三步是权限检查。一般下载服务都不是免费的,需要用户有一定的积分,或者已经购买了内容,或者用户的身份有下载权限等。第四步,下载主要业务逻辑。根据下载的内容id,该步骤获得存储内容的地址,并将内容返回给用户的设备。最后一步是后期运营,一般用于扣除用户积分或者金钱消费,记录用户数据。
以上下载步骤在我们最终的框架中进行了定义,每次下载的具体业务实现都是按照预先定义的步骤进行开发的,保证了下载过程的规范性,为整个下载系统的日志收集和监控奠定了基础。
示意图代码:
描述下载行为
下载行为实际上是一种网络请求。我们需要收集这种网络请求的一些附加信息,结合当前的应用场景和这种行为的结果来很好地描述这种下载过程。下载行为通常由终端用户发起,终端用户在特定场景中下载特定的内容对象。用户通常具有帐户id、终端IP地址、浏览器或设备信息以及cookie信息的特征。场景包括用户发起下载行为的产品线、下载行为的来源、下载时间、下载过程的结果等。内容包括用户下载的内容的类型、内容的id、内容的标题以及其他可以描述内容的信息。
收集这些数据可以大大提高我们快速定位问题和监控下载服务稳定性以及业务数据变化的能力。
提供基于组件的基本模块。
软件架构设计本身是一件复杂的事情,但事实上,业界已经进化出一种有效的处理方式,那就是“通过组件化来分离关注点,以降低局部复杂度”。事实上,无论容器、中间件、消息、数据库等等。我们现在用的都是某种意义上组件化的产品。这样做的好处是它们可以在不同的系统中重用。正是这种重用,成就了今天的互联网级架构。
对应我们具体的下载服务,反作弊,频率限制,权限检查,身份检查等。都可以开发成通用化、组件化的功能模块,从而提高开发效率,降低多次迭代带来的风险。
目前代码的下载和转储分别覆盖pc、wap、applet等合作接口。每个接口代码中有些逻辑是独立的,冗余度高,逻辑不一致。要解决这个问题,可以将一些基础服务抽象、解耦,开发成独立的、可复用的基础模块,完全可以改变。对于一些有特殊要求的逻辑,比如PC一天下载M次的限制,WAP一天下载N次的限制,通常是通过参数或者配置文件来控制,以保持灵活性。
例如,我们对不同类型的文件有不同的检查权。对于单个付费文档,需要在下载过程中检查用户是否购买了该文档,而对于VIP免费文档,只需要检查用户是否有VIP身份。对于VIP专属文档,除了检查VIP身份,还需要检查用户是否有足够的下载权限。这些股权规则不是固定的,随着业务的发展会有新的股权规则。将股权控制权封装成独立模块后,以后添加和修改股权就很容易了。
规范异常处理机制,自动收集日志。
任何服务都需要考虑异常处理机制。这里所说的异常既包括程序逻辑中的异常,也包括业务逻辑中的异常。程序异常,如指针错误、变量类型错误等。,一般是程序员考虑的。实际业务执行过程中也会有例外,比如没有VIP身份下载VIP专用文件,一天下载超过限额后继续下载文件。很多开发者通常不太在意这种业务异常,但是下载服务对我们来说很重要。我们需要记录这个异常,以帮助我们分析异常情况。
以前下载过程非常混乱,没有标准的错误提示。该框架重新定义了错误代码,并标准化了异常处理。添加异常收集机制。如果框架检测到任何一步返回的错误代码,就会自动记录下载日志,如果下载过程最终成功,也会记录下载日志。最后,格式化返回的错误消息和数据。
在这种下载微服务框架下,业务开发只需要实现各自下载服务的下载器,其他步骤如流程定义、行为采集、日志投放等都由框架自动完成。主框架将监控执行过程。当执行完成时,它将获得下载行为数据,并自动将其写入日志。
在日志存储上,由于下载量巨大,单表存储不方便,采用分月分表的方式。因为这些数据只是用于运营定位和一些数据分析,并不作为线上业务使用,所以这种分表方式完全符合我们的使用场景。
支持运营分析工具和输出监控
新的下载服务框架不仅收集数据,还产生相应的操作工具、报告、监控等。如果有客户投诉,客服人员可以自行查看下载记录,看用户下载是否成功以及对应的日志。并且增加了实时监控。如果成功下载/失败的数量在十分钟内剧烈波动,将向RD人员发送警报消息。
04
效果和总结经过以上改造,如果再遇到类似问题,处理的方式就完全不同了:事件
图书馆用户A:刚买了一个文档,下载提示失败。请再试一次。原因是什么?
图书馆B:您好,经查询,您下载的文档属于第三方问题。在下载的时候,对方服务的稳定性出现了问题。我们已经联系合作伙伴解决了,现在没事了。
库产品:我们发现XX黑产工具使用非法手段下载我们的内容,需要紧急在所有下载入口对该工具启动屏蔽策略。
图书馆研发:好,改变一切。



