没有接触 Apache Module 开发的人可能觉得这是一个很深奥的事情,其实对于有一定经验的人来说还是挺简单的。当然最好是有这么一个环境,一些"SMTH系"的人的 blog 时常会提到什么什么时候又写了一个 Apache Module,语气犹如吃饭睡觉一样稀松平常;深受清华影响的 SOHU 也是如此,动辄就会有个人跳出来和你讨论某样业务如果用 Apache Module 来实现会如何如何,久而久之,就会在思维深处认为写 Apache Module 简直是天经地义。
1. 最通常的用法就是 ap_hook_handler. 这里是 http request 处理的最后时期。而且注册的所有的 handler 都会执行一遍。我做的模块的最核心的流程就是在某些条件下增加一个 HTTP Header 交给最终的内容处理引擎(比如JSP/PHP之类);以及设置一个 Response HTTP Header 项,当 Apache 开始向浏览器返回 Response 的时候,会把我这里添加的项目也输出出去。
2. ap_hook_handler 会应用于所有的请求,有些时候会显得效率有些低——比如对静态文件就没有必要执行额外的处理,这时候用 input_filter 可能会比较好。通过 AddInputFilter 可以设定对某些 Directory/Location 才执行对应的 filter 操作。不过据说 filter 应用也有一些效率问题,需要做详细的 benchmark 才能有结论。
input_filter 的另一个用途就是保持长连接,比如 webim 就可以通过这个方式来实现 Server 端的业务。
3. post_config 阶段可以用来检查运行模块所需要的参数是否都在 httpd.conf 里面被正确配置了。不知道 Apache 的人出于什么样阴暗的心理,post_config 会被执行两次!?这里有人提出了解决方案,如何确保自己的代码只运行一次,而不至于在 error_log 里面留下连续两行同样的LOG如同可笑的弱智bug。
由于我写的这个模块将会被部署到很多台很多台服务器上,万一哪天需要更换模块就需要找出所有部署的系统进行更新。于是每次 Apache 启动后会向一台中央服务器发送一条记录,通知该服务器维护人员的联系方式。这个流程也放在 post_config 阶段,此时 Apache 还没有 spawn 子进程,如果连接并发送记录花很长时间的话会影响 Apache 的正常服务。通常的思维是发 UDP 包出来,但这样的话需要额外写一个 UDP Server 接受它们,于是我在模块里面无耻的 fork 出一个子进程,利用 APR 提供的 socket 函数,大概 10 几行代码就搞定一次 HTTP 请求,然后马上 exit
评论
呵呵,不是有本书就是讲写apache模块
Write Apache Modules With Perl and C
国外alexa排名50左右的www.mixi.jp 还有排名71的livejournal都是采用mod_perl
谢谢
试试提到的保证初始化一次的方法,这个对我很有帮助,谢谢!
似乎没必要这么麻烦
由于我写的这个模块将会被部署到很多台很多台服务器上,万一哪天需要更换模块就需要找出所有部署的系统进行更新。.....
可以用一个rpm包替代,这样以后别人要更新维护项目,只要rpm -qa|grep apache
就知道里面装了多少模块子包,然后要升级或是删除都方便。
要考虑到系统管理员基本都是很不耐烦也很怕出故障之后找问题的。而且也要便于安装
自己定制RPM包不错的
apache 的入门太难了
我想写一个调整 http 代理 返回数据的模块。
就是 A => Apache => B =>Apache =>A
在 B=>Apache=>A 这个过程中调整一些东西
看了代码,好复杂啊