formatuu 发表于 2018-11-24 09:16:29

动态加载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
  

  三、大功告成






  

  

  




页: [1]
查看完整版本: 动态加载apache模块