1. Nginx编译安装
- nginx-1.18.0.tar.gz
#!/bin/bash
GREEN='echo -e \033[1;32m'
RED='echo -e \033[1;31m'
END='\033[0m'
DIR='nginx-1.18.0'
PKG=$DIR.tar.gz
#1. download src code
wget -qP /usr/local/src http://nginx.org/download/nginx-1.18.0.tar.gz
#2. create nginx user
id nginx && $REDnginx already exists!$END &> /dev/null || useradd -s /sbin/nologin -r nginx
#3. install dependencies
yum -y install gcc pcre-devel openssl-devel zlib-devel &> /dev/null
#4. uncompress nginx.tar.gz
cd /usr/local/src
tar -xf $PKG
#5. compile nginx
cd $DIR
./configure --prefix=/apps/nginx \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--with-pcre \
--with-stream \
--with-stream_ssl_module \
--with-stream_realip_module
#6. make && make install
make && make install
#7. modify access
chown -R nginx.nginx /apps/nginx
#8. create soft-link
ln -s /apps/nginx/sbin/* /usr/sbin
#9. backup conf
cp /apps/nginx/conf/nginx.conf{,.bak}
#10. setup pid folder
mkdir /apps/nginx/run
sed -ri 's@^#(pid).*@\1 /apps/nginx/run/nginx.pid;@' /apps/nginx/conf/nginx.conf
#11. create service unit
cat > /lib/systemd/system/nginx.service <
2. Nginx核心配置
2.1 配置文件说明
- 主配置文件结构: 四部分
# main block: 主配置项, 即全局配置端, 对http, mail都有效
#事件驱动相关的配置
event {
}
# http/https 协议相关配置端
http {
}
# 默认配置文件不包括下面两个语句块
# mail 协议相关配置段
mail {
}
# stream 服务器相关配置段
stream {
}
2.2 全局配置
- 全局配置段常见的配置指令分类
正常运行必备的配置
优化性能相关配置
用于调式及定位问题相关的配置
事件驱动相关的配置
- 全局配置说明
user nobody [nobody];
# 启动nginx工作进程的用户和组, 如果编译时指定了运行用户, 那么这里可以注释掉, 或者改成和编译选项一致
worker_processes [number | auto];
# 启动nginx worker进程的数量, 一般设为和cpu核心数相同, 充分利用cpu, 避免进程间竞争资源
# 同时并且配合worker_cpu_affinity指令, 把工作进程绑定到指定的cpu核心上, 避免进程在不同的cpu核心来回跳转, 导致需要重新加载进程信息到新的cpu缓存, 带来性能损失
# 可以手动指定开启几个工作进程, 也可使用auto, 自动按照cpu核心数去开启对应数目的worker进程
worker_cpu_affinity 00000001 00000010 00000100 00001000 ...;
# 将nginx工作进程绑定到指定的cpu核心, 默认nginx是不进行进程绑定的, 绑定并不是意味着当前nignx进程独占一核心cpu, 别的进程也可以跑在这核cpu, 只是nginx该worker进程必须跑在该cpu
# 但是可以保证此进程不会允许在其他cpu核心上, 这就极大减少了nginx的工作进程在不同的cpu核心上的来回跳转, 减少了cpu对进程的资源分配和回收以及内存管理等, 因此可以有效地提升nginx服务器的性能
示例:
work_processes 4; # 开启4个worker进程
work_cpu_affinity 00000010 00001000 0010000 10000000; # 进程和第1,3,5,7核cpu进行绑定
[19:51:50 root@nginx ~]#ps axo pid,cmd,psr | grep nginx
927 nginx: master process /apps 0
928 nginx: worker process 1 # 该进程跑在1号cpu
929 nginx: worker process 3
930 nginx: worker process 5
931 nginx: worker process 7
1434 vim /apps/nginx/conf/nginx. 0
1451 grep --color=auto nginx 0
# 可以配合watch命令, 对运行状况进行监控
[19:54:57 root@nginx ~]#watch -n 0.5 'ps axo pid,cmd,psr | grep nginx'
daemon off;
# 让nginx以前台运行, 用于测试, docker等环境
master_process off | on; # 是否开启nginx的master-worker工作模式, 默认为on, off为只用master相应请求, 仅用于开发调试场景
error_log logs/error.log notice;
# 错误日志记录配置, 语法: error_log /PATH/TO/FILE [debug | info | notice | warn | error | crit | alert | emerg]
pid logs/nginx.pid;
# pid文件保存路径, 这里的pid是master的pid
worker_priority 0;
# 工作进程优先级, 默认0, (-20 ~ 19), nice优先级
示例:
[20:05:48 root@nginx ~]#ps axo pid,cmd,ni | grep nginx
927 nginx: master process /apps 0
928 nginx: worker process 0
1434 vim /apps/nginx/conf/nginx. 0
1595 grep --color=auto nginx 0
worker_rlimit_nofile 65536;
# 所有worker进程能打开的文件数量上限, 包括: nginx的所有连接(例如与后端服务器的连接等), 而不仅仅是与客户的的连接
# 另一个考虑因素是实际的并发连接数不能超过系统级别的最大文件打开文件数的限制. 最好与ulimit -n(单个进程能接受的最大连接数×worker进程总数)的值保持一致
示例:
worker_rlimit_nofile 100000;
vim /etc/security/limits.conf # 修改后, 重启服务器生效
* - nproc 100000
* - nofile 100000
events {
worker_connections 1024; # 设置单个工作进程的最大并发连接数, 也要调大
use epoll; # 使用epoll事件驱动, 默认就是epoll, 需要放在events语句块, 否则语法报错
accept_mutex_on; # on为同一时刻一个请求轮流由worker进程处理, 防止同时唤醒所有worker进程, 避免多个睡眠被唤醒的设置; 默认为off, 新请求会唤醒所有worker进程, 此过程也成为'惊群', 因此nginx刚安装完要进行适当的优化, 建议设置为on
multi_accept_on; # on时nginx服务器的每个工作进程可以同时接受多个新的网络连接, 此指令默认为off, 即默认一个工作进程只能一次接受一个新的网络连接, 打开后能同时接受多个, 建议设置为on
}
- 优化项总结
worker_processes [number | auto];
worker_cpu_affinity 00000001 00000010 00000100 00001000 ...;
worker_priority 0;
worker_rlimit_nofile 65536;
vim /etc/security/limits.conf
* - nproc 100000
* - nofile 100000
event{
worker_connections 1024;
use epoll;
accept_mutex_on;
multi_accept_on;
}
需要重启nginx服务
systemctl restart nginx
2.3 http配置块
- http协议相关的配置结构
http {
... # 各server虚拟主机的公共配置
... # 各server虚拟主机的公共配置
server { # 每个server用于定义一个虚拟主机
...
}
server {
...
server_name # 虚拟主机名
root # 主机目录名
alias # 路径别名
location [OPERATOR] URL { # 指定URL的特性
...
if condition {
...
}
}
}
}
- http协议配置说明
http {
include mime.types; # 导入支持的文件类型, 是相对于/apps/nginx/conf的目录
default_type application/octet-stream; # 除mime.types中包括的文件类型, 都默认定义为octet-stream类型,如果通过浏览器访问不属于mime.types定义的文件类型的文件那么浏览器会直接下载
#可以修改默认类型为test/html, 这样即使访问了不属于mime类型的文件, 也会被当做html格式, 直接尝试打开, 而不是下载到本地. 不过不同的浏览器效果不同, 一般谷歌浏览器会直接打开, 有些浏览器还是会直接下载文件
# 日志配置部分
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
# 自定义优化参数
sendfile on;
#tcp_nopush on; # 在开启了sendfile的情况下, 会把多个响应报文合并后统一发送给客户端, 服务器节省了资源, 但是客户端都会有延迟. 需要根据服务器负载情况进行调整, 当负载不高时, 无需开启, 可以直接发给客户端, 当过高时, 可以考虑开启
#tcp_nodelay off; # 在开启了keepalived模式下的连接是否启用tcp_nodelay选项, 当为off时, 延迟0.2s发送, 默认on时, 不延迟发送, 立即发送响应报文给用户
#keepalive_timeout 0;
keepalive_timeout 65 65; # 设置会话保持时间, 第二个值为响应首部: keep-alived:timeout=65, 可以和第一个值不同
#gzip on; # 开启文件压缩
# 虚拟主机设置
server {
listen 80; # 设置监听地址和端口, 10.0.0.238:80 | 80
server_name locahost; # 设置server_name, 基于server_name来区分虚拟主机, 可以以空格隔开写多个并支持正则表达式, 如: *.wang.com www.wang.*
#charset koi8-r; # 设置编码格式, 默认是俄语, 改成utf-8. 不过不改也没关系, 前端网站代码都会指定字符集, 另外, 如果这里去掉注释, 那么在客户端查看响应报文是可以看到服务器端字符集
#access_log logs/host.access.log main;
}
server {
...
server_name
root
alias
location [OPERATOR] URL {
...
if condition {
...
}
}
}
}
2.3.1 MIME
# 在响应报文中指定的文件扩展名映射至MIME对应的类型
include mime.types; # 导入支持的文件类型, 是相对于/apps/nginx/conf的目录
default_type application/octet-stream; # 除mime.types中包括的文件类型, 都默认定义为octet-stream类型,如果通过浏览器访问不属于mime.types定义的文件类型的文件那么浏览器会直接下载. 如果需要通过浏览器访问不在mime.types里的类型, 不让浏览器直接下载, 那么可以修改default_type为包含在mime.types里的类型, 比如html
2.3.2 响应报文字段
# 是否在响应报文中的Content-Type显示指定的字符集, 默认off不显示
charset CHARSET;
# 示例
charset utf-8;
# 是否在响应报文的Server首部显示nginx版本信息. 可以在http,server和location语句块指定. on为显示nginx和版本信息, off不会显示版本但是还会显示nginx. build和string是商业版支持的功能
server_tokens on | off | build | string
# 如果想要修改整个Server字段, 需要修改nginx源码, 将已有的nginx二进制文件做备份, 然后重新编译nginx, 然后用新的nginx二进制文件, 替换掉旧的. 然后重启nginx服务
2.4 核心配置实例
- 基于不同的ip地址, 端口, 和域名来实现不同的虚拟主机, 依赖于核心模块[ngx_http_core_module]
2.4.1 新建pc和mobile Web站点
pc.wang.org
m.wang.org
- 准备存放pc和mobile主页面的目录
[22:09:54 root@nginx ~]#mkdir -pv /data/nginx/html/pc
mkdir: created directory '/data/nginx'
mkdir: created directory '/data/nginx/html'
mkdir: created directory '/data/nginx/html/pc'
[22:26:33 root@nginx ~]#mkdir -pv /data/nginx/html/mobile
mkdir: created directory '/data/nginx/html/mobile'
- 修改配置文件, 指定include目录, 将pc和mobile网站的配置文件单独存放
[22:26:37 root@nginx ~]#vim /apps/nginx/conf/nginx.conf
...
#}
include /apps/nginx/conf.d/*.conf; # include指令需要放到http语句块
}
[22:27:17 root@nginx ~]#mkdir -pv /apps/nginx/conf.d/
mkdir: created directory '/apps/nginx/conf.d/'
[20:55:23 root@nginx ~]#nginx -s reload
- 创建pc和mobile的主页面
[22:27:29 root@nginx ~]#echo "pc website" > /data/nginx/html/pc/index.html
[22:30:24 root@nginx ~]#echo "mobile website" > /data/nginx/html/mobile/index.html
- 编辑配置文件
- m.wang.org
[22:37:05 root@nginx ~]#cat /apps/nginx/conf.d/mobile.conf
server {
listen 80;
server_name m.wang.org;
# root 指定网站数据的总目录
root /data/nginx/html/mobile;
# index 指定默认主页面, 默认就是index和index.html
index index index.html;
}
- pc.wang.org
[22:37:40 root@nginx ~]#cat /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name pc.wang.org;
# root 指定网站数据的总目录
root /data/nginx/html/pc;
# index 指定默认主页面, 默认就是index和index.html
index index index.html;
}
- 找一个客户端, 设置域名解析
10.0.0.86 pc.wang.org m.wang.org
- 重启nginx
[22:46:30 root@nginx ~]#nginx -s reload
- 访问测试
[22:53:01 root@client ~]#curl pc.wang.org
pc website
[22:53:02 root@client ~]#curl m.wang.org
mobile website
[22:53:05 root@client ~]#curl 10.0.0.86 # 通过ip访问, 访问的是默认页面
Welcome to nginx!
...
注意: 这里之所以通过ip访问, 访问的是主配置文件里的默认站点, 是因为, 默认站点在主配置文件中的顺序是排在我们定义include目录之上的, 因此优先级高, 通过ip访问访问的就是默认站点, 如果我们把include指令放在http语句块里,server语句块上面, 那么就比默认站点的server语句块优先级高了, 这时候通过ip访问访问到的就是include定义的/apps/nginx/conf.d/目录下的第一个配置文件定义的站点信息
- 修改主配置文件测试
[22:52:47 root@nginx ~]#vim /apps/nginx/conf/nginx.conf
http {
include /apps/nginx/conf.d/*.conf;
[23:01:20 root@nginx ~]#nginx -s reload
[23:03:00 root@nginx ~]#ls /apps/nginx/conf.d/
mobile.conf pc.conf
[22:54:21 root@client ~]#curl 10.0.0.238
mobile website # 访问到的是mobile, 因为在conf.d目录排在前面
- 将主配置文件配置恢复, 把include放在最下方
[23:06:37 root@nginx ~]#vim /apps/nginx/conf/nginx.conf
...
#}
include /apps/nginx/conf.d/*.conf;
}
[23:06:32 root@nginx ~]#nginx -s reload
此时, 一个nginx服务器上, 有三个站点
10.0.0.86 - Nginx默认页面
pc.wang.org
mobile.wang.org
补充:
include指令的位置, 只是决定了通过ip访问时, 访问的是默认站点, 还是虚拟主机站点
并不会真正影响对于默认站点的访问, 默认站点本身也就是一个虚拟主机, 因此, 也是可以通过在其server语句块中定义server_name来访问, 默认的server_name是localhost
一般include指令放在后面, 不要影响默认站点设置
2.4.2 root 与 alias指令
- root: 指定web站点的家目录
- root可以放在server语句块用来指定虚拟主机站点的家目录, 也就是在磁盘目录的起始位置
- 也可以放在location语句块, 配合location语句块(location /URL)来自定义某个URL的磁盘目录起始位置
- 如果在location语句块中定义了root, 那么访问location 后定义的URL, 实际访问的是root+location
- 在定义location语句块的时候, 磁盘文件的绝对路径等于root+location
示例1:
[21:29:24 root@nginx ~]#vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name pc.wang.org;
root /data/nginx/html/pc;
index index index.html;
location /about { # 只定义location URL, root还是用站点的默认root
}
}
# 此时, 访问pc.wang.org/about, 实际访问的是磁盘上,/data/nginx/html/pc/about目录下的默认文件, 因为, 该about目录还没有创建, 因此, 访问会出现404报错
[21:28:35 root@CentOS-8-5 ~]#curl pc.wang.org/about
404 Not Found
404 Not Found
nginx/1.18.0
# 在服务器上创建about目录, 并添加默认index.html页面
[21:32:29 root@nginx ~]#echo /data/nginx/html/pc/about > /data/nginx/html/pc/about/index.html
# 再次测试访问
[21:32:50 root@CentOS-8-5 ~]#curl pc.wang.org/about -L # curl浏览器需要加-L禁止跳转
/data/nginx/html/pc/about
[23:22:10 root@nginx ~]#vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name pc.wang.org;
# root 指定网站数据的总目录
root /data/nginx/html/pc;
# index 指定默认主页面, 默认就是index和index.html
index index index.html;
location /about { # 这时, 如果从浏览器访问pc.wang.org/about, 那么nginx会到/opt/html/about目录下, 去找默认页面
root /opt/html; # 在location语句块定义了root, 那么就限定了这个location的根是从哪开始. 如果在location中没有定义root, 那么就用server语句块中定义的root, 这时访问pc.wang.org/about, 实际访问的是/data/nginx/html/pc/about目录下的默认文件
}
}
示例2:
[21:32:37 root@nginx ~]#vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name pc.wang.org;
root /data/nginx/html/pc;
index index index.html;
location /about {
root /opt/html; # 给location单独定义了root, 那么访问pc.wang.org/about时, 访问的就是/opt/html/about目录下的默认文件
}
}
[23:26:44 root@nginx ~]#mkdir -pv /opt/html/about
mkdir: created directory '/opt/html'
mkdir: created directory '/opt/html/about'
[23:26:50 root@nginx ~]#echo "about page" > /opt/html/about/index.html
[23:27:03 root@nginx ~]#nginx -s reload
[23:27:35 root@client ~]#curl pc.wang.org/about
301 Moved Permanently
301 Moved Permanently
nginx/1.18.0
[23:27:38 root@client ~]#curl pc.wang.org/about -L
about page
[23:27:43 root@client ~]#curl pc.wang.org/about/ # 通过curl去访问时, 需要用'/'补全路径, 否则会自动跳转, 在浏览器访问不用, 浏览器会自动补全'/'
about page
[23:27:59 root@client ~]#curl pc.wang.org # 主站点还是正常访问, 因为root /data/nginx/html/pc; 是配置在server语句块里的
pc website
- alias: 定义路径别名
- 会把访问的路径, 重新定义到其指定的路径, 是文档映射的另一种机制
- alias只能用在location语句块
示例:
[23:44:01 root@nginx ~]#vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name pc.wang.org;
# root 指定网站数据的总目录
root /data/nginx/html/pc;
# index 指定默认主页面, 默认就是index和index.html
index index index.html;
location /about { # 这时, 访问pc.wang.org/about实际访问的是pc.wang.org/opt/html, 也就是磁盘opt/html目录下的默认文件, 而非root目录下的/opt/html
alias /opt/html;
}
}
[23:44:15 root@nginx ~]#echo "/opt/html/index.html" > /opt/html/index.html
[23:45:27 root@nginx ~]#nginx -s reload
[23:46:05 root@client ~]#curl pc.wang.org/about/
/opt/html/index.html
注意: 利用alias时, 如果location的URL最后有'/'补全, 那么alias的URL最后也必须有"/"补全, 否则访问会报错403
示例:
[21:44:10 root@nginx ~]#vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name pc.wang.org;
root /data/nginx/html/pc;
index index index.html;
location /about/ {
alias /opt/html;
}
}
nginx -s reload
[21:44:14 root@CentOS-8-5 ~]#curl pc.wang.org/about/
403 Forbidden
403 Forbidden
nginx/1.18.0
2.4.3 location详细使用
- 在一个server中location配置段可以存在多个, 用于实现从URI到文件系统的路径映射, nginx会根据用户请求的URI(也就是域名后的路径)来检查定义的所有的location, 按一定的优先级别找出一个最佳匹配, 而后应用该localtion中的设置
语法规则:
location [ = | ~ | ~* | ^~ ] URI { ... }
= # 用于标准uri前, 需要请求字符串与uri精确匹配, 大小写敏感, 如果匹配成功就立即停止向下匹配, 并立即处理请求
比如: 定义location = /index.html, 那么用户就必须访问/index.html才会匹配
^~ # 用于标准uri前, 表示包含正则表达式, 并且匹配以指定的正则表达式开头, 对uri的最左边部分做匹配检查, 不区分字符大小写
比如: 定义location ^~ /static, 那么用户只要访问/static开头的uri都是可以匹配的, /static1, /static2...
不带符号 # 匹配起始于此uri的所有的uri, 不区分大小写
比如: location /static, 用户访问任何起始于/static的路径都可以匹配, /static/a.css可以匹配
~ # 用于标准uri前, 表示包含正则表达式, 并且区分大小写
比如: 定义location ~ /static, 那么只要访问的路径, 包含static字符串即可, /images/static123, 满足条件, 因为包含了static字符串, 不过 ~ 是区分大小写的, 如果/images/STATIC123那就不能匹配了
~* # 用于标准uri前, 表示包含正则表达式, 并且不区分大小写
比如: 定义location ~* /static, 那么只要访问的路径, 包含static字符串即可, /images/static123,满足条件, 而且, ~* 是不区分大小写的, 访问/images/statiC123, 也会被匹配
\ # 用于标准uri前, 表示包含正则表达式并且转义字符. 可以将 . * ? 等转义为普通符号
# 匹配优先级从高到低:
=, ^~, ~|~*(哪个location在前, 哪个生效) , 不带符号
2.4.3.1 匹配案例-精确匹配 =
在server部分使用location配置一个web界面, 例如: 当访问nginx服务器的/logo.jpg的时候, 要显示指定的html文件的内容
精确匹配一般用于组织的logo等相对固定的URL, 匹配优先级最高
范例: 精确匹配logo
[01:06:10 root@nginx ~]#vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name pc.wang.org;
location / {
root /data/nginx/html/pc;
}
location = /logo.jpg {
# 必须精确访问pc.wang.org/logo.jpg, 才会匹配, 一旦匹配成功, 就会到/data/nginx/images下去找logo.jpg
root /data/nginx/images;
index index.html;
}
}
[01:14:33 root@nginx ~]#mkdir -pv /data/nginx/images
mkdir: created directory '/data/nginx/images'
[01:16:26 root@nginx ~]#ls /data/nginx/images
logo.jpg
[01:16:56 root@nginx ~]#nginx -s reload
测试访问:
-
区分大小写
如果只访问pc.wang.org, 那么会走第一个location /, 正常访问站点家目录
2.4.3.2 区分大小写 ~
- ~ 实现区分大小写的模糊匹配, 以下范例中, 如果访问的uri中包含大写字母的JPG, 则以下location匹配Ax.JPG不成功, 因为 ~ 区分大小写, 那么当用户的请求被执行匹配时发现location中定义的是小写的jpg, 则匹配失败, 即要么继续匹配其他的location(如果有), 要么报错给客户端
[01:16:57 root@nginx ~]#mkdir -pv /data/nginx/html/image
mkdir: created directory '/data/nginx/html/image'
[01:35:01 root@nginx ~]#ls /data/nginx/html/image
Ax.jpg
[01:32:18 root@nginx ~]#vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name pc.wang.org;
location / {
root /data/nginx/html/pc;
}
# 匹配大写字母A开头, 后面跟一个或0个字符的.jpg文件
location ~ /A.?\.jpg {
root /data/nginx/html/image;
index index.html;
}
}
- 此时, 如果把/data/nginx/html/image下的Ax.jpg文件, 移动到 /data/nginx/html/pc目录下, 那么用户访问pc.wang.org/Ax.jpg时, 也会出现404报错, 因为, 当访问pc.wang.org/Ax.jpg是符合location ~ /A.?.jpg模式的, 那么就会在其root( root /data/nginx/html/image )下寻找Ax.jpg文件, 如果找不到就会报错404, 而不会去其他的location再匹配. 也就是如果匹配到了某个location, 那么即使该location的root下没有要找的文件, 也不会去别的location再进行匹配
[15:46:42 root@nginx /data/nginx/html/image]#mv Ax.jpg /data/nginx/html/pc/
2.4.3.3 不区分大小写
~* 用来对用户请求的uri做模糊匹配, uri中无论都是大写, 都是小写或者大小写混合, 此模式都会匹配, 通常使用此模式匹配用户request中的静态资源并继续做下一步操作, 此方式使用较多
注意: 此方式中, 对于Linux文件系统上的文件仍然是区分大小写的, 如果磁盘文件不存在, 仍然会报404, 也就是说, 一但匹配成功了, 那么Linux上必须有用户访问的文件才行.
[01:38:13 root@nginx ~]#vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name pc.wang.org;
location / {
root /data/nginx/html/pc;
}
location ~* /A.?\.jpg {
root /data/nginx/html/image;
index index.html;
}
}
[01:59:14 root@nginx ~]#nginx -s reload
准备两个图片文件
[02:02:48 root@nginx /data/nginx/html/image]#ls
ax.jpg Ax.jpg
访问Ax.jpg
访问ax.jpg
访问不同的文件, 结果不同, 说明虽然匹配时不区分大小写, 但是一旦匹配成功, 落到Linux目录里查找文件就是区分大小了, 因为Linux文件系统区分大小写
2.4.3.4 URI开始
- ^~ 只要是访问以定义的uri起始的文件, 都会匹配, 不区分大小写
[02:12:03 root@nginx ~]#vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name pc.wang.org;
location / {
root /data/nginx/html/pc;
}
location ^~ /image { # 这时只要访问的uri是以/image开始的就可以匹配, /images1/a.jpg,/image2/b.jpg,/image/jpg/c.jpg都会匹配
root /data/nginx/html/image; # 注意, 因为定义了root, 那么要访问的文件, 一定要在 /data/nginx/html/image目录下存在才行, 否则404
index index.html;
}
}
[02:12:58 root@nginx ~]#nginx -s reload
# /data/nginx/html/image/image下创建一个c.jpg文件
[02:13:01 root@nginx ~]#mkdir /data/nginx/html/image/image
[02:16:27 root@nginx ~]#ls /data/nginx/html/image/image/
c.jpg
测试访问:
示例:
用户访问pc.wang.org/image1/jpg/d.jpg, 此时/image1/jpg/d.jpg符合^~ /image, 因此会去/data/nginx/html/image/image1/jpg的目录下, 查找d.jpg文件
[15:59:58 root@nginx /data/nginx/html/image]#mkdir -pv /data/nginx/html/image/image1/jpg
mkdir: created directory '/data/nginx/html/image/image1'
mkdir: created directory '/data/nginx/html/image/image1/jpg'
[16:02:18 root@nginx /data/nginx/html/image]#cd /data/nginx/html/image/image1/jpg
[16:02:45 root@nginx /data/nginx/html/image/image1/jpg]#rz -E
rz waiting to receive.
[16:02:47 root@nginx /data/nginx/html/image/image1/jpg]#ls
d.jpg
补充示例:
location /api-py {
alias /data/nginx/api-py;
index index.html
#这时访问pc.wang.org/api-py, 实际访问的是/data/nginx/api-py路径下的页面, 因为这里是别名, 别名就是url和磁盘文件的映射. 而访问/api-py, 因为符合location 不带 URI, 即用户访问任何起始于/api-py的文件, 都匹配, 所以该条location会匹配
location /api-py {
root /data/nginx/api-py;
index index.html
#这时访问pc.wang.org/api-py, 实际访问的是/data/nginx/api-py/api-py, 因为是root, 那么访问时的真实路径是root+location
}
2.4.3.5 文件名后缀
[02:16:31 root@nginx ~]#mkdir /data/nginx/static
[02:39:06 root@nginx ~]#ls /data/nginx/static/
d.jpg
[02:39:09 root@nginx ~]#vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name pc.wang.org;
location / {
root /data/nginx/html/pc;
}
location ~* \.(gif|jpg|jpeg)$ { # 静态页面, 只要是以定义的格式结尾的文件, 就都转到相应的目录
root /data/nginx/static;
index index.html;
}
}
[02:40:57 root@nginx ~]#nginx -s reload
2.4.3.6 优先级
location = > location ^~ 路径 > location ~,~* 正则顺序(看谁写在前面) > location 完整路径 > location部分路径 > 不带符号 /
2.4.3.7 生产使用案例
# 直接匹配网站的根, 会加速Nginx访问处理, 因为一般网站的主页面都是访问量最大的
location = / {
...;
}
location / {
...;
}
# 静态资源配置方法1
location ^~ /static {
...;
}
# 静态资源配置方法2
location ~* \.(gif|jpg|...)$ {
...;
}
# 多应用配置
location ~* /app1 {
...;
}
location ~* /app2 {
...;
}
补充: location = / 和 location /的特殊情况
server {
listen 80;
server_name pc.wang.org;
root /data/nginx/html/pc1;
index index index.html;
location = / {
root /data/nginx/html/pc2;
}
location / {
root /data/nginx/html/pc3;
}
}
[17:22:34 root@nginx ~]#nginx -s reload
[17:22:37 root@nginx ~]#mkdir /data/nginx/html/pc1
[17:23:07 root@nginx ~]#mkdir /data/nginx/html/pc2
[17:23:08 root@nginx ~]#mkdir /data/nginx/html/pc3
[17:23:09 root@nginx ~]#echo /data/nginx/html/pc1 > /data/nginx/html/pc1/index.html
[17:23:28 root@nginx ~]#echo /data/nginx/html/pc2 > /data/nginx/html/pc2/index.html
[17:23:33 root@nginx ~]#echo /data/nginx/html/pc3 > /data/nginx/html/pc3/index.html
当 = / 和 / 同时存在, 并且location的URL后没有接文件名, 如果用户访问'/', 那么location / 会生效
访问pc.wang.org, location / 生效
server {
listen 80;
server_name pc.wang.org;
root /data/nginx/html/pc1;
index index index.html;
location = /index.html {
root /data/nginx/html/pc2;
}
location /index.html {
root /data/nginx/html/pc3;
}
}
~
# 如果location的URL接了文件名, 那么=号生效
[17:31:20 root@nginx ~]#curl pc.wang.org/index.html
/data/nginx/html/pc2
匹配规则中有的是不区分大小的, 但是实际落到磁盘文件, 还是区分大小写的
定义在location中的root的优先级是比server中的root优先级高的
2.4.5 Nginx四层访问控制
- 访问控制基于模块ngx_http_access_module实现, 可以通过匹配客户端源ip地址进行限制
- 如果能在防火墙设备控制, 最好不要在nginx配置, 可以更好的节约资源
# deny
location = / {
root /data/nginx/html/pc;
index index.html;
deny all;
}
[12:42:39 root@nginx ~]#nginx -s reload
此时任何人都无法访问
[12:10:23 root@client ~]#curl pc.wang.org
403 Forbidden
403 Forbidden
nginx/1.18.0
只允许10.0.0.86访问
location / {
root /data/nginx/html/pc;
allow 10.0.0.86; # 允许规则需要放在deny前面
deny all;
}
[18:01:54 root@nginx ~]#curl pc.wang.org
pc website
2.4.6 Nginx账户认证功能
- 有ngx_http_auth_basic_module模块提供此功能
创建允许登录账号
yum -y install httpd-tools #提供htpasswd工具
[12:46:40 root@nginx ~]#htpasswd -cb /apps/nginx/conf/.htpasswd user1 123456 # -c创建文件, 多次-c会覆盖源文件
Adding password for user user1
[12:47:00 root@nginx ~]#htpasswd -b /apps/nginx/conf/.htpasswd user2 123456
Adding password for user user2
[12:47:10 root@nginx ~]#tail /apps/nginx/conf/.htpasswd
user1:$apr1$NTDtA42B$yO.tjrHVn/j2vUqesJty81
user2:$apr1$d6BI7W.D$vXhfMwKpOocEIjApwEt0F/
配置nginx
location = /login {
root /data/nginx/html/pc;
index index.html;
auth_basic "login password";
auth_basic_user_file /apps/nginx/conf/.htpasswd;
}
[12:48:28 root@nginx ~]#nginx -s reload
curl http://user1:[email protected]/login/ # 这里URL要补全/, 否则会提示401, 需要认证
2.4.7 自定义错误日志
- 默认, logs/access.log和error.log会记录所有虚拟主机的日志
- access.log记录访问成功和失败的日志
- error.log记录访问失败的日志
- 可以针对不同的虚拟主机, 设置独立的日志, 也就是每个网站, 一个独立的访问和错误日志
案例: 给pc.wang.org配置独立的错误日志
server {
listen 80;
server_name pc.wang.org;
error_page 500 502 503 504 404 /error.html; # 将这些报错都转到/error.html下
error_log /data/nginx/logs/pc_wang_org_error.log; # 定义该虚拟主机的错误日志路径
location = /error.html { # 指定错误页面位置
root /data/nginx/html/pc;
}
}
[12:55:09 root@nginx ~]#mkdir /data/nginx/logs
[18:12:39 root@nginx ~]#nginx -s reload
#定义错误页面
[13:10:48 root@nginx ~]#vim /data/nginx/html/pc/error.html
error.html
[13:11:29 root@nginx ~]#tail /data/nginx/logs/pc_wang_org_error.log
2021/01/07 13:09:21 [error] 1578#0: *43 open() "/apps/nginx/html/dasdasd" failed (2: No such file or directory), client: 10.0.0.1, server: pc.wang.org, request: "GET /dasdasd HTTP/1.1", host: "pc.wang.org"
2.4.8 自定义错误页面
范例: 如果出现404, 就跳转到/index.html, 实现只要用户访问的页面不存在, 就跳转到网站默认页面. 不过访问记录还是会被记录到错误日志. 并且返回给客户端的状态码是404
server {
listen 80;
server_name pc.wang.org;
error_page 404 /index.html; # 404跳转到/index.html
error_log /data/nginx/logs/pc_wang_org_error.log; # error_log /data/nginx/logs/pc_wang_org_error.log debug; 也可以调整记录的日志级别
location = /index.html {
root /data/nginx/html/pc;
}
}
范例: 404通过302跳转到主页面, 5xx错误, 转到/50x.html
error_page 404 =302 /index.html; # 404返回302状态码
error_page 500 502 503 504 /50x.html
location = /50x.html {
}
2.4.9 长连接配置
- 断开条件: 连接时长, 或请求次数
keepalive_timeout timeout [header_timeout]; # 设定保持连接的超时时长, 0表示禁止长连接, 默认为75s, 通常配置在http字段, 作为站点全局设置
keepalive_requests number; # 在一次长连接上, 所允许请求的资源的最大数量, 默认为100次, 建议适当调大, 比如: 500
范例:
keepalive_requests 3; # 单次连接, 最多请求3从就会断开连接
keepalive_time 65 60; # 开启长连接后, 返回客户端的会话保持时间为60s, 单次长连接累计请求达到指定次数请求或65秒就会被断开. 后面的60为发送给客户端的应答报文头部中显示的超时时间设置为60s, 如果不设置, 客户端将不显示超时时间. 65为服务器真正的断开时间, 而60是浏览器显示的断开时间
响应报文头部: Keep-ALive:timeout=60 # 设置为60后, 浏览器收到的服务器响应报文提示超时时间是60秒
Connection:close # 如果不设置长连接, 那么浏览器收到的响应报文就会显示close
2.4.10 nginx作为下载服务器配置
ngx_http_autoindex_module 模块处理下载请求, 并生成目录列表, 可以作为下载服务器配置使用
默认情况下, 一个路径下面如果没有index.html默认页面, 那么是不允许访问的, 会报错403, 而nginx作为下载服务器时, 目录是可以没有index.html的
范例: 配置下载服务器
- 先创建目录和文件
[13:59:34 root@nginx ~]#mkdir /data/nginx/html/pc/download
[13:59:54 root@nginx ~]#touch /data/nginx/html/pc/download/file{1..5}.txt
[14:00:01 root@nginx ~]#mkdir /data/nginx/html/pc/download/ios
[14:00:11 root@nginx ~]#dd if=/dev/zero of=/data/nginx/html/pc/download/ios/ubuntu.iso
594313+0 records in
594313+0 records out
304288256 bytes (304 MB, 290 MiB) copied, 5.03828 s, 60.4 MB/s
- 编辑配置文件
location /download {
autoindex on;
autoindex_exact_size on; # on显示精确大小, off显示模糊大小
autoindex_localtime on; # on显示当地时间, off显示格林威治时间
limit_rate 1024k; # 下载限速
root /data/nginx/html/pc;
}
- 测试下载
- 此时, 对于一些文本文件, 会直接在浏览器打开, 需要做额外的配置实现下载
location /download {
autoindex on;
if ($request_filename ~* ^.*?\.(txt|doc|pdf|rar|gz|zip|docx|exe|xlsx|ppt|pptx)$){
add_header Content-Disposition: 'attachment;';
}
autoindex_exact_size on;
autoindex_localtime on;
limit_rate 1024k;
root /data/nginx/html/pc;
}