Nginx 是什么?
NGINX 为世界上最繁忙的网站加速内容和应用的交付过程,并提高安全性、可用性和可扩展性。NGINX是用于 Web 服务、负载均衡、反向代理、内容缓存、媒体流传输等场景的开源软件,且F5 NGINX 提供云原生的、Kubernetes 友好的开源和商业解决方案,如今已成为全世界最流行的 web 服务器!
这是 Nginx 站点上的 description,可以了解到:
- Nginx 是一个 web 服务器
- Nginx 提供了负载均衡、反向代理、内容缓存、媒体流传输等场景
为什么要学习 Nginx
对于前端同学来说
前端项目最终打包完后生成的是 index.html 和一些相关的资源。这些资源没法直接用于访问,于是我们需要一个服务器来提供服务,Nginx 就是一个 web 服务器
对于后端同学来说
后端的算力是寸土寸金的,我们期望更多的能力用来处理业务,Nginx 是一个可以实现动静分离的服务器。
动静分离是将网站静态资源(html,javascript,css,img等文件)与后台应用分开部署,提高用户访问静态代码的速度,降低对后台应用访问
Nginx 的优点
- 一种轻量级的web服务器
- 设计思想是事件驱动的异步非阻塞处理(类node.js)
- 占用内存少、启动速度快、并发能力强
- 扩展性好,第三方插件非常多
- 在互联网项目中广泛应用
Nginx 的概念
反向代理
正向代理和反向代理
正向代理
正向代理一般用于用户无法直接访问目标服务器,需要一个代理服务器来访问。这种情况下代理服务器在作用上等于一个用户,由他发起真正的请求,获取真正的响应,然后将结果告诉用户。(是站在用户这边的)
反向代理
反向代理一般是用于保护真实服务器的,反向代理隐藏了真实服务器的地址,用户只与代理服务器交互,一定程度上保护了真实服务器
配置反向代理
server {
listen 8080;
server_name localhost;
location / {
root html; # Nginx默认值
index index.html index.htm;
}
proxy_pass http://localhost:8000; # 反向代理配置,请求会被转发到8000端口
}
负载均衡
负载均衡场景
当公司的业务增长到一定量时,就会需要多台服务器(服务器集群)来支持请求。但是用户不会去记多个服务器的地址,用户只期望有一个入口。这种场景就需要负载均衡来处理。
在服务器集群中,请求不是绝对平均的访问到每一台服务器,而是相对平均或者更具权重来处理。
负载均衡内容
- 分摊了请求压力
- 保证用户访问的稳定性
- Nginx 带有健康检查,会定期的轮训各个服务器,避免出现请求打到异常服务器的情况
# 负载均衡:设置domain
upstream domain {
server localhost:8000;
server localhost:8001;
}
server {
listen 8080;
server_name localhost;
location / {
# root html; # Nginx默认值
# index index.html index.htm;
proxy_pass http://domain; # 负载均衡配置,请求会被平均分配到8000和8001端口
proxy_set_header Host $host:$server_port;
}
}
Nginx 命令
Nginx 常用命令
- nginx:启动服务
- nginx -s stop:关闭服务
- nginx -s reload:重启
- pkill -9 nginx:强制重启
Nginx 配置
#进程, 可更具cpu数量调整
worker_processes 1;
events {
#连接数
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
#连接超时时间,服务器会在这个时间过后关闭连接。
keepalive_timeout 10;
# gizp压缩
gzip on;
# 直接请求nginx也是会报跨域错误的这里设置允许跨域
# 如果代理地址已经允许跨域则不需要这些, 否则报错(虽然这样nginx跨域就没意义了)
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers X-Requested-With;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
# srever模块配置是http模块中的一个子模块,用来定义一个虚拟访问主机
server {
listen 80;
server_name localhost;
# 根路径指到index.html
location / {
root html;
index index.html index.htm;
}
# localhost/api 的请求会被转发到192.168.0.103:8080
location /api {
rewrite ^/b/(.*)$ /$1 break; # 去除本地接口/api前缀, 否则会出现404
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://192.168.0.103:8080; # 转发地址
}
# 重定向错误页面到/50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
进程配置
worker_processes 8; # Nginx 进程数,建议按照CPU数目来指定,一般为它的倍数 (如:2个四核的CPU计为8)
worker_rlimit_nofile 65535; #一个Nginx 进程打开的最多文件描述符数目
worker_connections 65535;#每个进程允许的最多连接数
http配置
http {
sendfile on # 高效传输文件的模式 一定要开启
keepalive_timeout 65 # 客户端服务端请求超时时间
# 直接请求nginx也是会报跨域错误,这里设置允许跨域
# 如果代理地址已经允许跨域则不需要这些, 否则报错(虽然这样nginx跨域就没意义了)
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers X-Requested-With;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
}
server 配置
server {
listen 80; # 监听端口
server_name dev1-cd.hongsong.club; # 域名 Host
# path
location / {
proxy_pass http://127.0.0.1:10086/; # 代理配置
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
一些常见配置
反向代理
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend_server:8080; # 后端 Java 服务
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
负载均衡
http {
upstream backend {
least_conn; # 每次选择当前连接数最少的服务器
server backend1.example.com weight=6;
server backend2.example.com weight=3;
server backend3.example.com weight=2;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
}
}
}
动静态分离
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://app_server:8000;
}
location /static/ {
alias /var/www/static_content/;
}
}
缓存代理
http {
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;
server {
listen 80;
server_name example.com;
location / {
proxy_cache my_cache;
proxy_pass http://backend_server:8080;
add_header X-Cache-Status $upstream_cache_status;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
}
}
}
限制IP访问
server {
listen 80;
server_name example.com;
location / {
allow 192.168.1.0/24; # 允许内部网段
deny all; # 拒绝其他地址
proxy_pass http://backend_server:8080;
}
}
Http 认证
server {
listen 80;
server_name example.com;
location /secure/ {
auth_basic "Restricted Area";
auth_basic_user_file /etc/nginx/.htpasswd;
}
}
WS 代理
server {
listen 80;
server_name example.com;
location /ws/ {
proxy_pass http://websocket_server:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
}
请求限制
http {
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=1r/s; # 每秒最多1个请求
server {
listen 80;
server_name example.com;
location / {
limit_req zone=mylimit burst=5; # 突发请求最多5个
proxy_pass http://backend_server:8080;
}
}
}
请求重定向
server {
listen 80;
server_name example.com;
location /old-page {
return 301 https://example.com/new-page; # 301 永久重定向
}
}
HTTPS
server {
listen 443 ssl;
server_name secure.example.com;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
root /var/www/secure_html;
index index.html;
}
}
ssl_certificate和 ssl_certificate_key :定义SSL证书和私钥文件路径。
ssl_protocols和 ssl_ciphers :配置支持的SSL协议和加密套件,确保连接的安全性。
基本前端服务(qiankun子应用)
server {
listen 8000;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
try_files $uri $uri/ /index.html; # 尝试文件,如果没有找到则返回 index.html
add_header Access-Control-Allow-Origin *;
}
# location ~* .(css|js|html)$ {
# root html;
# index index.html;
# add_header Access-Control-Allow-Origin *;
# }
location ~* .(gif|jpg|jpeg|bmp|png|ico|txt|js|css)$ {
rewrite ^/APC_WEBWATCH/(.*)$ /$1 last;
add_header Access-Control-Allow-Origin *;
}
# 匹配 .html 文件,保持原样请求
location ~* .html$ {
# 不需要任何额外的配置,只是确保这个 location 块存在
add_header Access-Control-Allow-Origin *;
}
location /APC_WEBWATCH/inter-api {
proxy_pass http://10.30.71.205:10676/inter-api; # 替换为后端服务器的地址和端口
proxy_set_header Host $host; # 保持主机头
proxy_set_header X-Real-IP $remote_addr; # 真实的客户端 IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 转发的IP
proxy_set_header X-Forwarded-Proto $scheme; # 转发的协议
}
location /inter-api {
proxy_pass http://10.30.71.205:10676; # 替换为后端服务器的地址和端口
proxy_set_header Host $host; # 保持主机头
proxy_set_header X-Real-IP $remote_addr; # 真实的客户端 IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 转发的IP
proxy_set_header X-Forwarded-Proto $scheme; # 转发的协议
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
详细配置
# 启动进程,通常设置成和cpu的数量相等
worker_processes 1;
# 全局错误日志定义类型,[debug | info | notice | warn | error | crit]
error_log logs/error.log;
error_log logs/error.log notice;
error_log logs/error.log info;
# 进程pid文件
pid /var/run/nginx.pid;
# 工作模式及连接数上限
events {
# 仅用于linux2.6以上内核,可以大大提高nginx的性能
use epoll;
# 单个后台worker process进程的最大并发链接数
worker_connections 1024;
# 客户端请求头部的缓冲区大小
client_header_buffer_size 4k;
# keepalive 超时时间
keepalive_timeout 60;
# 告诉nginx收到一个新连接通知后接受尽可能多的连接
# multi_accept on;
}
# 设定http服务器,利用它的反向代理功能提供负载均衡支持
http {
# 文件扩展名与文件类型映射表义
include /etc/nginx/mime.types;
# 默认文件类型
default_type application/octet-stream;
# 默认编码
charset utf-8;
# 服务器名字的hash表大小
server_names_hash_bucket_size 128;
# 客户端请求头部的缓冲区大小
client_header_buffer_size 32k;
# 客户请求头缓冲大小
large_client_header_buffers 4 64k;
# 设定通过nginx上传文件的大小
client_max_body_size 8m;
# 开启目录列表访问,合适下载服务器,默认关闭。
autoindex on;
# sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,对于普通应用,
# 必须设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为 off,以平衡磁盘与网络I/O处理速度
sendfile on;
# 此选项允许或禁止使用socke的TCP_CORK的选项,此选项仅在使用sendfile的时候使用
#tcp_nopush on;
# 连接超时时间(单秒为秒)
keepalive_timeout 65;
# gzip模块设置
gzip on; #开启gzip压缩输出
gzip_min_length 1k; #最小压缩文件大小
gzip_buffers 4 16k; #压缩缓冲区
gzip_http_version 1.0; #压缩版本(默认1.1,前端如果是squid2.5请使用1.0)
gzip_comp_level 2; #压缩等级
gzip_types text/plain application/x-javascript text/css application/xml;
gzip_vary on;
# 开启限制IP连接数的时候需要使用
#limit_zone crawler $binary_remote_addr 10m;
# 指定虚拟主机的配置文件,方便管理
include /etc/nginx/conf.d/*.conf;
# 负载均衡配置
upstream aaa {
# 请见上文中的五种配置
}
# 虚拟主机的配置
server {
# 监听端口
listen 80;
# 域名可以有多个,用空格隔开
server_name www.aaa.com aaa.com;
# 默认入口文件名称
index index.html index.htm index.php;
root /data/www/sk;
# 图片缓存时间设置
location ~ .*.(gif|jpg|jpeg|png|bmp|swf)${
expires 10d;
}
#JS和CSS缓存时间设置
location ~ .*.(js|css)?${
expires 1h;
}
# 日志格式设定
#$remote_addr与 $http_x_forwarded_for用以记录客户端的ip地址;
#$remote_user:用来记录客户端用户名称;
#$time_local:用来记录访问时间与时区;
#$request:用来记录请求的url与http协议;
#$status:用来记录请求状态;成功是200,
#$body_bytes_sent :记录发送给客户端文件主体内容大小;
#$http_referer:用来记录从那个页面链接访问过来的;
log_format access '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $http_x_forwarded_for';
# 定义本虚拟主机的访问日志
access_log /usr/local/nginx/logs/host.access.log main;
access_log /usr/local/nginx/logs/host.access.404.log log404;
# 对具体路由进行反向代理
location /connect-controller {
proxy_pass http://127.0.0.1:88;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
# 后端的Web服务器可以通过X-Forwarded-For获取用户真实IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
# 允许客户端请求的最大单文件字节数
client_max_body_size 10m;
# 缓冲区代理缓冲用户端请求的最大字节数,
client_body_buffer_size 128k;
# 表示使nginx阻止HTTP应答代码为400或者更高的应答。
proxy_intercept_errors on;
# nginx跟后端服务器连接超时时间(代理连接超时)
proxy_connect_timeout 90;
# 后端服务器数据回传时间_就是在规定时间之内后端服务器必须传完所有的数据
proxy_send_timeout 90;
# 连接成功后,后端服务器响应的超时时间
proxy_read_timeout 90;
# 设置代理服务器(nginx)保存用户头信息的缓冲区大小
proxy_buffer_size 4k;
# 设置用于读取应答的缓冲区数目和大小,默认情况也为分页大小,根据操作系统的不同可能是4k或者8k
proxy_buffers 4 32k;
# 高负荷下缓冲大小(proxy_buffers*2)
proxy_busy_buffers_size 64k;
# 设置在写入proxy_temp_path时数据的大小,预防一个工作进程在传递文件时阻塞太长
# 设定缓存文件夹大小,大于这个值,将从upstream服务器传
proxy_temp_file_write_size 64k;
}
# 动静分离反向代理配置(多路由指向不同的服务端或界面)
location ~ .(jsp|jspx|do)?$ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:8080;
}
}
}
gzip 压缩
# gzip模块设置
gzip on; #开启gzip压缩输出
gzip_min_length 1k; #最小压缩文件大小
gzip_buffers 4 16k; #压缩缓冲区
gzip_http_version 1.0; #压缩版本(默认1.1,前端如果是squid2.5请使用1.0)
gzip_comp_level 2; #压缩等级
# 设置什么类型的文件需要压缩
gzip_types text/plain application/x-javascript text/css application/xml;
# 用于设置使用Gzip进行压缩发送是否携带“Vary:Accept-Encoding”头域的响应头部
# 主要是告诉接收方,所发送的数据经过了Gzip压缩处理
gzip_vary on;
基本配置
worker_processes auto; // 处理进程
worker_connections 65535; // 最大并发链接数
keepalive_timeout 75s; // 连接超时时间
gzip on; // 是否开启压缩传输
gzip_min_length 1kb; // 最小压缩文件
gzip_comp_level 2; // 压缩率
client_max_body_size 50mb; // 最大上传文件
server_names_hash_bucket_size 512; // 服务器名字的hash表大小
client_header_buffer_size 32kb; // 客户端请求头buffer大小
client_body_buffer_size 512kb; // 请求主体缓冲区
一些常见的正则匹配式
静态资源
location ~* .(gif|jpg|jpeg|bmp|png|ico|txt|js|css)$ {
rewrite ^/xpt-supgpt-unmanned-factory/(.*)$ /$1 last;
root /usr/share/nginx/html;
}
请求代理
location ^~ /api/ {
proxy_pass http://backend_service;
}
HTML 文件
location ~* .html$ {
root /var/www/html;
}
特定路径(例如/about和/contact)
location ~ ^/(about|contact)$ {
# 处理关于和联系方式请求
}
缓存相关
强缓存
强缓存是在请求和响应的生命周期内,直接从浏览器的缓存中获取数据,而不需要向服务器发送请求。主要涉及以下两种HTTP头:
Cache-Control:指示浏览器如何缓存资源。
-
max-age:定义资源在缓存中可以保留的时间(秒),如Cache-Control: max-age=3600表示资源可以缓存一小时。public/private:public允许任何缓存,private只允许用户的浏览器缓存。
Expires:过期时间,表示资源的有效期,较早的缓存机制,现在大多用于兼容性。
location /images/ {
expires 30d; # 设置强缓存过期时间为30天
add_header Cache-Control "public, max-age=2592000"; # 最大缓存时间为30天
}
协商缓存
协商缓存是一种动态的缓存机制,当强缓存过期后,浏览器会向服务器发送请求,询问资源是否被修改。主要是通过以下两个HTTP头实现:
location /api/ {
add_header Last-Modified $date_gmt; # 添加Last-Modified头
add_header ETag "$request_time"; # 添加ETag头
expires epoch; # 禁用强缓存
}
文件缓存
http {
open_file_cache max=1000 inactive=20s; # 最大缓存1000个文件,20秒无访问后淘汰
open_file_cache_valid 30s; # 30秒内不会重新打开文件
}
重定向
return
server {
listen 80;
server_name example.com www.example.com;
return 301 https://example.com$request_uri;
}
rewrite
server {
listen 80;
server_name example.com;
location / {
rewrite ^/old-path(.*)$ /new-path$1 permanent;
}
}
结合条件重定向
server {
listen 80;
server_name example.com;
if ($http_user_agent ~* "iPhone") {
rewrite ^/(.*)$ /mobile/$1 redirect;
}
}