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 1月 22 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 1月 22 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 无法正常工作