[关闭]
@ronaldoooo 2014-11-28T03:31:15.000000Z 字数 5681 阅读 2136

荆楚网移动站

项目总结

荆楚网 技术研发中心
蔡乾
2014年11月28日



一. 项目背景

随着移动互联网的快速发展,荆楚网移动端流量快速增长。荆楚网页面并未对移动页做适配,之前的移动页面通过百度转码完成,样式无法自定义,需要设计自己的移动端页面。由于在原有的CMS系统中并不能实现绑定两个模板(在一次发布中),故需要通过程序获取已发布页面信息,生成等移动端页面。


二. 项目人员

何龙华

蔡乾


三. 项目日程

3.1 计划日程

计划时间 项目阶段
2014-08-20 完成需求分析和概要设计工作,开始详细设计,进入编码阶段
2014-09-15 完成编码和单元测试,进入系统测试和试运营
2014-10-15 完成前端界面显示,完成系统测试工作,系统可正式上线

3.2 实际日程

实际时间 项目阶段
2014-08-05 项目启动
2014-08-07 初步了解项目背景,环境搭建完毕,开始考虑总体设计以及实现方案
2014-08-11 完成V1版本总体设计文档,以及关键类的详细设计文档,基本确定了采集的思路
2014-08-12 开始初步编码工作,几个关键类的实现。总体逻辑参照UCenter Home
2014-08-17 关键类编码基本完成,在图片的处理上确定了抓取再转存方案,并开始相应编码工作
2014-08-21 图片转存完成,并且合并入原有项目。并就准备初版上线的三个频道开始测试工作,在测试过程中,发现了采集方式无法解决的一些问题,比如同一个目录下不同模板,开始考虑放弃采集的方式
2014-08-25 与今日头条合作的项目加入,增加现有逻辑,并合并进移动站项目
2014-08-31 讨论决定不采用图片转存方式,直接引用**原始图片*
2014-09-04 今日头条页面上线,V1版代码进入自动运行阶段
2014-09-05 查看日志过程中发现头条页面生成过程中的致命缺陷
2014-09-06 找出缺陷原因,是因为根据docID来取数据的错误逻辑所致。这时开始考虑到需要依据pubtime建立索引,并从接口提取数据
2014-09-09 接口需求完成,并与接口提供方对接,开始从接口获取数据
2014-09-15 项目后台转稿整体逻辑基本完成,持续测试的同时,开始着手开发管理界面
2014-09-19 管理界面完成,开始项目重构,同时参考其它网站现有的页面来初步考虑前端的显示样式
2014-09-25 组图页显示方案确定,采用轮播插件
2014-10-11 重构完成,改变了项目的整体框架,移动站页面生成由V1代码转入V2版本,开始持续测试,工作重点转入前端页面制作
2014-10-15 大部分首页内容确定,依照首页数据,自动生成首页页面信息
2014-10-17 首页模板制作完成,依照首页模板,套用数据生成页面,同时制作文章页模板
2014-10-27 内网域名解析完成,项目在内网部署完成
2014-11-13 模板制作基本完成,项目进入自动运行阶段

3.3 日程偏差

项目阶段 预计时间 实际时间 总结
需求概要设计 20日 10日 需求变更比较大,加之项目初期对现有系统不太熟悉,无法做出完善的设计。此处10天是指分析和得出初版设计方案的时间。
详细设计编码 25日 40日 低估了前端代码开发的时间。并且,由于前期设计的不完备使得项目整体需要重构。重构的时间也被计算在内。由于组件的单元测试是手动完成,单元测试的时间也被计算在编码过程中。
系统测试 25日 30日 系统测试时间基本符合预期

注:以上时间均包含双休日,不包含法定假日。

3.4 日程分析

预期的开发过程是瀑布式的,其实开发过程更接近迭代式。实际开发过程也证明,螺旋式的迭代升级,更适合该项目的开发。


四. 软件质量

4.1 软件模块

软件系统在主要功能上分为稿件生成后台管理两大块。

模块名称 简介
稿件生成(核心功能) 完成稿件、首页的批量生成,存放
后台管理 提供手动发稿,删稿的后台入口,以及简单的用户管理

4.2 运行环境

项目 配置
测试环境 虚拟机
操作系统 CentOS
CPU 未知
系统内存 4G bytes
PHP版本 5.2.17
PHP运行内存 512M

注:该环境为测试环境,运行内存在实际环境中可调整。

4.3 质量参数

项目 参数 备注
每次最高转稿数量(可正常执行) 6000+ 系统每5分钟运行一次,这是一次运行时转稿的最高负荷。如果在5分钟内新发布稿件超出此数字,系统有缓冲机制可避免崩溃,将一次的转稿任务分为多次来进行。
每次转稿崩溃阈值 15000+ 这是取数据接口能够承受的最大量,如果再5分钟内新发布稿件超过此数字,取数据接口会崩溃。
手动重新发布最长天数 15-20 这是根据现有荆楚网发稿量的估计值,按照每天新发布1000篇稿子来估计。如果手动发布设置的时间距今超过15天,程序有可能会崩溃。(后台管理界面并未提供手动批量发布的入口。)

在测试环境中,为PHP分配512M运行内存,系统仅会在一次性读取稿件数量超过15000时发生崩溃,该崩溃原因是接口负荷过高。在实际运行中,一次的转稿量最高在100-1000数量级,所以一般不会发生系统崩溃的情况。


五. 后台接口

5.1 简介

后台接口是指向管理人员(非技术人员)提供的接口,供管理人员对移动站页面进行而使用。管理人员可进入后台页面,输入管理账号登录管理页面。目前后台地址是http://10.99.113.11/wap/admin/login.html

5.2 后台功能

5.2.1 登录

输入账号和密码进行登录。

测试账号:

账号: testcnhubei
密码: testtest

错误流程:

5.2.2 权限

后台包含三种权限:

用户管理权限相当于超级用户,包含以上全部权限。

超级用户可以通过后台系统创建、删除用户,可对用户发稿、删稿权限进行控制,但不可通过后台管理超级用户。如需管理超级用户,需要技术人员手动完成。

登录后,在用户首页可以查看自己的权限。超级用户可以在用户列表中查看他人权限。

5.2.3 发稿

具有发稿权限的用户,可以在后台点击发稿件选项,进入发稿流程

发稿流程中,用户输入稿件的源url地址(即PC端页面地址),再点击发布。如该稿件属于移动站转稿范围,则会被转为相应WAP页面,存放于相应位置。

5.2.4 删稿

具有删稿权限的用户,可以在后台点击删稿件选项,进入删稿流程

删稿流程中,用户输入稿件的地址,点击确认,可以删除相应的WAP页面。

5.2.5 修改密码

用户可点击修改密码选项,修改自身登录密码。


六. 项目细节

6.1 移动站转码流程

移动站转稿分为两种:

在向接口取出所需文章信息之后,套用预先写好的页面模板,生成相应的移动页。

具体的转稿流程如下:

Created with Raphaël 2.1.2开始按时间批量转稿?获得上次转稿截止时间从接口获取数据稿件是否处理完结束分析稿件类型套用相应模板分析写入路径写入文件获得待转稿件源URLyesnoyesno

6.2 溢出缓存

由于php5.2版本依照refcount进行内存清理的机制,在转稿过程中,如数据量过大,可能发生内存溢出。在发生这种情况时,程序会保存运行状态,并清空运行内存。在下一次运行的过程中,程序会首先检测上次的运行状态。如果上次有未完成的工作记录,程序会读取该记录,并从上次的状态继续进行。此时,遇到上次已经处理过的稿件便不会处理。

由于接口的负荷大约是15000篇稿件每次,而在测试的512M的PHP运行内存中,一次转稿的最高数量大约在6000篇左右。这种缓存机制确保了转稿程序在一次转稿任务中获取的任务量在6000-15000之间时候可以正常工作。

如果这个数字超过了接口的最高负荷,程序依然无法正常运行。
具体的缓存流程见下图。

Created with Raphaël 2.1.2开始读入记录有未完成任务?写入比对数组继续任务获取一篇稿件信息比对url,是否已转?未转完的稿件?内存将近溢出?保存转稿记录退出清空转稿记录转稿,加入记录新建任务yesnoyesnoyesnoyesno

6.3 MVC分离

6.3.1 Model层

model层主要负责数据的读写,以及与该model关联的行为,以及基本数据结构定义。

model层基本位于models文件夹中。

主要类:

6.3.2 View层

View层主要采用Smarty模板实现与业务逻辑的分离。

Controller获取必要信息后,将信息处理,扔给View层。Smarty模板负责依照所获信息来生成静态页面。

Smarty模板位于templates文件夹中。页面公共的部分做成公共调用,部分同类页面之间有继承关系,减少维护的成本。

6.3.3 Controller层

Controller提供程序的控制逻辑。位于程序根目录下。

Controller对外提供相应接口:


七. 总结和经验

该项目的实际上线日期比预期时间晚了将近一个月左右。在项目的初期,何龙华一直帮我提的就是充分设计再做实现。但由于这是我初来荆楚网所做的第一个项目,对实际业务情况了解不足,所做的初版设计在实现后逐步被发现问题,在频繁的变更下表现得适应性极差。

由于设计的缺陷,我们甚至在测试阶段发现了设计上的一个致命的逻辑错误,这个错误导致所转稿件有很大一部分会缺失。由于改缺陷是设计阶段就注入了,在编码的过程中该缺陷也被多次放大。多次改动也使得项目代码混乱不堪,此时我开始考虑做重构。最后的事实是,除了转稿和数据库等的逻辑代码外(大致统计这部分不到200LOC),我几乎重写了全部的项目代码。这一项就花费了将近10个工作日的时间。

重构的版本(以下称V2版)完全抛弃了之前总体基于Ucenter Home的代码框架,依照OO Programming的开闭原则对项目模块进行功能分离,极大提高了可拓展性,也降低了维护的风险。

在今后的开发中,如有可能我会选择一套完备的开源框架(如YII, LARAVEL等),以更好的实现MVC三层的分离,也免去了重复造轮子的过程。

从软件开发的过程看来,比较影响效率的是代码同步问题。在初期我们曾经用SVN做过一段时间的同步,但由于远程代码库搭建在本机上,同步过程需主机保持开机。在项目部署在服务器上之后,由于服务器上并未搭建SVN,SVN同步的方式基本就没有使用了。此时同步代码基本靠download before write,这种方式的风险显而易见,在开发过程中就出现过一方的变更被另外一方覆盖的情况。

所幸的是,本项目仅两人参与编码,分工比较明确,在异常变更时也能非常容易发现变更的发起者。一旦项目组人数超过2人,这种手动同步的方式就难以维持项目正常进行。

在转稿过程中,如果遇到大量稿件同时出现,可能会导致内存溢出。在后续的sitemap过程中,何龙华与我也仔细研究过php运行时内存溢出的问题。

由于测试服务器采用php5.2版本,该版本仅采用refcount方式进行内存管理,对循环中malloc的内存回收尚存在缺陷。而php官方在php5.3有出台一个重大补丁,针对内存管理增加了GC模块。事后在sitemap制作的过程中也实际证明,同样的程序在不同的版本环境下运行,占用内存大不相同。

我尝试在运行时,手动去在数据结构中注销变量以释放内存空间。该方式虽然能在一定程度上解决内存溢出的问题,但是却影响了程序执行的效率。实际生产时并没有采用这种方式。

内存溢出仅会发生在php脚本运行时间较长的情况下。(在实际情况中这个值大概超过了一分钟。)PHP作为脚本语言,是否适合常驻内存运行,在业界尚存在讨论。

PHP作为C语言的上层封装,在写程序的时候应当多关注底层实现,才能在效率上更进一步。


八. 致谢

移动站从开始开发到上线获得了大家的大力帮助与支持。

感谢 @邵慧芬 提供的漂亮设计稿,使得移动站能够有个靓丽的形象展示给用户!

感谢 @王明望 制作的移动站模板以及trs平台上稿件适配上提供的帮助!

感谢 @王甫、@周硙 提供CMSTOP、TRS平台的数据,这是移动站数据之源!感谢在方案制定过程中提供的建议,帮助甚多!

感谢 @程志丹 在数据同步等运维上提供的帮助,有了数据同步移动站才能对外发布!

感谢 @何龙华 在工作中对我的指导,不厌其烦地帮我解释产品细节流程、排查细节问题,在与你协作的过程中受益良多!

感谢各位领导对移动站的大力支持!

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注