Apache编译后无法正常工作

Posted 诺克大叔

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Apache编译后无法正常工作相关的知识,希望对你有一定的参考价值。

问题分析和解决

因为某个场景的需求,要在一个国产系统Rocky4.2(国产凝思4.2操作系统)上安装Apache,虽说此系统是基于Redhat 5.8开发的,但是发现yum安装源包管理,RPM命令倒是能用,但是底层依赖完全没有,这就尴尬了,so,只能源码编译安装了。

当编译完成,启动完成Apache后发现,Apache进程立马僵尸了,状态如下:

localhost:/data/app/httpd-2.4.26/bin # ps aux |grep http
root     22676  0.0  0.0  73888  2016 ?        Ss   10:26   0:00 /data/app/httpd-2.4.26/bin/httpd -k start
daemon   22683  0.0  0.0      0     0 ?        Z    10:26   0:00 [httpd] <defunct>
daemon   22684  0.0  0.0      0     0 ?        Z    10:26   0:00 [httpd] <defunct>
daemon   22685  0.0  0.0      0     0 ?        Z    10:26   0:00 [httpd] <defunct>
daemon   22686  0.0  0.0      0     0 ?        Z    10:26   0:00 [httpd] <defunct>
root     22688  0.0  0.0   5036   936 pts/3    S+   10:26   0:00 grep http

访问默认的页面It works!都访问不出来,查看日志报错如下:

./httpd: symbol lookup error: ./httpd: undefined symbol: apr_skiplist_init
./httpd: symbol lookup error: ./httpd: undefined symbol: apr_skiplist_init
./httpd: symbol lookup error: ./httpd: undefined symbol: apr_skiplist_init
./httpd: symbol lookup error: ./httpd: undefined symbol: apr_skiplist_init
./httpd: symbol lookup error: ./httpd: undefined symbol: apr_skiplist_init
./httpd: symbol lookup error: ./httpd: undefined symbol: apr_skiplist_init
./httpd: symbol lookup error: ./httpd: undefined symbol: apr_skiplist_init
./httpd: symbol lookup error: ./httpd: undefined symbol: apr_skiplist_init

一直在报如上错误。

既然报apr的问题,应该跟Apache加载apr的动态链接库有关系,那就查看一下Apache加载APR的情况:

localhost:/data/app/httpd-2.4.26/bin # ./httpd -V
Server version: Apache/2.4.26 (Unix) Server built:   Jan 23 2019 09:39:28 Server's Module Magic Number: 20120211:68 Server loaded:  APR 1.3.0, APR-UTIL 1.5.4 Compiled using: APR 1.5.2, APR-UTIL 1.5.4 Architecture:   64-bit Server MPM:     event  threaded:     yes (fixed thread count)    forked:     yes (variable process count) Server compiled with.... -D APR_HAS_SENDFILE -D APR_HAS_MMAP -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled) -D APR_USE_SYSVSEM_SERIALIZE -D APR_USE_PTHREAD_SERIALIZE -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT -D APR_HAS_OTHER_CHILD -D AP_HAVE_RELIABLE_PIPED_LOGS -D DYNAMIC_MODULE_LIMIT=256 -D HTTPD_ROOT="/data/app/httpd-2.4.26" -D SUEXEC_BIN="/data/app/httpd-2.4.26/bin/suexec" -D DEFAULT_PIDLOG="logs/httpd.pid" -D DEFAULT_SCOREBOARD="logs/apache_runtime_status" -D DEFAULT_ERRORLOG="logs/error_log" -D AP_TYPES_CONFIG_FILE="conf/mime.types" -D SERVER_CONFIG_FILE="conf/httpd.conf"

如上可知我编译的时候编译的apr的版本是1.5.2, 但是Apache没有loaded我编译的版本APR 1.5.2,而现在工作loaded的是APR 1.3.0

这有两个问题,1是这个版本太低了,2是这个版本是个系统自带的猜想,不可控,既然知道问题了,那就想办法让Apache工作load我编译安装的版本吧。

查看Apche所需的动态链接库:

localhost:~ # cd /data/app/httpd-2.4.26/bin
localhost:/data/app/httpd-2.4.26/bin # ldd ./httpd    linux-vdso.so.1 =>  (0x00007fffba3ff000)    libpcre.so.1 => /data/app/pcre-8.32/lib/libpcre.so.1 (0x00007f05eed40000)    libaprutil-1.so.0 => /data/app/apr-util-1.5.4/lib/libaprutil-1.so.0 (0x00007f05eeb1d000)    libexpat.so.1 => /usr/lib64/libexpat.so.1 (0x00007f05ee8fa000)    libapr-1.so.0 => /usr/lib64/libapr-1.so.0 (0x00007f05ee6d1000)    libuuid.so.1 => /lib64/libuuid.so.1 (0x00007f05ee4ce000)    libcap.so.2 => /lib64/libcap.so.2 (0x00007f05ee2ca000)    librt.so.1 => /usr/lib64/librt.so.1 (0x00007f05ee0c0000)    libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007f05ede89000)    libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f05edc6e000)    libdl.so.2 => /lib64/libdl.so.2 (0x00007f05eda6a000)    libc.so.6 => /lib64/libc.so.6 (0x00007f05ed72a000)    /lib64/ld-linux-x86-64.so.2 (0x00007f05eef5b000)    libattr.so.1 => /lib64/libattr.so.1 (0x00007f05ed526000)

Tips: 在ldd命令打印的结果中,=>左边的表示该程序需要连接的共享库之so名称,右边表示由Linux的共享库系统找到的对应的共享库在文件系统中的具体位置。默认情况下/etc/ld.so.conf文件中包含有默认的共享库搜索路径。

如上可知Apache加载的apr的共享库文件的路径是/usr/lib64/libapr-1.so.0,下面让我们来看看这是什么鬼:

localhost:/data/app/httpd-2.4.26/bin # ls -l /usr/lib64/libapr-1.so.0
lrwxrwxrwx 1 sys sys 17  122 09:21 /usr/lib64/libapr-1.so.0 -> libapr-1.so.0.3.0

localhost:/data/app/httpd-2.4.26/bin # ls -l /usr/lib64/libapr-1.so.0.3.0
-rwxr-xr-x 1 sys sys 170776  122 09:21 /usr/lib64/libapr-1.so.0.3.0

localhost:/data/app/httpd-2.4.26/bin # rpm -qf /usr/lib64/libapr-1.so.0.3.0
file /usr/lib64/libapr-1.so.0.3.0 is not owned by any package

如上可知是个软链接,那就好办了,那就把这个文件软链删除,然后软链到我自己的编译的apr的动态库路径,然后在apache load,操作如下:

localhost:/data/app/httpd-2.4.26/bin # rm -rf /usr/lib64/libapr-1.so.0
localhost:/data/app/httpd-2.4.26/bin # ln -s /data/app/apr-1.5.2/lib/libapr-1.so.0.5.2 /usr/lib64/libapr-1.so.0

重启Apache试试,在查看一下状态:

localhost:/data/app/httpd-2.4.26/bin # ./httpd -V
Server version: Apache/2.4.26 (Unix) Server built:   Jan 23 2019 09:39:28 Server's Module Magic Number: 20120211:68 Server loaded:  APR 1.5.2, APR-UTIL 1.5.4 Compiled using: APR 1.5.2, APR-UTIL 1.5.4 Architecture:   64-bit Server MPM:     event  threaded:     yes (fixed thread count)    forked:     yes (variable process count) Server compiled with.... -D APR_HAS_SENDFILE -D APR_HAS_MMAP -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled) -D APR_USE_SYSVSEM_SERIALIZE -D APR_USE_PTHREAD_SERIALIZE -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT -D APR_HAS_OTHER_CHILD -D AP_HAVE_RELIABLE_PIPED_LOGS -D DYNAMIC_MODULE_LIMIT=256 -D HTTPD_ROOT="/data/app/httpd-2.4.26" -D SUEXEC_BIN="/data/app/httpd-2.4.26/bin/suexec" -D DEFAULT_PIDLOG="logs/httpd.pid" -D DEFAULT_SCOREBOARD="logs/apache_runtime_status" -D DEFAULT_ERRORLOG="logs/error_log" -D AP_TYPES_CONFIG_FILE="conf/mime.types" -D SERVER_CONFIG_FILE="conf/httpd.conf" localhost:/data/app/httpd-2.4.26/bin # curl -XGET http://localhost
<html><body><h1>It works!</h1></body></html>

如上可知达到目的了,加载的版本跟我预先编译的是一致的了,默认的页面也可以访问了,问题到这里暂时告落一阶段。


知识补充

如果你使用ldd命令没有找到对应的共享库文件和其具体位置,可能是两种情况引起的:

  • 共享库没有安装在该系统中;

  • 安装了,但是共享库保存在/etc/ld.so.conf文件列出的搜索路径之外的位置。

通常情况下, 许多开放源代码的程序或函数库都会默认将自己安装到/usr/local目录下的相应位置(如:/usr/local/bin 或 /usr/local/lib 等), 以便与系统自身的程序或函数库相区别。而许多Linux系统的/etc/ld.so.conf文件中默认又不包含/usr/local/lib

因此,往往会出现已经安装了共享库,但是却无法找到共享库的情况。具体解决办法如下:

检查/etc/ld.so.conf文件,如果其中缺少/usr/local/lib目录,就添加进去。

注意: 在修改了/etc/ld.so.conf文件或者在系统中安装了新的函数库之后,需要运行一个命令:ldconfig,该命令用来刷新系统的共享库缓存,即/etc/ld.so.cache文件。为了减少共享库系统的库搜索时间,共享库系统维护了一个共享库so名称的缓存文件/etc/ld.so.cache。因此,在安装新的共享库之后,一定要运行ldconfig刷新该缓存。

以上是关于Apache编译后无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

升级 macOS Sierra 后 apache 无法正常工作

安装 OS X El Capitan 后,Apache 无法正常工作

带有复选框和自定义适配器的 ListView,片段无法正常工作

无法从 onListItemClick 开始片段

使用片段共享过渡时返回过渡无法正常工作

使用GestureDetector后,单击或选择内部WebView无法正常工作