10 min read

Nginx 入门

Nginx 入门
Nginx 入门

转载自 Geekhour 的文章
Nginx 笔记
本⽂档为 GeekHour 的《30 分钟 Nginx ⼊⻔教程》的配套笔记⽂档,转载请注明出处。

本⽂档所有内容均来⾃于 Nginx 官⽹,仅供学习使⽤。
nginx admin guide
nginx documentation

Nginx 简介

Nginx 是⽬前最流⾏的 Web 服务器,
最开始是由⼀个叫做 igor 的俄罗斯的程序员开发的,
2019 年 3 ⽉ 11 ⽇被美国的 F5 公司以 6.7 亿美元的价格收购,
现在 Nginx 是 F5 公司旗下的⼀款产品了。

Nginx 的版本

Nginx 开源版本主要分为两种,⼀种是稳定版,⼀种是主线版。
主线版(mainline):主线版是最新的版本,功能会⽐较多,会包含⼀些正在开发中的体
验性模块功能,但是也可能会有⼀些新的 bug。
稳定版(Stable):稳定版是经过⻓时间测试的版本,不会有太多的 bug,也不会包含⼀
些新的功能。

Nginx 启动

nginx

查看 nginx 进程

ps -ef | grep nginx
# > % ps -ef | grep nginx
#  501 21086     1   0 10:26am ??         0:00.00 nginx: master process nginx
#  501 21087 21086   0 10:26am ??         0:00.00 nginx: worker process

nginx 分为 master 和 worker 进程, nginx 拥有一个 master 进程和多个 worker 进程(配置文件)

Nginx 的配置⽂件

使用nginx -V 查看 nginx 的编译参数包括配置文件--conf-path, 安装目录--prefix参数
在 macos 下 配置文件位置/opt/homebrew/etc/nginx/nginx.conf

  • 更改配置文件中的worker_processes 可以添加 worker 的数量, 一般设置为 cpu 内核数量, 可以是auto
  • 可以使用nginx -t 检查配置文件是否正确
  • 使用nginx -s reload 来重新加载配置文件

Nginx 的配置⽂件是 可以使⽤ nginx -t nginx.conf 来查看配置⽂件的位置和检查配置⽂件是否正确。

配置⽂件的结构

Nginx 的配置⽂件是由⼀系列的指令组成的,每个指令都是由⼀个指令名和⼀个或者多个参数
组成的。
裹。
指令和参数之间使⽤空格来分隔,指令以分号 ; 结尾,参数可以使⽤单引号或者双引号来包
配置⽂件分为以下⼏个部分:

# 全局块
worker_processes 1;
events {
# events块
}
http {
# http块
server {
# server块
location / {
# location块
}
}
}

全局块

全局块是配置⽂件的第⼀个块,也是配置⽂件的主体部分,主要⽤来设置⼀些影响 Nginx 服务
器整体运⾏的配置指令,主要包括配置运⾏ Nginx 服务器的⽤户(组)、允许⽣成的 worker
process 数、进程 PID 存放路径、⽇志存放路径和类型以及配置⽂件引⼊等。

# 指定运⾏Nginx服务器的⽤户,只能在全局块配置
# 将user指令注释掉,或者配置成nobody的话所有⽤户都可以运⾏
# user [user] [group]
# user nobody nobody;
user nginx;
# 指定⽣成的worker进程的数量,也可使⽤⾃动模式,只能在全局块配置
worker_processes 1;
# 错误⽇志存放路径和类型
error_log /var/log/nginx/error.log warn;
# 进程PID存放路径
pid /var/run/nginx.pid;

events 块

events {
# 指定使⽤哪种⽹络IO模型,只能在events块中进⾏配置
# use epoll
# 每个worker process允许的最⼤连接数
worker_connections 1024;
}

http 块

http 块是配置⽂件的主要部分,包括 http 全局块和 server 块。

http {
    # nginx 可以使⽤include指令引⼊其他配置⽂件
    include /etc/nginx/mime.types;

    # 默认类型,如果请求的URL没有包含⽂件类型,会使⽤默认类型
    default_type application/octet-stream; # 默认类型

    # 开启⾼效⽂件传输模式
    sendfile on;

    # 连接超时时间
    keepalive_timeout 65;

    # access_log ⽇志存放路径和类型
    # 格式为:access_log <path> [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];
    access_log /var/log/nginx/access.log main;

    # 定义⽇志格式
    "$request" '
    log_format main '$remote_addr - $remote_user [$time_local]
    '$status $body_bytes_sent "$http_referer" '
    '"$http_user_agent" "$http_x_forwarded_for"';

    # 设置sendfile最⼤传输⽚段⼤⼩,默认为0,表示不限制
    # sendfile_max_chunk 1m;

    # 每个连接的请求次数
    # keepalive_requests 100;
    # keepalive超时时间
    keepalive_timeout 65;

    # 开启gzip压缩
    # gzip on;

    # 开启gzip压缩的最⼩⽂件⼤⼩
    # gzip_min_length 1k;
    # gzip压缩级别,1-9,级别越⾼压缩率越⾼,但是消耗CPU资源也越多
    # gzip_comp_level 2;
    # gzip压缩⽂件类型
    # gzip_types text/plain application/javascript application/x-
    javascript text/css application/xml text/javascript application/x-httpd-
    php image/jpeg image/gif image/png;

    # upstream指令⽤于定义⼀组服务器,⼀般⽤来配置反向代理和负载均衡
    upstream www.example.com {
        # ip_hash指令⽤于设置负载均衡的⽅式,ip_hash表示使⽤客户端的IP进⾏hash,
        这样可以保证同⼀个客户端的请求每次都会分配到同⼀个服务器,解决了session共享的问题
        ip_hash;
        # weight ⽤于设置权重,权重越⾼被分配到的⼏率越⼤
        server 192.168.50.11:80 weight=3;
        server 192.168.50.12:80;
        server 192.168.50.13:80;
    }
    server {
        # 参考server块的配置
    }
}

server 块

server 块是配置虚拟主机的,⼀个 http 块可以包含多个 server 块,每个 server 块就是⼀个虚拟主机。

server {
    # 监听IP和端⼝
    # listen的格式为:
    # listen [ip]:port [default_server] [ssl] [http2] [spdy]
    [proxy_protocol] [setfib=number] [fastopen=number] [backlog=number];
    # listen指令⾮常灵活,可以指定多个IP和端⼝,也可以使⽤通配符
    # 下⾯是⼏个实际的例⼦:
    # listen 127.0.0.1:80; # 监听来⾃127.0.0.1的80端⼝的请求
    # listen 80; # 监听来⾃所有IP的80端⼝的请求
    # listen *:80; # 监听来⾃所有IP的80端⼝的请求,同上
    # listen 127.0.0.1; # 监听来⾃来⾃127.0.0.1的80端⼝,默认端⼝为80
    listen 80;
    # server_name ⽤来指定虚拟主机的域名,可以使⽤精确匹配、通配符匹配和正则匹配等
    ⽅式
    # server_name example.org www.example.org; # 精确匹配
    # server_name *.example.org; # 通配符匹配
    # server_name ~^www\d+\.example\.net$; # 正则匹配
    server_name localhost;
    # location块⽤来配置请求的路由,⼀个server块可以包含多个location块,每个
    location块就是⼀个请求路由
    # location块的格式是:
    # location [=|~|~*|^~] /uri/ { ... }
    # = 表示精确匹配,只有完全匹配上才能⽣效
    # ~ 表示区分⼤⼩写的正则匹配
    # ~* 表示不区分⼤⼩写的正则匹配
    # ^~ 表示普通字符匹配,如果匹配成功,则不再匹配其他location
    # /uri/ 表示请求的URI,可以是字符串,也可以是正则表达式
    # { ... } 表示location块的配置内容
    location / {
        # root指令⽤于指定请求的根⽬录,可以是绝对路径,也可以是相对路径
        root /usr/share/nginx/html; # 根⽬录
        # index指令⽤于指定默认⽂件,如果请求的是⽬录,则会在⽬录下查找默认⽂件
        index index.html index.htm; # 默认⽂件
    }
    # 下⾯是⼀些location的示例:
    location = / {
        root /usr/share/nginx/html;
        index index.html index.htm;
    }
    location ^~ /images/ {
        root /usr/share/nginx/html;
    }
    location ~* \.(gif|jpg|jpeg)$ {
        root /usr/share/nginx/html;
    }
    location !~ \.(gif|jpg|jpeg)$ {
        root /usr/share/nginx/html;
    }
    location !~* \.(gif|jpg|jpeg)$ {
        root /usr/share/nginx/html;
    }
    # error_page ⽤于指定错误⻚⾯,可以指定多个,按照优先级从⾼到低依次查找
    error_page 500 502 503 504 /50x.html; # 错误⻚⾯
    location = /50x.html {
        root /usr/share/nginx/html;
    }
}

Nginx 的常⽤命令

nginx # 启动Nginx
nginx -c filename # 指定配置⽂件
nginx -V # 查看Nginx的版本和编译参数等信息
nginx -t nginx -s quit # 优雅停⽌Nginx
nginx -s stop # 快速停⽌Nginx
nginx -s quit #优雅退出nginx
nginx -s reload # 重新加载配置⽂件
nginx -s reopen # 重新打开⽇志⽂件

反向代理

  • 正向代理: 代理客户端访问服务器
    2024-09-10T141819.png
  • 反向代理: 代理服务端 隐藏服务器 ip,端口信息
    2024-09-10T145358.png

修改 nginx.conf
在 http 块添加

upstream name {
        #ip_hash;
        server 127.0.0.1:8000 weight=4;
        server 127.0.0.1:8001;
        server 127.0.0.1:8002;
    }

在 http.server 块添加

location /backendLocation {
            proxy_pass http://name;
        }

此时访问localhost:8080/backendLocation 会访问以上的三个服务器
nginx 默认的策略是轮询, 可以添加weight= number 添加权重
可以使用ip_hash, 同一个 ip 发来的请求使用同一个服务器连接,可以解决 session 问题

https 协议

默认端口 443
使用 openssl 生成证书:

openssl genrsa -out private.key 2048  #生成私钥文件
openssl req -new -key private.key -out cert.csr  # 根据私钥生成证书签名请求文件CSR文件
openssl x509 -req -in cert.csr -out cacert.pem -signkey private.key # 使用私钥对证书申请进行签名从而生成证书文件 pem文件

更改 conf 配置,添加 server 模块

server {
        listen 443 ssl;
        server_name localhost;
        #证书文件
        ssl_certificate /opt/homebrew/etc/nginx/cacert.pem;
        #证书私钥文件
        ssl_certificate_key /opt/homebrew/etc/nginx/private.key;

        ssl_session_cache shared:SSL:1m;
        # ssl验证配置有效期
        ssl_session_timeout 5m;
        #安全链接可选的加密协议
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
        #加密算法
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
        #服务器首选加密算法
        ssl_prefer_server_ciphers on;
        location / {
            root html;
            index index.html index.htm;
        }

添加重定向

server {
        listen 80;
        server_name richardthunder.shop www.richardthunder.shop;
        return 301 https://$server_name$request_uri;
    }

虚拟主机

多个网站配置在同一服务器上
使用 server 块实现多个虚拟主机
因为在nginx.conf最后有include servers/*;, 所以在/opt/homebrew/etc/nginx/servers 目录下的配置,也会被包含
可以将虚拟主机定义在servers/ 目录下

#新建servers目录
mkdir /opt/homebrew/etc/nginx/servers
#添加如下内容
server {
    listen 3300;
    server_name localhost;
    location / {
        root /Users/richard/code/Archived/webPages/jQuery;
        index index.html index.htm;
    }
}
#其中root指向网页文件, 端口可以自定义,servername指向了域名
#执行如下命令重载配置文件
nginx -s reload

Nginx 的常⽤模块

模块名(Module Name) 描述(Description)
http_access_module 接受或者拒绝特定的客户端请求
http_auth_basic_module HTTP 基本认证,使⽤⽤户名和密码来限制对资源的访问
http_autoindex_module ⾃动索引,⽤于显示⽬录列表
http_browser_module 从 User-Agent 请求头中获取和识别客户端浏览器
http_charset_module 添加特定的字符集到 Content-Type 响应头中
http_empty_gif_module 返回⼀个 1 像素的透明 GIF 图⽚
http_fastcgi_module FastCGI ⽀持
http_geo_module 从 IP 地址中获取地理位置信息
http_gzip_module Gzip 压缩⽀持
http_limit_conn_module 限制并发连接数
http_limit_req_module 限制请求速率
http_map_module 从变量中获取值
http_memcached_module Memcached ⽀持
http_proxy_module 反向代理⽀持
http_referer_module 防盗链
http_rewrite_module URL 重写
http_scgi_module 转发请求到 SCGI 服务器
http_ssi_module 处理和⽀持 SSI(Server Side Includes)
http_split_clients_module 根据客户端 IP 地址或者其他变量将客户端分配到组中,⼀般⽤于 A/B 测试
http_upstream_hash_module 启⽤⼀致性哈希负载均衡
http_upstream_ip_hash_module 启⽤ IP 哈希负载均衡
http_upstream_keepalive_module 启⽤⻓连接负载均衡
http_upstream_least_conn_module 启⽤最少连接负载均衡
http_upstream_zone_module 启⽤共享内存负载均衡
http_userid_module 为客户端设置⼀个唯⼀的 ID(UID、cookie)
http_uwsgi_module 转发请求到 uWSGI 服务器,⼀般⽤于 Python 应⽤