Nginx快速上手

236 阅读15分钟

Nginx 常用版本

常用版本分为四大阵营

Nginx 开源版 nginx.org/

Nginx plus 商业版 www.nginx.com/

Openresty openresty.org/

Tengine tengine.taobao.org/

Nginx 安装

官网下载安装包 nginx: download

安装 gcc

yum install -y gcc

解压 nginx 安装包

tar -zxvf nginx-1.21.6.tar.gz 

编译安装

./configure --prefix=/usr/local/nginx
make & make install

可能出现以下类似报错

./configure: error: the HTTP rewrite module requires the PCRE library.
You can either disable the module by using --without-http_rewrite_module
option, or install the PCRE library into the system, or build the PCRE library
statically from the source with nginx by using --with-pcre=<path> option.

安装依赖

yum install -y pcre pcre-devel
yum install -y zlib zlib-devel

再次执行

./configure --prefix=/usr/local/nginx
make & make install

启动 Nginx

./nginx # 启动
./nginx -s stop # 快速停止
./nginx -s quit # 优雅关闭,在退出前完成已经接受的连接请求
./nginx -s reload # 重新加载配置

以上命令需要在 nginx 的 sbin 目录下执行

安装 Nginx 为系统服务

创建启动文件

vim /usr/lib/systemd/system/nginx.service

编写启动文件

[Unit]
Description=nginx - web server
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s stop
ExecQuit=/usr/local/nginx/sbin/nginx -s quit
PrivateTmp=true
[Install]
WantedBy=multi-user.target

注意ExecStartPre...属性,Exec后面的内容,就是systemctl xxx命令的参数,而启动文件的名称nginx.service,就为systemctl xxx xxx.service中的目标服务,例如ExecStart配置,对应的命令为systemctl start nginx

重新加载系统服务

systemctl daemon-reload

使用系统服务命令启动 nginx

systemctl start nginx

设置 nginx 服务为开机自启动

systemctl enable nginx.service

关于防火墙

关闭防火墙

systemctl stop firewalld

禁用防火墙(避免开机自启)

systemctl disable firewalld

放行端口

firewall-cmd --zone=public --add-port=80/tcp --permanent

重启防火墙

firewall-cmd --reload

Nginx 基本使用

Nginx 运行流程

nginx 基础配置文件

一个默认的去除注释的最简nginx.conf配置如下

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    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;
        }
    }
}

使用cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c可以快速查看cpu核心数以及cpu型号

worker_processes

工作线程数,默认为 1,代表开启一个业务进程(也就是 worker 进程)

worker_processes 的值, 简单来说可以配置为当前物理机的 cpu 内核数

worker_connections

单个 worker 进程可接受的连接数,一般来说不用调整

include mime.types

引入 http mime 类型文件,或者也可以使用include引入额外的nginx.conf文件,关于mime.types文件的内容如下

types {
    # 申明浏览器应该如何处理响应的数据(展示、下载、播放等) 
    # text/html html htm shtml; 的配置则代表浏览器应该以网页形式渲染 .html .htm .shtml 后缀的文件
    text/html                                        html htm shtml;
    text/css                                         css;
    text/xml                                         xml;
    image/gif                                        gif;
    image/jpeg                                       jpeg jpg;
    application/javascript                           js;
    application/atom+xml                             atom;
    application/rss+xml                              rss;

    text/mathml                                      mml;
    text/plain                                       txt;
    text/vnd.sun.j2me.app-descriptor                 jad;
    text/vnd.wap.wml                                 wml;
    text/x-component                                 htc;

    image/avif                                       avif;
    image/png                                        png;
    image/svg+xml                                    svg svgz;
    image/tiff                                       tif tiff;
    image/vnd.wap.wbmp                               wbmp;
    image/webp                                       webp;
    image/x-icon                                     ico;
    image/x-jng                                      jng;
    image/x-ms-bmp                                   bmp;

    font/woff                                        woff;
    font/woff2                                       woff2;

    application/java-archive                         jar war ear;
    application/json                                 json;
    application/mac-binhex40                         hqx;
    application/msword                               doc;
    application/pdf                                  pdf;
    application/postscript                           ps eps ai;
    application/rtf                                  rtf;
    application/vnd.apple.mpegurl                    m3u8;
    application/vnd.google-earth.kml+xml             kml;
    application/vnd.google-earth.kmz                 kmz;
    application/vnd.ms-excel                         xls;
    application/vnd.ms-fontobject                    eot;
    application/vnd.ms-powerpoint                    ppt;
    application/vnd.oasis.opendocument.graphics      odg;
    application/vnd.oasis.opendocument.presentation  odp;
    application/vnd.oasis.opendocument.spreadsheet   ods;
    application/vnd.oasis.opendocument.text          odt;
    application/vnd.openxmlformats-officedocument.presentationml.presentation
                                                     pptx;
    application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
                                                     xlsx;
    application/vnd.openxmlformats-officedocument.wordprocessingml.document
                                                     docx;
    application/vnd.wap.wmlc                         wmlc;
    application/wasm                                 wasm;
    application/x-7z-compressed                      7z;
    application/x-cocoa                              cco;
    application/x-java-archive-diff                  jardiff;
    application/x-java-jnlp-file                     jnlp;
    application/x-makeself                           run;
    application/x-perl                               pl pm;
    application/x-pilot                              prc pdb;
    application/x-rar-compressed                     rar;
    application/x-redhat-package-manager             rpm;
    application/x-sea                                sea;
    application/x-shockwave-flash                    swf;
    application/x-stuffit                            sit;
    application/x-tcl                                tcl tk;
    application/x-x509-ca-cert                       der pem crt;
    application/x-xpinstall                          xpi;
    application/xhtml+xml                            xhtml;
    application/xspf+xml                             xspf;
    application/zip                                  zip;

    application/octet-stream                         bin exe dll;
    application/octet-stream                         deb;
    application/octet-stream                         dmg;
    application/octet-stream                         iso img;
    application/octet-stream                         msi msp msm;

    audio/midi                                       mid midi kar;
    audio/mpeg                                       mp3;
    audio/ogg                                        ogg;
    audio/x-m4a                                      m4a;
    audio/x-realaudio                                ra;

    video/3gpp                                       3gpp 3gp;
    video/mp2t                                       ts;
    video/mp4                                        mp4;
    video/mpeg                                       mpeg mpg;
    video/quicktime                                  mov;
    video/webm                                       webm;
    video/x-flv                                      flv;
    video/x-m4v                                      m4v;
    video/x-mng                                      mng;
    video/x-ms-asf                                   asx asf;
    video/x-ms-wmv                                   wmv;
    video/x-msvideo                                  avi;
}

此配置主要用于nginx服务器在响应头中申明响应的文件类型,至于是哪种文件类型,则需要在include mime.types引入的mime.types文件中进行确定

如果mime.types中没有所需的文件类型,也可自行添加,例如video/mp4 mp5,代表以mp4的方式播放.mp5后缀的文件

default_type application/octet-stream;

用于配置如果mime.types中没有匹配的文件类型,那么默认使用二进制进行传输

sendfile no

使用 linux 的 sendfile(socket, file, len) 高效网络传输,也就是数据 0 拷贝

如果没有开启 sendfile,当客户端请求 nginx 服务器上的某个文件时,nginx 会先将文件读取到自己的应用程序内存中,然后再将文件内容复制到 nginx 所属的网络接口,再由此网络接口将文件响应给客户端,这中间多了一层复制的环节

开启了 sendfile 则恰好相反,nginx 只需要通过发送一个sendfile信号通知对应的网络接口,这个sendfile信号应该包含 socket 的连接信息,对应的文件信息等,而网络接口收到信号后,直接将文件响应给客户端,效率得到提升

keepalive_timeout 65

连接存活的超时时间

server

一个 server 代表一个虚拟主机,可以理解为一个站点,多个 server 之间互不干扰

server {
    listen       80; # 当前 server 监听的端口号
    server_name  localhost; # 当前主机名, 也可以配置域名, 客户端通过主机名请求到 nginx

    location / { # 匹配的请求路径
        root   html; # 文件的根目录,这是一个相对路径, 默认相对于 /usr/local/nginx 目录, 即 nginx 安装的主目录
        index  index.html index.htm; # 文件默认首页
    }

    error_page   500 502 503 504  /50x.html; # 错误码对应的页面
    # 配置了请求的 uri 为 /50x.html 时, 对应的根目录, 代表在此目录下查找请求的资源
    location = /50x.html {
        root   html;
    }
}

针对location的匹配路径,匹配的是请求的uri,并非请求的完整路径,例如https://www.baidu.com/hello,这整个请求地址可以叫做url,而域名或者ip之后的路径,叫做uri,即/hello

虚拟主机与域名解析

hosts 文件解析解析域名

在 nginx 的配置中,一个server代表一个虚拟主机,如果一台 nginx 服务器只是单独配置一个server,那就只能使用一个域名或者ip来访问,在访问数量较少的情况下,浪费了服务器资源

实际上 nginx 支持配置多个server来响应不同域名或ip的请求,也是就说,将不同的域名都解析到同一个nginx服务器的ip上,尤其是在前端部署时,通过将不同的域名解析到不同的资源目录,实现一台服务器部署多个前端应用

为了实现上述效果,需要先配置域名,最为方便的是配置本地域名,前提是域名对应的ip也在本地能够访问到的内网环境下

在 win11 中,使用管理员方式运行【记事本】,之后添加如下内容,之后在浏览器中就可以通过web1.com直接访问到192.168.31.150这个ip上的 nginx

192.168.31.150 web1.com

如果配置不生效,可以参考 windows修改hosts文件不生效(非DNS缓存问题)_TianXinCoord的博客-CSDN博客

虚拟主机域名配置

现在多个域名都指向了同一个nginx服务器,那么就需要在nginx的配置中,配置虚拟主机的域名以及多个站点,实现不同域名访问,响应不同站点内容的效果

首先是配置不同端口的虚拟主机,实现所说的效果,详细配置如下

# 多端口虚拟主机配置
worker_processes  1;

events {
    worker_connections  1024;
}

http {
    # 这里因为使用的非默认的配置文件且配置文件路径发生了改变, 需要将引入的一些文件路径改为绝对路径
    include       /usr/local/nginx/conf/mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    # 站点1
    server {
        # 监听 80 端口
        listen       80;
        server_name  localhost;

        location / {
            # 资源根路径为 /www/web1
            root   /www/web1;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /www/web1;
        }
    }

    # 站点2
    server {
        # 监听 88 端口
        listen       88;
        server_name  localhost;

        location / {
            # 资源根路径为 /www/web2
            root   /www/web2;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /www/web2;
        }
    }
}

以上配置通过不同端口访问nginx服务器的ip时,nginx 会根据访问的端口,分别响应/www/web1 /www/web2目录下的资源

下面通过域名来区分不同的站点,这也是实际项目部署时会用到的方式,因为网站部署后,不可能再让用户输入端口号来访问站点,这缺乏用户体验

通过域名的形式访问nginx服务器时,如果是http协议,则默认会访问80端口,https默认为443端口,这里因为是本地,所以下面的配置中,监听的依然是80端口,详细配置如下

# 多域名虚拟主机配置
worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       /usr/local/nginx/conf/mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    # 站点1
    server {
        listen       80;
        # 主机名配置, 客户端如果使用此主机名访问,则请求会被此虚拟主机处理
        server_name  web1.com; # web1.com 域名

        location / {
            root   /www/web1;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /www/web1;
        }
    }

    # 站点2
    server {
        listen       80;

        server_name  web2.com; # web2.com 域名

        location / {
            root   /www/web2;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /www/web2;
        }
    }
}

以上配置都监听的是80端口,使用域名区分站点,这样客户端只需要使用不同的域名访问即可,无需区分端口号

需要注意的是,多个server块配置中的server_namelisten不能重复

server_name 匹配规则

在虚拟主机的 server_name 中,有一些匹配的特定规则

首先,如果当前配置文件中没有匹配的server_name,那么默认会找到配置文件中第一个server_name中的配置的资源,多个server_name的匹配顺序为从上到下,一旦匹配到第一个,则不会继续向下匹配

但有一种情况需要注意,如果第一个或前一个server_name使用了通配,但当前配置文件中有更精确的server_name匹配,nginx 会使用精确匹配的server_name


一个server_name后,可以跟多个匹配规则,如下配置,当前server可以同时匹配aaa.dddhhhjjj.topbbb.dddhhhjjj.top两个域名

server_name  aaa.dddhhhjjj.top bbb.dddhhhjjj.top;

支持通配符匹配,如下

# 匹配 dddhhhjjj.top 域名下的所有子域名的请求
server_name *.dddhhhjjj.top;

# 后缀匹配
server_name www.dddhhhjjj.*;

通配符并不是 nginx 中server_name的最高匹配优先级,最高优先级为完全匹配,参考如下博客 [nginx中server的匹配顺序 - 大明湖畔的守望者 - 博客园 (cnblogs.com)](www.cnblogs.com/wangzhisdu/…. 首先,在nginx.conf中创建2个server,1个完全匹配,1个通配符匹配. 通配符server放在最前,以证明完全匹配的优先级与配置顺序无关. 接下来配置域名映射.,vim %2Fetv%2Fhosts. 访问测试:. 结论:完全匹配的优先级高于通配符匹配.)


除了上述匹配规则,nginx 还支持正则匹配,例如

# 匹配域名为数字开头, .top 结尾的请求
server_name ~^[0-9]+\.dddhhhjjj\.top$;

反向代理 & 负载均衡

反向代理

反向代理指的是将客户端的请求,通过代理服务器进行转发,间接的请求到服务端;与之相对的还有正向代理,正向代理是客户端主动的设置代理服务器,通过代理服务器来访问目标服务,二者的区别如下图

反向代理

正向代理

通过图可以很明显的看出,二者的区别在于代理服务器的服务边界,反向代理代理的是服务端,而正向代理代理的是客户端

在正向代理中,客户端明确知道有这个代理服务器,而在反向代理中,客户端事先不能知道自己的请求是否被代理过,这样具备一定的安全性,无需对外暴露服务端的 ip 地址

如果使用了正反向代理,那么相对于客户端和服务的来说,代理服务器就是一个网关,所有的网络活动都会通过代理服务器,如果代理服务器的带宽过小,那么可能就会出现网络拥堵的情况

负载均衡

负载均衡是将请求分发到服务器集群的一种行为,假设现在后台某一服务有多台机器,那么负载均衡会通过负载均衡算法(轮询,hash)等,将请求的压力分摊到不同的服务器,以提升服务的吞吐量及负载能力

nginx 配置反向代理

在 nginx 中,主要通过proxy_pass来配置反向代理的目标,可以是一个url,可以是ip或域名,也可以带上端口号,如下示例,也可以指定uri

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       /usr/local/nginx/conf/mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;

    server {
        listen       80;
        server_name  localhost;

        location / {
        	# 配置反向代理的目标地址 
	    	proxy_pass http://192.168.1.19:8883/proxy;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

需要注意的是,如果反向代理的地址请求协议为https,那么在未配置证书的情况下,nginx无法代理成功

nginx 配置负载均衡

nginx 中,负载均衡需要配合反向代理一起使用,具体配置如下

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       /usr/local/nginx/conf/mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;

    # 配置一组负载均衡目标服务器, 注意这里的【servers】代表的就是负载均衡组的名称
    upstream servers {
        server 192.168.1.19:8883;
        server 192.168.1.19:8889;
    }

    server {
        listen       80;
        server_name  localhost;

        location / {
        # 在反向代理中, 直接使用【servers】即可将请求负载均衡到服务器组的多台服务器
        # 而【servers】之后也可以跟 uri 等额外内容, 无特殊语法要求, 将【servers】理解为占位符即可 
	    proxy_pass http://servers/proxy;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

负载均衡策略

权重 & down & backup

权重

在负载均衡组中,可以通过配置权重weight来分配每台服务器被负载访问到的概率,如下

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       /usr/local/nginx/conf/mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;

    upstream servers {
        # 通过 weight 来配置权重, 值越大, 被负载访问的概率越高
        server  192.168.185.244:8883 weight=8 down;
        server  192.168.185.244:8889 weight=3;
    }

    server {
        listen       80;
        server_name  localhost;

        location / {
	    proxy_pass http://servers/proxy;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

down

对于负载均衡组中某一服务器节点,可以配置down属性,标识其不再参与负载均衡,在某些服务器压力过大时可以使用,配置如下

upstream servers {
    # 通过 weight 来配置权重, 值越大, 被负载访问的概率越高
    server  192.168.185.244:8883 weight=8 down;
    server  192.168.185.244:8889 weight=3;
}

backup

配置了backup的服务器节点会被作为备用节点,当其余节点访问失败时(包括请求超时、标识为 down 等情况),请求会被负载到backup标识的节点,如下配置

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       /usr/local/nginx/conf/mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;

    upstream servers {
        # 假设现在 192.168.185.244:8883 的服务器宕机, 那么配置了 backup 的 192.168.185.244:8889 服务器会被启用
        # 但如果当前还存在正常的非 backup 节点, 那么 backup 节点不会被负载到
        server  192.168.185.244:8883 weight=8;
        server  192.168.185.244:8889 weight=3 backup;
    }

    server {
        listen       80;
        server_name  localhost;

        location / {
	    proxy_pass http://servers/proxy;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

weight down backup这几个配置实际上并不常用,因为不太灵活,需要手动修改配置且重启 nginx 服务器

动静分离

动静分离指的是将.css .js .image这类静态资源的请求,直接交给 nginx 服务器处理,而无需再代理到后台的tomcat服务器,由此减轻tomcat服务器的压力

动静分离的配置主要通过 location 区分静态资源的访问路径,对应的 location 会直接请求到静态资源,如下

location /css {
    # 静态资源统一存放在 static 目录下对应的目录,例如这里的 css 资源则存放在 static/css 目录下
    root /usr/local/nginx/static;
    index index.html index.htm;
}
location /images {
    root /usr/local/nginx/static;
    index index.html index.htm;
}
location /js {
    root /usr/local/nginx/static;
    index index.html index.htm;
}

location 匹配

一份简单够用的 Nginx Location 配置讲解 - 掘金 (juejin.cn)