Nginx在CentOS7基于源代码编译安装【作者Leo】

1)前言

在CentOS7下,可以使用yum直接安装Nginx,但官方编译不具备第三方模块,比如常用的下列第三方模块:

a)nginx-sticky-module-ng:基于Cookie的会话保持模块

b)nginx_upstream_check_module:检查后端服务器健康模块

c)nginx-upstream-fair:比内建的负载均衡更加智能的负载均衡模块

因此,如果需要使用这些功能模块,我们通常需要基于源代码编译安装Nginx。

下面的安装过程使用的CentOS版本为CentOS 7.4.1708,即CentOS-7-x86_64-DVD-1708.iso

 

2) 删除已安装的Nginx

如果是通过yum或rpm非源码安装,删除命令如下:

# systemctl stop nginx

# systemctl disable nginx

# yum -y remove nginx

# rm -rf /usr/share/augeas/lenses/dist/nginx.aug

# rm -rf /usr/lib64/nginx

# rm -rf /var/lib/nginx

# rm -rf /var/log/nginx

# rm -rf /etc/nginx

# rm -rf /usr/share/nginx

# rm -rf /usr/local/lib64/perl5/auto/nginx

# rm -rf /usr/local/lib64/perl5/nginx.pm

# rm -rf /usr/lib/systemd/system/nginx.service

# rm -rf /etc/init.d/nginx

# rm -rf /usr/sbin/nginx

# rm -rf /run/nginx.pid

如果是通过源代码编译安装,删除命令如下:

如果编译源代码文件夹存在,进入源代码文件夹运行,

# make uninstall

如果不存在,则需要手动删除nginx,运行下面命令找到nginx安装了哪些文件及所在文件夹:

# find / | grep nginx

通常使用非源码安装中的rm命令即可删除。

 

3)下载编译安装所需的程序包和源代码

a)安装下载和编译基础程序包:

# yum -y install wget tar git gcc make pcre pcre-devel zlib zlib-devel

b)安装OpenSSL(如果是已经通过源代码编译安装了的OpenSSL,则不需安装):

# yum -y install openssl openssl-devel

c)安装Nginx附加模块所需依赖程序包:

# yum -y install GeoIP GeoIP-devel libxslt-devel gd gd-devel perl-ExtUtils-Embed

d)创建源代码文件夹并下载源代码:

# mkdir /usr/src/nginx

# cd /usr/src/nginx

# git clone https://github.com/gnosek/nginx-upstream-fair.git

# git clone https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng.git

# git clone https://github.com/yaoweibin/nginx_upstream_check_module.git

# wget http://nginx.org/download/nginx-1.14.0.tar.gz

# tar -xvzf nginx-1.14.0.tar.gz

# cd /usr/src/nginx/nginx-1.14.0

上面Nginx稳定版本是1.14.0(本人测试使用1.15.2也编译安装通过)

e)确认编译Nginx所需openssl库文件所在文件夹:

# find / | grep '\/ssl\.h\|\/libssl\.a\|\/libcrypto\.a'

通过yum或rpm安装的openssl(本人使用yum安装,OpenSSL版本为:OpenSSL 1.0.2k-fips,使用命令openssl version可查看版本信息),通常在 /usr/local 文件夹会找到ssl.sh、libssl.a和libcrypto.a三个文件(即确认了编译参数--with-openssl=/usr/local)。

f)修改源代码中配置文件:

# vi /usr/src/nginx/nginx-1.14.0/auto/lib/openssl/conf

找到:

CORE_INCS="$CORE_INCS $OPENSSL/.openssl/include"

CORE_DEPS="$CORE_DEPS $OPENSSL/.openssl/include/openssl/ssl.h"

CORE_LIBS="$CORE_LIBS $OPENSSL/.openssl/lib/libssl.a"

CORE_LIBS="$CORE_LIBS $OPENSSL/.openssl/lib/libcrypto.a"

CORE_LIBS="$CORE_LIBS $NGX_LIBDL"

CORE_LIBS="$CORE_LIBS $NGX_LIBPTHREAD"

替换为:

CORE_INCS="$CORE_INCS $OPENSSL/include"

CORE_DEPS="$CORE_DEPS $OPENSSL/include/openssl/ssl.h"

CORE_LIBS="$CORE_LIBS $OPENSSL/lib64/libssl.a"

CORE_LIBS="$CORE_LIBS $OPENSSL/lib64/libcrypto.a"

CORE_LIBS="$CORE_LIBS $NGX_LIBDL"

CORE_LIBS="$CORE_LIBS $NGX_LIBPTHREAD"

(或者,编译时可以不使用--with-openssl参数,而是直接将配置文件中的$OPENSSL使用实际路径替换)

 

4)执行下面命令编译并安装

# ./configure --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mtune=generic' --with-ld-opt='-Wl,-z,relro -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -m64 -Wl,-E' --user=nginx --group=nginx --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --pid-path=/var/run/nginx.pid --lock-path=/var/lock/subsys/nginx --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --with-openssl=/usr/local --with-debug --with-compat --with-file-aio --with-http_auth_request_module --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_sub_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_stub_status_module --with-mail=dynamic --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream=dynamic --with-stream_ssl_module --with-http_geoip_module=dynamic --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_slice_module --with-http_perl_module=dynamic --add-module=/usr/src/nginx/nginx-sticky-module-ng --add-module=/usr/src/nginx/nginx_upstream_check_module

# make

# make install

# openssl dhparam -out /etc/nginx/dhparams.pem 2048

创建Nginx运行所需文件夹及权限设置:

# mkdir /etc/nginx/conf.d

# mkdir /etc/nginx/default.d

# mkdir /usr/share/nginx/logs

# mkdir -p /var/lib/nginx/tmp/client_body

# mkdir -p /var/lib/nginx/tmp/proxy

# mkdir -p /var/lib/nginx/tmp/fastcgi

# mkdir -p /var/lib/nginx/tmp/uwsgi

# mkdir -p /var/lib/nginx/tmp/scgi

# chown -R nginx.nginx /var/lib/nginx/

# chmod -R 770 /var/lib/nginx/

 

5)创建自启动脚本

a)使用systemd服务方式(Nginx执行程序支持,强烈建议):

# vi /usr/lib/systemd/system/nginx.service

内容如下:

[Unit]

Description=The nginx HTTP and reverse proxy server

After=network.target remote-fs.target nss-lookup.target



[Service]

Type=forking

PIDFile=/run/nginx.pid

# Nginx will fail to start if /run/nginx.pid already exists but has the wrong

# SELinux context. This might happen when running `nginx -t` from the cmdline.

# https://bugzilla.redhat.com/show_bug.cgi?id=1268621

ExecStartPre=/usr/bin/rm -f /run/nginx.pid

ExecStartPre=/usr/sbin/nginx -t

ExecStart=/usr/sbin/nginx

ExecReload=/bin/kill -s HUP $MAINPID

KillSignal=SIGQUIT

TimeoutStopSec=5

KillMode=process

PrivateTmp=true



[Install]

WantedBy=multi-user.target

启用nginx.service:

# systemctl enable nginx.service

启动Nginx:

# systemctl start nginx

停止Nginx:

# systemctl stop nginx

 

b)使用init.d脚本:

# vi /etc/init.d/nginx

内容如下:

#!/bin/sh
#
# nginx - this script starts and stops the nginx daemin
#
# chkconfig:   - 85 15
# description:  Nginx is an HTTP(S) server, HTTP(S) reverse \
#               proxy and IMAP/POP3 proxy server
# processname: nginx
# config:      /etc/nginx/nginx.conf
# pidfile:     /var/run/nginx.pid
# user:        nginx

# Source function library.
. /etc/rc.d/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0

nginx="/usr/sbin/nginx"
prog=$(basename $nginx)

NGINX_CONF_FILE="/etc/nginx/nginx.conf"

lockfile=/var/run/nginx.lock

start() {
    [ -x $nginx ] || exit 5
    [ -f $NGINX_CONF_FILE ] || exit 6
    echo -n $"Starting $prog: "
    daemon $nginx -c $NGINX_CONF_FILE
    retval=$?
    echo
    [ $retval -eq 0 ] && touch $lockfile
    return $retval
}

stop() {
    echo -n $"Stopping $prog: "
    killproc $prog -QUIT
    retval=$?
    echo
    [ $retval -eq 0 ] && rm -f $lockfile
    return $retval
}

restart() {
    configtest || return $?
    stop
    start
}

reload() {
    configtest || return $?
    echo -n $"Reloading $prog: "
    killproc $nginx -HUP
    RETVAL=$?
    echo
}

force_reload() {
    restart
}

configtest() {
  $nginx -t -c $NGINX_CONF_FILE
}

rh_status() {
    status $prog
}

rh_status_q() {
    rh_status >/dev/null 2>&1
}

case "$1" in
    start)
        rh_status_q && exit 0
        $1
        ;;
    stop)
        rh_status_q || exit 0
        $1
        ;;
    restart|configtest)
        $1
        ;;
    reload)
        rh_status_q || exit 7
        $1
        ;;
    force-reload)
        force_reload
        ;;
    status)
        rh_status
        ;;
    condrestart|try-restart)
        rh_status_q || exit 0
            ;;
    *)
        echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
        exit 2
esac

 

启用nginx:

# chkconfig --add nginx

# chkconfig --level 345 nginx on

启动Nginx:

# service nginx start

停止Nginx:

# service nginx stop

检查Nginx版本及支持的模块:

# nginx -V

检查Nginx配置文件是否正确:

# nginx -t

 

6)常见问题及解决办法

a)自动跳转至80端口

Nginx默认反向后的端口为80,因此存在被代理后的端口为80的问题,这就导致访问出错。主要原因在Nginx的配置文件的host配置时没有设置响应的端口。

错误的配置文件如下:

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

如上,Host配置只有host,没有对应的port,这就导致在被代理的地方取得错误的端口。本文以java为例:

String scheme = httpRequest.getScheme();

String serverName = httpRequest.getServerName();

int port = httpRequest.getServerPort();

//服务请求地址

String requestURI = scheme+"://"+serverName+":"+port+"/index.jsp";

这时,取得的port为80,虽然nginx监听的端口为8080。于是,修改nginx的配置文件,将Host后面的改为 $host:$server_port即可,正确的配置文件如下:

proxy_set_header Host $host:$server_port;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

 

b)Nginx无法启动或停止

通常以systemd服务方式配置Nginx自启动时,如果 /etc/nginx/nginx.conf 文件中配置了:

pid logs/nginx.pid;

将可能导致使用命令systemctl start nginx和systemctl stop nginx无法启动或停止Nginx服务,因此需要删除该配置行。

 

c)使用Cookie会话保持

首先确认Nginx编译包含了nginx-sticky-module-ng第三方模块(命令为:nginx -V),在 /etc/nginx/nginx.conf 文件中的upstream片段中增加sticky配置,如:

upstream bim-server.backend {

#ip_hash;

sticky name=myapp_route hash=md5;

server 192.168.0.1:8080 weight=1 max_fails=3 fail_timeout=60s;

server 192.168.0.2:8080 weight=1 max_fails=3 fail_timeout=60s;

server 192.168.0.3:8080 weight=1 max_fails=3 fail_timeout=60s;

}

(ip_hash和sticky不要同时使用,参考:https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng

 

d)如何查看已安装程序包信息(包括版本),如:查看OpenSSL程序包

使用yum查看:

# yum list installed | grep 'openssl'

使用rpm查看:

# rpm -qa | grep 'openssl'

如果是源代码编译安装的,只能手动确认可执行文件是否存在。如果是以root用户安装的,可执行程序通常都在/sbin或/usr/bin目录下。

 

 

7)资源参考

a)Nginx第三方模块列表:https://www.nginx.com/resources/wiki/modules/

b)Nginx动态模块清单:https://www.nginx.com/products/nginx/modules/

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值