nginx

作者本人也搭建了一个docker镜像加速器,需要的朋友随时联系作者,镜像加速嘎嘎快,快速解决docker镜像拉不下的问题,文章最后带有作者wx,先好好学习吧。

nginx

一 系统I/O模型:

1.1.1 同步/异步

关注的是事件处理的消息通信机制,即在等待一件事情的处理结果时,被调用者是否提供完成通知。

同步:synchronous,调用者等待被调用者返回消息后才能继续执行,如果被调用者不提供消息返回则为同步,同步需要调用者主动询问事情是否处理完成。

异步:asynchronous,被调用者通过转态、通知或回调机制主动通知调用者,即异步会主动返回被调用者的状态给调用者。

同步:进程发出请求调用后,内核不提供通知机制,即文件IO处理完成后不通知进程,需要进程自己去问内核是否处理完成
异步:进程发出请求调用后,内核会在调用处理完成后返回调用结果给进程,nginx时异步的。

在这里插入图片描述

1.1.2: 阻塞/非阻塞

关注调用者在等待结果返回之前所处的状态

阻塞:blocking,指IO操作需要彻底完成后才返回到用户空间,调用结果返回之前,调用者被挂起,干不了别的事情
非阻塞:nonblocking,指IO操作被调用后立即返回给用户一个状态值,无需等到IO操作彻底完成,最终的调用者结果返回之前,调用者不会被挂起,可以去做别的事情。

在这里插入图片描述

1.1.3:系统IO模型组合:

在这里插入图片描述

二 nginx基础

2.1 nginx功能介绍

静态的web资源服务器html,图片,js,css,txt等静态资源

结合FastCGI/uWSGI/SCGI等协议反向代理动态资源请求

http/https协议的反向代理

imap4/pop3协议的反向代理
tcp/udp协议的请求转发(反向代理)

2.1.1:基础特性
特x性:
模块化设计,较好的扩展性
高可靠性
支持热部署:不停机更新配置文件,升级版本,更换日志文件
低内存消耗:10000个keep-alive链接模式下的非活动连接,仅需2.5M内存
event-driven,aio,mmap,sendfile


基本功能:
静态资源的web服务器
http协议反向代理服务器
pop3/imap4 协议反向代理服务器
FastCGI(lnmp),uWSGI(python)等协议
模块化(非DSO),如zip,SSL模块
2.1.2:和web服务相关的功能
虚拟主机(server)
支持 keep-alive 和管道连接(利用一个连接做多次请求)
访问日志(支持基于日志缓冲提高其性能)
url rewrite
路径别名
基于IP及用户的访问控制
支持速率限制及并发数限制
重新配置和在线升级而无须中断客户的工作进程(reload工作原理 生成两个相同的进程,把新的请求转发到这两个进程上去,原先那两个处理完后在销毁)

在这里插入图片描述

2.2:nginx组织结构

web请求处理机制:
1、多进程方式:服务器每接收到一个客户端请求就有服务器的主进程生成一个子进程相应客户端,直到用户关闭连接,这样的优势是处理速度快,各子进程之间相互独立,但是如果访问过大会导致服务器资源耗尽而无法提供请求。
2、多线程方式:与多进程方式类似,但是每收到一个客户端请求会有服务进程派生出一个线程来个客户方进行交互,一个线程的开销远远小于一个进程,因此多线程方式在很大程度减轻了web服务器对系统资源的要求,但是多线程也有自己的缺点,即当多个线程位于同一个进程内工作的时候,可以相互访问同样的内存地址空间,所以他们相互影响,另外一旦主进程挂掉则所有子线程都不能工作了,II S服务器使用了多线程的方式,需要间隔一段时间就重启一次才能稳定
2.2.1: 组织模型

nginx是多进程组织模型,而且是一个由Master主进程和Worker工作进程组成。
在这里插入图片描述

主进程(master process)的功能

读取Nginx 配置文件并验证其有效性和正确性
建立、绑定和关闭socket连接
按照配置生产、配置和结束工作进程
接受外界指令,比如重启、升级及退出服务器等指令
不中断服务,实现平滑升级,升级失败进行回滚处理,重启服务并应用新的配置
开启日志文件,获取文件描述符
编译和处理perl脚本

工作进程(worker process)的功能

接受处理客户的请求
将请求依次送入各个功能模块进行处理
IO调用,获取响应数据
与后端服务器通信,接收后端服务器的处理结果
缓存数据,访问缓存索引,查询和调用缓存数据
发送请求结果,响应客户的请求
接收主程序指令,比如重启、升级和退出等

清空20G日志文件 echo > a.log 不能rm -rf

在这里插入图片描述

2.2.2: 进程间通信

在这里插入图片描述

2.2.3 编译安装nginx
编译的三个过程:
configure 按照参数生成makefile文件
make 按照makefile文件生成模块
make install 把模块拷贝到指定的路径
官方源码包下载地址
https://nginx.org/en/download.html

安装依赖的文件
yum -y install pcre pcre-devel zlib zlib-devel gcc gcc-c++ glibc glibc-devel systemd-devel zip zlib-devel openssl openssl-devel wget
pcre pcre-devel:使nginx支持正则表达式
zlib zlib-devel:使nginx支持gzip压缩
openssl openssl-devel:使nginx支持https


[root@k8s-vip nginx-1.20.2]#./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-file-aio \ 
--with-stream \ 
--with-stream_ssl_module \ 
--with-stream_realip_module \ 
--add-module=/usr/local/src/nginx-module-vts/(Prometheus抓取数据的模块) \ 
[root@k8s-vip nginx-1.20.2]# make
[root@k8s-vip nginx-1.20.2]# make install
[root@k8s-vip nginx-1.20.2]# useradd nginx


编写service文件
vim /usr/lib/systemd/system/nginx.service
[Unit]
Description=The nginx HTTP and reverse proxy server
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target

[Service]
Type=forking
PIDFile=/apps/nginx/logs/nginx.pid
# Nginx will fail to start if /run/nginx.pid already exists but has the wrong
# SELinux context. This might happen when running `nginx -t` from the cmdline.
# https://bugzilla.redhat.com/show_bug.cgi?id=1268621
ExecStartPre=/usr/bin/rm -f /apps/nginx/logs/nginx.pid
ExecStartPre=/apps/nginx/sbin/nginx -t
ExecStart=/apps/nginx/sbin/nginx
ExecReload=/apps/nginx/sbin/nginx -s reload
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=process
PrivateTmp=true

[Install]
WantedBy=multi-user.target

在这里插入图片描述

2.2.4 yum 安装nginx
yum install epel-release
yum install nginx -y
2.2.5 默认的配置文件

在这里插入图片描述

三 nginx核心配置

3.1:全局配置

nginx 配置网站 https://nginx.org/en/docs/ngx_core_module.html#daemon

user nginx nginx; 启动Nginx工作进程的用户和组
worker_processes [number | auto]; #启动Nginx工作进程的数量
worker_cpu_affinity auto; #将Nginx工作进程绑定到指定的CPU核心,默任Nginx是不进行进程绑定的,绑定并不是意味着当前nginx进程独占以一核心CPU,但是可以保证此进程不会运行在其他核心上,这就极大减少了ngnx的工作进程在不同的cpu核心上的来回跳转,减少了CPU对进程的资源分配与回收以及内存管理等,因此可以有效的提升nginx服务器的性能。

[root@k8s-vip ~]# while true; do curl 172.16.10.105/234.jpg sleep 0.2s;done;
[root@k8s-vip conf]# watch -n1 'ps -axo pid,cmd,psr | grep nginx' #查看进程变化
  2275 nginx: master process /apps   0
 79168 nginx: worker process         0
 79169 nginx: worker process         1
 82972 grep nginx                    0

#错误日志记录配置,语法:error_log file [debug | info | notice | warn | error | crit | alert | emerg]
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
error_log  /apps/nginx/logs/error.log error;

#pid文件保存路径
pid /apps/nginx/logs/nginx.pid;


worker_priority 0; #工作进程nice值, -20-19  越低优先级越高
worker_rlimit_nofile 65536; #这个数字包括Nginx的所有连接(例如与代理服务器的连接,与后端服务器的连接等),而不仅仅是与客户端的连接,另一个考虑因素是实际的并发连接数不能超过系统级别的最大文件数的限制


daemon off; #前台运行Nginx服务用于测试、docker等环境
master_process off|on; #是否开启Nginx的master-worker工作模式,仅用于开发调试场景

events {   #事件模型配置参数
    worker_connections  1024; #设置单个工作进程的最大并发链接数
    use epoll; # 使用epoll事件驱动,Nginx支持众多的事件驱动,比如select、poll、epoll,智能设置在events模块中
    accept_mutex on;#优化同一时刻只有一个请求而避免多个睡眠进程被唤醒的设置,on为防止被同时唤醒,默认为off,全部唤醒的过程也成为"惊群",因此nginx刚安装完以后要进行适当的优化。
    multi_accept on;#Nginx服务器的每个工作进程可以同时接受多个新的网络连接,但是需要在配置文件中配置,此指令默认为关闭,即默认为一个工作进程只能一次接受一个新的网络连接,打开后几个同时接受多个。
}

3.2:http详细配置

http {
    include       mime.types; #导入支持的文件类型
    default_type  application/octet-stream; #设置默认的类型,会提示下载不匹配的类型文件
#日志配置部分
    #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; #实现文件零拷贝 (原理:nginx调内核,内核调cpu,cpu吧数据调内存,不在往进程拷贝(也不会再进程中构建响应报文,节省两次内存到进程的时间),内存吧数据拷到socket区域,构建响应报文。)
    #tcp_nopush     on; #在开启了sendfile的情况下,合并请求后同意发送给客户端
	#tcp_nodelay on | off; #在开启keepalived模式下的连接是否启动TCP_NODELAY选项,当为off时,延迟0.2s发送,默认为On时,不延迟发送,立即发送用户响应报文。
    #keepalive_timeout  0;
    keepalive_timeout  65 65;#设置会话保持时间

    #gzip  on;# 开启文件压缩
     server {
        listen       80;#设置监听地址和端口
        server_name  localhost;#设置server name,可以以空格隔开写多个并支持正则表达式。如*.magedu.com

        #charset koi8-r;#设置编码格式,默认是俄语模式,可以改为utf-8

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
        }

        #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;
        }
        #location ~ \.php$ { #以http的方式转发php请求到指定web服务器
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ { #以fastcgi的方式转发php请求到php处理
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}
        
        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {#拒绝web形式访问指定文件,如很多网站都是通过.htaccess文件来改变自己的重定向等功能。
        #    deny  all;
        #}
        location ~ /passwd.html {
            deny all;
        }
    }       
 

3.3 正则表达式

/:正则表达式的开始和结束符号。

^:表示匹配文本的开头。例如,/^abc/ 表示匹配以 "abc" 开头的文本。

$:表示匹配文本的结尾。例如,/abc$/ 表示匹配以 "abc" 结尾的文本。

.:匹配任意单个字符,不包括换行符。例如,/a.c/ 表示匹配以 "a" 开头,"c" 结尾,中间有任意一个字符的文本。

|:表示或,可以用于匹配多个表达式中的任意一个。例如,/abc|def/ 表示匹配 "abc" 或 "def"。

[]:表示字符集,用于匹配一组字符中的任意一个。例如,/[abc]/ 表示匹配字母 "a"、"b" 或 "c" 中的任意一个。

():表示分组,可以将一部分正则表达式放在括号中,并对它们进行分组匹配。例如,/(ab)+/ 表示匹配一或多个 "ab"。

?:表示可选,用于匹配前面的字符或表达式出现零次或一次。例如,/a?b/ 表示匹配零个或一个 "a",后面紧跟一个 "b"。

*:表示零个或多个,用于匹配前面的字符或表达式出现零次或多次。例如,/ab*c/ 表示匹配一个 "a",后面跟着零个或多个 "b",最后紧跟一个 "c"。

+:表示一或多个,用于匹配前面的字符或表达式出现一次或多次。例如,/ab+c/ 表示匹配一个 "a",后面跟着一个或多个 "b",最后紧跟一个 "c"。

{}:表示重复次数,用于指定前面的字符或表达式重复出现的次数范围。例如,/ab{2,4}c/ 表示匹配一个 "a",后面跟着两到四个 "b",最后紧跟一个 "c"。

\:表示转义字符,用于将特殊字符转义为普通字符。例如,/a\./ 表示匹配一个 "a",后面跟着一个 "."。

以上是一些常见的正则表达式符号和元字符的说明,还有一些比较重要的符号和元字符:

[] 中的 ^:表示不在字符集中,用于匹配不属于指定字符集中的任意字符。例如,/[^abc]/ 表示匹配除了 "a"、"b"、"c" 之外的任意字符。

[] 中的 -:表示字符范围,用于匹配指定范围内的任意字符。例如,/[a-z]/ 表示匹配任意小写字母。

() 中的 |:表示分组中的或,可以用于匹配分组中的任意一个表达式。例如,/(ab|cd)/ 表示匹配 "ab" 或 "cd"。


3.4 核心配置实例:

基于不同的IP、不同的端口以及不用的域名实现不同的虚拟主机,依赖于核心模块ngx_http_core_module实现。

3.4.1:构建一个PC web站点
[root@k8s-vip conf.d]# mkdir /apps/nginx/conf/conf.d
[root@k8s-vip conf.d]# cat /apps/nginx/conf/conf.d/pc.conf
server {
   listen 80;
   server_name pc.gf.com;
   location / {
       root /data/nginx/html/pc;
    }
}
[root@k8s-vip conf.d] mkdir /date/nginx/html/pc -p
[root@k8s-vip conf.d] echo "pc server" >/date/nginx/html/pc/index.html
[root@k8s-vip conf.d] vim /apps/nginx/conf/nginx.conf
        include /apps/nginx/conf/conf.d/*.conf;
[root@k8s-vip conf.d] /apps/nginx/sbin/nginx -s reload
访问测试
3.4.2:构建一个Mobile web站点
server {
   listen 80;
   server_name mobile.gf.com;
   location / {
       root /data/nginx/html/mobile;
    }
}
mkdir /data/nginx/html/mobile
echo 'mobile server' > /data/nginx/html/mobile/index.html
/apps/nginx/sbin/nginx -s reload
访问测试
3.4.3: root与alias

root: 指定web的家目录,在定义location的时候,文件的绝对路径等于root+location,如

server {
   listen 80;
   server_name pc.gf.com;
   location / {
       root /data/nginx/html/pc;
    }
    location /about {
       root /data/nginx/html/pc; #必须要在html目录中创建一个about目录才可以访问,否则报错.
       index index.html;
       }
}
mkdir /data/nginx/html/pc/about
echo about > /data/nginx/html/pc/abount/index.html
重启nginx并访问测试

alias:定义路径别名,会把访问的路径重新定义到其指定的路径:如

server {
   listen 80;
   server_name pc.gf.com;
   location / {
       root /data/nginx/html/pc;
    }
    location /about {# 使用alias的时候uri后面如果加了斜杠则下面的路径配置必须加斜杠,否则403
       alias /data/nginx/html/pc; #当访问about的时候,会显示alias定义的/data/nginx/html/pc里面的内容。
       index index.html;
       }
}
重启nginx并访问测试
3.4.4: location的详细使用:

在没有使用正则表达式的时候,nginx会先在server中的多个location选取匹配度最高的一个uri,uri是用户请求的字符串,即域名后面的web文件路径,然后使用该location模块的正则url和字符串,如果匹配成功就结束搜索,并使用location处理此请求。

语法规则: location [=|~|~*|^~] /uri/ {...}
= #用于标准的uri前,需要请求字符串与uri精确匹配,如果匹配成功就停止向下匹配并立即处理请求。
~ #用于标准的uri前,表示包含正则表达式并且区分大小写,并且匹配
!~ #用于标准的uri前,表示包含正则表达式并且区分大小写,并且不匹配

~* #用于标准的uri前,表示包含正则表达式并且不区分大小写,并且匹配
!~* #用于标准的uri前,表示包含正则表达式并且不区分大小写,并且不匹配

^~ #用于标准的uri前,表示包含正则表达式并且匹配以什么开头
$  #用于标准的uri前,表示包含正则表达式并且匹配以什么结尾
\  #用于标准的uri前,表示包含正则表达式并且转义字符。可以转. * ?等
*  #用于标准的uri前,表示包含正则表达式并且代表任意长度的任意字符

在这里插入图片描述

在这里插入图片描述

3.4.4.1:匹配案例-精确匹配

在server部分使用location配置一个web界面,要求:当访问nginx服务器/login的时候要显示指定html文件的内容

server {
   listen 80;
   server_name pc.gf.com;
   location / {
       root /data/nginx/html/pc;
    }
    location /about {
       root /data/nginx/html/pc;
       index index.html;
       }
    location = /1.jpg {
       root /var/nginx/image;
       index index.html;
       }
}
上传图片到/var/nginx/image,重启nginx并访问测试
访问测试   pc.gf.com/1.jpg
3.4.4.2 匹配案例-区分大小写

如果uri中包含大写字母,则一下location匹配Ax.jpg条件不成功,因为~为区分大小写,那么当用户的请求被执行匹配时发现location中定义的是大写的A,则匹配失败,即要么继续往下匹配其他的location(如果有),要么报错给客户端

location ~ /A.?\.jpg { #匹配除换行符\n之外的其他任何单字符0次或多次
       root /var/nginx/image;
       index index.html;
       }
3.4.4.3 匹配案例-不区分大小写
location ~* /A.?\.jpg {
       root /var/nginx/image;
       index index.html;
       }
3.4.4.4 匹配案例-URI开始:
server {
   listen 80;
   server_name pc.gf.com;
   location / {
       root /data/nginx/html/pc;
    }
    location ^~ /images { #匹配以images开头
       root /data/nginx/html/pc;
       index index.html;
       }
    location  /images1 {
       root /data/nginx/html/pc;
       index index.html;
       }
}

3.4.4.5:匹配案例-文件名后缀
server {
   listen 80;
   server_name pc.gf.com;
   location / {
       root /data/nginx/html/pc;
    }
    location ~* \.(gif|jpg|jpeg|bmp|png|tiff|tif|ico|wmf|js)$ {
       root /data/nginx/images;
       index index.html;
       }
} 


    location ~ /images/.*\.((gif|jpg|jpeg|bmp|png|tiff|tif|ico|wmf|js))$ {
       root /data;
       index index.html;
       valid_referers none blocked server_names
          ~\.baidu\.  ~\.google\.;
       if ($invalid_referer) {
            return 403;
          }
       }
重启nginx并访问测试
3.4.4.6:匹配案例-优先级:
server {
   listen 80;
   server_name pc.gf.com;
   location / {
       root /data/nginx/html/pc;
    }
    location ~* /1.jpg {
       root /data/nginx;
       index index.html;
       }
    location = /1.jpg { #通常用于精确匹配指定文件,如favicon.ico、index.jsp等
       root /data/nginx/images;
       index index.html;
       }
}
匹配优先级: = ^~ ~/~* /
location优先级:(location =) > (location 完整路径) > (location ^~路径) > (location ~ ~* 正则顺序) > (location 部分起始路劲) > (/)
3.3.4.7:生产使用案例
直接匹配网站根会加速Nginx访问处理:
location = /index.html {
  ...;
}
location = / {
  ...;
}
静态资源配置
location ^~ /static {
  ...;
}
location ~* \.(gif|jpg|jpeg|bmp|png|tiff|tif|ico|wmf|js)$ {
  ...;
}
多应用配置
location ~* /app1 {
  ...;
}
location ~* /app2 {
  ...;
}

3.5: nginx三层访问控制:

访问控制基于模块ngx_http_access_module实现,可以通过匹配客户端源ip地址进行限制

    location ~* /1.jpg {
       root /data/nginx;
       index index.html;
       allow 172.16.10.105;
       deny all; #先永许小部分,在拒绝大部分
       }

3.6:Nginx账户认证功能:

[root@k8s-vip ~]# yum install -y httpd-tools -y
[root@k8s-vip ~]# htpasswd -cbm /apps/nginx/conf/.htpasswd gf 123456 #第一次要创建文件
[root@k8s-vip ~]# htpasswd -bm /apps/nginx/conf/.htpasswd zyr 123456
    location /login {
        root /data/nginx/html/pc;
        index index.html;
        auth_basic "login passwd";
        auth_basic_user_file /apps/nginx/conf/.htpasswd;
        }

3.7:自定义错误页面

server {
   listen 80;
   server_name pc.gf.com;
   location / {
       root /data/nginx/html/pc;
    }
    location ~* /1.jpg {
       root /data/nginx;
       index index.html;
       #allow 172.16.10.105;
       deny all;
       }
    error_page   500 502 503 504 404  /error.html;
    location = /error.html {
        root   /data/nginx;
     }
}

3.8:自定义访问日志

server {
   listen 80;
   server_name pc.gf.com;
   access_log /var/nginx/logs/pc.gf.com-access.log main;
   error_log /var/nginx/logs/pc.gf.com-error.log info;
   location / {
       root /data/nginx/html/pc;
    }
    location ~* /1.jpg {
       root /data/nginx;
       index index.html;
       #allow 172.16.10.105;
       deny all;
       }
    error_page   500 502 503 504 404  /error.html;
    location = /error.html {
        root   /data/nginx;
     }
}

3.9: 检测文件是否存在

try_files会按顺序检测文件是否存在,返回第一个找到的文件或文件夹(结尾加斜线表示为文件夹,如果所有文件或文件夹都找不到,会进行一个内部重定向到最后一个参数。只有最后一个参数可以引起一个内部重定向,之前的参数只设置内部URI的指向。最后一个参数是回退URI且必须存在,否则会出现内部500错误)

访问:http://127.0.0.1/
$uri:/index.html
$request_uri:/  

location /images {
       root /data/nginx/html;
       try_files $uri /images/index.html;
       #try_files $uri $uri/index.html $uri.html =404;
       #try_files $uri =404;
   }
重启nginx测试,当访问到http://pc.gf.com/images/1 等不存在的uri会显示/images/index.html,如果是自定义状态码则会显示在返回数据的状态码中。

3.10:长连接配置:

keepalive_requests number: 在一次长连接上所永许请求的资源的最大数量,默认为100次

keepalive_timeout number:设定保持连接超时时长,0表示禁止长连接,默认为75s,通常配置在http字段作为站点全局配置


                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

忙里偷闲学python

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值