PHP任务队列

服务端开发经常会有任务队列的需求,比如数据入库(为降低数据库写入压力,必须排队进行),项目编译,项目上线等。这类需求一般是离线的,对队列的性能要求不高。更多的是考虑如何降低开发,部署和维护的成本。

github上可以找到的开源消息队列非常多。使用的技术也很多样。我们项目中只用到php,redis,mysql。所以如果有一个任务队列能够只使用php和redis,那我们的开发,部署,维护成本会小很多。

实现思路很简单,用php常驻进程监听redis 队列,有新任务到达则启动该任务,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    function run($queue) {
        while (true) {
            $pid = pcntl_fork();
            if ($pid == -1) {
                $this->log('fatal', '子进程fork失败');
                usleep(1000000);
            } else if ($pid == 0) {     //  子进程执行, 执行完成后必须主动退出
                try {
                    $task_id = $this->taskqueue->pop($queue);
                    if (empty($task_id)) {
                        usleep(1000000);
                    } else {
                        $this->handle_task($queue, $task_id);
                    }  
                    exit(0);
                } catch (Exception $ex) {
                    $this->log('fatal', '异常:'. $ex->getMessage());
                    exit(1);
                }  
            } else {                    // 父进程执行
                pcntl_wait($status);
            }  
        }  
    }

其中taskqueue对象负责与redis交互,对外提供pop push 等方法,代码很简单,就略了。

注意问题:

1. php必须使用多线程,不可用单进程。实际使用中发现单进程模式在运行一段时间后就会意外退出或者卡死,这个其实容易理解,毕竟php生下来就没打算被用做守护进程。

2. 直接使用linux的nohup … & 命令启动程序,仍然有问题,进程意外退出就麻烦了。可以用supervisor加监控。

后续工作,如果能够只使用php,不依赖redis就更好了,会更加容易使用和维护。近期把redis的队列功能封装为php扩展。

模块设计的一些经验

这里说的“模块”特指能够实现某一功能的程序或者子程序。模块设计其实指的就是如何组织代码,实现功能,基本可以表述为“为实现特定功能,应该把代码拆分为几个函数或类,这些函数或类应该放在几个文件里,这些文件应该放在几个文件夹里”。

为什么模块设计就是指如何组织代码?

MVC框架,做web开发的肯定都懂,它给出了一种通用的代码组织方案,即按照代码的功能,划分为模型、视图、控制器。可是具体到模型,或控制器的内部,代码又应该如何组织呢?除了按照功能进行划分,还有其他划分方法吗?

设计模式,码农都懂。但不是每个码农都能把正确的模式应用在的特定的场景上。如何知道该使用什么模式?

带着这两个问题,我们逐一说说下列原则:

1. 隔离业务代码与基础库代码。业务代码是指不具备服用价值的,为解决特定业务问题而写的代码。基础库代码会在不同业务代码中复用。为了实现业务代码与基础库代码的分离,在js中最初级的方法就是把基础库函数放到一个文件里,高级点的可能还回按命名空间组织在一起。

未完待续…

新手,高级新手,胜任,精通,专家

最近在看《程序员的思维修炼》,了解到成为某一领域专家的人必须经过的五个步骤。认真审视自己,发现我到目前为止还没有一项技术达到精通的程度,前端至多只能算是胜任,服务端至多只能算是高级新手。非常勤奋的专研某一领域5年能到精通,10年才可能成为专家。只怪我入行太晚。

踏踏实实做技术吧,后面的路还长着呢。没什么影响力就去创业等同于“碰运气”。保守的人还是选择稳健的长线投资策略更合适。

最简单的内容管理系统是什么样的?

内容管理系统,英文名 CMS (Content Manage System),是网站运营必不可少的工具。CMS按解决问题领域的不同,可以分为很多种,开源的项目也非常多,我正在用的wordpress就是其中之一。最简单的内容管理系统,应该具有如下特征:

1. 管理线上内容,就像管理磁盘上的文件一样,模式都是:新建文件,编辑,保存;或者,打开已有文件,编辑,保存。除此以外,不要引入任何不好理解的概念,有些CMS系统就会引入“专题”,“栏目”等很难理解的概念。

但仅仅把内容管理设计的跟管理磁盘上的文件一样,还是不够的。因为,运营人员可能不懂技术。不可能让他们直接编辑html原文件。所以,最简单的内容管理系统,还应具备如下特征:

继续阅读

用github管理你的vim配置

用vim搞开发两年多了,一直用很混乱的的方式管理vim配置和插件。今天有空,整理了一下。

整理结果在此: https://github.com/kingzs70/vimrc

以后换开发机只需要执行如下命令,即可安装好开发环境:

1
2
3
git clone https://github.com/kingzs70/vimrc.git ~/
cp ~/vimrc ~/.vimrc
git clone https://github.com/gmarik/vundle.git ~/.vim/bundle/vundle

打开vim,执行

1
:BundleInstall

原理参见:https://github.com/gmarik/vundle

继续阅读

前端还是全端?

题目描述的是前端工程师的职业发展路线问题,即应该在纵向上深入专研前端,还是应该在横向上拓展到后端,其他客户端,或者设计领域。在我看来,这是问题毫无意义。任何期望通过求解这个问题,获得职业发展路线答案的行为,都是在浪费时间。

作为技术人员,很多人内心深处最想要的都是通过创造一个产品来影响世界。但几乎所有人都不知道达成这一目标的路径。所以我们只能跟着那些已经找到那条路径的幸运儿走。一旦选择跟随,就必须向别人证明自己的价值。这些价值的体现方式包括:

  • 技术突破,帮助产品实现重要功能;
  • 深入业务,通过提供工具和服务为公司节省大量成本;
  • 提供想法,驱动产品向着正确的方向发展;
  • 团队管理,付出一个人的成本提高团队的整体效率;
  • 运营推广,为产品开拓市场,献计献策。

如果一个人在产品团队中的工作不是通过以上方式体现价值,那他每天的工作就只是在以体力或脑力换工资。而思考本文题目描述的问题的人,基本都是这一类人,我也在其中。
继续阅读

看你学历也不错,为什么选择前端啊?

今天有人问我这样一个问题:“看你学历也不错,为什么选择前端啊?”。之前被人问过好多次这个问题,甚至自己也在问自己。

每当我听到这个问题,心情是很复杂的:

气愤。你们可能误解前端了。

在过去,前端给人感觉就是做网页的。写写 html,css,复杂点的页面还需要写一些脚本。工作难度主要集中在处理浏览器兼容性上。但总体上,技术含量不高。

如今,前端早已不是这样。浏览器性能和功能越来越强大,技术标准越来越完善,大公司(Google,Facebook,Microsoft)都在推动web技术的发展,越来越多的PC应用被迁移到浏览上,firefox、chrome都在推出webOS,浏览器提供的编程接口越来越接近操作系统的编程接口,web技术是目前唯一能够真正解决跨平台问题的技术。

继续阅读

JavaScript函数与函数作用域

昨天问了自己一个问题:究竟是应该把一个小的领域研究透彻,成为专家,还是应该在横向上不断拓展的自己的知识面,成为所谓的复合型人才。过去我一直认为后者是对的。现在发现,只有那些在某一领域真正成为专家的人,才有资格在横向上拓展自己。否则你给人的印象只能是浮躁,虽然什么都能做,但没有一项能做到极致。引发我这个思考的是两个JavaScript问题:

问题一:如下两次alert的输出是什么?

1
2
3
4
5
6
7
var a = 1;
function func(){
  alert(a);
  var a = 2;
  alert(a);
}
func();

问题二:如下alert的输出依次是什么?

1
2
3
4
5
6
7
8
9
10
11
12
function func(){
  alert(1);
}
func();
var func = function(){
  alert(2);
}
func();
function func(){
  alert(3);
}
func();

继续阅读

我对前端职业发展的看法

在github上看到一篇阿里巴巴无线前端团队的面试试题,第一道就是“你对前端职业发展有何看法?”。这也是我在面试别人时每次必问的题目。听了太多答案,今天,我也整理下自己工作两年来对前端的一些认识。

1. 什么是前端?

前端作为一个工作,其主要工作领域是浏览器端,核心技术包括 JavaScript,css,html 等。还要处理服务器通信,以及部分服务器脚本开发的工作,比如发布、测试脚本,jsp、php页面脚本。有时,还需要与产品经理、交互设计,共同完成一些交互设计。可以看出,前端处于设计与后台的中间领域,起到承上启下的作用。这也就要求前端工程师的知识面在横向上必须要广。服务器技术要懂,产品与交互也要懂。所以经常有前端工程师称自己游走在设计与编码的边缘。

2. 前端工作有技术含量吗?

继续阅读

关于产品设计,我的7条原则

声明:我是一个前端工程师,产品设计并非我的主业。但相信每个人对“产品设计”都会有自己的一些原则。

作为一个前端工程师,有时,由于工作需要也会需要做一些产品的工作。对于一个毫无产品设计经验的人来说,我最关心的就是“产品设计有什么原则值得遵循”。这些原则不能保证产品成功,但至少可以降低产品失败的概率。以下原则主要源于两本书《结网》《启示录》,我结合近期的项目经验,融入了一些个人理解。

原则一. 从概念开始。

产品设计一定是从概念开始。引用《结网》的一副图片,原图源于Scott McCloud的《理解漫画》
继续阅读