使用Nginx部署常规项目足够了

使用Nginx部署常规项目足够了

Nginx 是一款轻量级的高性能 Web 服务器和反向代理服务器,它以其高并发、低内存消耗和稳定性而闻名。Nginx 可以处理静态文件、反向代理动态内容、负载均衡等任务,是构建高可用、高性能 Web 架构的重要组成部分。

为什么使用 Nginx 部署常规项目足够了?

  1. 高性能

Nginx 采用异步非阻塞的事件驱动模型,可以处理大量的并发连接。与传统的多线程或多进程服务器相比,Nginx 在高并发情况下具有更低的内存消耗和更高的性能。

  1. 稳定性

Nginx 具有高度的稳定性,能够在长时间运行中保持稳定的性能。它可以自动处理故障和错误,确保服务的可用性。

  1. 反向代理和负载均衡

Nginx 可以作为反向代理服务器,将请求转发到后端的应用服务器。通过配置负载均衡算法,可以将请求均匀地分发到多个应用服务器上,提高系统的可用性和性能。

  1. 静态文件服务

Nginx 可以高效地处理静态文件请求,如图片、CSS、JavaScript 等。它可以直接将静态文件返回给客户端,减少了应用服务器的负载。

  1. 易于配置和管理

Nginx 的配置文件简单易懂,易于配置和管理。可以通过修改配置文件来实现各种功能,如反向代理、负载均衡、静态文件服务等。

nginx.conf默认配置文件分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

//配置工作进程数,如果大于1,则以多进程的方式运行
worker_processes 1;


//配置影响Nginx服务器或与用户的网络连接
events {
//单个工作进程可以同时打开的最大连接数
//最大客户端连接数由worker_processes和worker_connections决定
worker_connections 1024;
}


//可以嵌套多个server
http
{
//包含其他文件到nginx.conf配置文件中,mime.types文件包含了各种文件类型
include mime.types;
//设置默认的文件类型,'application/octet-stream'是一种通用的二进制文件类型
default_type application/octet-stream;
//启用内核级别的文件传输优化
sendfile on;
//长连接时间,超过时间Nginx会关闭该连接,包括HTTP和WebSocket
keepalive_timeout 65;
//配置虚拟主机的相关参数
server
{
//监听的端口
listen 80;
//监听的域名
server_name localhost;
//配置请求的路由,以及各种页面的处理情况
location / {
root html;
index index.html index.htm;
}
//配置错误页面
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}

根据nginx.conf 默认配置文件可分为6个模块:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

全局模块
events模块
http模块
upstream模块

server模块
localtion块
localtion块
....
server模块
localtion块
localtion块
...
....

全局模块:配置影响nginx全局的指令,比如运行nginx的用户名,nginx进程pid存放路径,日志存放路径,配置文件引入,worker进程数等。

events模块:配置影响nginx服务器或与用户的网络连接。比如每个进程的最大连接数,选取哪种事件驱动模型(select/poll epoll或者是其他等等nginx支持的)来处理连接请求,是否允许同时接受多个网路连接,开启多个网络连接序列化等。

http模块:可以嵌套多个server,配置代理,缓存,日志格式定义等绝大多数功能和第三方模块的配置。如文件引入,mime-type定义,日志自定义,是否使用sendfile传输文件,连接超时时间,单连接请求数等。

server模块:配置虚拟主机的相关参数比如域名端口等等,一个http中可以有多个server。

location模块:配置url路由规则。

upstream模块:配置上游服务器的地址以及负载均衡策略和重试策略等等。

location路由配置规则

1
2
3
location [ = | ~ | ~* | ^~ ] uri  {
...
}
  1. 通用匹配

通用匹配使用一个 / 表示,可以匹配所有请求。相当于 switch 中的 default。

1
2
3
4
location / {
root dist;
index index.html index.htm;
}
  1. 无修饰符的前缀匹配

无修饰符的前缀匹配,匹配前缀是配置的的url

1
2
3
4
location /prefix_match {
alias dist;
index index.html index.htm;
}

提示:前缀匹配使用alias来寻找资源

匹配结果

1
2
3
4
5
6
7
curl http://www.locatest.com/prefixmatch     ✅ 301
curl http://www.locatest.com/prefixmatch? ✅ 301
curl http://www.locatest.com/PREFIXMATCH ❌ 404
curl http://www.locatest.com/prefixmatch/ ✅ 200
curl http://www.locatest.com/prefixmatchmmm ❌ 404
curl http://www.locatest.com/prefixmatch/mmm ❌ 404
curl http://www.locatest.com/aaa/prefixmatch/❌ 404

域名/prefixmatch,域名/prefixmatch? 和域名/prefixmatch/ 这三个url能够匹配上无修饰符的前缀匹配。

  1. ^~ 有修饰符的前缀匹配

1
2
3
location ^~ /exactprefixmatch{    
[ configuration ]
}

匹配结果

1
2
3
4
5
6
7
curl http://www.locatest.com/exactprefixmatch     ✅ 200
curl http://www.locatest.com/exactprefixmatch/ ✅ 200
curl http://www.locatest.com/exactprefixmatch? ✅ 200
curl http://www.locatest.com/exactprefixmatchmmm ✅ 200
curl http://www.locatest.com/exactprefixmatch/mmm ✅ 200
curl http://www.locatest.com/aaa/exactprefixmatch ❌ 404
curl http://www.locatest.com/EXACTPREFIXMATCH ❌ 404

域名/exactprefixmatchmmm 和域名/exactprefixmatch/mmm 是可以匹配上的,而不带修饰符的前缀匹配这两个类型的url是匹配不上的直接返回了404

  1. = 精确匹配

1
2
3
4
5
6
7
8
location = /test {
return 200 "hello";
}

# /test ok
# /test/ not ok
# /test2 not ok
# /test/2 not ok
  1. ~ 区分大小写的正则匹配

1
2
3
4
5
6
7
8
location ~ ^/test$ {
[ configuration ]
}

# /test ok
# /Test not ok
# /test/ not ok
# /test2 not ok
  1. ~* 不区分大小写的正则匹配
1
2
3
4
5
6
7
8
9
location ~* ^/test$ {     
[ configuration ]
}


# /test ok
# /Test ok
# /test/ not ok
# /test2 not ok
  1. 匹配优先级

优先级,从高到底:

精确匹配 =

前缀匹配 ^~

正则匹配 *

通用匹配

  1. root 与 alias 的区别

  • root 是直接拼接 root + location
1
2
3
location /i/ {
root /data/w3;
}

当请求 /i/top.gif ,/data/w3/i/top.gif 会被返回。

  • alias 是用 alias 替换 location
1
2
3
location /i/ {
alias /data/w3/images/;
}

当请求 /i/top.gif ,/data/w3/images/top.gif 会被返回

  1. server 和 location 中的 root

server 和 location 中都可以使用 root,采取就近原则,如果 location 中能匹配到,就是用 location 中的 root 配置,忽略 server 中的 root,当 location 中匹配不到的时候,则使用 server 中的 root 配置

解决跨域

假设页面地址:http://192.168.31.115:8080

假设请求接口地址:http://v.juhe.cn/laohuangli/d?date=2014-09-09&key=dae46b9a6abb27fecaace80f47624f

配置Nginx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server {
listen 8088;
server_name 192.168.31.115;


location / {
proxy_pass http://192.168.31.115:8080/; //反向代理
}


location /laohuangli {
proxy_pass http://v.juhe.cn/laohuangli;
}
}

将页面地址代理到8088端口,将接口地址也代理到8088端口

页面中请求接口

1
2
3
fetch('http://192.168.31.115:8088/laohuangli/d?date=2014-09-09&key=dae46b9a6abb27fecaace80f47624f').then(res=>res.json()).then(res=>{
console.log(res)
})

访问页面:http://192.168.31.115:8088/

gzip压缩

1
2
3
4
5
6
7
8
9
10
11
12
http{
gzip on; # 是否开启gzip
gzip_min_length 1k;# 开始压缩的最小长度(再小就不要压缩了,意义不在)
gzip_buffers 4 16k; # 缓冲(压缩在内存中缓冲几块? 每块多大?)
gzip_http_version 1.1;# 开始压缩的http协议版本(可以不设置,目前几乎全是1.1协议)
gzip_comp_level 2;# 推荐6 压缩级别(级别越高,压的越小,越浪费CPU计算资源)
gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml;# 对哪些类型的文件用压缩 如txt,xml,html ,css
gzip_vary on; # 是否传输gzip压缩标志
gzip_proxied expired no-cache no-store private auth; #Nginx做为反向代理的时候启用 例如如果header中包含”Expires”头信息,启用压缩
gzip_disable "MSIE [1-6]\."; #正则匹配UA,配置禁用gzip条件。此处表示ie6及以下不启用gzip(因为ie低版本不支持)
gzip_static on; #开启后会寻找以.gz结尾的文件,直接返回,不会占用cpu进行压缩,如果找不到则不进行压缩
}

默认是动态压缩,即对每个请求是先压缩后输出。可配置gzip_static on;直接读取生成好的gz文件(前端打包时生成gz文件)

将HTTP请求转到HTTPS

在服务器上监听80端口,使用重定向

1
2
3
4
5
6
server
{
listen 80;
server_name 47.101.161.174;
return 301 https://$host$request_uri; //永久性重定向
}

这样,如果访问http://service.com 将会跳转到 https://service.coms

使用HTTP2

在监听443端口后加http2即可开启

1
listen 443 ssl http2;

负载均衡

将请求分配给空闲服务器处理(电话号码同一个,但是不同客服接听)

1
2
3
4
5
6
7
8
9
10
11
12
upstream firstdemo {
server 192.168.31.123:8081;
server 192.168.31.123:8082;
}

server {
listen 8080;
server_name localhost;
location / {
proxy_pass http://firstdemo;
}
}

负载均衡:upstream name {},两个server分别对应着不同的服务器

proxy_pass http://firstdemo,代理到firstdemo里两个服务器上

灰度系统:可判断cookie版本,走不同服务器

静态资源服务器

把不常修改的静态资源文件放到nginx的静态资源目录中去,这样在访问静态资源时直接读取nginx服务器本地文件目录之后返回,这样就大大减少了后端服务的压力同时也加快了静态资源的访问速度

步骤一:在/www/server/nginx/html下创建images文件夹

步骤二:在Nginx进行配置(注意location的访问方式不同,root指定路径也不同)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
server
{
listen 80;
server_name 127.0.0.1;
index index.html index.htm index.php;
root /www/server/nginx/html;


#error_page 404 /404.html;
include enable-php.conf;


location ^~ /images/
{
expires 1d;
}


access_log /www/wwwlogs/access.log;
}

访问 http://127.0.0.1/images/1.png

实则访问:/www/server/nginx/html/images/lifecycle.png

防盗链

1
2
3
4
5
6
7
location ~ .*\.(jpg|png|gif)$ { # 匹配防盗链资源的文件类型
# 通过 valid_referers 定义合法的地址白名单 $invalid_referer 不合法的返回403
valid_referers none blocked 127.0.0.1;
if ($invalid_referer) {
return 403;
}
}

请求限制

对于大流量恶意的访问,会造成带宽的浪费,给服务器增加压力。往往对于同一 IP 的连接数以及并发数进行限制。

关于请求限制主要有两种类型:

limit_conn_module 连接频率限制

limit_req_module 请求频率限制

1
2
3
4
5
6
# $binary_remote_addr 远程IP地址 zone 区域名称 10m内存区域大小
limit_conn_zone $binary_remote_addr zone=coon_zone:10m;
server {
# conn_zone 设置对应的共享内存区域 1是限制的数量
limit_conn conn_zone 1;
}
1
2
3
4
5
6
7
8
# $binary_remote_addr 远程IP地址 zone 区域名称 10m内存区域大小 rate 为请求频率 1s 一次
limit_req_zone $binary_remote_addr zone=req_zone:10m rate=1r/s;
server {
location / {
# 设置对应的共享内存区域 burst最大请求数阈值 nodelay不希望超过的请求被延迟
limit_req zone=req_zone burst=5 nodelay;
}
}

总结

通过以上介绍,我们可以看出 Nginx 是一款功能强大的 Web 服务器和反向代理服务器,它可以满足常规项目的部署需求。Nginx 的高性能、稳定性、反向代理和负载均衡、静态文件服务、易于配置和管理等特点,使得它成为了众多开发者的首选。在实际应用中,我们可以根据项目的需求,灵活地配置 Nginx,以实现高效的项目部署。

作者

步步为营

发布于

2024-12-11

更新于

2025-03-15

许可协议