为什么要重构SEO项目?如何进行SEO项目重构及重构方案

运营推广
2022-06-20 10:18:28
文章摘要

笔者最近一段时间一直在对原有的SEO项目进行重构,目前已经进入重构的后期阶段,想和大家一起分享一下整个重构的细节,对于原SEO项目主要存在几个方面的问题。

笔者最近一段时间一直在对原有的SEO项目进行重构,目前已经进入重构的后期阶段,想和大家一起分享一下整个重构的细节,对于原SEO项目主要存在几个方面的问题。


什么是SEO项目


SEO(Search EngineOptimization),搜索引擎优化,利用搜索引擎(目前主要指Google)的规则提高网站在搜索引擎内的自然排名和网站的品牌影响力。用户在搜索引擎上搜索相应的关键字,点击搜索结果直接跳转到SEO的着陆页(Landing Pages),然后通过Landing Pages将流量引到需要推广的网站,从而将这些流量转化成订单。SEO项目主要是根据不同的推广维度设计相应的Landing Pages,并为这些Landing Pages提供相应的数据,目前该项目主要涵盖酒店和机票两大产线,后续可能会接入更多的产线。


SEO项目重构


为什么要重构


对于原SEO项目主要存在以下几个方面的问题:


代码耦合


前端代码和服务端代码全部耦合在同个项目里面,在开发过程中相互依赖,页面信息模块化,可配置化,支持AB测试等一系列的功能都很难实。


现数据存储


SEO项目的数据和之前的其它系统存储在同一个DB中,并且部分数据表是共用的,必然导致某些表中的字段从SEO项目的角度来看是无用的但又不能去掉。


数据更新


数据全部更新完一次约2-3天,整个过程需要人工干预,如果更新过程中出现了任何问题需要重新进行全量更新,并且还存在脏数据,主要分为两类:一类是数据表中某个字段的值部分是正确的,部分是不正确的;另一类是数据不完整,比如:如果某个城市没有任何酒店或者机场,则这条城市数据是没有意义的,因为在做城市维度推广的时候,这个城市下面是没有任何酒店或者机场的数据的。


需求无法满足


在SEO页面的底部需要根据一定的规则计算相关的链接信息,计算某一个站点的某一个产线在某一种特定语种下需要的时间约为4小时,现有16个站点,每个站点有15种语种和有3个产线,计算出所有站点下所有语种和产线的链接信息需要的时间为16*15*3*4=2880小时(120天),显然目前的实现方案是无法满足业务需求的。


为什么会存在以上这些问题?主要原因如下:


需求迭代太快


IBU一直处于高速发展的状态,很多需求都是需要在很短的时间,快速的完成,并且对未来需求的变化很难把握,在做需求的过程中难免会选择一些短期的,尝试性的,快速见效的方案。


开发人员少


在重构之前整个SEO项目仅1-2个人来完成所有的开发工作,当需求源源不断涌现时,开发人员难免会措手不及,应接不暇。


数据复杂


目前SEO几乎需要与机票和酒店相关的所有数据,而这些数据的收集过程又是极其分散、复杂和繁锁的,收集某条数据时可能需要采集多个数据源的数据才能将这条数据中的所有字段补全,并且数据量大导致更新时间长,数据之间的关联性高从而导致数据更新过程中加大了保证数据完整性的难度。


技术选型


项目的技术选型对整个项目来说至关重要,这里主要表述的是服务端的技术选型(前端的技术选型主要由汪桂洋团队负责)。


开发语言


去掉了之前的部分代码采用Java实现,部分代码采用PHP实现的方案,将开发语言统一定为Java。主要原因是公司主推Java语言,团队中所有成员最熟练掌握的编程语言都是Java。


数据存储


在数据存储方面主要采用MySQL数据库,去掉了之前一部分数据采用ES存储,另一部分数据采用MySQL存储的方案。SEO项目中酒店的数据量最大,也仅千万级,对于MySQL来说是完全没有问题的。


RPC框架


公司提供了两种对外暴露服务的方式,一种是通过Baiji契约实现的,另一种是CDubbo。未选择后者的主要原因是当时刚推出来,在稳定性上可能会略差于前者,同时整个团队对前者的理解更深入,使用的也多一些,降低学习成本。


设计方案


SEO项目的整体架构如下图所示:


1、Vampire


主要是用来采集数据并转换成格式化的数据。采集数据的方式主要有增量和全量两种,数据来源可以是MQ、DB和API(后面还会接入更多的数据源)。其核心思想是通过并发的方式拉取来自不同数据源的数据并将这些数据进行转换成格式化的数据,然后调用Faba的写接口将数据写入DB中。


由于全量数据的数据量较大,所以在整个过程中拉取全量数据最为复杂。从目前来看更新全量数据绝大多数情况是采用调用API的方式,需要考虑被调用API的QPS、响应时间、更新一次的时间间隔、API的返回报文大小(有些情况需要考虑分页)、API的超时时间、Gateway超时时间、网络带宽、数据之间的依赖关系等,从而确定Vampire在调用API时的线程数、调用频次、调用周期、调用时间(一般在非高峰期调用)、部署时的机器数量、虚拟机的CPU核数和内存大小等,针对调用不同的API需要对不同参数进行优化。增量更新相对而言简单一些,主要采用MQ的对接方式,需要考虑先发送的消息后到达,后发送的消息先到达的情况、重复消息、消息丢失、MQ中队列的大小等。在整个拉取数据的过程中还需要考虑数据提供方可能出现脏数据或者无法支撑Vampire带来的流量,因此还需要支持暂停、恢复、强制更新等功能。


无论是增量还是全量的方式拉取数据,最后都需要转换成格式化的数据并写入DB,这个转换过程的处理速度至关重要,因为Vampire从整体上来看其实是一个生产者和消费者模型,生产者是接入的各种不同数据源,而消费者则是将拉取的数据进行转化然后调用Faba提供的写接口,快速完成数据的转换工作。理想情况下应该是生产者的生产速度等于消费者的消费速度,当生产速度大于消费速度时,生产出来未被来得及消费的数据就会囤积在内存中,容易造成OOM,所以在实际使用的时候一般是消费速度大于生产速度,而对于Vampire而言,生产者的速度是接入各数据源的流量之和,随着数据源的增加而增加,但是消费者的消费能力是固定的,所以要想提高整个数据采集和转化的吞吐量,本质上是要提高消费者的速度,也就是提高Faba的Write接口的速度(后面会详细讲解Faba处理数据的机制)。目前生产环境部署了4台8核8G的虚拟机,Vampire的处理能力可以达到每秒10K+,处理1000W条数据耗时约30min。


2、Faba


该子项目主要是为整个SEO项目提供数据Read和Write操作。其中Write接口主要由Vampire调用,用来补充数据,Vampire将采集到并转换好的数据通过调用Faba的Write接口将数据写入DB,Read接口主要是对外提供访问数据的方式,由Service来调用。


Write接口主要是采用异步的方式实现的,Vampire在调用时会将数据先暂存到一个消息队列中,然后再来消费这些数据,这样处理的好处在于:首先提高了Write接口的QPS和响应时间,其次可以将一些相同的操作进行合并成批量的操作,从而尽量减少DB连接数的消耗,最后可以在写入时尽可能的对一个批次的写入的数据进行去重,减少不必要的写入操作。Write接口的设计需要考虑三个方面的因素:


一、支持幂等


因为写入的数据来源于消息队列,消息队列会有重试的机制,所以在写入的时候需要支持幂等。其实消息队列也不能保证数据是有序到达的,数据是否有序到达仅对增量拉取数据有影响,对于全量拉取数据没有影响,因为在全量拉取数据时,每条数据当且仅当只会被拉取一次,所以对每条数据的更新操作是相互独立的无需考虑先后顺序。对于增量拉取数据而言,假设一条城市数据在同一时刻先后将城市名称从A修改到B,再从B修改到C,这两条更新的操作会被有序的推送到Vampire,然后再由Vampire转换成格式化数据后调用Faba的Write接口,从消息队列中消费这两条数据时可能会先收到城市名称从B修改到C的数据,后收到从A修改到B的数据,这时会以两条数据发生修改的时间做为时间戳,在DB中更新数据时只更新当前时间戳大于这条数据在DB中的更新时间,其余的全部过滤掉,也就是城市名称从B修改到C的数据会被更新到DB,从A修改到B的数据会被过滤掉。


二、消费速率


很容易看出在整个写入的过程中的瓶颈是DB的写操作,公司DB的连接池大小是100,也就是说通过多线程来消费消息队列中的数据,线程池的大小不要超过100,确定了消费者的消费能力,生产者的生产能力只需要通过简单的计算就可以确定了,理论上只需要将生产者单位时间内生产数据的总量等于消费者线程数100*每个批次内数据平均条数,这只是一个理想的情况,实际情况可能还需要考虑三个因素:


1)消息队列的大小,也就是囤积数据的能力,这个与机器内存有关;


2)可接受的数据延时时间,也就是一条数据从进入消息队列到写入DB的时间;


3)IO的处理能力,往DB中写数据会产生大量的IO操作,特别是在进行批量写入操作时,之前由于这个因素没有考虑到,导致和SEO的DB在同一台物理机器上的其它DB的以前正常的读写操作出现大量的超时告警。


三、数据优先级


Vampire会从不同的数据源来拉取数据,不同的数据源会提供某一条数据中的若干个字段,不同的数据源的数据质量也会有所不一样,也就是不同数据源对同一条数据中的若干个字段有不同的优先级,优先级高的数据质量高,这个优先级是在接入数据源时定义的,所以在更新数据时还需要根据数据的优先级来判断数据是否更新,目前同一条数据的同一个字段的数据源只有一个,所以可以先不考虑这方面的问题。


Write接口的性能


Read接口目前主要是从DB中读取数据,其性能主要取决于以下两个方面的因素:


一、数据库表结构的设计


在设计时尽量减少数据的冗余,将原来的每张数据表垂直拆分成多张数据表,根据业务需求建立好索引,让每一条查询的SQL语句都走索引,对于复杂的SQL查询,拆分成多条简单的SQL,然后让每条简单的SQL都命中索引,并且将这些简单的SQL尽可能的复用,如果某一条SQL查询出来的结果会比较大需要分页,这时会通过对SQL的执行进行解析,确定出合理的页大小,对于复杂查询和分页查询多数据情况下都是通过执行多条简单的SQL将返回的结果通过程序组装的方式完成的


二、接口的设计


对外的Read接口在设计时也是尽量的简单,这里的简单包括入参简单和返回值简单。入参简单指的是调用接口传入的参数尽可能的少且传入的每个参数都是必要的,例如:某一个接口有A、B和C三个参数,假设通过A和C这两个参数可以间接推导出B这个参数,这时B这个参数就是没有必要的,应该去掉;返回值简单指的是返回的报文不要太多,在设计时一般小于4KB,同时返回的报文中的数据字段都是有用的。在整套接口拆分的过程中还需要考虑两个重要的因素:1)所有接口通过若干次的组合调用是否可以获取DB中的所有有用数据;


2)完成一个特定的功能需要调用多个简单接口的次数尽可能的少,尽量多调用响应快的接口,少调用响应略慢的接口。在单机4核4G,Tomcat连接数200,DB连接数100的环境下,数据量为1KW+时,Read接口直接访问数据库,不走缓存,对于简单的查询QPS最高可以达到1400+,对于复杂的多条件分页查询QPS最低可达到400+


Faba中的缓存分为本地缓存和分布式缓存两种。对于本地缓存主要存储一些数据体量小,访问频次高,数据不一致性要求低的数据;分布式缓存主要是通过Redis作为载体来实现的,存储一些数据体量相对较大,value小,访问频次高的数据。同时在缓存数据时对数据量小的数据尽量做到全量缓存,定期更新,对于数据量大的数据采用LRU淘汰策略来更新缓存,在缓存空间固定的情况下,提高缓存命中率。由于根据目前的需求来看仅通过直连DB的方式达到的QPS已经可以满足了,所以开发缓存的优先级较低,目前还在开发过程,接口性能方面的数据暂时还不能给出。


3、Service


根据对业务需求的分析发现,每个产线的SEO页面都是由若干套页面组成的,每套页面都是从不同的角度来推广,每个页面由若干个Module组成,一个Module对应一个接口。以机票为例:机票的SEO页面会包含出发地和机场这两套页面,出发地这套页面由A、B和C这三个Module组成,机场这套页面由B、C和D这三个Module组成,这时仅需要开发4个接口分别实现A、B、C和D这4个Module对应的功能即可,可以很好的提高接口的复用性。同时,也可以通过配置让一个页面中的某个Module在不同的语种、币种、城市等维度中展示不同的数据。


4、Page


该项目主要由前端团队负责,这里不做详细描述。


5、Portal


主要由4个模块组成,其中Config模块可以根据不同的语种、币种等条件进行配置来控制Service中的各接口在不同参数情况下的返回结果、排序方式等;Log模块主要用来记录Vampire数据更新的进度、更新时长和日志等;AB Test模块主要是配合Config模块实现不同配置之间的对比,从而帮助业务人员更好的做出抉择;Statistic模块主要用来统计Faba中缓存的命中率等性能方面的数据


总结


SEO项目的核心在于数据,如何采集数据,更新数据,将质量较好的数据在每次的更新中逐渐沉淀下来是整个项目的关键;接口、数据表设计的尽量简单是提高整个项目性能的根本。本文只是大致描述了一下SEO项目重构的整体方案,对于设计方案中的具体实现细节并未做过多的描述,同时有些非核心功能还在开发中,对此感兴趣的同学可以留言,也欢迎大家拍砖。


扫码关注我们
小程序二维码

查看演示

微信公众号二维码

关注微信公众号

你觉得这篇文章怎么样?

关于小二CMS

高端定制网站领域著名服务商

我们立足合肥,业务覆盖安徽、全国及全球市场。我们凭借一支经验丰富、创意独特、协作无间的专业技术团队,专注于将最优技术通过高效简捷的途径呈现给客户,量身打造最佳解决方案。我们致力于通过持续努力,成为客户在信息化领域值得托付、共创价值的长期战略合作伙伴,协助客户在新经济时代敏锐捕捉商机,拓展发展空间,构筑强大竞争力。

小程序开发
公众号开发
高端网站开发
系统开发
商城开发
外贸网站建设
网站优化推广
安全运维

扫描二维码与小二CMS创始人沟通

7×24小时专业技术支持

高端网站定制
系统开发(OA、CRM)
商城开发
外贸网站建设
公众号/小程序
安全运维
创始人微信二维码

扫一扫添加微信

关于我们

超讯兴网络科技一家专注于高端网站建设、微信小程序开发、移动端应用研发及企业数字化转型服务的技术驱动型企业。我们致力于通过前沿技术研发实力与匠心独运的创意设计,为客户提供从策划、设计到开发、部署运维的一站式数字化解决方案。

自2013年成立以来,我们已成功交付3000+个精品项目,服务客户遍布金融、零售、制造、教育、医疗、互联网等多个行业领域。我们拥有资深的技术团队与丰富的实战经验,擅长复杂业务逻辑梳理与建模、高性能系统架构设计、跨平台应用开发、用户体验(UX/UI)深度优化及企业级系统安全保障。

我们相信,每一个成功的项目都源于对客户需求的深刻理解与极致追求。选择超讯兴网络科技,就是选择一个懂技术、懂设计、更懂您业务痛点的数字化成长伙伴,让我们携手将您的品牌愿景与市场机遇转化为可落地的数字现实,共同驱动业务增长与品牌价值升级。

致力于通过数字化技术赋能企业,帮助客户实现业务增长与品牌升级,成为您值得信赖的技术合作伙伴。

我们的优势
01

七年专注高端网站建设

02

服务上千企业积淀厚口碑

03

资深策划洞悉行业与用户

04

前沿技术栈紧跟时代发展

05

前端代码深度优化SEO友好

06

千家成功案例品质可信赖

07

精英团队高效协同创精品

08

多重防护保障数据安全

09

独家源码出售握牢自主权

10

完善售后体系全程护无忧

11

快速响应需求变更迭代

12

架构灵活支持二次开发

13

云服务器部署稳定可靠

14

免费提供一年技术支持

15

项目按期交付信誉保障

16

数据定期备份安全无忧

我们的不同

我们是一支年轻而充满激情的团队,痴迷代码,沉醉设计,坚信设计与编程不仅是工作,更是生活的信仰——"非设计,不生活;无兄弟,不编程!"

团队成员来自国内外顶尖设计公司与软件企业,精通网站设计与开发,已成功交付数百个项目,涵盖品牌官网、电商平台、小程序及移动端应用。

使命 以技术之力,助力改变命运
宗旨 客户第一,品质至上
信念 客户的成功,才是我们真正的成功

产品演示

产品演示二维码

请使用微信扫描二维码

查看产品演示

QQ客服

扫码添加好友,随时为您解答

QQ二维码

扫描二维码添加客服

QQ号:460623785
或保存二维码在QQ中识别

微信客服

扫码添加好友,随时为您解答

微信二维码

扫描二维码添加客服

微信号:
或保存二维码在微信中识别

微信咨询
QQ咨询
电话咨询
在线客服
回到顶部