ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Linux下Nginx 1.16.1源码编译安装与生产环境定制指南

Linux下Nginx 1.16.1源码编译安装与生产环境定制指南 1. 项目概述为什么选择源码编译安装Nginx在Linux世界里部署一个Web服务器尤其是Nginx方法有很多。新手可能更习惯用yum install nginx或apt-get install nginx一键搞定省时省力。但作为一名有经验的运维或开发者我总会优先考虑从源码tar包开始编译安装特别是对于生产环境或需要深度定制的场景。今天要聊的就是在Linux系统上手动编译安装Nginx 1.16.1这个特定版本的全过程。你可能会问包管理器这么方便为什么还要“自讨苦吃”原因有几个。第一版本控制。系统仓库里的Nginx版本往往比较旧或者不是你想要的特定版本比如1.16.1它可能是一个长期支持分支中某个稳定的次版本。手动编译让你能精确锁定任何一个历史版本。第二模块定制。Nginx的强大在于其模块化架构。通过源码编译你可以自由选择启用或禁用哪些模块。比如默认安装可能不包含http_realip_module用于获取用户真实IP或http_sub_module内容替换而这些在生产环境中可能是必需的。第三优化与安全。你可以针对当前服务器的CPU架构如启用特定的GCC优化参数进行编译获得更好的性能。同时你能完全掌控编译参数和依赖库的版本避免因系统仓库中某些依赖库版本不兼容或存在已知漏洞而引入风险。所以这篇内容就是为你准备的如果你需要部署一个特定版本、高度定制化、或用于学习Nginx内部机制的服务器环境那么跟着我从下载tar包开始一步步走到一个完全受你控制的Nginx服务。2. 环境准备与依赖解析动手之前兵马未动粮草先行。编译安装不像二进制安装那样“开箱即用”它需要你的系统具备编译环境和必要的依赖库。这一步没做好后面会报各种千奇百怪的错误。2.1 系统与权限确认首先确保你在一个干净的Linux环境下操作我以最常见的CentOS 7.x或Rocky Linux 8作为演示系统但原理通用于大多数发行版。你需要一个具有sudo权限的普通用户或者直接使用root用户。为了安全我建议使用普通用户在需要提权时使用sudo。打开终端先更新一下系统软件包列表这是一个好习惯sudo yum update -y # 或者对于Debian/Ubuntu系统sudo apt update sudo apt upgrade -y2.2 安装编译工具链编译C/C项目核心工具是GCCGNU Compiler Collection、Make和Automake等。在CentOS/RHEL系列中它们通常被打包在Development Tools组里。sudo yum groupinstall -y Development Tools这条命令会安装包括gcc,gcc-c,make,automake,autoconf,libtool在内的一整套工具。安装完成后可以用gcc --version和make --version验证。2.3 安装Nginx核心依赖库Nginx的某些功能依赖于第三方库。以下是几个最关键、最常遇到的依赖缺少它们会导致configure脚本报错或者编译出的Nginx缺少重要功能。PCRE库Perl Compatible Regular Expressions。Nginx的http核心模块和rewrite模块需要它来处理正则表达式这是实现URL重写、条件判断的基础。没有它Nginx的很多核心功能将无法使用。zlib库用于GZIP压缩。Nginx的http_gzip_module模块依赖它用来压缩响应内容节省带宽。OpenSSL库如果你需要HTTPSSSL/TLS支持这是必须的。它用于http_ssl_module模块。即使你现在不用我也强烈建议装上以备不时之需。在CentOS/RHEL上安装这些开发包sudo yum install -y pcre pcre-devel zlib zlib-devel openssl openssl-devel注意这里安装的是pcre-devel、zlib-devel和openssl-devel而不仅仅是pcre、zlib和openssl。-devel包包含了编译时需要的头文件.h文件和静态链接库.a文件而基础包只包含运行时库.so文件。这是新手最容易踩的坑之一只装了运行时库导致编译时找不到头文件而失败。实操心得在某些最小化安装的服务器上可能连wget或curl都没有。你可以用yum install -y wget来安装wget方便我们下一步下载源码包。3. 源码获取与解压环境准备好了现在让我们把Nginx 1.16.1的源码请到服务器上来。3.1 下载特定版本的Nginx源码包Nginx官网提供了稳定的版本下载。我们将使用wget命令直接从官网下载。为了保持目录整洁我习惯在/usr/local/src目录下操作这个目录通常用于存放本地安装的软件源码。cd /usr/local/src sudo wget http://nginx.org/download/nginx-1.16.1.tar.gz这里URL中的nginx-1.16.1.tar.gz就是我们要的版本。你可以通过访问http://nginx.org/download/来查看所有可用版本。下载过程通常很快。3.2 解压源码包并进入目录下载下来的是一个.tar.gz格式的压缩包这是Linux下标准的源码分发格式。我们需要用tar命令解压。sudo tar -zxvf nginx-1.16.1.tar.gz解释一下tar的参数-z表示通过gzip过滤器进行解压因为文件后缀是.gz。-x表示解压extract模式。-v表示显示解压过程的详细信息verbose让你看到正在解压哪些文件。-f后面必须紧跟文件名指定要操作的文件。解压完成后当前目录下会生成一个nginx-1.16.1的文件夹。进入这个目录后续所有操作都在这里进行。cd nginx-1.16.1现在你可以用ls命令查看一下目录结构会看到auto,conf,src,configure等文件和文件夹。其中configure脚本就是我们接下来配置编译选项的关键。4. 编译配置定制你的Nginx这是整个过程中最具技术含量和决定性的步骤。configure脚本会检查你的系统环境并根据你提供的参数生成一个适合当前系统的Makefile。4.1 运行configure脚本在源码目录下直接运行./configure但通常我们会带上很多参数。一个常见的基础配置命令如下./configure \ --prefix/usr/local/nginx \ --usernginx \ --groupnginx \ --with-http_ssl_module \ --with-http_realip_module \ --with-http_gzip_static_module \ --with-http_stub_status_module \ --with-pcre让我逐一解释这些参数的含义和重要性--prefix/usr/local/nginx这是安装目录。编译安装的软件默认会安装到这个路径下。/usr/local是系统级本地软件的推荐安装位置与包管理器安装的软件通常在/usr分开便于管理。--usernginx --groupnginx指定Nginx工作进程运行时使用的用户和组。为了安全Nginx主进程master process以root启动因为需要绑定80端口而实际处理请求的工作进程worker processes会切换到这里指定的非特权用户nginx。你需要事先创建这个用户和组sudo useradd -r -s /sbin/nologin nginx。-r创建系统用户-s /sbin/nologin禁止其登录shell。--with-http_ssl_module启用HTTPS支持模块。非常重要即使暂时不用也建议启用。--with-http_realip_module启用真实IP模块。当Nginx前面有代理如CDN、负载均衡器时这个模块可以正确获取到客户端的真实IP而不是代理服务器的IP。对于日志记录和安全策略至关重要。--with-http_gzip_static_module启用静态文件GZIP预压缩模块。它允许Nginx直接发送预先压缩好的.gz文件而不是实时压缩能降低CPU消耗。--with-http_stub_status_module启用状态监控模块。它提供了一个简单的网页显示Nginx当前的连接数、请求数等基本状态信息是监控的基础。--with-pcre显式声明使用我们已安装的PCRE库。虽然configure通常能自动找到但显式声明更稳妥。注意事项configure脚本会输出大量检查信息。请务必仔细阅读最后几行。如果看到Configuration summary并且没有明显的错误error提示通常意味着配置成功。如果中途报错最常见的原因是依赖库没装全或没装开发包即缺少-devel包。错误信息通常会明确指出缺少哪个库比如the HTTP rewrite module requires the PCRE library这时你就需要回头检查pcre-devel是否已安装。4.2 进阶配置选项除了上述基础模块你还可以根据需求启用更多模块--with-http_sub_module内容替换模块。--with-http_v2_module启用HTTP/2协议支持需要同时启用SSL模块。--with-stream启用TCP/UDP代理模块用于做四层负载均衡。--with-threads启用线程池支持用于处理慢速I/O操作避免阻塞工作进程。你可以通过运行./configure --help查看所有可用的配置选项。但记住一个原则按需启用。不必要的模块会增加二进制文件大小和潜在的安全面。5. 编译与安装配置成功后目录下会生成适配你系统的Makefile文件。接下来就是标准的make编译和make install安装两步。5.1 执行编译运行make命令它会根据Makefile中的指令调用GCC等工具将C源码编译成可执行文件。make这个过程会花费一些时间具体取决于你的服务器CPU性能。屏幕上会滚动输出编译信息。只要配置阶段没问题编译阶段通常会很顺利。5.2 执行安装编译完成后将编译好的文件安装到之前--prefix指定的目录/usr/local/nginx。sudo make install这里需要sudo权限因为要向系统目录/usr/local下写入文件。安装过程会创建目录、复制二进制文件、配置文件、默认HTML页面等。安装完成后你可以切换到安装目录查看成果cd /usr/local/nginx ls -l你会看到几个主要目录sbin/nginxNginx的主程序二进制文件。这是我们启动服务的核心。conf/配置文件目录里面的nginx.conf是主配置文件。html/默认的网站根目录里面有index.html和50x.html错误页面。logs/日志目录将来access.log和error.log会在这里生成。6. 管理Nginx服务现在Nginx已经安装到你的系统里了但它还不是一个系统服务。我们需要创建服务管理脚本并设置开机自启。6.1 创建Systemd服务单元文件推荐现代Linux发行版大多使用Systemd来管理服务。我们为Nginx创建一个服务文件。sudo vim /etc/systemd/system/nginx.service将以下内容粘贴进去[Unit] DescriptionThe nginx HTTP and reverse proxy server Afternetwork.target remote-fs.target nss-lookup.target [Service] Typeforking PIDFile/usr/local/nginx/logs/nginx.pid ExecStartPre/usr/local/nginx/sbin/nginx -t ExecStart/usr/local/nginx/sbin/nginx ExecReload/usr/local/nginx/sbin/nginx -s reload ExecStop/bin/kill -s QUIT $MAINPID PrivateTmptrue Usernginx Groupnginx [Install] WantedBymulti-user.target关键点解析TypeforkingNginx以守护进程模式运行主进程会fork出子进程。PIDFile指定Nginx主进程的PID文件位置Systemd靠这个文件来跟踪服务。ExecStartPre在启动前执行nginx -t测试配置文件语法这是一个非常好的安全实践避免配置错误导致服务启动失败。ExecReload定义重载命令对应nginx -s reload用于平滑重载配置不中断服务。User和Group指定服务以nginx用户和组运行与编译时的配置一致。保存退出后重新加载Systemd配置并启用开机自启sudo systemctl daemon-reload sudo systemctl enable nginx.service6.2 启动、停止与重载Nginx现在你可以用熟悉的systemctl命令来管理Nginx了# 启动Nginx sudo systemctl start nginx # 查看状态 sudo systemctl status nginx # 停止Nginx sudo systemctl stop nginx # 重启Nginx sudo systemctl restart nginx # 重载配置文件平滑重启 sudo systemctl reload nginx启动后使用sudo systemctl status nginx如果看到active (running)的字样并且下面没有红色的错误日志说明服务启动成功。6.3 防火墙与访问测试如果服务器开启了防火墙如firewalld需要放行HTTP(80)和HTTPS(443)端口sudo firewall-cmd --permanent --add-servicehttp sudo firewall-cmd --permanent --add-servicehttps sudo firewall-cmd --reload现在打开你的浏览器访问服务器的IP地址例如http://你的服务器IP。你应该能看到Nginx的默认欢迎页面上面写着“Welcome to nginx!”。恭喜你一个由你亲手编译定制的Nginx服务器已经成功运行7. 核心配置文件初探与基础优化安装完成只是第一步让Nginx按照你的意愿工作关键在于配置。主配置文件是/usr/local/nginx/conf/nginx.conf。让我们看看它的基本结构和几个可以立即优化的点。7.1 配置文件结构速览用sudo vim /usr/local/nginx/conf/nginx.conf打开文件你会看到它由多个“块”组成主要是events,http,server,location等。main全局配置在文件最外层包括worker进程数、错误日志路径等。events配置影响Nginx服务器与用户的网络连接如worker连接数。http嵌套所有HTTP相关的配置可以包含多个server块。server定义一个虚拟主机网站监听特定的IP和端口。location在server块内用于匹配特定的URI路径并定义如何处理指向这些路径的请求。7.2 几个立即可以调整的优化参数在nginx.conf的main或events或http块中可以调整以下参数以更好地适应你的服务器硬件。worker进程数worker_processes指令。设置为auto默认会让Nginx自动检测CPU核心数。对于计算密集型的场景可以设置为等于或略多于CPU逻辑核心数。查看核心数grep processor /proc/cpuinfo | wc -l。worker_processes auto; # 或 worker_processes 4;单个worker最大连接数events块中的worker_connections指令。它定义了每个worker进程可以同时处理的最大连接数。这个值受限于系统级别的“最大打开文件数”限制ulimit -n。events { worker_connections 1024; }最大并发连接数理论值 worker_processes*worker_connections。对于反向代理由于每个客户端连接可能对应两个到后端服务器的连接这个值需要更大。启用高效文件传输模式在http块内设置sendfile on;。它允许Nginx直接在内核空间将文件数据从一个文件描述符复制到另一个绕开了用户空间对于传输静态大文件效率提升显著。http { sendfile on; tcp_nopush on; # 与sendfile on配合使用在数据包满或到达发送周期时才发送提升网络效率 # ... 其他配置 }连接超时时间适当调整超时可以释放无用连接节省资源。http { keepalive_timeout 65; # 客户端连接保持活动状态的时间 client_header_timeout 15; # 读取客户端请求头超时时间 client_body_timeout 15; # 读取客户端请求体超时时间 send_timeout 15; # 向客户端发送响应的超时时间 }修改配置后务必测试语法并重载sudo /usr/local/nginx/sbin/nginx -t # 测试配置文件语法 sudo systemctl reload nginx # 平滑重载配置nginx -t命令是你的好朋友任何配置修改后运行它检查语法是否正确可以避免因配置错误导致服务崩溃。8. 常见问题排查与解决实录即使按照步骤操作在实际环境中也可能遇到各种问题。这里记录几个我踩过的坑和解决方法。8.1 启动失败端口80被占用现象执行sudo systemctl start nginx后status显示失败查看日志sudo tail -f /usr/local/nginx/logs/error.log发现类似bind() to 0.0.0.0:80 failed (98: Address already in use)的错误。原因80端口已被其他程序占用常见的是Apache (httpd)、或者其他Nginx实例。排查与解决找出占用端口的进程sudo netstat -tlnp | grep :80或sudo ss -tlnp | grep :80。如果确实是其他Web服务器如Apache且你不再需要它可以停止并禁用sudo systemctl stop httpd sudo systemctl disable httpd。如果是未知进程根据netstat输出的PID用ps aux | grep PID查看详情再决定是否终止。如果希望Nginx使用其他端口可以修改nginx.conf中server块的listen指令例如listen 8080;。8.2 403 Forbidden 错误现象浏览器访问显示403 Forbidden。原因这是权限问题。最常见的原因是Nginx工作进程nginx用户对网站根目录默认是/usr/local/nginx/html没有读取(r)权限。排查与解决检查目录权限ls -ld /usr/local/nginx/html。确保nginx用户有权限访问。一个简单的修复方法是sudo chown -R nginx:nginx /usr/local/nginx/html sudo chmod -R 755 /usr/local/nginx/html注意在生产环境中权限设置需要更精细这里仅为示例。检查nginx.conf中server块内的root指令指定的目录路径是否正确以及该目录是否存在。检查index指令指定的默认首页文件如index.html是否存在。8.3 平滑重载reload后旧工作进程不退出的“僵尸”进程现象执行sudo systemctl reload nginx后用ps aux | grep nginx发现有很多旧的worker进程仍然存在状态为worker process is shutting down但长时间不退出。原因这些进程正在处理长连接如WebSocket或未完成的请求。Nginx的平滑重载机制是启动新的worker进程来接替工作让旧的worker处理完当前请求后再退出。这是正常设计。排查与解决这通常不是问题只是表明有持续连接。你可以观察这些进程它们会在完成工作后自动退出。如果它们真的卡住了例如因为后端服务故障你可以强制关闭首先用sudo kill -QUIT 旧master进程PID关闭旧的master进程谨慎操作会中断该master下的所有连接或者直接sudo systemctl restart nginx非平滑重启会中断服务。8.4 自定义编译的模块不生效现象编译时添加了--with-http_sub_module但在配置文件中使用sub_filter指令时Nginx报错未知指令。原因模块虽然编译进了Nginx二进制文件但可能没有在需要使用它的http、server或location块中通过load_module指令动态加载对于某些模块或者更常见的是你错误地重启了服务但使用的nginx命令不是新编译的那个。排查与解决绝对路径确保你启动、测试、重载Nginx时使用的都是新安装的二进制文件即/usr/local/nginx/sbin/nginx。避免直接使用nginx命令因为系统PATH可能指向旧版本。检查模块是否真的被编译进去/usr/local/nginx/sbin/nginx -V大写V。输出信息会包含configure arguments:里面列出了所有编译时的配置参数确认你的模块在其中。对于动态模块需要在nginx.conf顶部使用load_module指令加载对应的.so文件。8.5 日志文件不生成或没权限写入现象/usr/local/nginx/logs/目录下没有access.log或error.log或者日志内容为空。原因Nginx进程对日志目录没有写入(w)权限。排查与解决检查日志目录的所有者和权限sudo ls -ld /usr/local/nginx/logs/确保目录所有者为nginx用户或启动Nginx的用户并有写权限sudo chown -R nginx:nginx /usr/local/nginx/logs/如果目录不存在Nginx可能无法启动。需要手动创建并设置权限sudo mkdir -p /usr/local/nginx/logs sudo chown nginx:nginx /usr/local/nginx/logs9. 后续维护与升级建议源码安装的Nginx后续的维护和升级也需要手动进行。9.1 备份配置文件你的所有自定义配置都在/usr/local/nginx/conf/目录下尤其是nginx.conf和conf.d/或sites-enabled/如果你采用了这种组织方式下的文件。在每次升级或重大修改前务必备份。sudo cp -r /usr/local/nginx/conf /path/to/your/backup/nginx_conf_backup_$(date %Y%m%d)9.2 升级Nginx版本假设你想从1.16.1升级到1.18.0仅举例请选择稳定版本。按照同样的流程下载新版本源码包解压进入目录。关键步骤运行configure时使用与旧版本完全相同的参数。你可以通过/usr/local/nginx/sbin/nginx -V命令查看旧版本的编译参数直接复制过来使用。执行make进行编译。但不要立即执行make install。备份旧的可执行文件sudo cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old。将新编译好的二进制文件复制到安装目录sudo cp objs/nginx /usr/local/nginx/sbin/nginx。objs/目录是make编译后生成二进制文件的位置。测试新二进制文件sudo /usr/local/nginx/sbin/nginx -t。平滑升级向旧的主进程发送USR2信号启动新的主进程然后逐步关闭旧的工作进程。一个更稳妥的方法是直接使用Systemd重启会有关断但短暂sudo systemctl restart nginx验证sudo systemctl status nginx和/usr/local/nginx/sbin/nginx -v。9.3 添加新模块如果想给已安装的Nginx添加一个当初编译时未包含的模块例如http_image_filter_module你需要重新编译。获取与当前运行版本完全一致的Nginx源码包。使用nginx -V输出的旧参数并加上新的模块参数例如--with-http_image_filter_module重新运行configure。执行make。千万不要make install这会覆盖你的配置文件。备份旧二进制文件后用新的objs/nginx覆盖旧的。测试并重载服务。这个过程本质上是一次“二进制替换”式的升级。
返回列表