动态加载apache模块

动态加载apache模块


   工作中往往随着业务的改变和新功能的添加,会使用到不同的模块,但是我们编译apache的时候却没有指定。我们可以重新编译apache指定相应模块,可是大多数情况是不允许重新编译的,也很麻烦。所以大部分人都会使用动态加载模块,下面来说一下apache如何动态添加模块。


一、环境介绍

   想要动态加载模块,必须要有同一版本的apache源码包

   可以使用

   /usr/local/apache/bin/apachectl -v 查看当前版本

   Server version: Apache/2.2.22 (Unix)

   我的版本为2.2.22,那么就需要apache2.2.22 版本的源码包 httpd-2.2.22.tar.gz

   源码包中有一个modules目录,里面放着各种未编译的源码程序

   编译这些程序的时候需要 gcc 支持,可以使用

   rpm -qa | grep gcc 命令查看是否已经安装

   gcc-4.1.2-54.el5

   libgcc-4.1.2-54.el5

   gcc-gfortran-4.1.2-54.el5

   gcc-c++-4.1.2-54.el5

   我这里已经装过了,没有安装可使用

   yum install gcc* -y 进行安装

   如果安装mod_rewrite模块,是需要gdb支持的,可以使用下面命令安装

   yum install gdb* -y 进行安装

二、编译模块

   对apache的模块如果动态编译通常可以使用 /path/apxs -c *.c来完成

   下面以mod_rewrite和mod_ssl模块为例,讲解下安装过程

   首先安装mod_rewrite模块,我们进入源码包的modules/mappers/目录,因为mod_rewrite模块的源码在这个目录下面,注意不是安装目录

   cd httpd-2.2.22/modules/mappers/

  查看里面是否包含mod_rewrite模块源码

   ls | grep mod_rewrite

   mod_rewrite.c

   mod_rewrite.dep

   mod_rewrite.dsp

   mod_rewrite.exp

   mod_rewrite.h

   mod_rewrite.mak

  果然在这里,使用下面命令编译

   /usr/local/apache/bin/apxs -c mod_rewrite.c -lgdbm (如果不是mod_rewrite模块不需要加 -lgdbm)

   gcc -shared -o mod_rewrite.so mod_rewrite.o

   这样在当前目录下(即:httpd-2.2.22/modules/mappers/)就会生成一个名为mod_rewrite.so的模块

   我们可以手动将这个模块移动到apache默认的模块目录下

   mv mod_rewrite.so /usr/local/apache/modules/

   然后修改httpd.conf文件,加入下面内容

   LoadModule rewrite_module     modules/mod_rewrite.so

   当然也可以使用命令直接将mod_rewrite.so添加到/usr/local/apache/modules/目录下,并且在httpd.conf中写入

   LoadModule rewrite_module     modules/mod_rewrite.so

   使用下面命令即可

   /usr/local/apache/bin/apxs -i -a -n rewrite /http-2.2.22/modules/mappers/mod_rewrite.so 

   检测下语法,可使用命令

   /usr/local/apache/bin/apachectl -t

   如果返回值为Syntax OK,那么恭喜添加成功

   如果返回值为不能定位API”之类的错误,那就是说明LoadModule后面的模块名的语法要根据您的apache版本加以改变。一般apache的配置文件中会写一个例子,按照它的格式写就好。

   例如这种格式

   #LoadModule mod_rewrite_module     modules/mod_rewrite.so

   如果没有错误重启apache

   /usr/local/apache/bin/apachectl restart

   查看是否加载成功,可使用下面的命令

   /usr/local/apache/bin/apachectl  -M

   如果显示内容中包含rewrite_module 则成功,不包含则失败。

   其他模块也可按同一方法编译安装,但不包括mod_ssl模块,我在编译mod_ssl模块时遇到了其他问题


   再来看一下mod_ssl模块

   先进入mod_ssl模块所在目录

   cd httpd-2.2.22/modules/ssl/

   使用下面命令编译

   /usr/local/apache/bin/apxs -c mod_rewrite.c

   报错

   mod_ssl.c:553: 错误:expected ‘{’ at end of input

   apxs:Error: Command failed with rc=65536

   谷歌之后加上了-DHAVE_OPENSSL参数

   /usr/local/apache/bin/apxs -c -DHAVE_OPENSSL mod_ssl.c

   没有报错,继续执行

   gcc -shared -o mod_ssl.so mod_ssl.o

   /usr/local/apache/bin/apxs -i -a -n ssl /httpd-2.2.22/modules/ssl/mod_ssl.so

   

   检测语法

   /usr/local/apache/bin/apachectl -t

   出现undefined symbol: ssl_cmd_SSLMutex错误

   谷歌了一下,搜到下面内容

       undefined symbol: ssl_cmd_SSLMutex

       或
       undefined symbol: X509_free
       通产是由于静态连接了 openssl的库照成的(默认)。
       需要使用 -lcrypto -lssl -ldl
       命令如下:
       /path/apxs -I/path/openssl/include -L/path/openssl/lib -c *.c -l crypto -l ssl -l dl
       openssl 编译的时候需要增加 shared参数

       /usr/local/apache/bin/apxs -a -i -c -D HAVE_OPENSSL=1 -I /usr/include/openssl/ -L /usr/lib/openssl/engines/lib ./mod_ssl.c

   于是重新编译,问题依旧。

   搞了两天,还是同样的错误,没有办法,最后在虚拟机上重新编译了相同版本的apache,并且使用了--enable-mods-shared=all参数,动态编译了所有的模块。

   这样在apache的modules目录下就生成了所有的apache模块,也就包括了mod_ssl模块,复制到线上服务器

   检测语法OK,问题解决

   /usr/local/apache/bin/apachectl -t

   Syntax OK

   虽然这不是一个好方法,但也算是一个办法,也希望直接编译成功的大神不吝指点。

   重启apache

   /usr/local/apache/bin/apachectl restart

   查看是否加载成功

   /usr/local/apache/bin/apachectl  -M

   显示内容中包含ssl_module


三、大功告成







你可能感兴趣的:(动态加载apache模块)