热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

在ApacheHTTPD服务器中使用DSO完全分析

文章标题:在ApacheHTTPD服务器中使用DSO完全分析。Linux是中国IT实验室的一个技术频道。包含桌面应用,Linux系统管理,内核研究,嵌入式系统和开源等一些基本分类

  Apache HTTP 服务器是一个模块化(或说积木式)的程序,管理员可以选择一些模块来增加服务器的某些功能。这些模块,可以在创建服务器程序时静态地编译到httpd服务器的二进制代码中,也可以编译成一些独立于服务器程序的Dynamic Shared Objects (DSOs)文件。DSO 文件可以在编译服务器程序时创建,也可以在以后利用Apache扩展工具apxs来单独创建。  这篇文档,将描述如何使用DSO 模块,以及其背后的原理。
  
  实现
  Apache HTTPD对DSO 的支持,即对单个模块的动态加载,是基于一个叫mod_so的模块来实现的,此时mod_so必须被静态地编译到HTTP服务器内核中。这是除了core以外唯一不能以dso方式编译的模块。实际操作时,其它的Apache模块可以在编译服务器程序时通过单独指定来将其编译为DSO文件,正如安装文档中讲述的,此时configure的设置参数应为--enable-xxxx=shared(xxxx为模块的名字,如rewrite等)。 当一个模块被编译为一个名为mod_foo.so的DSO文件后,就可以在httpd.conf文件中用mod_so的LoadModule命令,告诉服务器在启动或重新启动时将此模块加载。
  
  为了简化创建Apache模块(尤其是第三方模块)的DSO文件的过程,apache提供了一个新工具名叫apxs(APache eXtenSion)。它可以脱离apache的源码将模块编译成DSO文件。它的实现思路非常简单: 在安装Apache时,configure脚本的 make install 过程会安装Apache的C头文件,并在apxs程序(apxs是一个perl脚本)中对依赖于具体平台的编译器和连接器设置一些标志(Flag),以供创建DSO文件。通过这种方式,用户就可以利用apxs在没有Apache源码树且无需针对当前平台的编译器和连接器进行配置(以生成DSO格式目标文件)的情况下编译Apache模块了。
  
  使用概要说明
  创建和安装一个 Apache发布的(distributed) 模块,比方说将mod_foo.c编译成mod_foo.so:
  
  $ ./configure --prefix=/path/to/install --enable-foo=shared
  $ make install
  
  创建和安装一个第三方的Apache模块,比方说将mod_foo.c编译成mod_foo.so:
  
  $ ./configure --add-module=module_type:/path/to/3rdparty/mod_foo.c --enable-foo=shared
  $ make install
  
  为以后安装(非HTTPD编译时安装)模块配置Apache:
  
  $ ./configure --enable-so
  $ make install
  
  (要编译全部Aapache模块,用./configure --enable-mods-shared=all --with-egd --with-devrandom --enable-so,但对experimental一类的模块,需要特别指定,如./configure --enable-mods-shared=all --with-egd --with-devrandom --enable-so --enable-cache=shared --enable-disk_cache=shared --enable-mem_cache=shared --enable-proxy=shared --enable-proxy_cOnnect=shared --enable-proxy_ftp=shared --enable-proxy_http=shared --enable-file_cache=shared --enable-charset_lite=shared --enable-case_filter=shared --enable-case_filter_in=shared --enable-ssl=shared 。具体有哪些模块可以编译而没有打开编译开关,可在前面的那个configure运行的最后看看哪一个是no.)
  
  利用apxs在没有Apache源码树的情况下,创建和安装第三方的Apache模块:
  
  $ cd /path/to/3rdparty
  $ apxs -c mod_foo.c
  $ apxs -i -a -n foo mod_foo.la
  
  在所有的情况下,当一个模块编译完成后,必须在httpd.conf使用LoadModule命令在告诉 Apache激活这个模块.
  
  背景知识
  在现代的Unix的派生版本中,有一种非常好的机制,叫做Dynamic Shared Objects (DSO) 的动态连接/和加载,它提供了一种方法,将一段代码编译成一种特殊格式后可在一个可执行程序运行时将这段程序加载到它的地址空间中。
  
  这种加载通过可以通过两种方式做到: 在一个可执行程序开始运行后通过一个叫ld.so的系统程序自动加载,或在可执行程序内部通过Unix加载器(loader)的系统编程接口的系统调用dlopen()/dlsym()来手工加载。
  
  在第一种方式中,DSO通常被叫作共享库或DSO库,以libfoo.so或libfoo.so.1.2的形式命名。它们被存放在系统目录中(通常是/usr/lib),它们与可执行程序的联系是在编译这个可执行程序时,通过传递给连接器一个-lfoo参数来建立的。这里对库的引用直接编码在可执行程序中,因而在程序运行时,Unix加载器会通过以下途径寻找libfoo.so:在系统目录/usr/lib下,在通过-R连接参数传递给连接器后被编码在可执行程序中的路径中,在通过环境变量LD_LIBRARY_PATH指定的目录中。加载器会解析出来那些在可执行程序中使用但是在DSO定义的标志(symbol)。
  
  可执行程序中的标志,通常不会被DSO引用(因为它是一个可重用的基本代码库),因而就不再进行进一步的解析。可执行程序自己不需要做任何事情就可以使用来自DSO的标志,因为Unix加载器已经做了相关的解析工作。(实际上,加载ld.so的代码是使用动态库的可执行程序启动代码的一部分). 动态加载基本代码库的优点是很明显的:库的代码只需在一个系统库(如libc.so)中保存一次,这样可以节省每个程序的磁盘空间。
  
  在第二种方式中,DSO通常被叫作共享对象或DSO文件,命名它们时可以使用任意的扩展名,虽然规范的命名是foo.so的样子。这些文件通常存放在程序所在的目录(或子目录)中,它们与执行它们的程序没有自动建立的联系。相反,可执行程序在运行时通过dlopen手工将DSO加载。此时,来自DSO供执行程序用的标志没有被解析。相反,Unix加载器自动解析所有DSO中使用的来自可执行程序和它已经加载的DSO 库的标志(尤其是来自无处不在的libc.so的所有标志)。在这种方式中,DSO取得可执行程序的标志集合的信息,就象是被静态地连接到可执行程序中一样。
  
  最后,为利用DSO's API,可执行程序须通过dlsym()来解析来自DSO的特定标志,供在以后的分派表等处使用。也就是说:可执行程序要想使用来自DSO的标志,须手工解析它。这样一种机制的优点,不需要的程序段不必加载(因而可以节省内存的使用) ,直到我们讨论的程序需要它时。当需要时,这些程序段可以被动态的加载,来扩展基本程序的功能。
  
  虽然DSO机制听起来简单,用起来只少有一个比较困难的步骤,就是当用DSO来扩展程序的功能时(第二种方式)时,对来自可执行程序、供DSO使用的标志的解析。为什么呢? 因为"反向解析" DSO 使用的来自可执行程序标志集合的标志是与函数库的设计相逆的 (函数库没有任何关于那些使用它的程序的信息),而且没有平台提供这种功能,这也不是一个标准化的功能。实际上,可执行程序的全局标志常常不能再次输出,因而也无法供DSO使用。要利用DSO来动态扩展一个程序的功能,找到一种方法来强制连接器输出所有全局标志是必须解决的主要问题。
  
  共享库的方法就是一个典型,因为它是DSO机制最初设计的目标,因而它被用于操作系统提供的几乎所有类型的函数库中。从另一方面来说,利用共享对象来扩展功能的程序并不是很多。
  
  到1998年,只有很少的软件包在程序运行时利用DSO机制来扩展它们的功能:Perl 5(通过它的XS机制和DynaLoader模块), Netscape Server,等。从版本1.3开始, Apache 也加入了这个群体,因为Apache早就用模块的概念来扩展它的功能,且在内容利用基于分派链(dispatch-list-based )的方法来将外部的模块连接到Apache的核心功能中。因此,Apache实际上注定要用DSO来在运行时加载模块的。
  
  长处和不足
  上述的基于DSO的功能有以下优点:
  
  服务器在运行时更加灵活,因为实际的服务器进程可以通过配置文件的LoadModule命令动态的组配,而不必在编译时通过配置参数指定。例如,通过这种方式,虽然只安装了一次,但服务器可以以多种形态运行(如标准版本或SSL版本,简化版本或增强版本[含mod_perl,php3等])
  
  即使在安装完成后,服务器仍可以很方便地用第三方的模块进行功能扩展。这至少对销售商的软件支持有帮助,他们可以创建一个apache的核心程序包,和一个包含PHP3, mod_perl, mod_fastcgi等扩展功能的扩展包。
  
  更容易地开发 Apache模块原型,因为借用DSO和apxs,你可以脱离Apache的源码而只需apxs -i命令就可以开发和编译模块,利用apachectl restart 命令,就可以让新开发的模块在在apache服务器中运行。
  
  DSO 也有下列不足
  DSO并不是在任何平台都可以使用,因为有一些平台不支持动态将一段代码加载到另一个程序的地址空间中
  
  服务器在启动时慢大约20%,因为加载器要作标志解析。
  
  在运行时,在有些平台上服务器大约慢5%,因为PIC( position independent code )代码需要更复杂的组配技巧来解决相对地址的问题,而对绝对地址的情况没有这种开销所以会快一些。
  
  因为并不是所有的平台都支持DSO模块连接(ld -lfoo)其它基于DSO的库(如基于out的平台通常不提供这个功能而基于ELF的平台则可以),所以不能将DSO机制用于所有类型的模块。换句话说,可以编译为DSO文件的模块限制为那些:引用的标志只来自apache内核、来自C函数库(libc)、来自其它的Aapche内核使用的动态或静态库、或含有PIC代码的静态库文件(libfoo.a)。使用其它代码的唯一机会,要么确定apache内核已经对此引用,要能自己通过dlopen()加载代码。
推荐阅读
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • PHP组合工具以及开发所需的工具
    本文介绍了PHP开发中常用的组合工具和开发所需的工具。对于数据分析软件,包括Excel、hihidata、SPSS、SAS、MARLAB、Eview以及各种BI与报表工具等。同时还介绍了PHP开发所需的PHP MySQL Apache集成环境,包括推荐的AppServ等版本。 ... [详细]
  • 本文介绍了RPC框架Thrift的安装环境变量配置与第一个实例,讲解了RPC的概念以及如何解决跨语言、c++客户端、web服务端、远程调用等需求。Thrift开发方便上手快,性能和稳定性也不错,适合初学者学习和使用。 ... [详细]
  • mac php错误日志配置方法及错误级别修改
    本文介绍了在mac环境下配置php错误日志的方法,包括修改php.ini文件和httpd.conf文件的操作步骤。同时还介绍了如何修改错误级别,以及相应的错误级别参考链接。 ... [详细]
  • 如何提高PHP编程技能及推荐高级教程
    本文介绍了如何提高PHP编程技能的方法,推荐了一些高级教程。学习任何一种编程语言都需要长期的坚持和不懈的努力,本文提醒读者要有足够的耐心和时间投入。通过实践操作学习,可以更好地理解和掌握PHP语言的特异性,特别是单引号和双引号的用法。同时,本文也指出了只走马观花看整体而不深入学习的学习方式无法真正掌握这门语言,建议读者要从整体来考虑局部,培养大局观。最后,本文提醒读者完成一个像模像样的网站需要付出更多的努力和实践。 ... [详细]
  • 目录浏览漏洞与目录遍历漏洞的危害及修复方法
    本文讨论了目录浏览漏洞与目录遍历漏洞的危害,包括网站结构暴露、隐秘文件访问等。同时介绍了检测方法,如使用漏洞扫描器和搜索关键词。最后提供了针对常见中间件的修复方式,包括关闭目录浏览功能。对于保护网站安全具有一定的参考价值。 ... [详细]
  • Tomcat安装与配置教程及常见问题解决方法
    本文介绍了Tomcat的安装与配置教程,包括jdk版本的选择、域名解析、war文件的部署和访问、常见问题的解决方法等。其中涉及到的问题包括403问题、数据库连接问题、1130错误、2003错误、Java Runtime版本不兼容问题以及502错误等。最后还提到了项目的前后端连接代码的配置。通过本文的指导,读者可以顺利完成Tomcat的安装与配置,并解决常见的问题。 ... [详细]
  • .htaccess文件 ... [详细]
  • 1、概述首先和大家一起回顾一下Java消息服务,在我之前的博客《Java消息队列-JMS概述》中,我为大家分析了:然后在另一篇博客《Java消息队列-ActiveMq实战》中 ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 本文介绍了使用PHP实现断点续传乱序合并文件的方法和源码。由于网络原因,文件需要分割成多个部分发送,因此无法按顺序接收。文章中提供了merge2.php的源码,通过使用shuffle函数打乱文件读取顺序,实现了乱序合并文件的功能。同时,还介绍了filesize、glob、unlink、fopen等相关函数的使用。阅读本文可以了解如何使用PHP实现断点续传乱序合并文件的具体步骤。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
author-avatar
哈王豐3_408
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有