背景

笔者日常工作里面包括了云上运维工作,包括(业务)云服务器的管理、云中间件和云服务器自建中间件的部署和维护。云负载均衡产品一般称为CLB或者SLB,从实现上猜测是基于Nginx进行二次开发。由于云负载均衡中间件的费用比较高,一般选用云服务器自建Nginx集群,那么就需要”精通”Nginx的安装(和卸载)过程。写本文的时间为2021-11前后,所用的系统和软件版本如下:

系统或软件 版本
CentOS 7.x
Nginx 1.20.1

前置依赖安装

手动编译Nginx源码之前,至少需要安装这几个依赖:

软件包 功能 链接
gccgcc-c++ GCC编译器 gccgcc-c++
pcrepcre-devel Perl Compatible Regular Expressionsperl兼容的正则表达式库 pcre
zlibzlib-devel 提供了很多种压缩和解压缩方式 zlib
opensslopenssl-devel 密码算法、常用的密钥和证书封装管理功能及TLS/SSL协议支持 openssl

安装gccgcc-c++

sudo yum -y install gcc gcc-c++

安装pcrepcre-devel

sudo yum -y install pcre pcre-devel

安装zlibzlib-devel

sudo yum -y install zlib zlib-devel

安装opensslopenssl-devel

sudo yum -y install openssl openssl-devel

安装前置依赖软件包完成后就可以进行源码编译安装,在此之前可以先了解一下Nginx的常用编译参数。

Nginx常用编译参数

Nginx官方文档的《Building nginx from Sources》章节中有详细展示所有支持的编译参数,这里只简单列举和介绍一下常用的参数。基础参数:

参数 功能 默认值
--prefix=path Server所有文件保存路径,同时是configure操作中所有使用相对路径的前缀路径,理解为最终的安装路径即可 /usr/local/nginx
--sbin-path=path Nginx二进制执行文件的绝对路径(包含文件名) prefix/sbin/nginx
--modules-path=path 动态模块加载目录 prefix/modules
--conf-path=path 默认配置文件nginx.conf的绝对路径,这里其实可以随意命名,不叫nginx.conf也可以 prefix/conf/nginx.conf
--error-log-path=path 异常日志文件绝对路径,可以在nginx.conf中修改 prefix/logs/error.log
--pid-path=path Nginx主进程的PID存储文件 prefix/logs/nginx.pid
--lock-path=path .lock文件的放置路径 prefix/logs/nginx.lock
--user=name worker进程启动用户,要求是非特权用户,可以在nginx.conf中修改 -
--group=name worker进程启动用户组,要求是非特权用户所在用户组,可以在nginx.conf中修改 -

基础参数如果指定了绝对路径,则优先使用绝对路径,否则使用$prefix/改配置项的相对路径,当然prefix本身有默认值,同时也支持覆盖默认值。接着是启用内置模块和禁用内置模块编译的参数,格式如下:

# 启用模块
--with-${module_name}_module
# 禁用模块
--without-${module_name}_module

有很多可以选用的内置模块,这里就不列举出来。举个例子,如果需要添加SSLHTTPS)支持和静态文件gzip压缩,那么需要添加下面两个模块:

--with-http_ssl_module --with-http_gzip_static_module 

扩展模块和动态模块加载(例如Lua模块可以基于这种方式引入):

# 扩展模块引入
--add-module=path
# 动态模块引入
--add-dynamic-module=path

临时文件(HTTP请求日志和缓存文件):

# HTTP请求日志,默认值prefix/logs/access.log,这里有个大坑就是不会自动分割,文件大了要自行考虑分割或者压缩方案
--http-log-path=path
# 客户端请求BODY临时文件存放目录,默认值prefix/client_body_temp
--http-client-body-temp-path=path
# 代理服务器接收数据临时文件存放目录,默认值prefix/proxy_temp
--http-proxy-temp-path=path
# FastCGI服务器接收数据临时文件存放目录,默认值prefix/fastcgi_temp
--http-fastcgi-temp-path=path
# uwsgi服务器接收数据临时文件存放目录,默认值prefix/uwsgi_temp
--http-uwsgi-temp-path=path
# SCGI服务器接收数据临时文件存放目录,默认值prefix/scgi_temp
--http-scgi-temp-path=path

还有一部分和前置依赖类库pcrezlibopenssl等相关以及硬件相关的配置这里不再详述。

Nginx编译安装

先下载Nginx的源码压缩包,下载的链接在http://nginx.org/en/download.html,这里一般情况下建议选用stable version(稳定版本):

下载和解压源码包:

# 新建目录
mkdir -p /data/nginx
cd /data/nginx
# 下载源码
wget http://nginx.org/download/nginx-1.20.1.tar.gz
# 下载完成后解压到当前目录 => 解压完成后的目录为nginx-1.20.1
tar -zxvf nginx-1.20.1.tar.gz
# 进入解压后的目录
cd nginx-1.20.1

接着开始编译配置,前文提到过默认的$prefix目录为/usr/local/nginx,这里笔者自定义prefix=/data/nginx

  • 命令行执行:
./configure \ 
--prefix=/data/nginx \
--with-http_stub_status_module \
--with-http_ssl_module \
--with-http_gzip_static_module
  • 单行命令执行(方便放在.sh脚本或者复制执行)
./configure --prefix=/data/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module

这里./configure的多行或者单行命令是同一条预编译配置的命令,笔者只是区分出来方便不同场景下的拷贝和执行,不要盲目分别执行一次。

这里编译时候添加了几个模块,功能如下:

  • with-http_stub_status_module:监控Nginx的客户端状态
  • with-http_ssl_moduleSSL协议支持(如果想启用HTTPS支持,必须引入此模块)
  • with-http_gzip_static_module:静态资源gzip压缩支持

最后执行编译命令:

make && make install

看到最终输出make[1]: Leaving directory字样(如下图)即是编译成功。

编译完成后所有输出目录和文件的树形结构如下:

添加软链让nginx命令可以全局执行:

ln -s /data/nginx/sbin/nginx /usr/local/bin/nginx

然后验证Nginx的版本:

<= nginx -v
=> nginx version: nginx/1.20.1

至此,Nginx编译安装成功,如果想要添加新的模块或者移除现有的模块,修改预编译配置,按照整个编译和安装流程重新走一遍就行。

Nginx常用命令

Nginx常用命令如下:

命令描述 命令 示例
启动 nginx(使用默认配置$prefix/nginx.conf)或者nginx -c $dir/nginx.conf nginx -c /data/nginx/conf/nginx.conf
默认配置检查 nginx -t nginx -t
主进程接收stop信号,停止 nginx -s stop -
主进程接收quit信号,退出 nginx -s quit -
主进程接收reopen信号,相当于kill -USR1 nginx.pid,一般针对于log,用于文件分割时候打开新文件 nginx -s quit -
主进程接收reload信号,相当于kill -USR2 nginx.pid,热加载配置 nginx -s reload -

nginx -s stop理解为快速关闭,不管当前Nginx有没有正在处理的请求。nginx -s quit是另一种优雅的关闭方式,Nginx在退出前完成已经接受的连接请求。

如果想要Nginx在系统启动的时候启动,可以把之添加到系统服务中,添加新系统服务文件vim /lib/systemd/system/nginx.service和编写该文件脚本:

[Unit]
Description=nginx
After=network.target

[Service]
Type=forking
ExecStart=/data/nginx/sbin/nginx
ExecReload=/data/nginx/sbin/nginx -s reload
ExecStop=/data/nginx/sbin/nginx -s quit
PrivateTmp=true

[Install]
WantedBy=multi-user.target

:wq保存脚本文件后,通过chmod 755 /lib/systemd/system/nginx.service添加权限。完成后即可通过系统服务去调用Nginx

功能 命令
启动Nginx systemctl start nginx.service
停止Nginx systemctl stop nginx.service
重启Nginx systemctl restart nginx.service
查看Nginx状态 systemctl status nginx.service
设置Nginx开机自动启动 systemctl enable nginx.service
禁用Nginx开机自动启动 systemctl disable nginx.service

小结

安装完Nginx后就可以根据需要对每个单独的域名新建一个${HOST_NAME}.conf进行配置,配置完成之后调用nginx -s reload刷新配置即可,刷新前可以使用nginx -t验证配置文件的正确性。如果需要添加一些新的module或者添加修改原有的编译,则需要修改make相关参数(也就是./configure中的参数)并且重新进行编译,最终把得到的二进制包sbin/nginx替换原来旧的二进制包即可。关于Nginx的更深入用法有机会会在其他文章中介绍(日志分割、location规则、使用consul做动态负载均衡等等)。

参考资料:

(本文完 c-2-d e-a-20211110 这是一篇2年前的文章写了忘记发,润色依稀再发。下一篇文章谈谈云服务器自建Nginx集群的详细过程)