跳到主要内容

Nginx

Nginx 介绍

一、nginx 简介

Nginx 是一款高性能的 Web 服务器和反向代理服务器,它的配置文件非常重要,因为它决定了 Nginx 服务器如何处理请求和响应。在这篇文章中,我们将详细讨论 Nginx 配置文件,并提供一些实用的配置示例和技巧

二、基础语法规则

Nginx 配置文件以块结构为基础,一个块以花括号 " 开始,以花括号 " 结束。每个块可以包含多个指令,在指令之间使用分号 ";" 分隔。注释以 "#" 开始。 例:

This is a comment

http {
server {
listen 80; # Listen on port 80
location / {
root /var/www/html;
index index.html;
}
}
}

三、nginx 配置文件结构

... #全局块

events { #events 块
...
}

http #http 块
{
... #http 全局块
server #server 块
{
... #server 全局块
location [PATTERN] #location
{
...
}
location [PATTERN]
{
...
}
}
server
{
...
}
... #http 全局块
}

1、全局块:配置影响 nginx 全局的指令。一般有运行 nginx 服务器的用户组,nginx 进程 pid 存放路径,日志存放路径,配置文件引入,允许生成 worker process 数等。只有一个全局块,在配置文件的最顶部。 2、events 块:配置影响 nginx 服务器或与用户的网络连接。有每个进程的最大连接数,选取哪种事件驱动模型处理连接请求,是否允许同时接受多个网路连接,开启多个网络连接序列化等。 3、Http 块:可以嵌套多个 server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。如文件引入,mime-type 定义,日志自定义,是否使用 sendfile 传输文件,连接超时时间,单连接请求数等。最多有一个 Http 块 4、server 块:配置虚拟主机的相关参数,一个 http 中可以有多个 server(location 块)。 5、location 块:配置请求的路由,以及各种页面的处理情况。

四、全局配置

全局配置包括 Nginx 的基本设置,如 worker_processes、error_log 等。

  • worker_processes 指令定义了 Nginx 使用的 worker 进程的数量。对于多核 CPU 的服务器,通常设置为与 CPU 核心数相等或略少一些。

  • error_log 指令指定日志文件的位置。

  • pid 指令指定进程 ID 文件的位置。 示例:

    user nginx;
    worker_processes auto;
    error_log /var/log/nginx/error.log;
    pid /run/nginx.pid;

五、Server 块

一个 server 块定义了一个虚拟站点,该站点可以通过不同的域名或 IP 地址进行访问。

  • listen 指令指定服务器监听的端口号。

  • server_name 指令定义了服务器的域名或 IP 地址。

  • access_log 指令定义了请求日志的位置。

  • root 指令定义了服务器站点的根目录。

    server {
    listen 80;
    server_name example.com;
    access_log /var/log/nginx/example.com.access.log;
    root /var/www/example.com;
    }

六、location 块

一个 location 块定义了服务器中处理请求的不同位置。

  • location 指令后面是一个路径,可以用来匹配请求 URL。

  • proxy_pass 指令将请求转发到另一个服务器。

  • try_files 指令将请求重写为不同的文件名。

  • rewrite 指令根据正则表达式重写 URL。 示例:

    location /images/ {
    root /var/www/;
    autoindex on;
    }

    location /api/ {
    proxy_pass http://backend;
    }

    location / {
    try_files $uri $uri/ /index.php?$args;
    }

    location /blog {
    rewrite ^/blog(.\*)$ /index.php?page=$1 last;
    }

七、HTTPS 配置

在配置 Nginx 的 HTTPS 网站时,需要确保服务器上已安装了 SSL 证书,并使用以下指令配置 HTTPS:

  • listen 指令与端口号 443 配合使用以启用 SSL。

  • ssl_certificate 指令指定 SSL 证书的路径。

  • ssl_certificate_key 指令指定 SSL 证书私钥的路径。

  • ssl_protocols 指令列出允许使用的 SSL 协议版本。

  • ssl_ciphers 指令指定允许使用的加密算法。 示例:

    server {
    listen 443 ssl;
    server_name example.com;
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ...
    }

八、负载均衡配置

在配置 Nginx 的负载均衡时,需定义多个 upstream 服务器和相应的 server。

  • upstream 指令定义了负载均衡的服务器列表。

  • server 指令在 upstream 内定义每个服务器的 IP 和端口号。

  • proxy_pass 指令将请求转发到 upstream 中的一个服务器。

  • proxy_set_header 指令设置请求头。 示例:

    http {
    upstream backend {
    server backend1.example.com;
    server backend2.example.com;
    server backend3.example.com;
    }
    server {
    listen 80;
    location / {
    proxy_pass http://backend;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    }
    }
    }

九、nginx 常用功能

1、Http 代理,反向代理 作为 web 服务器最常用的功能之一,尤其是反向代理。 Nginx 在做反向代理时,提供性能稳定,并且能够提供配置灵活的转发功能。Nginx 可以根据不同的正则匹配,采取不同的转发策略,比如图片文件结尾的走文件服务器,动态页面走 web 服务器,只要你正则写的没问题,又有相对应的服务器解决方案,你就可以随心所欲的玩。并且 Nginx 对返回结果进行错误页跳转,异常判断等。如果被分发的服务器存在异常,他可以将请求重新转发给另外一台服务器,然后自动去除异常服务器。

2、负载均衡 Nginx 提供的负载均衡策略有 2 种:内置策略和扩展策略。内置策略为轮询,加权轮询,Ip hash。 Ip hash 算法,对客户端请求的 ip 进行 hash 操作,然后根据 hash 结果将同一个客户端 ip 的请求分发给同一台服务器进行处理,可以解决 session 不共享的问题。

3、web 缓存 Nginx 可以对不同的文件做不同的缓存处理,配置灵活,并且支持 FastCGI_Cache,主要用于对 FastCGI 的动态程序进行缓存。配合着第三方的 ngx_cache_purge,对制定的 URL 缓存内容可以的进行增删管理。

4、配置文件示例

########### 每个指令必须有分号结束。#################
#user administrator administrators; #配置用户或者组,默认为 nobody nobody。
#worker_processes 2; #允许生成的进程数,默认为 1
#pid /nginx/pid/nginx.pid; #指定 nginx 进程运行文件存放地址
error_log log/error.log debug; #制定日志路径,级别。这个设置可以放入全局块,http 块,server 块,级别以此为:debug|info|notice|warn|error|crit|alert|emerg
events {
accept_mutex on; #设置网路连接序列化,防止惊群现象发生,默认为 on
multi_accept on; #设置一个进程是否同时接受多个网络连接,默认为 off
#use epoll; #事件驱动模型,select|poll|kqueue|epoll|resig|/dev/poll|eventport
worker_connections 1024; #最大连接数,默认为 512
}
http {
include mime.types; #文件扩展名与文件类型映射表
default_type application/octet-stream; #默认文件类型,默认为 text/plain
#access_log off; #取消服务日志
log_format myFormat '$remote_addr–$remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for'; #自定义格式
access_log log/access.log myFormat; #combined 为日志格式的默认值
sendfile on; #允许 sendfile 方式传输文件,默认为 off,可以在 http 块,server 块,location 块。
sendfile_max_chunk 100k; #每个进程每次调用传输数量不能大于设定的值,默认为 0,即不设上限。
keepalive_timeout 65; #连接超时时间,默认为 75s,可以在 http,server,location 块。

upstream mysvr {
server 127.0.0.1:7878;
server 192.168.10.121:3333 backup; #热备
}
error_page 404 https://www.baidu.com; #错误页
server {
keepalive_requests 120; #单连接请求上限次数。
listen 4545; #监听端口
server_name 127.0.0.1; #监听地址
location ~*^.+$ { #请求的url过滤,正则匹配,~为区分大小写,~*为不区分大小写。
#root path; #根目录
#index vv.txt; #设置默认页
proxy_pass http://mysvr; #请求转向mysvr 定义的服务器列表
deny 127.0.0.1; #拒绝的ip
allow 172.18.5.54; #允许的ip
}
}

}

上面是 nginx 的基本配置,需要注意的有以下几点: 1、几个常见配置项: $remote_addr 与 $http_x_forwarded_for 用以记录客户端的ip地址; $remote_user :用来记录客户端用户名称; $time_local :用来记录访问时间与时区; $request :用来记录请求的 url 与 http 协议; $status :用来记录请求状态;成功是200; $body_bytes_sent :记录发送给客户端文件主体内容大小; $http_referer :用来记录从那个页面链接访问过来的; $http_user_agent :记录客户端浏览器的相关信息; 2、惊群现象:一个网路连接到来,多个睡眠的进程被同时叫醒,但只有一个进程能获得链接,这样会影响系统性能。 3、每个指令必须有分号结束。

配置实例

基础配置

user root;
worker_processes 1;

events {
worker_connections 10240;
}

http {
log_format '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent"';
include mime.types;
default_type application/octet-stream;
sendfile on;
#autoindex on;
#autoindex_exact_size off;
autoindex_localtime on;
keepalive_timeout 65;
gzip on;
gzip_disable "msie6";
gzip_min_length 100;
gzip_buffers 4 16k;
gzip_comp_level 1;
gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_types "*";
gzip_vary off;
server_tokens off;
client_max_body_size 200m;

server {
listen 80 default_server;
server_name _;
return 403 /www/403/index.html;
}

include ../serve/*.conf;
}

隐藏 Nginx 版本信息

http {
server_tokens off;
}

禁止ip直接访问80端口

server {
listen 80 default;
server_name _;
return 500;
}

启动 web 服务 (vue 项目为例)

server {
# 项目启动端口
listen 80;
# 域名(localhost)
server_name _;
# 禁止 iframe 嵌套
add_header X-Frame-Options SAMEORIGIN;

# 访问地址 根路径配置
location / {
# 项目目录
root html;
# 默认读取文件
index index.html;
# 配置 history 模式的刷新空白
try_files $uri $uri/ /index.html;
}

# 后缀匹配,解决静态资源找不到问题
location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
root html/static/;
}

# 图片防盗链
location ~/static/.*\.(jpg|jpeg|png|gif|webp)$ {
root html;
valid_referers *.deeruby.com;
if ($invalid_referer) {
return 403;
}
}

# 访问限制
location /static {
root html;
# allow 允许
allow 39.xxx.xxx.xxx;
# deny 拒绝
deny all;
}
}

PC端和移动端使用不同的项目文件映射

server {
......
location / {
root /home/static/pc;
if ($http_user_agent ~* '(mobile|android|iphone|ipad|phone)') {
root /home/static/mobile;
}
index index.html;
}
}

一个web服务,配置多个项目 (location 匹配路由区别)

server {
listen 80;
server_name _;

# 主应用
location / {
root html/main;
index index.html;
try_files $uri $uri/ /index.html;
}

# 子应用一
location ^~ /store/ {
proxy_pass http://localhost:8001;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

# 子应用二
location ^~ /school/ {
proxy_pass http://localhost:8002;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

# 静态资源读取不到问题处理
rewrite ^/api/profile/(.*)$ /(替换成正确路径的文件的上一层目录)/$1 last;
}

# 子应用一服务
server {
listen 8001;
server_name _;
location / {
root html/store;
index index.html;
try_files $uri $uri/ /index.html;
}

location ^~ /store/ {
alias html/store/;
index index.html index.htm;
try_files $uri /store/index.html;
}

# 接口代理
location /api {
proxy_pass http://localhost:8089;
}
}

# 子应用二服务
server {
listen 8002;
server_name _;
location / {
root html/school;
index index.html;
try_files $uri $uri/ /index.html;
}

location ^~ /school/ {
alias html/school/;
index index.html index.htm;
try_files $uri /school/index.html;
}

# 接口代理
location /api {
proxy_pass http://localhost:10010;
}
}

配置负载均衡

upstream my_upstream {
server http://localhost:9001;
server http://localhost:9002;
server http://localhost:9003;
}

server {
listen 9000;
server_name test.com;

location / {
proxy_pass my_upstream;
proxy_set_header Host $proxy_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

SSL 配置 HTTPS

server {
listen 80;
server_name www.xxx.com;
# 将 http 重定向转移到 https
return 301 https://$server_name$request_uri;
}

server {
listen 443 ssl;
server_name www.xxx.com;
ssl_certificate /etc/nginx/ssl/www.xxx.com.pem;
ssl_certificate_key /etc/nginx/ssl/www.xxx.com.key;
ssl_session_timeout 10m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;

location / {
root /project/xxx;
index index.html index.htm index.md;
try_files $uri $uri/ /index.html;
}
}