<-
Apache HTTP 服务器 2.4 > 动态共享对象(DSO)

动态共享对象(DSO)支持

Apache HTTP Server是一个模块化程序,管理员可以在其中选择一组模块来选择要包含在服务器中的功能。模块将被编译为与主httpd 二进制文件分开存在的动态共享对象(DSO)。DSO模块可以在构建服务器时进行编译,也可以在以后使用Apache扩展工具(apxs)进行编译和添加。

或者,可以在httpd构建服务器时将模块静态编译为二进制文件。

本文档介绍了如何使用DSO模块以及其使用背后的理论。

支持Apache!

也可以看看

最佳

实作

DSO对加载单个Apache httpd模块的支持基于名为的模块,该模块mod_so必须静态编译到Apache httpd内核中。它是唯一 core不能放入DSO本身的模块。实际上,所有其他分布式Apache httpd模块都将放入DSO。将模块编译成名为DSO 的文件后,mod_foo.so可以在文件中使用mod_soLoadModule指令在 httpd.conf服务器启动或重新启动时加载该模块。

可以通过安装文档中 讨论configure--enable-mods-static选项禁用针对单个模块的DSO构建 。

为了简化针对Apache httpd模块(尤其是第三方模块)的DSO文件的创建,提供了一个名为apxsAPache eXtenSion)的支持程序。它可用于在Apache httpd源代码树之外构建基于DSO的模块。这个想法很简单:当安装Apache HTTP服务器configuremake install程序安装在Apache httpd的C头文件并提出依赖于平台的编译器和连接器选项构建DSO文件到apxs 程序。这样,用户可以使用apxs其编译Apache httpd模块源,而无需使用Apache httpd分发源树,而无需摆弄平台相关的编译器和链接器标志以获取DSO支持。

最佳

使用摘要

为了让您大致了解Apache HTTP Server 2.x的DSO功能,以下是一个简短的摘要:

  1. 例如,将分布式 Apache httpd模块 构建并安装mod_foo.c到其自己的DSO中 mod_foo.so

    $ ./configure --prefix=/path/to/install --enable-foo
    $ make install

  2. 在启用所有模块的情况下配置Apache HTTP Server。服务器启动期间将仅加载基本集。您可以通过激活或停用中的LoadModule指令 来更改已加载模块的集合httpd.conf

    $ ./configure --enable-mods-shared=all
    $ make install

  3. 有些模块仅对开发人员有用,无法构建。使用模块时设置全部。要构建包括开发人员模块在内的所有可用模块,请使用realall。另外,LoadModule可以通过configure选项激活所有内置模块的 指令 --enable-load-all-modules

    $ ./configure --enable-mods-shared=reallyall --enable-load-all-modules
    $ make install

  4. 例如,使用以下命令在Apache httpd源代码树之外 构建第三方 Apache httpd模块 mod_foo.c并将其安装到其自己的DSO中 : mod_foo.so apxs

    $ cd /path/to/3rdparty
    $ apxs -cia mod_foo.c

在所有情况下,一旦编译了共享模块,就必须使用LoadModule in指令httpd.conf告诉Apache httpd激活该模块。

有关更多详细信息,请参见apxs文档

最佳

背景

在现代Unix派生工具上,存在一种称为动态共享对象的动态链接/加载的机制,该机制提供了一种以特殊格式构建程序代码段的方法,以便在运行时将其加载到可执行程序的地址空间中。 。

这种加载通常可以通过两种方式完成:由ld.so启动可执行程序时调用的系统程序自动完成,或通过编程系统接口从执行程序中手动通过系统调用与Unix加载器一起手动执行 dlopen()/dlsym()

在第一种方式中,DSO通常称为共享库DSO库,并命名为 libfoo.solibfoo.so.1.2。它们驻留在系统目录中(通常是/usr/lib),并且通过指定-lfoolinker命令在构建时建立到可执行程序的链接。此硬编码库引用到可执行程序文件,以便在起动时Unix加载器能够定位libfoo.so/usr/lib,在路径经由像接头选项硬编码-R或通过环境变量配置的路径 LD_LIBRARY_PATH。然后,它解析DSO中可用的可执行程序中的任何符号(但尚未解析)。

DSO通常不引用可执行程序中的符号(因为它是通用代码的可重用库),因此无需进行进一步的解析。可执行程序无需使用DSO中的符号就可以自己做任何事情,因为完整的解析是由Unix加载器完成的。(实际上,要调用的代码 ld.so是运行时启动代码的一部分,该代码链接到已绑定为非静态的每个可执行程序中)。动态加载公共库代码的优势显而易见:库代码只需要存储一次,就可以在系统库之类的系统库中libc.so节省每个程序的磁盘空间。

第二种方法通常将DSO称为共享对象DSO文件,并且可以使用任意扩展名进行命名(尽管规范名称为 foo.so)。这些文件通常位于特定于程序的目录中,并且没有自动建立指向使用它们的可执行程序的链接。相反,可执行程序在运行时通过以下方式手动将DSO加载到其地址空间中:dlopen()。此时,尚未完成来自DSO的可执行程序符号解析。但是,相反,Unix加载器会从可执行程序及其已加载的DSO库导出的符号集中自动解析DSO中的任何(尚未解析的)符号(尤其是来自普遍存在的所有符号libc.so)。这样,DSO就可以像直接将它静态链接一样,获取可执行程序符号集的知识。

最后,为了利用DSO的API,可执行程序必须解析DSO中的特定符号, dlsym()以便以后在调度表内部使用 换句话说:可执行程序必须手动解析它需要的每个符号才能使用它。这种机制的优点是,在相关程序需要可选程序部件之前,不需要加载它们(因此不会浪费内存)。必要时,可以动态加载这些程序部分以扩展基本程序的功能。

尽管这种DSO机制听起来很简单,但这里至少有一个困难的步骤:使用DSO扩展程序时,从可执行程序中解析DSO的符号(第二种方法)。为什么?因为从可执行程序的符号集中“反向解析” DSO符号违反了库设计(库不了解其所使用的程序),并且在所有平台上都不可用,也没有标准化。实际上,可执行程序的全局符号通常不会重新导出,因此无法在DSO中使用。找到一种方法来强制链接器导出所有全局符号是使用DSO在运行时扩展程序时必须解决的主要问题。

共享库方法是典型的方法,因为它是DSO机制的设计目的,因此几乎用于操作系统提供的所有类型的库。

最佳

的优点和缺点

上述基于DSO的功能具有以下优点:

DSO具有以下缺点:

可用语言: zh  |  fr  |  ja  |  ko  |  TR 

最佳

注释

注意:
这不是“问答”部分。此处放置的评论应指向有关改进文档或服务器的建议,如果实施或被认为无效/偏离主题,我们的主持人可以将其删除。有关如何管理Apache HTTP Server的问题,应直接指向我们的IRC频道#httpd(位于Freenode上),或发送至我们的邮件列表
目前,此页面已禁用评论。