在启动
nginx
时,可能碰到过这种情况:
[centos@localhost ~]$ sudo /usr/sbin/nginx
[sudo] centos 的密码:
nginx: [emerg] module "/usr/lib64/nginx/modules/ngx_http_image_filter_module.so" is not binary compatible in /usr/share/nginx/modules/mod-http-image-filter.conf:1
这种情况一般是第三方模块编译中包含的签名和使用的 nignx 不一致导致的。
解决如下:
首先,通过 nginx -V
查看编译使用选项(即当前配置的 configure 参数):
[centos@localhost ~]$ nginx -V
nginx version: nginx/1.16.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx1.16.1 --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --user=nginx --group=nginx --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --with-select_module --with-poll_module --with-threads --with-file-aio --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_geoip_module=dynamic --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_auth_request_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --with-mail=dynamic --with-mail_ssl_module --with-stream --with-stream_ssl_module --with-stream_realip_module --with-stream_geoip_module=dynamic --with-stream_ssl_preread_module --with-compat --with-debug
之后,重新编译 nginx 源码生成的 .so
模块并复制到旧目标路径(即覆盖掉原有的)。操作时需要在 configure
命令上追加一个动态编译的选项 --add-dynamic-module=
或者直接调用 ./configure --with-compat --add-dynamic-module=
第三方模块动态编译命令。此处路径需要找到你要编译的动态模块,即 .c
文件,后面使用 cp
指令在迁移到目标文件即可。
[centos@localhost nginx-1.16.1]$ find . -name "*http_image_filter_module*"
./src/http/modules/ngx_http_image_filter_module.c
同时还要在该 modules
文件夹下新增 config
文件,该文件来自官网,需要根据实际情况进行调整。
[centos@localhost nginx-1.16.1]$ :<<!
这里为了文件的更加规则有序,不直接在 'modules' 里新加 'config' 文件,而是新建立 'ngx_http_image_filter_module' 文件,并将 '.c' 原文件复制到该目录中
!
[centos@localhost nginx-1.16.1]$ mkdir src/http/modules/ngx_http_image_filter_module
[centos@localhost nginx-1.16.1]$ cp src/http/modules/ngx_http_image_filter_module.c src/http/modules/ngx_http_image_filter_module/ngx_http_image_filter_module.c
[centos@localhost nginx-1.16.1]$ vim src/http/modules/ngx_http_image_filter_module/config
ngx_addon_name=ngx_http_image_filter_module
if test -n "$ngx_module_link"; then
ngx_module_type=HTTP
ngx_module_name=ngx_http_image_filter_module
ngx_module_srcs="$ngx_addon_dir/ngx_http_image_filter_module.c"
. auto/module
else
HTTP_MODULES="$HTTP_MODULES ngx_http_image_filter_module"
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_image_filter_module.c"
fi
[centos@localhost nginx-1.16.1]$ :<<!
在后续 make 编译阶段,发现错误
!
Assembler messages:
致命错误:can't create objs/src/http/modules/ngx_http_image_filter_module/ngx_http_image_filter_module.o: 没有那个文件或目录
make[1]: *** [objs/src/http/modules/ngx_http_image_filter_module/ngx_http_image_filter_module.o] 错误 2
make[1]: 离开目录“/home/centos/nginx-1.16.1”
make: *** [build] 错误 2
[centos@localhost nginx-1.16.1]$ :<<!
这里应该使该文件与nginx目录平级
!
[centos@localhost nginx-1.16.1]$ cd ..
[centos@localhost ~]$ cp -r nginx-1.16.1/src/http/modules/ngx_http_image_filter_module ngx_http_image_filter_module/
此处 config
文件来源,参考官方说明:Converting Static Modules to Dynamic Modules
完整流程如下:
在你编译 nginx 源码的文件里再次执行 ./configure
指令,如果你使用直接追加的命令, 注意
,原有的配置参数一定也要加入。
$ ./configure --prefix=/usr/local/nginx1.16.1 \
--sbin-path=/usr/sbin/nginx \
--conf-path=/etc/nginx/nginx.conf \
--user=nginx \
--group=nginx \
--pid-path=/var/run/nginx.pid \
--lock-path=/var/run/nginx.lock \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--with-select_module \
--with-poll_module \
--with-threads \
--with-file-aio \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_xslt_module=dynamic \
--with-http_image_filter_module=dynamic \
--with-http_geoip_module=dynamic \
--with-http_sub_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_mp4_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_auth_request_module \
--with-http_random_index_module \
--with-http_secure_link_module \
--with-http_degradation_module \
--with-http_slice_module \
--with-http_stub_status_module \
--with-mail=dynamic \
--with-mail_ssl_module \
--with-stream \
--with-stream_ssl_module \
--with-stream_realip_module \
--with-stream_geoip_module=dynamic \
--with-stream_ssl_preread_module \
--with-compat \
--with-pcre=../pcre-8.42 \
--with-pcre-jit \
--with-zlib=../zlib-1.2.11 \
--with-openssl=../openssl-1.1.1a \
--with-openssl-opt=no-nextprotoneg \
--with-debug \
--add-dynamic-module=../ngx_http_image_filter_module #追加的动态编译
或者采用动态编译的命令,显然这种命令比较方便,省去了了解原有 configure
配置参数的步骤:
$ ./configure --with-compat --add-dynamic-module=../ngx_http_image_filter_module
执行 make
编译命令,编译成功之后,不要继续执行 make install
。
$ make
最后将你重新编译生成的文件复制(覆盖)掉原文件即可,先将原路径下 .so
文件备份,防止意外:
[centos@localhost nginx-1.16.1]$ sudo mv /usr/lib64/nginx/modules/ngx_http_image_filter_module.so /usr/lib64/nginx/modules/ngx_http_image_filter_module.so-bak
[centos@localhost nginx-1.16.1]$ sudo cp objs/ngx_http_image_filter_module.so /usr/lib64/nginx/modules/
这样便完成了动态编译。配置如果没开,记得加载打开即可。
第三方模块动态编译官方网站参考:Compiling Third-Party Dynamic Modules for NGINX and NGINX Plus