Nginx服务
1. Nginx概念
1.1 Nginx简介
Nginx(发音为 “engine X”)是一款开源、高性能、高可靠的 Web 服务器软件。同时,它也被广泛用作反向代理、负载均衡器、HTTP 缓存和邮件代理。
它的核心特点是采用事件驱动和异步非阻塞的架构,这使得它能够用极少的系统资源处理海量的并发连接。与传统的、为每个连接创建一个线程或进程的服务器(如 Apache 的默认模式)相比,Nginx 的效率要高得多。
简单来说,您可以把 Nginx 想象成一个极其高效、聪明的“交通指挥官”:
- 作为 Web 服务器:它负责将网站的文件(如 HTML、图片、CSS)快速交付给用户的浏览器。
- 作为反向代理:它站在后端服务器(如应用服务器、Node.js、Python、Java 应用)的前面,接收所有客户端的请求,然后将请求转发给合适的后端服务器处理,最后将结果返回给客户端。这样做可以隐藏后端结构、提高安全性并提升性能。
- 作为负载均衡器:它可以将涌入的海量用户请求,平均分发到多个后端服务器上,防止任何一台服务器过载,从而保证应用的可用性和扩展性。
1.2 Nginx 的历史与发展
| 时间线 | 关键事件 | 意义 |
|---|---|---|
| 2002年 | 伊戈尔·赛索耶夫开始编写 | 为解决 C10K 性能问题而生。 |
| 2004年 | 首个公开版本发布 | 引入了革命性的事件驱动、异步非阻塞架构。 |
| 2000s末-2010s | 被全球高流量网站广泛采用 | 凭借其高性能和稳定性,市场份额迅速增长。 |
| 2011年 | 成立 Nginx Inc. 公司 | 推出商业版 Nginx Plus,实现商业化。 |
| 2019年 | 被 F5 ***works 收购 | 证明了其在现代应用交付领域的核心价值。 |
| 至今 | 成为云原生和微服务架构的基石 | 作为 API 网关和 Kuber***es Ingress,继续发挥关键作用。 |
2. Nginx核心特点
高性能、高并发、低内存占用 是 Nginx 的内在基因,源于其革命性的事件驱动和异步非阻塞架构。这使它有能力成为高效的流量入口。
反向代理和负载均衡 是建立在强大内在基因之上的核心功能。它们使 Nginx 从一个单纯的 Web 服务器,演变为现代应用架构中不可或缺的流量管理中枢。
2.1 高性能
含义:
Nginx 能够以极快的速度处理客户端的请求并返回响应。
技术原理:
- 事件驱动架构:Nginx 不像传统服务器(如 Apache 的 prefork 模式)那样为每个连接创建一个新的进程或线程。它使用一个主进程和多个工作进程。
- 异步非阻塞 I/O:这是高性能的关键。当一个工作进程处理一个请求时,如果该请求需要等待(比如读取磁盘文件或等待后端应用响应),它不会“阻塞”并干等着,而是会立刻去处理其他已经准备好的请求。只有当之前的请求数据准备好时,它才会回来继续处理。这就像一个高效的餐厅服务员,不会等一桌客人点菜时就在旁边干等,而是会去服务其他桌的客人。
-
使用高效的系统调用:例如,在处理静态文件时,Nginx 使用
sendfile系统调用,避免了数据在内核缓冲区和用户缓冲区之间的不必要的拷贝,极大地提升了文件传输效率。
结果:Nginx 在处理静态内容(如图片、CSS、JS 文件)和高并发短连接请求时,响应速度极快。
2.2 高并发
含义:
Nginx 能够同时处理非常大量(数万甚至数十万)的网络连接。
技术原理:
- “一个进程处理多连接”模型:传统的“一个进程/线程处理一个连接”的模型,在连接数暴涨时,会因进程/线程的上下文切换和内存消耗而达到性能瓶颈。Nginx 的每个工作进程都可以在一个线程内处理成千上万个连接,因为它的事件循环机制可以高效地管理这些连接的状态。
- 极低的内存占用 per connection:每个连接在 Nginx 中只占用极少的内存(通常只有几百字节),这与为每个连接分配一个独立的栈内存的线程模型形成鲜明对比。
结果:Nginx 是解决 C10K问题(即单机1万个并发连接)乃至 C100K问题 的理想选择,特别适合当今需要处理大量同时在线用户的互联网应用。
2.3 低内存占用
含义:
在相同的负载和连接数下,Nginx 占用的系统内存远低于传统的 Web 服务器。
技术原理:
- 精简的进程模型:Nginx 只需要运行少量固定的工作进程,内存占用稳定,不会因为连接数的增加而线性增长。
- 高效的内存管理:Nginx 设计了自身的内存池和数据结构,减少了频繁的内存分配和释放操作,避免了内存碎片。
结果:
- 降低成本:可以用配置较低的服务器处理更高的流量。
- 提高稳定性:内存占用可控,减少了因内存耗尽而导致服务器崩溃的风险。
2.4 反向代理
含义:
Nginx 作为客户端和后端服务器之间的一个中间层。客户端向 Nginx 发起请求,Nginx 将请求转发给后端的一台或多台服务器,并将从后端服务器得到的响应返回给客户端。
核心价值:
- 隐藏后端架构:客户端不知道真正提供服务的是哪台后端服务器,提高了安全性。
- 负载均衡:这是反向代理的自然延伸(见下一点)。
- SSL 终结:可以在 Nginx 上处理耗能的 HTTPS 加密/解密工作,减轻后端服务器的压力。
- 缓存:可以缓存后端服务器的响应,对于相同的请求,Nginx 可以直接返回缓存结果,无需再次访问后端。
- 动静分离:将动态请求(如 PHP, Java)代理给应用服务器,而静态请求(如图片)则由 Nginx 直接处理。
2.5 负载均衡
含义:
当有多台后端服务器时,Nginx 作为流量分配器,将进入的请求按照某种策略分发到不同的服务器上,以避免任何单一服务器过载。
核心价值:
- 提高可用性:如果一台后端服务器宕机,Nginx 可以将流量路由到其他健康的服务器。
- 提高扩展性:可以通过简单地增加后端服务器来水平扩展应用的处理能力。
- 提高性能:通过分散请求,确保每台服务器的负载都在合理范围内。
常用负载均衡算法:
- 轮询:依次将请求分发给每台服务器。
- 加权轮询:根据服务器的处理能力分配不同的权重,性能好的服务器获得更多请求。
- 最少连接:将请求发给当前连接数最少的服务器。
- IP 哈希:根据客户端 IP 地址计算哈希值,将同一 IP 的请求总是发给同一台后端服务器,用于保持会话(Session Persistence)。
3.Nginx实战
3.1 环境部署
# 关闭安全组件selinux以及防火墙
setenforce 0
systemctl disable --now firewalld
# rh9通过yum安装Nginx(需要配置仓库)
yum install nginx -y
# 服务管理
systemctl enable --now nginx #启动nginx服务(包括开机自启)
systemctl status nginx #查看nginx服务状态
nginx -V #查看nginx详细参数
nginx -t #检查nginx配置文件语法
3.2 Nginx常用配置文件
/etc/nginx/nginx.conf #主配置文件
/etc/nginx/conf.d/ #子配置目录
/etc/nginx/fastcgi.conf #php环境配置文件
/etc/nginx/fastcgi_params
/etc/nginx/*.default #默认配置
/usr/share/nginx/html #网页默认目录
/var/log/nginx/a***ess.log #访问日志
/var/log/nginx/error.log #错误日志
3.3 核心配置文件解析
/etc/nginx/nginx.conf
#配置层级
main { # 全局配置
events { # 事件模块
}
http { # HTTP模块
server { # 虚拟主机
location { # URI匹配
}
}
}
}
#全局配置段
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
#事件模块
events {
worker_connections 1024;
use epoll;
}
#http常用配置
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
include /etc/nginx/conf.d/*.conf; #加载子配置项
#server配置段
server {
listen 80; # 监听IPV4端口
server_name _; # 访问的域名
root /usr/share/nginx/html; # 网页默认目录
include /etc/nginx/default.d/*.conf; # 子配置文件存储路径
# location配置段
location / {
root /usr/share/nginx/html; # 相对路径网站根目录
alias /usr/share/nginx/html/; # 绝对路径网站根目录
index index.html index.htm; # 默认首页文件
deny 192.168.58.200; # 禁止访问的ip地址,可以为all
allow 192.168.58.1; # 允许访问的ip地址,可以为all
}
error_page 404 /404.html; # 404时返回给客户端的页面
location = /40x.html {
}
error_page 500 502 503 504 /50x.html; # 50x错误返回给客户端的页面
location = /50x.html {
}
}
# https虚拟主机定义
server {
listen 443 ssl http2; # 监听的IPV4端口(固定格式)
server_name _;
root /usr/share/nginx/html; # 网页默认目录
ssl_certificate "/etc/pki/nginx/server.crt"; # 证书存储路径
ssl_certificate_key "/etc/pki/nginx/private/server.key"; # 密钥存储
include /etc/nginx/default.d/*.conf;
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}
3.4 常用配置详解
server_name匹配规则
精确匹配:server_name www.example.***;
通配符匹配:server_name *.example.***;
正则匹配:server_name ~^www\.example\.*$;
匹配优先级:精确匹配 > 通配符匹配 (前缀>后缀)> 正则匹配
location匹配优先级
location = /uri # 精确匹配 (最高)
location ^~ /uri # 前缀匹配
location ~ pattern # 正则匹配(区分大小写)
location ~* pattern # 正则匹配(不区分大小写)
location /uri # 通用匹配 (最低)
4. 虚拟主机配置
4.1 基于IP的虚拟主机
# 添加IP地址
nmcli c modify ens160 +ipv4.addresses 192.168.58.101/24
nmcli c modify ens160 +ipv4.addresses 192.168.58.102/24
nmcli c up ens160
# 配置虚拟主机
vim /etc/nginx/conf.d/test.conf
server {
listen 80;
server_name 192.168.58.101;
root /www/ip101;
}
server {
listen 80;
server_name 192.168.58.102;
root /www/ip102;
}
#简易静态网站搭建
mkdir -p /www/ip{101,102}
echo ip101 > /www/ip101/index.html
echo ip102 > /www/ip102/index.html
4.2 基于端口的虚拟主机
# 配置虚拟主机
vim /etc/nginx/conf.d/test.conf
server {
listen 10001;
server_name 192.168.58.100;
root /www/port10001;
}
server {
listen 10002;
server_name 192.168.58.100;
root /www/port10002;
}
#简易搭建网站
mkdir -p /www/port{10001,10002}
echo port10001 > /www/port10001/index.html
echo port10002 > /www/port10002/index.html
4.3 基于域名的虚拟主机
域名定义:
是由一串用点分隔的名字组成的互联网上某一台计算机或计算机组的名称,用于在数据传输时对计算机的定位标识(有时也指地理位置)。由于IP地址不方便记忆并且不能显示地址组织的名称和性质,人们设计出了域名,并通过域名系统(DNS,Domain Name System)来将域名和IP地址相互映射,使人更方便地访问互联网,而不用去记住能够被机器直接读取的IP地址数串。
域名解析流程:
浏览器缓存–>操作系统缓存(hosts文件)–>路由缓存–>ISP的DNS服务器–>根服务器
windows下的hosts文件路径:C:\Windows\System32\drivers\etc\hosts (需要管理员权限)
Linux下的hosts文件路径:/etc/hosts
# 配置虚拟主机
vim /etc/nginx/conf.d/test.conf
server {
listen 80;
server_name www.zy.***;
root /www/zy;
}
server {
listen 80;
server_name www.shxkt.***;
root /www/shxkt;
}
#配置本地hosts映射
vim /etc/hosts
192.168.58.100 www.zy.*** www.shxkt.***
#windows客户端hosts配置
192.168.58.100 www.zy.*** www.shxkt.***
[!NOTE]
1.html网页文件必须存在
2.修改配置文件后需要重启nginx服务生效
5. HTTPS配置
5.1 HTTPS工作原理
SSL/TLS(SSL升级版本)工作流程
- ClientHello:客户端支持的协议版本、加密算法
- ServerHello:服务器确认协议、发送证书
- 密钥交换:客户端验证证书、生成会话密钥
- 加密通信:使用对称密钥加密数据传输
5.2 SSL证书配置
#证书配置汇总
openssl req -new -x509 -days 365 -nodes -out /etc/nginx/certs/brs.crt -keyout /etc/nginx/certs/brs.key -subj "/C=86/ST=sichuan/L=chengdu/O=openlab/OU=RHCE/***=server/emailAddress=andy@qq.***" -utf8
#在/etc/nginx/certs目录下制作整数所用的私钥文件brs.key
mkdir /etc/nginx/certs
openssl genrsa -aes128 2048 > /etc/nginx/certs/brs.key
# 制作证书
openssl req -utf8 -new -key /etc/nginx/certs/brs.key -x509 -days 365 -out /etc/nginx/zy.crt
# 在加载SSL支持的Nginx并使用上述私钥时除去必须的口令
cd /etc/nginx/certs
cp brs.key brs.key.org
openssl rsa -in brs.key.org -out brs.key
5.3 HTTPS服务器配置
vim /etc/nginx/conf.d/https.conf
server {
listen 443 ssl http2;
server_name www.brs.***;
root /www/brs;
ssl_certificate /etc/nginx/certs/brs.crt;
ssl_certificate_key /etc/nginx/certs/brs.key;
}
# HTTP重定向到HTTPS
server {
listen 80;
server_name www.brs.***;
return 301 https://www.brs.***;
}
#修改本地hosts域名映射关系
vim /etc/hosts
192.168.58.100 www.brs.*** #文件末尾添加
#windows客户端hosts配置
192.168.58.100 www.brs.***
6.LNMP部署
6.1LNMP定义
LNMP – Linux、Nginx、Mysql、Php
6.2LNMP环境搭建
安装基础服务
yum install nginx mysql-server php* -y
解压nextcloud(开源网站)压缩包
cd /
unzip unzip nextcloud-29.0.16.zip
设置nextcloud目录权限
chown -R nginx:nginx /nextcloud
chmod -R 777 /nextcloud
配置数据库
systemctl start mysqld #启动数据库
mysql> create database nextcloud; #创建数据库
mysql> create user 'nextcloud'@'localhost' identified by '123'; #创建用户及密码
mysql> grant all on nextcloud.* to 'nextcloud'@'localhost'; #设置权限
mysql> exit # 退出
systemctl restart mysqld #重启mysql使配置生效
配置nginx
vim /etc/nginx/conf.d/lnmp.conf
server {
listen 80;
server_name 192.168.58.101;
root /nextcloud;
index index.php index.html; #默认索引文件,优先级从左到右依次降低
location / {
try_files $uri $uri/ /index.php$request_uri; #匹配所有请求
}
location ~ \.php(?:$|/) { #正则表达式匹配所有.php结尾和包含.php/的请求
fastcgi_split_path_info ^(.+?\.php)(/.+)$; #分割请求路径为脚本路径和路径信息
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; #设置php脚本文件路径
fastcgi_param PATH_INFO $fastcgi_path_info; #传递信息给php脚本
fastcgi_pass unix:/run/php-fpm/www.sock;
fastcgi_index index.php;
}
}
#重启nginx
systemctl restart nginx
安装
启动浏览器并输入服务器IP地址,进入Nextcloud安装向导页面
设置自定义的管理员账号和密码
在数据库配置步骤中:
- 选择MySQL/MariaDB数据库
- 设置数据库用户名为nextcloud
- 密码设为123
- 指定数据库名称为nextcloud
- 主机地址保持为localhost
7. 故障排查
7.1日志分析
# 访问日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
a***ess_log /var/log/nginx/a***ess.log main;
error_log /var/log/nginx/error.log warn;
7.2状态监控
server {
listen 8080;
server_name localhost;
location /nginx_status {
stub_status on;
a***ess_log off;
allow 127.0.0.1;
deny all;
}
location /server_status {
stub_status on;
a***ess_log off;
allow 127.0.0.1;
deny all;
}
}
7.3排查常用命令
# 检查配置
nginx -t
# 查看进程
ps aux | grep nginx
# 查看端口
***stat -lntup | grep nginx
ss -lntup | grep nginx
# 实时日志
tail -f /var/log/nginx/a***ess.log
tail -f /var/log/nginx/error.log
# 压力测试
ab -n 1000 -c 100 https://www.brs.***/