一、Nginx简介
1.1 Nginx的特点和优点
- 高性能:Nginx采用了事件驱动、异步非阻塞的处理方式,可以处理大量并发连接请求,同时减少服务器资源的占用。它的吞吐量比传统的Web服务器高很多倍。
- 高可靠性:Nginx的架构是分布式的,可以通过多个节点实现负载均衡,提高系统的可靠性和可用性。同时,Nginx对请求的处理具有优秀的容错机制,能够在服务器出现故障时自动切换到备份服务器。
- 轻量级:Nginx的代码精简,功能简洁,占用资源少,启动和运行速度快。
- 可扩展性:Nginx具有良好的扩展性,支持多种模块和插件,可以通过添加模块和插件来实现更多的功能。
- 安全性:Nginx的安全性很高,可以通过限制访问IP、防止DDoS等多种方式来保护服务器的安全。
- 配置简单:Nginx的配置文件简单易懂,方便管理员进行配置和管理。
- 高度定制化:Nginx可以根据不同的需求进行高度定制化,可以按照实际需求选择相应的模块和插件来满足不同的需求。
1.2 Nginx的应用场景
- Web服务器:Nginx可以作为Web服务器,用于提供静态文件和动态页面的访问服务。由于Nginx具有高并发和高吞吐量的特点,所以在高访问量的Web应用中表现出色。
- 反向代理服务器:Nginx可以作为反向代理服务器,将请求转发给后端服务器,实现负载均衡、高可用、安全等功能。反向代理服务器可以解决访问压力大、单点故障等问题,保证系统的稳定性和可靠性。
- 高并发服务器:Nginx可以处理大量并发请求,适用于高并发、高吞吐量的应用场景,如在线视频、电子商务、社交媒体等领域。
- 静态资源服务器:Nginx可以作为静态资源服务器,提供图片、视频、CSS、JS等静态资源的访问服务。由于Nginx的静态文件处理速度非常快,可以提高网站的访问速度和性能。
- CDN缓存服务器:Nginx可以作为CDN缓存服务器,缓存静态文件,提高文件的访问速度,降低服务器的负载压力,提高系统的可靠性和可用性。
二、动静分离
2.1 什么是动静分离
动静分离是一种将动态内容和静态内容分别存放在不同的服务器或磁盘上的技术。它的核心思想是将网站中的静态资源(如图片、样式表、JavaScript等)和动态内容(如页面请求、数据库查询等)分别存放在不同的服务器上,从而提高网站的性能和可靠性。
2.2 为什么要进行动静分离
动静分离的好处有:
- 加速网站访问速度:由于静态资源无需动态生成,因此访问速度更快。通过将静态资源存放在独立的服务器上,可以减轻主服务器的负担,提高网站的响应速度。
- 降低服务器负载:将静态资源存放在独立的服务器上,可以减少主服务器的负载,提高服务器的稳定性和可靠性。如果在主服务器上处理所有的请求,可能会导致服务器崩溃或响应变慢。
- 提高可扩展性:将静态资源和动态内容分别存放在不同的服务器上,可以根据需要扩展静态资源服务器或动态内容服务器,提高网站的可扩展性。
动静分离是一种提高网站性能和可靠性的有效技术,可以加速网站的响应速度、降低服务器负载、提高网站的可扩展性。
2.3 如何实现动静分离
- 安装Nginx服务器并启动服务。在命令行中输入以下命令:
sudo apt-get update
sudo apt-get install nginx
sudo systemctl start nginx
- 修改Nginx的配置文件。打开Nginx的默认配置文件,找到默认的虚拟主机配置,一般是
/etc/nginx/sites-available/default
,在server块中添加以下配置:
server {
listen 80;
server_name example.com;
location / {
# 动态请求转发到动态内容服务器
proxy_pass http://dynamic_server;
}
location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
# 静态资源请求转发到静态资源服务器
root /var/www/static;
}
}
这里使用proxy_pass
将动态请求转发到http://dynamic_server
,使用root
将静态请求映射到本地/var/www/static
目录。注意,~*
表示区分大小写,如果不区分大小写可以使用~
。
- 配置动态内容服务器和静态资源服务器。动态内容服务器和静态资源服务器可以使用不同的服务器或磁盘。在这个例子中,我们使用两个本地目录来模拟这两个服务器。
mkdir /var/www/static
mkdir /var/www/dynamic
在/var/www/static
目录下放置静态资源,例如图片、样式表、JavaScript等。在/var/www/dynamic
目录下放置动态内容,例如动态生成的HTML页面、PHP文件等。
- 重启Nginx服务并测试。在命令行中输入以下命令:
sudo systemctl restart nginx
然后在浏览器中访问http://example.com
,Nginx会将静态资源请求转发到/var/www/static
目录,将动态请求转发到http://dynamic_server
。如果一切正常,您应该能够看到网站的内容。
以上是一个简单的Nginx实现动静分离的步骤。根据实际情况,您可以根据需要修改Nginx的配置文件,配置动态内容服务器和静态资源服务器。
三、压缩
3.1 为什么需要压缩
客户端发送响应时,它通常包含大量的文本数据(例如HTML、CSS、JavaScript、XML、JSON等),这些数据可能会占用很大的带宽,并且会影响Web应用程序的性能。为了解决这个问题,Nginx提供了压缩功能,可以压缩响应数据并将其发送到客户端。
Nginx压缩的主要优点包括:
- 减少网络带宽的使用:通过压缩响应数据,可以减少网络带宽的使用,从而提高Web应用程序的性能和吞吐量。在某些情况下,网络带宽可能非常有限,例如在移动设备上,压缩可以更好地利用网络带宽。
- 提高页面加载速度:压缩响应数据可以减少Web应用程序向客户端发送的数据量,从而加快页面加载速度。这对于那些包含大量文本数据的Web应用程序来说尤为重要。
- 改善用户体验:由于页面加载速度更快,因此用户将能够更快地访问您的Web应用程序,并享受更好的用户体验。
3.2 常见的压缩算法
Nginx支持多种压缩算法,以下是一些常见的压缩算法:
- gzip:gzip是一种广泛使用的压缩算法,它可以将文本数据压缩为gzip格式。gzip压缩算法是Nginx默认使用的压缩算法之一。
- deflate:deflate是一种广泛使用的压缩算法,它可以将文本数据压缩为deflate格式。deflate压缩算法也是Nginx默认使用的压缩算法之一。
- bzip2:bzip2是一种高效的压缩算法,可以将文本数据压缩为bzip2格式。尽管bzip2压缩算法比gzip和deflate压缩算法更加高效,但它的压缩速度较慢,因此在某些情况下可能不适用。
- lzma:lzma是一种高效的压缩算法,可以将文本数据压缩为lzma格式。lzma压缩算法比bzip2压缩算法更加高效,但压缩速度更慢。
- brotli:brotli是一种新的压缩算法,由Google开发。它可以将文本数据压缩为brotli格式,与gzip和deflate相比,brotli压缩算法具有更高的压缩比和更好的性能。但是,由于brotli压缩算法是较新的压缩算法,因此不是所有的Web浏览器都支持brotli格式。
3.3 如何在Nginx中进行压缩
- 确认Nginx已安装ngx_http_gzip_module模块,您可以在Nginx的编译选项中启用此模块。
- 打开Nginx配置文件,一般位于/etc/nginx/nginx.conf。
- 找到http块,这是Nginx中所有网站的全局配置块。在该块内添加以下指令以启用gzip压缩:
gzip on;
启用gzip压缩功能。
- 添加指令以指定需要压缩的文件类型。例如,您可以添加以下指令:
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
压缩文本文件、CSS文件、JSON文件、JavaScript文件和XML文件。
- 添加指令以指定压缩的最小文件大小。例如,您可以添加以下指令:
gzip_min_length 1024;
只有文件大小大于等于1KB的文件才会被压缩。
- 添加指令以指定压缩级别。例如,您可以添加以下指令:
gzip_comp_level 6;
使用gzip压缩级别6,级别范围是1-9。
- 添加指令以指定缓存区数量和大小。例如,您可以添加以下指令:
gzip_buffers 16 8k;
使用16个缓冲区,每个缓冲区大小为8KB。
- 添加指令以指定禁用gzip压缩的浏览器。例如,您可以添加以下指令:
gzip_disable "MSIE [1-6]\.(?!.*SV1)";
禁用所有早期版本的IE浏览器的gzip压缩。
- 保存并关闭配置文件,然后重新启动Nginx服务以使更改生效。
下面是一个相对完整的Nginx配置,其中包含启用gzip压缩的相关指令:
http {
# 基本配置
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# 启用gzip压缩
gzip on;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_disable "MSIE [1-6]\.(?!.*SV1)";
# 服务器配置
server {
listen 80;
server_name example.com;
# 静态文件目录
location /static/ {
alias /var/www/example/static/;
expires 1d;
access_log off;
}
# 动态请求转发
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
四、缓存
4.1 缓存的原理和作用
Nginx缓存的原理是在Nginx服务器中预先存储一份响应的副本,当客户端请求相同资源时,Nginx会直接返回缓存的响应,而不需要再次向后端服务器发送请求,从而提高了响应速度和性能。
需要注意的是,由于缓存会导致响应不再是实时的,因此在某些情况下需要手动刷新缓存或禁用缓存,以确保客户端能够获得最新的响应。
4.2 Nginx中的缓存机制
Nginx的缓存机制可以分为两种类型:内存缓存和磁盘缓存。
- 内存缓存 内存缓存将响应存储在内存中,读取速度快,但容量有限。内存缓存的配置如下:
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m inactive=60m;
该指令定义了缓存路径、缓存目录的层数、缓存键的存储区域名称以及缓存的最长不活动时间。使用内存缓存时,需要注意控制缓存的容量,避免过度使用内存导致服务器性能下降。
- 磁盘缓存 磁盘缓存将响应存储在磁盘上,容量较大,但读取速度相对较慢。磁盘缓存的配置如下:
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m inactive=60m;
proxy_cache_key "$scheme$request_method$host$request_uri";
该指令定义了缓存路径、缓存目录的层数、缓存键的存储区域名称以及缓存的最长不活动时间。使用磁盘缓存时,需要注意磁盘的读写速度和容量,避免缓存过多导致磁盘空间不足。
Nginx的缓存机制可以通过以下指令控制缓存的行为:
- proxy_cache_key:定义缓存键,用于标识相同的请求。
- proxy_cache_valid:指定缓存的有效期。
- proxy_cache_bypass:定义哪些请求不需要缓存。
- proxy_cache_methods:定义哪些请求方法需要缓存。
4.3 如何配置Nginx缓存
- 安装Nginx和ngx_cache_purge模块
如果没有安装Nginx,则需要先安装Nginx。如果需要使用ngx_cache_purge模块,则需要先下载、编译和安装该模块。
- 配置缓存路径和缓存区域
在Nginx配置文件中添加以下指令,定义缓存路径和缓存区域:
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m inactive=60m;
该指令定义了缓存路径为/var/cache/nginx,缓存目录的层数为1:2,缓存键的存储区域名称为my_cache,缓存的最长不活动时间为60分钟。
- 配置缓存规则
在需要缓存的代理服务器的location中添加以下指令,定义缓存规则:
location / {
proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_cache_bypass $http_purge_cache;
proxy_cache_valid 200 60m;
proxy_cache_valid 404 5m;
proxy_cache_valid any 0;
proxy_cache_methods GET HEAD;
proxy_cache my_cache;
proxy_pass http://backend_server;
}
上述配置指定了缓存键,缓存规则,缓存的有效期和请求方法等。其中,$http_purge_cache变量用于手动刷新缓存。
- 配置刷新缓存
可以在Nginx配置文件中添加以下指令,定义刷新缓存的规则:
location ~ /purge(/.*) {
proxy_cache_purge my_cache "$scheme$request_method$host$1";
}
该指令指定了刷新缓存的路径和刷新缓存的规则。
完整的Nginx缓存配置示例如下:
http {
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m inactive=60m;
proxy_cache_key "$scheme$request_method$host$request_uri";
server {
listen 80;
server_name example.com;
location / {
proxy_cache_bypass $http_purge_cache;
proxy_cache_valid 200 60m;
proxy_cache_valid 404 5m;
proxy_cache_valid any 0;
proxy_cache_methods GET HEAD;
proxy_cache my_cache;
proxy_pass http://backend_server;
}
location ~ /purge(/.*) {
proxy_cache_purge my_cache "$scheme$request_method$host$1";
}
}
}
五、黑白名单
5.1 什么是黑白名单
在Nginx中,黑白名单是用于限制或允许特定IP地址或IP地址段访问Nginx服务器的一种机制。黑名单用于禁止特定IP地址或IP地址段的访问,而白名单用于允许特定IP地址或IP地址段的访问。
5.2 黑白名单的应用场景
- 防止恶意访问:使用黑名单来防止恶意访问,例如针对特定IP地址或IP地址段的DDoS。
- 网络安全策略:使用白名单来限制对Nginx服务器的访问,只允许特定的IP地址或IP地址段进行访问。这可以帮助防止未经授权的访问和提高网络安全性。
- 地域限制:使用地理位置黑白名单来限制或允许特定地区的访问,例如限制某些国家或地区的用户访问。
- 流量控制:使用黑名单来限制某些IP地址或IP地址段的访问,以避免过度消耗服务器资源和带宽。
- 访问控制:使用黑白名单来控制特定的HTTP请求头或cookie,以允许或拒绝特定的用户或应用程序访问。
Nginx黑白名单是一种有效的安全机制,可以帮助限制对服务器的访问,提高网络安全性,减少恶意访问的影响。
5.3 如何在Nginx中配置黑白名单
在Nginx中配置黑白名单可以使用ngx_http_access_module模块,以下是详细的配置步骤:
- 在Nginx配置文件中添加如下代码块:
http {
...
# 定义黑名单和白名单
geo $blacklist {
default 0;
# 配置黑名单IP地址
include /path/to/blacklist.txt;
}
geo $whitelist {
default 0;
# 配置白名单IP地址
include /path/to/whitelist.txt;
}
}
在这个代码块中,我们使用geo模块来定义黑名单和白名单,其中$blacklist和$whitelist是我们定义的变量名。默认情况下,这两个变量的值都是0,即客户端IP地址不在黑白名单中。
- 配置黑名单和白名单的IP地址
在上一步中,我们已经定义了黑名单和白名单变量,现在我们需要在对应的文件中配置具体的IP地址。
在/path/to/blacklist.txt文件中,可以按照如下格式配置黑名单IP地址:
192.168.1.1/32;
10.0.0.0/8;
每行一个IP地址或网段,以分号结尾。
在/path/to/whitelist.txt文件中,可以按照如下格式配置白名单IP地址:
192.168.1.2/32;
同样每行一个IP地址或网段,以分号结尾。
- 在Nginx配置文件中对访问进行控制
在server块中,我们可以使用if语句来对客户端访问进行控制,具体方法如下:
server {
...
# 使用白名单进行访问控制
if ($whitelist = 0) {
return 403;
}
# 使用黑名单进行访问控制
if ($blacklist = 1) {
return 403;
}
}
在这个代码块中,我们首先使用if语句判断客户端IP地址是否在白名单内,如果不在,则返回403错误页面。然后我们再使用if语句判断客户端IP地址是否在黑名单内,如果在,则同样返回403错误页面。
需要注意的是,在if语句中进行访问控制会对Nginx性能产生一定的影响,因此应尽量避免使用复杂的条件语句。另外,为了避免被绕过访问控制,建议将黑白名单文件存储在受保护的位置,并设置访问权限。
六、跨域
6.1 什么是跨域
跨域(Cross-Origin)指的是在Web开发中,Web页面从不同的域名进行资源请求的行为。跨域问题是由于浏览器的同源策略造成的,同源策略是浏览器的一种安全机制,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。
6.2 如何在Nginx中解决跨域问题
- 打开Nginx配置文件,一般位于
/etc/nginx/nginx.conf
。 - 在配置文件中找到对应的
server
块,如果没有则新建。 - 在
server
块中添加以下内容:
location / {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers '*';
}
以上配置意为允许所有来源(Access-Control-Allow-Origin
)的请求,允许的方法包括GET、POST和OPTIONS(Access-Control-Allow-Methods
),允许所有的请求头(Access-Control-Allow-Headers
)。
- 重启Nginx服务,使配置生效。
注意:以上配置是允许所有来源的请求,这在实际生产环境中并不安全,应该根据具体需求配置允许的来源地址。同时,也可以根据需要配置其他跨域相关的HTTP响应头,如Access-Control-Allow-Credentials
、Access-Control-Expose-Headers
等。
七、高可用
7.1 什么是高可用
高可用(High Availability,HA)指的是系统或服务在遇到故障、错误或异常情况时,能够在不中断正常服务的情况下保持可用性和稳定性,从而达到尽可能长时间、高效地运行的能力。高可用性的目标是通过设计和实现容错性架构,从而在面对常见或预测不到的故障或异常情况时,尽量减少系统或服务中断的时间和影响。高可用性通常需要使用冗余系统、负载均衡、自动故障转移、容错技术等方式来保证。
7.2 Nginx的高可用架构
负载均衡集群
在这种方案中,多个Nginx服务器被部署在同一集群中,并且共享同一个IP地址和域名。负载均衡器将来自客户端的请求分配到不同的Nginx服务器上,每个服务器都可以提供相同的服务。如果其中一个服务器宕机或无法响应,则负载均衡器会自动将请求转发到其他可用的服务器上。这种方案可以实现高可用性和水平扩展,提高系统的性能和稳定性。
主备架构
在这种方案中,有两个Nginx服务器:主服务器和备份服务器。主服务器负责处理所有的请求,备份服务器处于闲置状态,等待主服务器出现故障时接管其工作。当主服务器宕机或无法响应时,备份服务器会接替主服务器的工作,提供服务。这种方案具有快速故障恢复的优势,但备份服务器的资源很大程度上被浪费。
Active-Standby架构
这种方案是一种改进的主备架构,主服务器和备份服务器之间会进行心跳检测,以便快速发现主服务器故障并迅速切换到备份服务器。同时,在正常工作情况下,备份服务器也可以承担一部分请求负载,充分利用其资源,提高系统的性能。这种方案具有快速故障恢复和资源利用率高的优势。
Nginx的高可用架构需要根据实际需求进行选择和配置,同时需要注意负载均衡、故障转移、资源利用率等方面的平衡。
7.3 如何实现Nginx的高可用
Nginx的高可用可以通过使用Keepalived和Nginx本身的特性来实现。下面是一个基于CentOS 7的Nginx高可用配置的详细步骤:
- 安装Keepalived和Nginx
在两台服务器上分别安装Keepalived和Nginx:
# 安装Keepalived
sudo yum install -y keepalived
# 安装Nginx
sudo yum install -y nginx
- 配置Nginx
在两台服务器上,将Nginx的配置文件进行修改。修改/etc/nginx/nginx.conf
,以支持反向代理和负载均衡:
http {
upstream backend {
server backend1.example.com:80 weight=5;
server backend2.example.com:80 weight=5;
}
server {
listen 80;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
以上配置中,upstream
定义了后端的服务器,其中weight
参数用于设置权重,以分配更多或更少的流量。server
定义了Nginx的监听端口和代理规则,将请求通过proxy_pass
转发到后端的服务器中。
- 配置Keepalived
在两台服务器上,编辑Keepalived的配置文件/etc/keepalived/keepalived.conf
:
global_defs {
router_id lb1 # 在两台服务器上分别设置不同的router_id
}
vrrp_script chk_nginx {
script "killall -0 nginx"
interval 2
weight 2
}
vrrp_instance VI_1 {
state MASTER # 在两台服务器上分别设置为MASTER和BACKUP
interface eth0 # 指定Keepalived使用的网络接口
virtual_router_id 51 # 在两台服务器上设置相同的virtual_router_id
priority 101 # 在MASTER上设置更高的priority值,BACKUP则较低
virtual_ipaddress {
192.168.1.100 # 配置一个虚拟IP地址
}
track_script {
chk_nginx
}
}
- 启动服务
在两台服务器上,启动Keepalived和Nginx服务:
# 启动Keepalived
sudo systemctl start keepalived
# 启动Nginx
sudo systemctl start nginx
现在,您可以使用虚拟IP地址(192.168.1.100)访问Nginx服务。如果主服务器宕机,备份服务器将接管服务,并自动将虚拟IP地址转移到自己的网络接口上。当主服务器重新启动时,它将成为备份服务器,等待下一次故障转移。
注意:这里的配置只是一个简单的示例,后续我会专门写一篇文章详细讲解。
八、性能优化
8.1 性能优化的目标和原则
性能优化的目标是提高系统的响应速度、并发处理能力和稳定性,同时减少资源消耗和成本开销。
性能优化的原则包括:
- 先量后质:在开始优化之前,先对系统进行性能测试和性能分析,确定系统的瓶颈所在,再有针对性地进行优化。
- 多思考、多测试、少猜测:优化过程中,要进行多种方法的尝试和测试,不要凭借猜测就盲目地修改代码。
- 全面优化、重点突破:优化过程中,要全面考虑系统的各个方面,但要重点突破系统的瓶颈,因为优化效果的提升往往是突破瓶颈所带来的。
- 空间换时间、时间换空间:在实际优化过程中,要权衡空间和时间的消耗,对于不同的系统、不同的场景,选择适合的优化方案。
8.2 Nginx的性能优化方法
- 调整工作进程数:通过调整worker_processes参数来控制Nginx的工作进程数,以适应系统的硬件资源。
- 配置文件缓存:开启nginx缓存机制,通过在nginx.conf中增加proxy_cache_path指令,配置缓存的路径和参数。
- 负载均衡优化:通过调整Nginx的负载均衡策略和算法来提高负载均衡的效率和性能。
- gzip压缩:通过开启gzip压缩来减少响应数据的大小,从而提高响应速度和网络传输效率。
- TCP/UDP优化:通过调整Nginx的TCP/UDP参数来优化网络传输效率,提高数据传输的稳定性和可靠性。
- 静态文件缓存:通过开启Nginx的静态文件缓存机制,缓存静态文件的响应结果,从而减少服务器负载,提高响应速度。
- SSL优化:通过开启Nginx的SSL协议优化,调整SSL参数,来提高SSL的性能和安全性。
- 动态模块优化:通过调整Nginx的动态模块参数来优化模块的性能和资源占用。
- 慢日志优化:通过开启Nginx的慢日志功能,记录访问超时或异常的请求,以便进行性能调优和故障排查。
- 系统内核优化:通过调整系统的内核参数,如tcp_fin_timeout、tcp_tw_reuse等,来提高系统的性能和稳定性。