2020-02-11
运维
0

目录

Nginx 进程结构
Nginx 配置文件结构
Nginx reload 解析
Nginx 热部署
核心指令
main段核心参数
event段核心参数
location
server_name
核心模块
主要模块
return 指令
rewrite 指令
autoindex模块
Nginx相关变量
Tcp变量
Request变量
特殊变量
root 和 alias的区别
root
alias
反向代理
proxy_pass
upstream
Nginx代理缓存
优势
缓存指令
HTTPS
优势
防止响应内容被篡改
防止服务器的数字签名被篡改
证书自签
CA搭建命令(服务器A)
申请证书(服务器B)
签发证书(服务器A)
Nginx配置HTTPS

作为前端开发人员,你经常需要将前端项目部署到服务器上以提供访问。但是,如果你的服务器性能不足或者流量过大,可能会导致网站访问缓慢甚至崩溃。这时候,Nginx 就是你的救星。Nginx 是一款高性能、高可靠性的 Web 服务器软件,它可以帮助你提高网站的性能和可靠性。除此之外,Nginx 还可以实现反向代理、负载均衡、静态资源缓存等功能,这些功能对于前端开发来说也是非常重要的。本文将为你详细介绍 Nginx 的基本概念、常用场景,帮助你快速掌握 Nginx 的使用技巧,提高你的工作效率。

Nginx 进程结构

Nginx两个核心功能:

  • 反向代理
  • web静态资源服务器

Nginx 进程

  • nginx 会有一个主进程(master进程),和多个工作进程(worker进程)
  • worker进程的数量默认为当前服务器的CPU核心数量(lscpu命令:查看核心数量),可以手动设定
  • 关闭一个worker进程,master进程会重新起来一个worker进程(数量保持和设定值一致)

Nginx 配置文件结构

image.png

Nginx reload 解析

  1. 向master进程发送HUP信号(reload命令)
  2. master进程检查配置语法是否正确
  3. master进程打开监听端口
  4. master进程使用新的配置文件启动新的worker进程
  5. master进程向老的worker进程发送QUIT信号
  6. 旧的worker进程关闭监听,处理完当前连接后关闭进程

总结:

  1. reload为平滑重启,重启期间,用户请求会有老worker进程处理。
  2. 老worker进程处理期间,不会接受新的请求,新的请求全部交由新worker处理。
  3. 老worker进程处理完请求以后,会关闭当前进程。

Nginx 热部署

  1. 确定新版nginx目录和旧版nginx一致
  2. 备份旧nginx文件
  3. kill -s SIGUSR2 20794 启动新进程,此时新老进程并存
  4. kill -s SIGWINCH 20794 关闭老进程的worker进程,但是老进程的master进程不会退出
  5. kill -s SIGQUIT 20794 上面步骤确认无误后,彻底关闭老线程

核心指令

main段核心参数

nginx
# user USERNAME # 解释:指定运行nginx的worker子进程的属主 user nginx; # pid DIR # 解释:指定运行nginx的master主进程的pid文件存放路径 pid /run/nginx.pid; # worker_rlimit_nofile NUMBER 重要 # 解释:指定worker子进程(单个)可以打开的最大文件句柄数 # 备注:linux的进程处理最大文件句柄数为65535,写特别大值没有什么意义。 worker_rlimit_nofile 20480; # worker_rlimit_core SIZE # 解释:指定worker子进程异常终止后的core文件,用于记录分析问题 # 备注:working_directory属于worker进程操作,需要给nginx写的权限 worker_rlimit_core 50M; working_directory /opt/nginx/tmp; # worker_processes NUMBER | auto 重要 # 解释:指定nginx启动的worker子进程数量 worker_processes 4; # worker_cpu_affinity CPUMASK1 CPUMASK2 ... # 解释:将每个worker子进程和CPU物理核心绑定 # 备注:将每个worker子进程与特定CPU物理核心绑定,优势在于:避免同一个worker子进程在不同的CPU核心上切换,缓存失效,降低性能;其不能真正的避免进程切换。 worker_cpu_affinity 0001 0010 0100 1000; # 4个物理核心,4个worker子进程 worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000; # 8个物理核心,8个worker子进程 worker_cpu_affinity 01 10 01 10; # 2个物理核心,4个worker子进程 # worker_priority NUMBER # 解释:指定worker子进程的nice值,以调整运行nginx的优先级,通常设定为负值,以优先调用nginx # 备注:Linux默认进程的优先级值是120,值越小越优先。nice值设定为-20到+19 worker_priority -10; # worker_shutdown_timeout TIME # 解释:指定worker子进程优雅退出时的超时时间 # 备注:防止优雅退出时,某些恶意请求或者请求延时,导致进程一直不会被关闭。 worker_shutdown_timeout 5s; # timer_resolution TIME # 解释:worker子进程内部使用的计时器精度,调整时间间隔越大,系统调用越少,有利于性能提升;反之,系统调用越多,性能下降 worker_resolution 100ms; # daemon on | off # 解释:设定nginx的运行方式,前台还是后台,前台用于调试,后台用于生产 示例:daemon off;

event段核心参数

nginx
# use select | poll | kqueue | epoll | /dev/poll | eventport # 解释:nginx使用何种事件驱动模型 # 备注:推荐不指定,让nginx自己选择 use epoll; # worker_connections NUMBER 重要 # 解释:worker子进程(单个)能够处理的最大并发连接数 #(稍大于65535/4)65535为linux处理的最大句柄,4为worker子进程数量 # 备注:数量不能超过worker_rlimit_nofile字段。ulimit -a 查看linux进程下允许的最大连接数,如果值比较小,需要修改。 worker_connections 17500; # 负载均衡互斥锁 start(accept_mutex,accept_mutex_delay,lock_file) # accept_mutex on | off # 解释:是否打开负载均衡互斥锁 # 备注:http请求到Master主进程时,它会给所有的worker进程发请求,然后由其中一个来接受这个请求,对于没有争抢到的worker进程,会造成性能消耗。开启该功能,Master主进程只会给一个worker进程发起请求,不会全部询问。 accept_mutex on; # accept_mutex_delay TIME # 解释:新连接分配给worker子进程的超时时间 # 备注:被分配的worker子进程如果当前特别繁忙,没有时间进行处理。会在时间段后,转发给其他worker进程进行处理。 accept_mutex_delay 200ms; # lock_file DIR (特别注意,需要放到main中) # 解释:负载均衡互斥锁文件存放路径 lock_file /logs/nginx.lock; # 负载均衡互斥锁 end # multi_accept on | off # 解释:worker子进程可以接收的新连接个数 # 备注:对性能影响不大,linux底层处理已经很快 multi_accept on;

location

location匹配符,优先级依次从高到低

  • = 精确匹配 (locaiton = /images/)
  • ^~ 匹配到即停止搜索 (location ^~ /images/)
  • ~ 正则匹配,区分大小写 (location ~ .(jpg|gif)$)
  • ~* 正则匹配,不区分大小写 (location ~* .(jpg|gif)$)
  • 不带任何符号 (location /)

存在的问题:location 使用=(精确匹配)时,location root 目录无法生效。只有在server 下定义root才会生效,不明白问题原因。

location 带/ 和不带/的区别?

  • location /test 会去找是否有test文件夹,如果没有的话,会去找是否有test文件
  • location /test/ 会去找是否有test文件夹,如果没有的话,不会去找是否有test文件,返回404

server_name

可以指定多个name

server_name name1 name2 name3;

四种匹配方式

备注:如果server_name存在多个,会首先以匹配方式优先级进行展示, 如果匹配方式相同,会根据出现前后的顺序进行展示。

精确匹配 > 左侧通配符匹配 > 右侧通配符匹配 > 正则匹配

核心模块

主要模块

  • stub_status模块 返回nginx目前响应状态和数量 (默认不安装)
  • limit_conn模块 用户限制客户端的并发连接数 (默认安装)
  • limit_req模块 用户限制客户端处理请求的平均速率 (默认安装)
  • access模块 限制特定IP或网段访问 (默认安装)
  • auth_basic模块 限制特定用户访问 (默认安装)
  • auth_request模块 基于http响应状态码做权限控制 (默认不安装)
  • rewrite模块 直接返回状态码或者重定向 (默认安装)
  • autoindex模块 列出目录结构 (默认安装)

return 指令

  • 停止处理请求,直接返回响应码或者重定向到其他URL
  • 执行该指令后,location中后续指令将不会被执行
nginx
# return code [text]; # return code URL; 此时URL可以写绝对路径,相对路径,http,https开头 # return URL; 此时URL只能写http,https开头 return 200 'text'; return 302 /b/;

rewrite 指令

根据指定正则表达式匹配规则

nginx
# rewrite regex replacement [flag] # flag可选值:last(继续匹配location段),break(不再匹配location段),redirect(302),permanent(301) rewrite ^(.*) http://www.cctv.com redirect;

autoindex模块

列出目录结构

nginx
autoindex on | off # 是否打开功能 autoindex_exact_size on | off # 文件大小是否精确到字节 autoindex_format html | xml | json | jsonp # 打开文件的格式 autoindex_localtime on | off # 是否开启本地时间,不开启,则为世界时间

Nginx相关变量

Tcp变量

nginx
remote_addr # 客户端IP地址 remote_port # 客户端端口 server_addr # 服务端IP地址 server_port # 服务端端口 server_protocol # 服务端协议 binary_remote_addr # 二进制格式的客户端IP地址 connection # TCP连接的序号,递增 connection_request # TCP连接的当前请求数量 proxy_protocol_addr # 若使用了proxy_protocol协议,则返回协议中地址,否则返回空 proxy_protocol_port # 若使用了proxy_protocol协议,则返回协议中 端口,否则返回空

Request变量

nginx
uri # 请求的URL,不包含参数 request_uri # 请求的URL,包含参数 scheme # 协议名,http或https request_method # 请求方法 request_length # 全部请求的长度,包括请求行,请求头,请求体 args # 全部参数字符串 arg_参数名 # 特定参数值 is_args # URL中有参数,则返回?;否则返回空 query_string # 与arg相同 remote_user # 由HTTP Basic Authentication协议传入的用户名 request_time # 处理请求已耗费时间 request_completion # 请求处理完成返回OK,否则返回空 server_name # 匹配上请求的server_name https # 若开启https ,则返回on,否则返回空 request_filename # 磁盘文件系统待访问文件的完整路径 document_root # 由URI和root/alias规则生成的文件夹路径 realpath_root # document_root中的软链接换成真实路径 limit_rate # 返回响应的速度上限值

特殊变量

nginx
host # 先看请求行,在看请求头,最后找server_name http_user_agent # 用户浏览器 http_referer # 从哪些链接过来的请求 http_via # 经过一层代理服务器,添加对应代理服务器的信息 http_x_forwarder_for # 获取用户真实IP http_cookie # 用户cookie

root 和 alias的区别

root

image.png

alias

image.png

反向代理

proxy_pass

# proxy_pass URL; # 备注:URL必须以http或者https开头,URL中可以携带变量 proxy_pass http://127.0.0.1:8080; proxy_pass http://127.0.0.1:8080/proxy; location /proxy { proxy_pass http://back_end; } # 路径为:http://back_end/proxy location /proxy { proxy_pass http://back_end/proxy; } # 路径为:http://back_end/proxy
nginx
proxy_method METHOD # 修改请求时的method proxy_http_version 1.0 | 1.1 # 修改请求时的http协议 proxy_set_header field value # 添加http请求头,若已有字段,则直接覆盖 proxy_set_body value # 添加http请求体

upstream

nginx
# 基于hash分配 # hash分配,根据给定的key,将一个请求固定指向一个主机。 # 访问一个固定的uri,后面的所有请求都会分配给一个对应的主机去处理 # 应对场景:集群上面对图片做了临时缓存,同一个资源多次请求,可能会分配到不同的服务器上,导致缓存命中率不高,以及资源时间的浪费。在此类场景下,很适合实用uri_hash策略。 upstream back_end { hash $request_uri; server 118.25.78.138:201; server 118.25.78.138:202; } # 基于ip_hash分配 # 基于用户IP分配,同一个IP只会分配到同一个主机下 # 应对场景:1.用户缓存,session之类的信息都读取同一台主机,会更高效 2.文件分片上传,每次分片可能分配到不同的服务器,导致最后分片无法合并。 upstream back_end { ip_hash; server 118.25.78.138:201; server 118.25.78.138:202; } # 基于主机最少连接数分配 # 基于主机的最少连接数进行分配,优先分配给当前连接数最少的主机。如果连接数都相等的话,会采用轮询的方式进行分配。 # 应用场景:上面的两种分配方式,有一个明显的缺点,没有根据主机当前的连接情况进行分配。假如此时某台主机,处于繁忙状态,此时正好又将请求分配到这台主机,显然这样是不合理的。 upstream back_end { zone test 10M; least_conn; server 118.25.78.138:201; server 118.25.78.138:202; }

server

nginx
# server ADDRESS [parameters]; # ADDRESS 可以使用域名和IP,域名不能用http,或者https开头。 # parameters 可选参数: # weight=number 权重值,默认为1 # max_conns=number 上游服务器的最大并发连接数 # fail_timeout=time 服务器不可用的判断时间(和max_fails配合使用) # max_fails=number 服务器不可用的检查次数(和fail_timeout配合使用) # backup 备份服务器,仅当其它服务器都不可用时,才会使用 # down 标记服务器长期不可用,离线维护 server 127.0.0.1:8080 weight=3 backup;

Nginx代理缓存

优势

使用nginx缓存的好处在于,只要有一个用户请求了某个资源,那么这个资源将会被缓存到nginx上,下次其他用户访问该资源时,nginx将不会去请求上游服务器,会直接读取缓存里的文件。

这样可以有效提升访问效率以及降低上游服务器的访问压力。

缓存指令

nginx
proxy_cache ZONE | off # 使用的代理缓存名称 # proxy_cache_path 设定代理缓存的相关参数(存放路径,名称,缓存详细信息等) # 可选参数 # path:缓存文件的存放路径 # level:path的目录层级 # use_temp_path:off直接使用path路径;on使用proxy_temp_path路径 # keys_zone:name是共享内存名称;size是共享内存大小 # inactive:在指定时间内没有被访问的缓存将会被清理;默认十分钟 # max_size:设定最大的缓存文件大小,超过将有CM进行清理 # manager_files:CM清理一次缓存文件,最大清理文件数;默认100 # manager_sleep:CM清理一次后进程的休眠时间;默认200毫秒 # manager_threshold:CM清理一次最长耗时;默认50毫秒 # loader_files:CL载入文件到共享内存,每批最多文件数;默认100 # loader_sleep:CL加载缓存文件到内存后,进程休眠时间;默认200毫秒 # loader_threshold:CL每次载入文件到共享内存的最大耗时;默认50毫秒 proxy_cache_path /etc/nginx/cache_temp levels=2:2 keys_zone=cache_zone:30m max_size=32g inactive=60m use_temp_path=off; proxy_cache_key STRING # 缓存内容保存的key信息 proxy_cache_valid [code...] TIME # 对哪些响应码进行保存 prxoy_node_cache STRING # 定义哪些内容不会经过缓存

HTTPS

优势

防止响应内容被篡改

数字签名: 将响应内容进行哈希算法加密,生成消息摘要,用私钥加密后传输给客户端。 客户端将收到的响应内容进行哈希算法加密,然后利用公钥解密传来的消息摘要。 两者对比,如果摘要一致,说明信息没有被篡改。

防止服务器的数字签名被篡改

CA会去处理

证书自签

CA搭建命令(服务器A)

bash
cd /etc/pki/CA/ (umask 077; openssl genrsa -out private/cakey.pem 1024) # 生成CA私匙 openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 365 # 生成CA证书请求 # 填写参考: # Country Name (2 letter code) [XX]:CN # State or Province Name (full name) []:Beijing # Locality Name (eg, city) [Default City]:Beijing # Organization Name (eg, company) [Default Company Ltd]:company-https # Organizational Unit Name (eg, section) []:IT # Common Name (eg, your name or your server's hostname) []:myhqq.cn # Email Address []:284942955@qq.com touch index.txt serial # index.txt:证书详细信息 serial:下一个证书编号 echo 01 > serial mkdir csr # 存放证书的文件夹

申请证书(服务器B)

bash
mkdir /etc/nginx/https cd /etc/nginx/https (umask 077; openssl genrsa -out https.key 1024) # 生成服务器私钥 openssl req -new -key https.key -out https.csr # 生成证书签发请求 # 填写参考: # Country Name (2 letter code) [XX]:CN # State or Province Name (full name) []:Beijing # Locality Name (eg, city) [Default City]:Beijing # Organization Name (eg, company) [Default Company Ltd]:https-test # Organizational Unit Name (eg, section) []:IT # Common Name (eg, your name or your server's hostname) []:www.myhqq.cn # Email Address []:284942955@qq.com # Please enter the following 'extra' attributes # to be sent with your certificate request # A challenge password []: 直接回车 # An optional company name []: 直接回车 scp https.csr root@129.211.61.3:/etc/pki/CA/csr/ # 将证书请求放到签发CA的服务器A下

签发证书(服务器A)

bash
vim /etc/pki/tls/openssl.cnf # 修改配置文件 # For the CA policy [ policy_match ] countryName = match stateOrProvinceName = optional 省份无需一致 organizationName = optional 组织名称无需一致 organizationalUnitName = optional commonName = supplied emailAddress = optional cd /etc/pki/CA/ openssl ca -in csr/https.csr -out https.crt -days 365 # 签发证书 scp https.crt root@118.25.78.138:/etc/nginx/https # 将签发后的证书转发给服务器B

Nginx配置HTTPS

配置方式1:同时监听80和443端口

nginx
server { listen 80; 监听80端口 listen 443 ssl; 监听443端口 ssl_certificate "/etc/nginx/https/https.crt"; ssl_certificate_key "/etc/nginx/https/https.key"; ssl_session_cache shared:SSL:1m; ssl_session_timeout 10m; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; server_name square-test.myhqq.cn; location / { root /data/square-test; try_files $uri /$uri /index.html; } }

配置方式2:80端口重定向到443端口,确保使用https

nginx
server { listen 80; server_name square-test.myhqq.cn; return 301 https://$host$request_uri; } server { listen 443 ssl http2; 监听443端口 并且启用http2.0 ssl_certificate "/etc/nginx/https/https.crt"; ssl_certificate_key "/etc/nginx/https/https.key"; ssl_session_cache shared:SSL:1m; ssl_session_timeout 10m; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; server_name square-test.myhqq.cn; location / { root /data/square-test; try_files $uri /$uri /index.html; } }

本文作者:BARM

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!