年轻司机介绍补预告片系统架构与cgi
作者:
| 更新日期:作为一个年轻的司机, 来公司已经两年了。刚来的时候,做了补预告片系统,现在简单介绍一下.
本文首发于公众号:天空的代码世界,微信号:tiankonguse
概要
这篇文章简单的记录做的一个简单的系统, 并介绍一下cgi相关的知识点.
项目背景
视频是一个用户粘性很低的行业.
而我们部门在这个行业刚起步, 很多视频内容都不完善, 即只有一个空专辑(比如XX电影的名字).
我曾问上级, 为什么不买往年的热门电影.
回答是: 对于往年的电影 如果现在去花钱买那些版权收益也不大, 对于以后的, 都是我们的, 都会买.
但是一个电影的预告片往往是不需要版权的, 所以这里就希望可以对往年的电影补充预告片, 这样用户进到这个专辑, 至少可以看几分钟相关的宣传内容.
项目介绍
这个项目的目的是给空专辑补充预告片.
由于是从无到有的过程, 需要快速支持, 不需要做一个完善的闭环系统.
这里分两个子项目:
- 已经有空专辑和预告片视频了. 我们需要通过某种方法识别他们(豆瓣ID), 然后关联起来.
- 只有一个空专辑, 没有预告片. 我们需要去互联网上抓取预告片, 然后关联起来.
系统的架构图大概如下:
项目实现
项目实际上分为几个模块(实际项目中对步骤进行调整优化了).
-
把空专辑与单视频通过豆瓣ID关联起来.
大概步骤如下:
1). 从A表中找到符合指定条件的空专辑
2). 从B表中找到专辑对应的豆瓣ID, 做豆瓣ID到专辑的反向关系(存在多个时, 保留最后一个专辑)
3). 从C表找到符合条件的单视频
4). 从D表找到单视频对应的豆瓣ID, 做豆瓣ID到视频的反向关系(存在多个时, 全部保留)
5). 扫表专辑的豆瓣ID列表, 在视频列表中看是否存在, 存在则把关系保存起来
6). 把找到的专辑和视频通过接口关联起来. -
对于没关联的空专辑抓取视频
这个步骤看上面的流程图就很清晰了. -
需要有个简单的系统供编辑处理
1). 添加任务
2). 展示任务列表
3). 编辑处理任务(编辑是否补上预告片)
4). 每日邮件发送统计情况
做这个项目的时候, 第一步和第三步是一期做的.这样可以快速的补充大量的预告片, 且准确度很高.
第二部分是二期做的, 需要抓取团队开发对应的功能, 而且由于是使用标题等资料搜索抓取的, 准确度很低很低.
优化
这个项目有个特点: 快速实现.
对于内部空专辑和单视频关联逻辑, 没什么优化的, 历史数据跑完了, 关联的数据就几乎为0了.
抓取视频的准确度较低, 倒是可以优化, 但是我们是以产品驱动的, 这个项目还没上线时就已经投入其他项目了(还好上线后编辑使用没出任何问题).
所以这个项目的总体架构就是上图介绍的.
项目结语
做上面项目第一期的时候, 实际上工作分为两部分:
- 一个简单的系统
- 编写关联程序, 调用系统接口添加任务.
做系统的时候, 发现周围的人都使用C++当做WEB服务器的后台开发语言, 他们还称此为cgi.
于是有必要了解一下cgi.
cgi介绍
CGI 的中文是通用网关接口.
阅读了WIKI, 发现把我们写的c++程序称为CGI是不恰当的.
因为CGI只是WEB服务器与动态处理程序之间的一个标准或协议, 我们平时写的php, python, perl和c++的二进制没有太大的区别, 都是接收请求, 处理, 返回结果.
当认识到CGI只是一个协议时, 我们心里自然就会想问另一个问题: WEB服务器与动态处理程序之间是什么关系?
答案也很快得到验证.
接着想到的第二个问题是: WEB服务器怎么识别我们的动态处理程序的.
这个问题其实是两个问题.
- WEB服务器怎么知道这个请求需要动态处理程序处理.
- WEB服务器怎么知道怎么执行这个动态处理程序.
对于第一个问题, WEB服务器往往是通过请求URL匹配的方式识别的.
对于第二个问题, 其实在linux上很容易回答: linux是怎么识别我们的脚本的?
在apache上, 我们通常使用ScriptAlias
来指定程序的位置.
而在nginx上, 我们则需要一个额外的调度器来调用对应的程序.
可以看看下面的测试程序, 我们用bash脚本也可以做网站了.
[user_00@V_10_157_52_39 /data/release/vunion.oa.com/cgi-bin]$ cat ./test.sh
#!/bin/sh
echo -e "Content-type:text/html\n\n"
echo -e "hello<br>"
echo -e "$0 $*<br>"
echo -e "${SCRIPT_NAME}<br>"
echo -e "${QUERY_STRING}<br>"
最后, 我们的问题是: 怎么传输数据的?
这个问题其实反而好回答了.
我们看看上面的bash脚本, 输入数据并没有使用参数传输.
对于bash, 传参有两种: 参数和环境变量.
CGI标准使用的是环境变量来传参的.
而对于输出数据, 直接使用标准输出来传送数据了(不考虑 std_err).
扩展问题: 我们使用什么框架来编写cgi
开源, 开源, 开源!!!
我们cgi基础框架是开源软件: clearsilver, 它封装了cgi相关操作.
然后前辈在clearsilver的基础上, 封装了一个cgiframe框架. 开发只需要实现两个函数即可: init初始化函数, process 逻辑处理函数.
这里就不多说了, 封装的好处是大家开发快, 缺点是很多人都不知道底层的原理了.
问题定位
这里把c++编写的程序称为WEB程序更合适点.
对于C++ 编译型WEB程序, 定位问题一般是固定的.
- 万能定位法: 打日志
- 常驻进程定位法: gdb + strace.
有人可能会说, cgi一般会先 fork 一个进程出来, 这个怎么定位呢?
其实答案很简单, gdb进入fork对应的进程即可, strace 进入fork对应的进程即可.
gdb: set follow-fork-mode child
strace: man strace # 我不会告诉你是-f参数
结语
年轻的司机语言表达能力不好, 结构的组织能力也不好.
其实要表达的有两点:
- 我们所在的部门起步较晚, 很多基础功能都没有, 但这不是理由, 我们会努力去做好一切的, 有问题可以随时反馈.
- cgi是进来接触的第一个知识点, 了解了原理后, 会发现什么语言编写的其实都一样的.
本文首发于公众号:天空的代码世界,微信号:tiankonguse
如果你想留言,可以在微信里面关注公众号进行留言。