nginx工作原理与配置

article/2025/10/4 12:48:47

nginx工作原理与配置

文章目录

  • nginx工作原理与配置
    • nginx的模块与工作原理
      • nginx的模块分类
      • nginx的工作原理
    • nginx的安装与配置
      • nginx安装
      • nginx配置
    • nginx的配置文件详解
      • nginx.conf配置详解
      • 用于调试、定位问题的配置参数
      • https配置
      • 基于用户认证
      • 开启状态界面
      • URL
      • URL - 统一资源定位器
      • 常见的 URL Scheme
      • rewrite
      • if
      • 基于浏览器实现分离案例
      • 防盗链案例
      • 反向代理与负载均衡

nginx的模块与工作原理

nginx由内核和模块组成。其中,内核的设计非常微小和简洁,完成的工作也非常简单,仅仅通过查找配置文件将客户端请求映射到一个location block(location是nginx配置中的一个指令,用于URL匹配),而在这个location中所配置的每个指令将会启动不同的模块去完成相应的工作。

nginx的模块分类

​ nginx的模块从结构上分为核心模块、基础模块和第三方模块

  • HTTP模块、EVENT模块和MAIL模块等属于核心模块
  • HTTP Access模块、HTTP FastCGI模块、HTTP Proxy模块和HTTP Rewrite模块属于基本模块
  • HTTP Upstream模块、Request Hash模块、Notice模块和HTTP Access Key模块属于第三方模块

用户根据自己的需要开发的模块都属于第三方模块。正是有了如此多模块的支撑,nginx的功能才会如此强大

nginx模块从功能上分为三类,分别是:

  • Handlers(处理器模块)。此类模块直接处理请求,并进行输出内容和修改headers信息等操作。handlers处理器模块一般只能有一个
  • Filters(过滤器模块)。此类模块主要对其他处理器模块输出的内容进行修改操作,最后由nginx输出
  • Proxies(代理器模块)。就是nginx的HTTP Upstream之类的模块,这些模块主要与后端一些服务比如fastcgi等操作交互,实现服务代理和负载均衡等功能

nginx模块分为:核心模块、事件模块、标准Http模块、可选Http模块、邮件模块、第三方模块和补丁等

  • nginx基本模块:所谓基本模块,指的是nginx默认的功能模块,它们提供的指令,允许你使用定义nginx基本功能的变量,在编译时不能被禁用,包括:
    • 核心模块:基本功能和指令,如进程管理和安全。常见的核心模块指令,大部分是放置在配置文件的顶部
    • 事件模块:在Nginx内配置网络使用的能力。常见的events(事件)模块指令,大部分是放置在配置文件的顶部
    • 配置模块:提供包含机制

nginx的工作原理

nginx的模块直接被编译进nginx,因此属于静态编译方式。

启动nginx后,nginx的模块被自动加载,与Apache不一样,首先将模块编译为一个so文件,然后在配置文件中指定是否进行加载。

在解析配置文件时,nginx的每个模块都有可能去处理某个请求,但是同一个处理请求只能由一个模块来完成。

nginx的进程架构:
启动nginx时,会启动一个Master进程,这个进程不处理任何客户端的请求,主要用来产生worker线程,一个worker线程用来处理n个request

在这里插入图片描述

下图展示了nginx模块一次常规的HTTP请求和响应的过程

在这里插入图片描述

下图展示了基本的WEB服务请求步骤

在这里插入图片描述

nginx的安装与配置

nginx安装

创建系统用户nginx

[root@localhost ~]# useradd -r -M -s /sbin/nologin nginx

安装依赖环境

[root@localhost ~]# yum -y install pcre-devel openssl openssl-devel gd-devel gcc gcc-c++
[root@localhost ~]# yum -y groups mark install 'Development Tools'
上次元数据过期检查:2:59:11 前,执行于 2021年10月25日 星期一 01时04分32秒。
依赖关系解决。
=============================================================软件包       架构        版本            仓库          大小
=============================================================
安装组:Development Tools事务概要
=============================================================完毕!

创建日志存放目录

[root@localhost ~]# mkdir -p /var/log/nginx
[root@localhost ~]# chown -R nginx.nginx /var/log/nginx

下载nginx

[root@localhost ~]# cd /usr/src/
[root@localhost src]# wget http://nginx.org/download/nginx-1.12.0.tar.gz
--2021-10-25 04:06:16--  http://nginx.org/download/nginx-1.12.0.tar.gz
正在解析主机 nginx.org (nginx.org)... 

编译安装

[root@localhost src]# ls
debug  kernels  nginx-1.12.0.tar.gz
[root@localhost src]# tar xf nginx-1.12.0.tar.gz
[root@localhost src]# cd nginx-1.12.0
[root@localhost nginx-1.12.0]# ./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-debug \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_image_filter_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_stub_status_module \
--http-log-path=/var/log/nginx/access.log \
--error-log-path=/var/log/nginx/error.log[root@localhost nginx-1.12.0]# make -j $(grep 'processor' /proc/cpuinfo | wc -l) && make install

nginx配置

服务控制方式,使用nginx命令

配置环境变量

[root@localhost ~]# echo 'export PATH=/usr/local/nginx/sbin:$PATH' > /etc/profile.d/nginx.sh
[root@localhost ~]# . /etc/profile.d/nginx.sh

服务控制方式,使用nginx命令

-t 检查配置文件语法

[root@localhost ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

-v 输出nginx的版本

[root@localhost ~]# nginx -v
nginx version: nginx/1.20.1

-c 指定配置文件的路径

[root@localhost ~]# nginx -s stop ; nginx -c /opt/nginx.conf  ##直接停掉然后启动
[root@localhost ~]# ps -ef|grep nginx
root       99290       1  0 03:32 ?        00:00:00 nginx: master process nginx -c /opt/nginx.conf
nginx      99291   99290  0 03:32 ?        00:00:00 nginx: worker process
nginx      99292   99290  0 03:32 ?        00:00:00 nginx: worker process
root      101138    1653  0 03:33 pts/0    00:00:00 grep --color=auto nginx

-s 发送服务控制信号,可选值有{stop|quit|reopen|reload}

[root@localhost ~]# nginx -s quit
[root@localhost ~]# ss -antl
State  Recv-Q Send-Q  Local Address:Port   Peer Address:Port Process                                                      
LISTEN 0      128           0.0.0.0:22          0.0.0.0:*                                                                 
LISTEN 0      128              [::]:22             [::]:*                                                      

nginx的配置文件详解

主配置文件:/usr/local/nginx/conf

  • 默认启动nginx时,使用的配置文件是:安装路径/conf/nginx.conf文件
  • 可以在启动nginx时通过-c选项来指定要读取的配置文件

nginx常见的配置文件及其作用

配置文件作用
nginx.confnginx的基本配置文件
mime.typesMIME类型关联的扩展文件
fastcgi.conf与fastcgi相关的配置
proxy.conf与proxy相关的配置
sites.conf配置nginx提供的网站,包括虚拟主机

nginx.conf配置详解

nginx.conf的内容分为以下几段:

  • main配置段:全局配置段。其中main配置段中可能包含event配置段
  • event {}:定义event模型工作特性
  • http {}:定义http协议相关的配置

Nginx配置文件示例

[root@localhost ~]# vim /usr/local/nginx/conf
# 全局块user www-data;  ##用户worker_processes  2;  ## 默认1,一般建议设成CPU核数1-2倍error_log  logs/error.log; ## 错误日志路径pid  logs/nginx.pid; ## 进程id# Events块events {# 使用epoll的I/O 模型处理轮询事件。# 可以不设置,nginx会根据操作系统选择合适的模型use epoll;# 工作进程的最大连接数量, 默认1024个worker_connections  2048;# http层面的keep-alive超时时间keepalive_timeout 60;# 客户端请求头部的缓冲区大小client_header_buffer_size 2k;}# http块http { include mime.types;  # 导入文件扩展名与文件类型映射表default_type application/octet-stream;  # 默认文件类型# 日志格式及access日志路径log_format   main '$remote_addr - $remote_user [$time_local]  $status ''"$request" $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';access_log   logs/access.log  main; # 允许sendfile方式传输文件,默认为off。sendfile     on;tcp_nopush   on; # sendfile开启时才开启。# http server块# 简单反向代理server {listen       80;server_name  domain2.com www.domain2.com;access_log   logs/domain2.access.log  main;# 转发动态请求到web应用服务器location / {proxy_pass      http://127.0.0.1:8000;deny 192.24.40.8;  # 拒绝的ipallow 192.24.40.6; # 允许的ip   }# 错误页面error_page   500 502 503 504  /50x.html;location = /50x.html {root   html;}}# 负载均衡upstream backend_server {server 192.168.0.1:8000 weight=5; # weight越高,权重越大server 192.168.0.2:8000 weight=1;server 192.168.0.3:8000;server 192.168.0.4:8001 backup; # 热备}server {listen          80;server_name     big.server.com;access_log      logs/big.server.access.log main;charset utf-8;client_max_body_size 10M; # 限制用户上传文件大小,默认1Mlocation / {# 使用proxy_pass转发请求到通过upstream定义的一组应用服务器proxy_pass      http://backend_server;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header Host $http_host;proxy_redirect off;proxy_set_header X-Real-IP  $remote_addr;} }}

配置指令:要以分号结尾,语法格式如下:

derective value1 [value2 ...];

支持使用变量:

  • 内置变量:模块会提供内建变量定义
  • 自定义变量:set var_name value

用于调试、定位问题的配置参数

daemon {on|off};    //是否以守护进程方式运行nginx,调试时应设置为off
master_process {on|off};    //是否以master/worker模型来运行nginx,调试时可以设置为off
error_log 位置 级别;    //配置错误日志

在这里插入图片描述
比如将配置文件中的记录日志的注释取消掉,然后可以修改日志级别,就有记录了,日志级别越低,越详细,但是无用的记录也越多,所以我们应该选择适当的日志级别,比如我们设置的是crit级别,但是看不出来什么错误,我们就可以降低级别来查看更详细的记录

[root@localhost ~]# ls /usr/local/nginx/logs/    ##先查看是否存在错误日志文件
nginx.pid
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf    ##编辑配置文件,开启错误日志
#user  nobody;
worker_processes  1;error_log  logs/error.log;           ##开启错误日志
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;#pid        logs/nginx.pid;
·····省略部分[root@localhost ~]# nginx -s reload    ##重新加载##发现已经出现了一个日志文件
[root@localhost ~]# ls /usr/local/nginx/logs/
error.log  nginx.pid

浏览器访问,使其产生一个错误日志
在这里插入图片描述
再去查看错误日志

[root@localhost ~]# cat /usr/local/nginx/logs/error.log    ##里面的记录就是上面访问页面的错误信息
2021/10/26 07:43:03 [error] 36057#0: *3 open() "/usr/local/nginx/html/liuqiang" failed (2: No such file or directory), client: 192.168.240.1, server: localhost, request: "GET /liuqiang HTTP/1.1", host: "192.168.240.60"

正常运行必备的配置参数
使用的时候直接在配置文件中指明使用的用户是nginx
pid文件位置也取消注释直接使用,因为默认注释掉也是使用的这个位置,当然也可以修改为其他位置

[root@localhost conf]# vim /usr/local/nginx/conf/nginx.conf1 2 user  nginx nginx;                # 取消注释,修改为nginx用户,nginx组3 worker_processes  1;
·····省略部分·············省略部分········7 #error_log  logs/error.log  info;8 9 pid        logs/nginx.pid;   # 取消注释·····省略部分········[root@localhost conf]# nginx -s reload         # 重新加载配置文件立即生效

设置worker线程最大可以打开的文件数
worker_rlimit_nofile number; #更改worker线程中最大开放文件数量的限制。用于在不重新启动主过程的情况下增加限制。默认为1024,但是1024太小了,所以我们可以设置为10240

[root@localhost ~]# cd /usr/local/nginx/conf/
[root@localhost conf]# vim nginx.conf1 2 user  nginx nginx;3 worker_processes  1;4 worker_rlimit_nofile 10240;   # #添加此行,并设置为10240,默认是1024
·····省略部分········[root@localhost conf]# nginx -s reload         # #重新加载配置文件立即生效

性能优化的配置参数
worker_processes n;
启动worker线程个数,把进程进行切换就是上下文切换,(寄存器)记录运行的位置,上下文切换的信息会一直被保存在CPU的内存中,直到被再次使用。

[root@localhost ~]# cd /usr/local/nginx/conf/
[root@localhost conf]# vim nginx.conf1 2 user  nginx nginx;3 worker_processes  3;      # 默认是1,更改就可以产生多个worker线程去处理4 worker_rlimit_nofile 10240;·····省略部分········[root@localhost conf]# nginx -s reload         # 重新加载配置文件立即生效

将进程绑定到某cpu核心中,避免频繁刷新缓存。绑定规则是核心数-1,比如总核心数为4,那么就绑定三个,另一个给其他使用
worker_cpu_affinity cpumask …;
#cpumask:使用8位二进制表示cpu核心,如:
0000 0001 //第一颗cpu核心
0000 0010 //第二颗cpu核心
0000 0100 //第三颗cpu核心
0000 1000 //第四颗cpu核心
0001 0000 //第五颗cpu核心
0010 0000 //第六颗cpu核心
0100 0000 //第七颗cpu核心
1000 0000 //第八颗cpu核心

[root@localhost ~]# cd /usr/local/nginx/conf/
[root@localhost conf]# vim nginx.confuser  nginx nginx;worker_processes  3;worker_rlimit_nofile 10240;worker_cpu_affinity 0001 0010 0100;  # 添加此行,为前面增加的三个worker线程绑定三个核心
·····省略部分········[root@localhost ~]# /usr/local/nginx/sbin/nginx -s stop;nginx  # 重启nginx
##查看是否生效: top命令,大写L搜索nginx,然后按小写f,移动到大写P,然后空格选中,最后按q退出就可以看见是否生效

在这里插入图片描述
计时器解析度。降低此值,可减少gettimeofday()系统调用的次数。减少worker线程中的定时器分辨率,从而减少系统呼叫的数量。默认情况下,每次收到内核事件时都会被调用。随着分辨率的降低,每个指定呼叫一次。
timer_resolution interval; (例如可以设置为 timer_resolution 100ms;)
指明worker进程的nice值,优先级是-20到19,指定的数字越小,优先级越高,相对优先级(可以调整) ,绝对优先级,100到139(无法调整) ,提高优先级可以先进行处理

worker_priority number;   [root@localhost ~]# ps -elf|grep nginx     # 查看发现worker线程的nice值是80,我们可以修改提高它的优先级,这样就可以优先进行处理
1 S root       34284       1  0  80   0 - 20408 -      01:35 ?        00:00:00 nginx: master process nginx
5 S nginx      34285   34284  0  80   0 - 28560 do_epo 01:35 ?        00:00:00 nginx: worker process
5 S nginx      34286   34284  0  80   0 - 28560 do_epo 01:35 ?        00:00:00 nginx: worker process
5 S nginx      34287   34284  0  80   0 - 28560 do_epo 01:35 ?        00:00:00 nginx: worker process
0 S root       99205   33695  0  80   0 -  2302 -      01:53 pts/0    00:00:00 grep --color=auto nginx[root@localhost ~]# cd /usr/local/nginx/conf/
[root@localhost conf]# vim nginx.conf1 2 user  nginx nginx;3 worker_processes  3;4 worker_rlimit_nofile 10240;5 worker_cpu_affinity 0001 0010 0100;6 worker_priority -20              # 添加此行来提高worker线程的优先级[root@localhost conf]# nginx -s reload         # 发送信号重新加载配置文件立即生效
[root@localhost ~]# ps -elf|grep nginx    # 查看发现worker线程的nice值提高为60
0 T root       78891    1460  0  80   0 - 11875 -      08:04 pts/0    00:00:00 vim /usr/local/nginx/conf/nginx.conf
1 S root       88430       1  0  80   0 - 20408 -      08:09 ?        00:00:00 nginx: master process nginx
5 S nginx      88431   88430  0  60   0 - 28556 do_epo 08:09 ?        00:00:00 nginx: worker process
5 S nginx      88432   88430  0  60   0 - 28556 do_epo 08:09 ?        00:00:00 nginx: worker process
5 S nginx      88433   88430  0  60   0 - 28556 do_epo 08:09 ?        00:00:00 nginx: worker process
0 S root       96763    1460  0  80   0 -  3087 -      08:13 pts/0    00:00:00 grep --color=auto nginx

事件相关的配置:event{}段中的参数配置
accept_mutex {off|on}; 互斥锁,互相排斥,mster调度用户请求至各worker进程时使用的负载均衡锁;on表示能让多个worker轮流地、序列化地去响应新请求 ,保持默认关闭的

accept_mutex {off|on};
lock_file logs/nginx.lock;      # accept_mutex用到的互斥锁锁文件路径(main段)

指明使用的事件模型,建议让nginx自行选择。指定要使用的连接处理。通常不需要明确说明,因为 nginx 默认情况下会使用最有效的方法

use [epoll | rtsig | select | poll]; 

每个进程能够接受的最大连接数
worker_connections 1024;

[root@localhost conf]# vim nginx.conf
·····省略部分········events {worker_connections  20480;  # 默认值是1024}
·····省略部分········# worker_connections 20480; 并发连接数 = 20480 * worker线程数量(3个)/2 # 使用ab命令测试并发,安装工具 **yum -y install httpd-tools**[root@localhost ~]# ab -n 30000 http://192.168.240.60/
This is ApacheBench, Version 2.3 <$Revision: 1843412 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/Benchmarking 192.168.240.60 (be patient)
Completed 3000 requests
Completed 6000 requests
Completed 9000 requests
Completed 12000 requests
Completed 15000 requests
Completed 18000 requests
Completed 21000 requests
Completed 24000 requests
Completed 27000 requests
Completed 30000 requests
Finished 30000 requestsServer Software:        nginx/1.20.1
Server Hostname:        192.168.240.60
Server Port:            80Document Path:          /
Document Length:        612 bytesConcurrency Level:      1
Time taken for tests:   4.177 seconds
Complete requests:      30000
Failed requests:        0
Total transferred:      25350000 bytes
HTML transferred:       18360000 bytes
Requests per second:    7182.64 [#/sec] (mean)
Time per request:       0.139 [ms] (mean)
Time per request:       0.139 [ms] (mean, across all concurrent requests)
Transfer rate:          5927.08 [Kbytes/sec] receivedConnection Times (ms)min  mean[+/-sd] median   max
Connect:        0    0   0.0      0       1
Processing:     0    0   0.1      0       3
Waiting:        0    0   0.1      0       3
Total:          0    0   0.1      0       3Percentage of the requests served within a certain time (ms)50%      066%      075%      080%      090%      095%      098%      099%      1100%      3 (longest request)

网络连接相关的配置参数
长连接的超时时长,默认为65s

[root@localhost conf]# vim /usr/local/nginx/conf/nginx.conf
·····省略部分········#keepalive_timeout  0;keepalive_timeout  65;     # 默认值#gzip  on;
·····省略部分········

设置可以通过一个保持活力连接服务的最大请求数量。请求的最大数目后,连接将关闭。
定期关闭连接是每个连接内存分配的必要条件。因此,使用过高的最大请求量可能导致内存使用过量,不推荐
keepalive_requests number; (可以添加在http段,server段,location段)

[root@localhost]# cd /usr/local/nginx/conf
[root@localhost conf]# vim nginx.conf
·····省略部分········server {listen       80;server_name  localhost;keepalived_requests 10000   # 可以添加在server段#charset koi8-r;
·····省略部分········

常需要进行调整的参数
worker_processes # worker线程数量
worker_connections # 并发连接数
worker_cpu_affinity # cpu核心数绑定
worker_priority # worker线程的优先级
nginx作为web服务器时使用的配置:http{}段的配置参数
http{…}:配置http相关,由ngx_http_core_module模块引入。nginx的HTTP配置主要包括四个区块,结构如下:

http {//协议级别include mime.types;default_type application/octet-stream;keepalive_timeout 65;gzip on;upstream {//负载均衡配置...}server {//服务器级别,每个server类似于httpd中的一个<VirtualHost>listen 80;server_name localhost;location / {//请求级别,类似于httpd中的<Location>,用于定义URL与本地文件系统的映射关系root html;index index.html index.htm;}}
}

http{}段配置指令:
server {}:定义一个虚拟主机,示例如下:

server{
​    listen 81;(端口)
​     server_name www.lp.com;(域名可以给多个)
​      location / {
​      root html/test;  (网站位置)  or  alias /var/www/html/;(别名,别名一定要写绝对路径,就是把资源放到另外一个位置,当有人访问时,看见的路径是/根下面,其实我们已经放在了另一个位置,防止被攻击)
​      index    index.html;​    }

listen:指定监听的地址和端口

listen address[:port];
listen port;

server_name NAME […]; 后面可跟多个主机,名称可使用正则表达式或通配符
当有多个server时,匹配顺序如下:

1.先做精确匹配检查
2.左侧通配符匹配检查,如*.idfsoft.com
3.右侧通配符匹配检查,如mail.*
4.正则表达式匹配检查,如~ ^.*.idfsoft.com$
5.default_server
root path; 设置资源路径映射,用于指明请求的URL所对应的资源所在的文件系统上的起始路径
alias path; 用于location配置段,定义路径别名

index file; 默认主页面

index index.php index.html;

error_page code […] [=code] URI | @name 根据http响应状态码来指明特用的错误页面,例如 error_page 404 /404_customed.html

[=code]:以指定的响应码进行响应,而不是默认的原来的响应,默认表示以新资源的响应码为其响应码,例如 error_page 404 =200 /404_customed.html
log_format定义日志格式

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;

location区段,通过指定模式来与客户端请求的URI相匹配
功能:允许根据用户请求的URI来匹配定义的各location,匹配到时,此请求将被相应的location配置块中的配置所处理,例如做访问控制等功能

语法:location [ 修饰符 ] pattern {…}

没有修饰符

[root@localhost local]# vim nginx/conf/nginx.conflocation / {root   html;index  index.html index.htm;}location /test {echo "test";}[root@localhost ~]# nginx -s reload[root@localhost ~]# curl http://192.168.240.60/test
test
[root@localhost ~]# curl http://192.168.240.60/test?sac
test
[root@localhost ~]# curl http://192.168.240.60/test?saccsac
test

精确匹配

[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conflocation =/test {echo "test";}[root@localhost ~]# nginx -s reload##如下内容就可正确匹配
[root@localhost ~]# curl http://192.168.240.60/test
test##如下内容则无法匹配
[root@localhost ~]# curl http://192.168.240.60/testd13
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.20.1</center>
</body>
</html>

正则表达式模式匹配(区分大小写)

[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf}location =~^/test {echo "test";}[root@localhost ~]# nginx -s reload
##如下内容就可正确匹配
[root@localhost ~]# curl http://192.168.240.60/test
test##如下内容则无法匹配
[root@localhost ~]# curl http://192.168.240.60/test/
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.20.1</center>
</body>
</html>

正则表达式模式匹配(不区分大小写)

[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conflocation = ~* ^/test {echo "test";}#error_page  404              /404.html;[root@localhost ~]# nginx -s reload[root@localhost ~]# curl http://192.168.240.60/tesT
test##如下内容则无法匹配
[root@localhost ~]# curl http://192.168.240.60/test/
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.20.1</center>
</body>
</html>

~:类似于无修饰符的行为,也是以指定模式开始,不同的是,如果模式匹配,则停止搜索其他模式
优先级次序
( location = 路径 ) --> ( location ^~ 路径 ) --> ( location ~ 正则 ) --> ( location ~* 正则 ) --> ( location 路径 )

查找顺序和优先级:由高到底依次为
1.带有=的精确匹配优先
2.正则表达式按照他们在配置文件中定义的顺序
3.带有^~修饰符的,开头匹配
4.带有*修饰符的,如果正则表达式与URI匹配
5.没有修饰符的精确匹配

示例

[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conflocation / {root   html;index  index.html index.htm;}location /test {echo "test1";}location ~ ^ /test {echo "test2";}location ~* /test {echo "test2";}[root@localhost ~]# nginx -s reload

优先级测试

[root@localhost ~]# curl http://192.168.240.60/test
test2
[root@localhost ~]# curl http://192.168.240.60/testid
test1
[root@localhost ~]# curl http://192.168.240.60/TEST
test3

https配置

[root@localhost ~]# mkdir -p /etc/nginx/ssl
[root@localhost ~]# cd /etc/nginx/ssl/
[root@localhost ssl]# openssl genrsa -out test.key 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
..........+++++
.......................................+++++
e is 65537 (0x010001)[root@localhost ssl]# openssl req -new -key test.key -out test.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:cn
State or Province Name (full name) []:hb
Locality Name (eg, city) [Default City]:wh
Organization Name (eg, company) [Default Company Ltd]:lq
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:loocahost
Email Address []:Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:[root@localhost ssl]#  openssl x509 -req -days 365 -in test.csr -signkey test.key  -out test.crt
Signature ok
subject=C = cn, ST = hb, L = wh, O = lq, CN = loocahost
Getting Private key

修改nginx配置文件

[root@localhost ~]# vim /usr/local/nginx/conf/nginx.con#server {listen       443 ssl;server_name  localhost;ssl_certificate      /etc/nginx/ssl/test.crt;ssl_certificate_key  /etc/nginx/ssl/test.key;ssl_session_cache    shared:SSL:1m;ssl_session_timeout  5m;ssl_ciphers  HIGH:!aNULL:!MD5;ssl_prefer_server_ciphers  on;location / {root   html;index  index.html index.htm;}}[root@localhost ~]# nginx -s reload
[root@localhost ~]# ss -antl
State  Recv-Q Send-Q  Local Address:Port   Peer Address:Port Process                                                      
LISTEN 0      128           0.0.0.0:80          0.0.0.0:*                                                                 
LISTEN 0      128           0.0.0.0:22          0.0.0.0:*                                                                 
LISTEN 0      128           0.0.0.0:443         0.0.0.0:*                                                                 
LISTEN 0      128              [::]:22             [::]:*    

访问测试
在这里插入图片描述
访问控制

注:用于location段,可以用主机地址表示,也可用网段表示,必须一起用
allow:设定允许那台或那些主机访问,多个参数间用空格隔开
deny:设定禁止那台或那些主机访问,多个参数间用空格隔开

在matser主机上修改nginx配置文件,将192.168.50.0网段禁止访问

[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conflocation / {root   html;index  index.html index.htm;allow  192.168.240.60/32;deny   192.168.240.50/32;}
[root@localhost ~]# nginx -s reload

主机为192.168.240.60访问

[root@localhost ~]# curl http://192.168.240.60
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>body {width: 35em;margin: 0 auto;font-family: Tahoma, Verdana, Arial, sans-serif;}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p><p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p><p><em>Thank you for using nginx.</em></p>
</body>
</html>

主机为192.168.240.50访问

[root@localhost ~]# curl http://192.168.240.60
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.20.1</center>
</body>
</html>

将deny字段改为all,表示在拒绝所有主机访问

[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
location / {root   html;index  index.html index.htm;allow  192.168.240.60/32;deny   192.168.240.50/32;deny all;}
[root@localhost ~]# nginx -s reload

再次访问
在这里插入图片描述

基于用户认证

auth_basic "欢迎信息";
auth_basic_user_file "/path/to/user_auth_file";

user_auth_file内容格式为:

username:password

这里的密码为加密后的密码串,建议用htpasswd来创建此文件:

htpasswd -c -m /path/to/.user_auth_file USERNAME

示例

[root@localhost ~]#  yum -y install httpd-tools[root@localhost ~]# htpasswd -c -m /usr/local/nginx/conf/.user-auth-file liu
New password: 
Re-type new password: 
Adding password for user liu[root@localhost ~]# cat /usr/local/nginx/conf/.user-auth-file 
liu:$apr1$l0zw0VO6$.nC.ltsYIHDQSJ.nl/ySA0[root@localhost ~]#  mkdir -p /usr/local/nginx/html/liu
[root@localhost ~]# echo "welcome to xu!" > /usr/local/nginx/html/liu/index.html[root@localhost ~]# vim /usr/local/nginx/conf/nginx.confZZlocation / {root   html;index  index.htm;auth_basic "me liu!";auth_basic_user_file "/usr/local/nginx/conf/.user-auth-file";}[root@localhost ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@localhost ~]# nginx -s reload

在这里插入图片描述

开启状态界面

开启status:

[root@localhost conf]# vim nginx.conflocation / {root   html;index  index.html index.htm;}location /status {stub_status;}[root@localhost conf]# nginx -s reload

在这里插入图片描述

状态页面信息详解:

状态码表示的意义
Active connections 2当前所有处于打开状态的连接数
accepts总共处理了多少个连接
handled成功创建多少握手
requests总共处理了多少个请求
Readingnginx读取到客户端的Header信息数,表示正处于接收请求状态的连接数
Writingnginx返回给客户端的Header信息数,表示请求已经接收完成, 且正处于处理请求或发送响应的过程中的连接数
Waiting开启keep-alive的情况下,这个值等于active - (reading + writing), 意思就是Nginx已处理完正在等候下一次请求指令的驻留连接

URL

HTML 统一资源定位器(Uniform Resource Locators)


URL 是一个网页地址。

URL可以由字母组成,如"runoob.com",或互联网协议(IP)地址: 192.68.20.50。大多数人进入网站使用网站域名来访问,因为 名字比数字更容易记住。


URL - 统一资源定位器

Web浏览器通过URL从Web服务器请求页面。

当您点击 HTML 页面中的某个链接时,对应的 标签指向万维网上的一个地址。

一个统一资源定位器(URL) 用于定位万维网上的文档。

一个网页地址实例: http://www.runoob.com/html/html-tutorial.html 语法规则:

scheme://host.domain:port/path/filename

说明:

    • scheme - 定义因特网服务的类型。最常见的类型是 http
    • host - 定义域主机(http 的默认主机是 www)
    • domain - 定义因特网域名,比如 runoob.com
    • :port - 定义主机上的端口号(http 的默认端口号是 80)
    • path - 定义服务器上的路径(如果省略,则文档必须位于网站的根目录中)。
    • filename - 定义文档/资源的名称

常见的 URL Scheme

以下是一些URL scheme:

Scheme访问用于…
http超文本传输协议以 http:// 开头的普通网页。不加密。
https安全超文本传输协议安全网页,加密所有信息交换。
ftp文件传输协议用于将文件下载或上传至网站。
file您计算机上的文件。

rewrite

语法:rewrite regex replacement flag;,如:

[root@localhost conf]# ls ../html/qiang/
xin.jpg[root@localhost conf]# vim nginx.conflocation /liu {rewrite ^/liu/(.*\.jpg)$ /qiang/$1 break;}[root@localhost conf]# nginx -s reload

在这里插入图片描述

此处的$1用于引用(.*.jpg)匹配到的内容,又如:

rewrite ^/bbs/(.*)$ http://www.idfsoft.com/index.html redirect;

如上例所示,replacement可以是某个路径,也可以是某个URL

常见的flag

flag作用
last基本上都用这个flag,表示当前的匹配结束,继续下一个匹配,最多匹配10个到20个 一旦此rewrite规则重写完成后,就不再被后面其它的rewrite规则进行处理 而是由UserAgent重新对重写后的URL再一次发起请求,并从头开始执行类似的过程
break中止Rewrite,不再继续匹配 一旦此rewrite规则重写完成后,由UserAgent对新的URL重新发起请求, 且不再会被当前location内的任何rewrite规则所检查
redirect以临时重定向的HTTP状态302返回新的URL
permanent以永久重定向的HTTP状态301返回新的URL

last

[root@localhost conf]# vim nginx.conflocation /liu {rewrite ^/liu/(.*\.html)$ /qiang/$1 last;}location /qiang {rewrite ^/qiang/(.*\.html)$ http://www.baidu.com last;}
[root@localhost conf]# nginx -s reload
#浏览器访问IP/liu/qiang.html时结果为百度页面

rewrite模块的作用是用来执行URL重定向。这个机制有利于去掉恶意访问的url,也有利于搜索引擎优化(SEO)

nginx使用的语法源于Perl兼容正则表达式(PCRE)库,基本语法如下:

标识符意义
^必须以^后的实体开头
$必须以$前的实体结尾
.匹配任意字符
[]匹配指定字符集内的任意字符
[^]匹配任何不包括在指定字符集内的任意字符串
|匹配 | 之前或之后的实体
()分组,组成一组用于匹配的实体,通常会有 | 来协助

捕获子表达式,可以捕获放在()之间的任何文本,比如:

^(hello|sir)$       //字符串为“hi sir”捕获的结果:$1=hi$2=sir//这些被捕获的数据,在后面就可以当变量一样使用了

if

语法:if (condition) {...}

应用场景:

  • server段
  • location段

常见的condition

  • 变量名(变量值为空串,或者以“0”开始,则为false,其它的均为true)
  • 以变量为操作数构成的比较表达式(可使用=,!=类似的比较操作符进行测试)
  • 正则表达式的模式匹配操作
    • ~:区分大小写的模式匹配检查
    • ~*:不区分大小写的模式匹配检查
    • !和!*:对上面两种测试取反
  • 测试指定路径为文件的可能性(-f,!-f)
  • 测试指定路径为目录的可能性(-d,!-d)
  • 测试文件的存在性(-e,!-e)
  • 检查文件是否有执行权限(-x,!-x)

基于浏览器实现分离案例

if ($http_user_agent ~ Firefox) {rewrite ^(.*)$ /firefox/$1 break;
}if ($http_user_agent ~ MSIE) {rewrite ^(.*)$ /msie/$1 break;
}if ($http_user_agent ~ Chrome) {rewrite ^(.*)$ /chrome/$1 break;
}

防盗链案例

location ~* \.(jpg|gif|jpeg|png)$ {valid_referers none blocked www.idfsoft.com;if ($invalid_referer) {rewrite ^/ http://www.idfsoft.com/403.html;}
}

反向代理与负载均衡

nginx通常被用作后端服务器的反向代理,这样就可以很方便的实现动静分离以及负载均衡,从而大大提高服务器的处理能力。

nginx实现动静分离,其实就是在反向代理的时候,如果是静态资源,就直接从nginx发布的路径去读取,而不需要从后台服务器获取了。

但是要注意,这种情况下需要保证后端跟前端的程序保持一致,可以使用Rsync做服务端自动同步或者使用NFSMFS分布式共享存储。

Http Proxy`模块,功能很多,最常用的是`proxy_pass`和`proxy_cache

如果要使用proxy_cache,需要集成第三方的ngx_cache_purge模块,用来清除指定的URL缓存。这个集成需要在安装nginx的时候去做,如:
./configure --add-module=../ngx_cache_purge-1.0 ......

nginx通过upstream模块来实现简单的负载均衡,upstream需要定义在http段内

upstream段内,定义一个服务器列表,默认的方式是轮询,如果要确定同一个访问者发出的请求总是由同一个后端服务器来处理,可以设置ip_hash,如:

upstream idfsoft.com {ip_hash;server 127.0.0.1:9080 weight=5;server 127.0.0.1:8080 weight=5;server 127.0.0.1:1111;
}

注意:这个方法本质还是轮询,而且由于客户端的ip可能是不断变化的,比如动态ip,代理,翻墙等,因此ip_hash并不能完全保证同一个客户端总是由同一个服务器来处理。

定义好upstream后,需要在server段内添加如下内容:

server {location / {proxy_pass http://idfsoft.com;}
}

http://chatgpt.dhexx.cn/article/2KJtp6XY.shtml

相关文章

Nginx工作原理和优化、漏洞

1. Nginx的模块与工作原理 Nginx由内核和模块组成&#xff0c;其中&#xff0c;内核的设计非常微小和简洁&#xff0c;完成的工作也非常简单&#xff0c;仅仅通过查找配置文件将客户端请求映射到一个location block&#xff08;location是Nginx配置中的一个指令&#xff0c;用…

nginx 工作原理

1. Nginx的模块与工作原理 Nginx由内核和模块组成&#xff0c;其中&#xff0c;内核的设计非常微小和简洁&#xff0c;完成的工作也非常简单&#xff0c;仅仅通过查找配置文件将客户端请求映射到一个location block&#xff08;location是Nginx配置中的一个指令&#xff0c;用…

nginx工作原理及配置

模块与工作原理 nginx由内核和模块组成。其中&#xff0c;内核的设计非常微小和简洁&#xff0c;完成的工作也非常简单&#xff0c;仅仅通过查找配置文件将客户端请求映射到一个location block&#xff08;location是nginx配置中的一个指令&#xff0c;用于URL匹配&#xff09…

Nginx工作原理

一、明确Nginx与Tomcat的区别 web上的server都叫web server&#xff0c;但是大家分工也有不同的。 nginx常用做静态内容服务和代理服务器&#xff0c;直面外来请求转发给后面的应用服务&#xff08;tomcat&#xff09;&#xff0c;tomcat更多用来做一个应用容器&#xff0c;让…

nginx工作原理详解

一、Nginx请求处理流程 图解&#xff1a; 进入nginx的大致三种流量&#xff1a;WEB、EMAIL及TCP Nginx中三个状态机&#xff1a; 传输层状态机&#xff1a;处理TCP/UDP四层传输层HTTP状态机&#xff1a;处理应用层MAIL状态机&#xff1a;处理邮件 状态机作用&#xff1a;Ngin…

nginx工作原理:

首先nginx,采用的是多线程&多路io复用模型,使用I/O多路复用技术的nginx,成就了”并发驱动”的服务器. nginx的框架模型: 进程组件角色: master进程: 监视工作进程的状态,当工作进程死掉后重启一个新的,处理信号和通知工作进程. work进程: 处理客户端请求,从主进程处获得…

原来使用 Spring 实现策略模式可以这么简单

策略模式作为一种软件设计模式&#xff0c;指对象有某个行为&#xff0c;但是在不同的场景中&#xff0c;该行为有不同的实现算法&#xff0c;可以替代代码中大量的 if-else。 比如我们生活中的场景&#xff1a;买东西结账可以使用微信支付、支付宝支付或者银行卡支付&#xf…

策略设计模式

介绍 Java策略模式(Strategy Pattern)是一种行为设计模式,它允许再运行时动态选择算法的行为.策略模式通过将算法封装在可互换的策略对象中,使得客户端代码能够轻松地切换算法,而无需修改原始代码.在策略模式中,每个算法都被实现为一个单独的策略类,这些策略类都实现了相同的接…

Java 设计模式——策略模式(行为型设计模式)

策略模式用我个人的理解就是&#xff1a; 用一种更灵活更优雅和更健壮的方式替换了if…else… 一、问题引入 当我们导出一些数据到Excel表格时&#xff0c;有时候需要从不同的维度导出&#xff08;如&#xff1a;个人维度&#xff0c;时间维度&#xff09;&#xff0c;不同维…

采用注解实现策略模式

目录 一、前言 二、采用简单的注解方式进行业务策略模式 &#xff08;一&#xff09;场景举例 &#xff08;二&#xff09;实现方案 1、基本代码准备 2、基本功能接口定义 3、定义注解与不同的策略实现 4、业务实际使用 5、测试及结果展示 三、采用组合的注解方式进行…

​JAVA设计模式(六)——策略模式

下图为所有设计模式&#xff0c;带标记为重点掌握以及工作中常用到的&#xff1a; 策略模式是行为型设计模式之一&#xff0c;其作用是让一个类的行为或其算法可以在运行时更改&#xff0c;该模式也算是我比较熟悉的模式之一了&#xff0c;因为之前项目中有幸遇到大佬用过&…

java 策略模式例子_策略模式—Java实现(转)

1. 现实需求 客户有了新的需求&#xff0c;这时我们直接新增策略即可&#xff0c;改很少的代码。基本符合我们面向对象原则中的开闭原则(对扩展开放&#xff0c;对修改关系)&#xff0c;实现了高内聚低耦合。 2. 策略模式定义 策略模式&#xff0c;又叫算法簇模式&#xff0c;就…

Java设计模式(五)策略模式-在SpringBoot项目中的实际应用

文章目录 什么是策略模式优点缺点使用场景结构图 策略模式的简单示例策略模式的项目实战场景实现 小结 什么是策略模式 官话&#xff1a;策略模式(Strategy Pattern)&#xff1a; 定义一系列算法类&#xff0c;将每一个算法封装起来&#xff0c;并让它们可以相互替换&#xff…

java调用微信加密_java微信消息加解密

今天心血来潮就信手拈来学了下微信消息加解密的知识,忽然觉得微信真的好强大。可能在大部分项目微信消息的加解密都用不上,但是仍然不排除有使用到的情况,如涉及金钱方面的微信应用包括商城类、金融类还有其他安全级别要求很高的微信应用。针对这些情况我觉得还是有必要分享…

spring如何使用策略模式

这里使用登录做例子介绍如何实现登录的多种策略 上图是策略模式的基础模型。 context Context上下文角色&#xff0c;也叫Context封装角色&#xff0c;起承上启下的作用&#xff0c;屏蔽高层模块对策略、算法的直接访问&#xff0c;封装可能存在的变化。 Strategy 策略角色…

java设计模式实战-(反射+策略模式)

学完23种设计模式&#xff0c;相信很多同学都疑问&#xff0c;除了单例模式、工厂模式其他模式还有运用的场景吗&#xff1f; 现在这里就举一个例子。 首先策略模式需要先有了解&#xff0c;我们常用策略模式解决实际开发中的if else特别多的场景。但是在实际的开发中&#x…

Java23种设计模式之策略模式【普通写法以及spring中的写法】

目录 设计模式简介策略模式的简介普通写法案例基于注解式改造的案例优缺点策略模式的使用场景 设计模式简介 将设计者的思维融入大家的学习和工作中&#xff0c;更高层次的思考&#xff01; • 创建型模式&#xff1a; – 单例模式、工厂模式、抽象工厂模式、建造者模式、原型…

Java设计模式-策略模式(支付业务的优化)

一、什么情况下使用策略模式 功能类似的业务功能&#xff0c;避免创建多个接口&#xff0c;大量if else 判断逻辑&#xff0c;简化代码 二、我以支付为例&#xff08;支付方式有微信&#xff0c;支付宝支付&#xff09; 1、新建策略抽象类或者接口 public interface ThirdP…

java策略模式实战示例

现已放在gitee上,可以不下载直接参考一下即: https://gitee.com/zhang-xiao-xiang/zxx-pattern 日常碰到的业务概述 登录类型,支付类型,供应商渠道,不同等级会员享受的优惠券价格不一样,等等业务判断,大量if else导致拓展(侧重新增)极其困难,维护(侧重修改)自然是改起来头痛(…

【JAVA设计模式】策略模式

1.什么是策略模式&#xff1f; 策略模式是对算法的包装&#xff0c;是把使用算法的责任和算法本身分割开来&#xff0c;委派给不同的对象管理&#xff0c;相同的事情-----选择不用同方式 &#xff08;不同实现&#xff09;举例子&#xff0c;最终可以实现解决多重if判断问题。 …