- 作者:老汪软件技巧
- 发表时间:2024-10-16 10:03
- 浏览量:
厚积薄发,静水流深,今天介绍nginx的一些使用
基本配置文件
# 工作进程, 启动nginx时启动多少个进程
worker_processes auto;
# 事件驱动模块
events {
# 每个work可以创建多少个连接
worker_connections 1024;
}
http {
# 引入外部文件, mime.types : 文件类型的对应关系, 告诉客户端(浏览器)以什么方式打开文件, 如果没有对应关系, 则会弹出下载提示框
# /etc/nginx/mime.types 文件中定义了各种文件扩展名对应的 MIME 类型。
include /etc/nginx/mime.types;
# 默认 MIME 类型,当找不到匹配的 MIME 类型时使用
# application/octet-stream 表示未知文件类型的二进制流。
default_type application/octet-stream;
# 是否开启数据零拷贝, 以提高静态文件传输效率
# sendfile 指令打开时,Nginx 会直接从内核缓存读取文件,提高性能。
sendfile on;
# 设置 keepalive 超时时间
keepalive_timeout 65;
# 指定客户端与服务器之间的空闲连接保持时间为 65 秒,节省资源。
# 虚拟主机配置
server {
# 监听 80 端口(HTTP 默认端口)
listen 80;
# 设置服务器名称, server_name 指定服务器的主机名,这里是 localhost
server_name localhost;
# 配置静态文件访问
location /wwjfiles/ {
# 将 /wwjfiles/ 请求映射到服务器根目录 /
# 例如,请求 /wwjfiles/file.txt 实际会访问服务器根目录下的 /wwjfiles/file.txt 文件。
root /; # 映射请求路径到实际文件路径
# 开启目录浏览功能
autoindex on;
# autoindex on 时,如果访问的路径是目录而没有 index 文件,Nginx 会生成该目录的文件列表页面。
}
# 根路径的请求处理
location / {
# 将请求的根路径映射到 /usr/share/nginx/html 目录
root /usr/share/nginx/html;
# 请求 / 时,会访问 /usr/share/nginx/html目录下的文件。
# 默认的首页文件设置
index index.html index.htm;
# 当访问根路径时,Nginx 会查找 index.html 或 index.htm 文件来响应请求。
}
# 错误页面的自定义设置
error_page 500 502 503 504 /50x.html;
# 如果出现 500, 502, 503 或 504 错误,Nginx 会显示 /50x.html 页面。
# 定义具体的错误页面响应处理
location = /50x.html {
# 设置错误页面的实际路径
root /usr/share/nginx/html;
# 500 系列错误页面将显示 /usr/share/nginx/html/50x.html 文件的内容。
}
}
# 可选:引入其他服务器配置文件
# include /etc/nginx/conf.d/*.conf;
# 使用 include 指令引入 /etc/nginx/conf.d 目录下的所有 .conf 文件,实现模块化配置。
}
hosts文件配置域名解析
服务器已经安装了nginx, 并且监听80端口:
# 虚拟主机配置
server {
listen 80;
server_name localhost;
location /wwjfiles/ {
root /;
}
}
如果在服务器的hosts文件中配置了域名, 那么请求网络资源时, 首先会去hosts文件中查找是否有该域名的对应IP, 如果有, 直接请求该路径, 如果没有, 再去请求公共的DNS查询IP
例如, 在服务器的hosts文件中追加该配置:
然后使用 curl tcwwjdr/wwjfiles/ip.txt 测试请求, 直接拿到了/wwjfiles目录下的ip.txt文件
虚拟主机原理
Nginx 的虚拟主机是一种技术,通过一个物理服务器运行多个网站或应用程序。这可以通过共享一个 IP 地址来实现,也可以通过使用不同的 IP 地址和端口进行区分。
Nginx 支持三种类型的虚拟主机:基于域名的虚拟主机、基于 IP 的虚拟主机和基于端口的虚拟主机。
基于域名的虚拟主机
基于域名的虚拟主机是 Nginx 最常用的一种虚拟主机方式。当服务器根据客户端的请求头中的 Host 字段来选择具体服务的站点时,就会使用这种方式。
工作原理示例
# 虚拟主机1,服务域名为 www.example.com
server {
listen 80;
server_name www.example.com;
location / {
root /var/www/example1;
index index.html;
}
}
# 虚拟主机2,服务域名为 www.test.com
server {
listen 80;
server_name www.test.com;
location / {
root /var/www/example2;
index index.html;
}
}
解释通配符匹配
监听所有以结尾的请求:
# 虚拟主机1,服务域名为 *.example.com
server {
listen 80;
server_name *.example.com;
...
}
监听所有以开头的请求:
# 虚拟主机1,服务域名为 *.example.com
server {
listen 80;
server_name www.example.*;
...
}
正则匹配
# 虚拟主机1,服务域名为 *.example.com
server {
listen 80;
# 正则匹配使用 ~ 前缀来指定
server_name ~^[0-9]+.mmban.com$;
...
}
基于端口的虚拟主机
基于端口的虚拟主机是通过为不同的应用分配不同的端口来实现的。可以在同一台服务器上,使用不同的端口号提供不同的网站或应用。
工作原理示例
# 虚拟主机1,监听80端口
server {
listen 80;
...
}
# 虚拟主机2,监听8080端口
server {
listen 8080;
...
}
解释基于 IP 的虚拟主机--了解
基于 IP 的虚拟主机方式较少使用,它依赖于为每个虚拟主机(网站或应用)分配一个独立的 IP 地址。通过服务器监听不同的 IP 地址,来为不同的 IP 提供不同的网站服务。
工作原理示例
# 虚拟主机1,监听 192.168.1.10
server {
listen 192.168.1.10:80;
location / {
root /var/www/example1;
index index.html;
}
}
# 虚拟主机2,监听 192.168.1.11
server {
listen 192.168.1.11:80;
location / {
root /var/www/example2;
index index.html;
}
}
解释反向代理代理和反向代理
代理(正向代理)是代表客户端向服务器发送请求的中介,常用于隐藏客户端的真实IP地址或提供缓存服务。
反向代理与代理相反,它代表服务器接收客户端请求,可以实现负载均衡、SSL终端等功能。
简单来说,代理用于替代请求,而反向代理用于保护和优化服务器。
正向代理和反向代理都需要可以通过nginx来实现, 具体是哪个, 需要通过用途来区分, 隐藏服务器就是方向代理, 隐藏客户端就是正向代理
请求转发URL匹配转发
需要在server块下的location里配置proxy_pass, 和root选项是二选一, 只会有一个生效
如下配置, 会将所有80的请求全部转发到192.168.0.113:8080, 例如请求192.168.0.113:80/test/test, 服务器会转发到192.168.0.113:8080/test/test
server {
listen 80;
server_name localhost;
location / {
# 所有80的请求全部转发到192.168.0.113:8080
proxy_pass http://192.168.0.113:8080;
}
}
URL匹配替换再转发
server {
listen 80;
server_name localhost;
location ~ ^/api/(.*)$ { # 使用正则表达式匹配 /api/ 开头的请求
rewrite ^/api/(.*)$ /$1 break; # 将 /api/xxx 路径重写为 /xxx
proxy_pass http://192.168.0.113:8080;
proxy_set_header Host $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; # 添加协议类型
}
}
说明:
1, ~ 表示正则表达式匹配。
2, ^/api/(.*)$ 匹配 /api/ 后的任何内容。
3, /$1 是正则表达式中的捕获组。在 rewrite 指令中,$1 代表匹配正则表达式括号中的第一个捕获组。例如上例中, ^/api/(.*)$ 这个正则表达式匹配以 /api/ 开头的 URL,其中 (.*) 表示捕获任意字符并放入第一个捕获组。
4, proxy_set_header Host $host;
作用:修改转发请求的 Host 头部。
含义:将客户端请求中的 Host 头部信息传递给后端服务器。$host 是 Nginx 内置的变量,表示请求中的主机名(通常是域名)。这对于后端服务器识别请求的原始域名非常重要。
5, proxy_set_header X-Real-IP $remote_addr;
作用:将客户端的真实 IP 地址传递给后端服务器。
含义:$remote_addr 是客户端的真实 IP 地址,Nginx 会把它写入 X-Real-IP 头部,这样后端服务器就可以获取到发起请求的真实客户端 IP 地址。
6, proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
作用:在 X-Forwarded-For 头部中记录请求经过的 IP 地址。
含义:X-Forwarded-For 是一个标准的 HTTP 头部,用来记录客户端的原始 IP 地址以及经过的所有代理服务器的 IP 地址。$proxy_add_x_forwarded_for 是一个特殊的 Nginx 变量,它会在原有的 X-Forwarded-For 值后面添加当前请求的 IP 地址。
7, proxy_set_header X-Forwarded-Proto $scheme;
作用:将请求的协议类型传递给后端服务器。
含义:$scheme 是 Nginx 的内置变量,表示客户端使用的协议(http 或 https)。通过在 X-Forwarded-Proto 头部中传递这个值,后端服务器可以知道请求是通过 HTTP 还是 HTTPS 发送的。
负载均衡
负载均衡是一种分配网络流量到多个服务器的技术,以提高性能和可用性。其主要目的是防止单个服务器过载,从而提高系统的可靠性和响应速度。
使用负载均衡可以提高系统的可扩展性和故障恢复能力,常见于高流量网站和应用中。
负载均衡通常通过以下几种方式实现:
轮询:将请求依次分配给每台服务器,简单易实现,但对每台服务器的负载无法考虑。最少连接:将请求发送到当前连接数最少的服务器,适用于连接持续时间不均匀的情况。加权轮询:为每台服务器分配权重,根据权重轮询分配请求,适用于性能差异明显的服务器。IP哈希:根据客户端IP地址计算哈希值,将请求分配到特定服务器,确保同一客户端总是连接到同一台服务器。健康检查:负载均衡器定期检查各个服务器的状态,确保只有健康的服务器接收请求。轮询
nginx配置, 所有请求192.168.0.113:80/test/test会被负载均衡到 192.168.0.113:8080/tset/test 和192.168.0.118:8080/tset/test
upstream target {
server 192.168.0.113:8080;
server 192.168.0.118:8080;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://target;
}
}
权重
权重, 10次中, 差不多有8次访问113, 差不多有2次机会访问118
这个 8次 和 2次 并不是绝对精准的,而是大致的比例。Nginx 的负载均衡是基于权重的概率分配,而不是严格按照每 10 次请求一定有 8 次发送到 192.168.0.113,2 次发送到 192.168.0.118。
upstream target {
server 192.168.0.113:8080 weight=8;
server 192.168.0.118:8080 weight=2;
}
...
不常用--down
服务下线, 不可用, 如下配置, 服务不会经过 113 和 115 :
upstream target {
server 192.168.0.113:8080 weight=8 down;
server 192.168.0.115:8080 down;
server 192.168.0.118:8080 weight=2;
server 192.168.0.120:8080 weight=3;
}
...
不常用--backup
如下配置, 120备用服务器, 当113 和 118 都不可用时(比如宕机或出现故障),请求才会被转发到 120 :
upstream target {
server 192.168.0.113:8080 weight=8;
server 192.168.0.118:8080 weight=2;
server 192.168.0.120:8080 backup;
}
...
静态文件
通过nginx转发到指定目录下获取静态资源
静态文件配置
# 使用 root
location /wwjfiles {
root /; # 请求 /wwjfiles/logo.png 被解析为 /wwjfiles/logo.png
}
# 使用 alias
location /wwjfiles {
alias /; # 请求 /wwjfiles/logo.png 被解析为 /logo.png , 该配置下想访问 /wwjfiles/logo.png, 需要请求 /wwjfiles/wwjfiles/logo.png
}
正则表达式配置
如下配置, 静态资源(js/css/图片)都直接从 目录 /html里获取, 接口转发到 192.168.0.113:8080 服务
server {
listen 80;
server_name localhost;
# 配置静态文件访问
location /js {
# 将 /js 请求映射到服务器目录 /html/js
root /html;
}
# 配置静态文件访问
location /css {
# 将 /css 请求映射到服务器目录 /html/css
root /html;
}
# 配置静态文件访问
location /img {
# 将 /img 请求映射到服务器目录 /html/img
root /html;
}
}
使用正则配置前面的动静分离配置
server {
listen 80;
server_name localhost;
# 配置静态文件访问
# ~表示开始正则匹配
# *表示不区分大小写
# /(js|css|img): 这是正则表达式,表示 URI 中包含 js、css 或 img 的请求都会被匹配到。| 是逻辑“或”操作符
location ~*/(js|css|img) {
# 将 /js 请求映射到服务器目录 /html
root /html;
}
}
URL Rewrite内部重写(rewrite指令)
内部重写意味着在Nginx内部改变请求的URL,而不会通知客户端,最终返回的资源仍然来自新的URL。Nginx会匹配到新的URL,并根据新的URL继续处理请求。
基本语法
rewrite <正则表达式> <替换后的URL> [flag];
常见的flag示例 1: 简单URL重写
假设你想将/blog/开头的请求重写到/news/路径。
server {
listen 80;
server_name example.com;
location / {
rewrite ^/blog/(.*)$ /news/$1 last;
}
}
解释:
例子:
示例 2: 根据条件重写URL
使用条件判断来有选择性地进行重写,例如当客户端的User-Agent是手机设备时,重写URL到移动版页面。
server {
listen 80;
server_name example.com;
if ($http_user_agent ~* "Mobile") {
rewrite ^/$ /mobile/ last;
}
}
解释:
例子:
外部重定向(return或rewrite带redirect)
外部重定向意味着服务器会告诉客户端URL已改变,并让客户端自行发起新的请求。通常这会伴随着HTTP 301或302状态码。
rewrite带redirect, rewrite指令也可以通过redirect标志触发外部重定向。
示例 1: 301永久重定向
将/old-page的请求永久重定向到/new-page。
server {
listen 80;
server_name example.com;
location / {
rewrite ^/old-page$ /new-page permanent;
}
}
解释:
例子:
示例 2: return指令实现302临时重定向
return指令也可用于实现重定向,例如临时重定向(302),不需要复杂的正则表达式匹配时使用。
server {
listen 80;
server_name example.com;
location / {
return 302 http://example.com/temp-page;
}
}
解释:
例子:
综合使用rewrite与location
rewrite常与location指令结合使用,达到精细化控制重写的目的。
示例 1: 针对特定路径的重写
server {
listen 80;
server_name example.com;
location /products {
rewrite ^/products/(.*)/details$ /new-products/$1/details last;
}
}
解释:
例子:
示例 2: 重定向根目录到特定页面
server {
listen 80;
server_name example.com;
location / {
rewrite ^/$ /home permanent;
}
}
解释:
例子: