diff --git a/nginx-md/第三章:Nginx特性.md b/nginx-md/第三章:Nginx特性.md new file mode 100644 index 0000000..dc1a372 --- /dev/null +++ b/nginx-md/第三章:Nginx特性.md @@ -0,0 +1,564 @@ +

Nginx特性

+ +**作者:行癫(盗版必究)** + +------ + +## 一:Nginx Proxy代理 + +![image-20221009194316358](https://xingdian-image.oss-cn-beijing.aliyuncs.com/xingdian-image/image-20221009194316358.png) + +#### 1.正向代理 + +​ 正向代理的过程隐藏了真实的请求客户端,服务器不知道真实的客户端是谁,客户端请求的服务都被代理服务器代替请求。我们常说的代理也就是正向代理,正向代理代理的是请求方,也就是客户端;比如我们要访问youtube,可是不能访问,只能先安装个FQ软件代你去访问,通过FQ软件才能访问,FQ软件就叫作正向代理 + +案例:贷款 + +​ 正向代理中,proxy和client同属一个LAN + +image-20221009194453786 + +#### 2.反向代理 + +​ 反向代理的过程隐藏了真实的服务器,客户不知道真正提供服务的人是谁,客户端请求的服务都被代理服务器处理。反向代理代理的是响应方,也就是服务端;我们请求www.baidu.com时这www.baidu.com就是反向代理服务器,真实提供服务的服务器有很多台,反向代理服务器会把我们的请求分转发到真实提供服务的各台服务器。Nginx就是性能非常好的反向代理服务器,用来做负载均衡 + +image-20221009194637284 + +​ 反向代理中,proxy和server同属一个LAN + +image-20221009194710521 + +#### 3.Nginx Proxy + +模块:ngx_http_proxy_module + +代理配置: + +```shell +代理 +Syntax: proxy_pass URL; #代理的后端服务器URL +Default: — +Context: location, if in location, limit_except + +缓冲区 +Syntax: proxy_buffering on | off; +Default: proxy_buffering on; #缓冲开关 +Context: http, server, location +proxy_buffering开启的情况下,nignx会把后端返回的内容先放到缓冲区当中,然后再返回给客户端 +(边收边传,不是全部接收完再传给客户端)。 + +Syntax: proxy_buffer_size size; +Default: proxy_buffer_size 4k|8k; #缓冲区大小 +Context: http, server, location + +Syntax: proxy_buffers number size; +Default: proxy_buffers 8 4k|8k; #缓冲区数量 +Context: http, server, location + +Syntax: proxy_busy_buffers_size size; +Default: proxy_busy_buffers_size 8k|16k;#忙碌的缓冲区大小控制同时传递给客户端的buffer数量 +Context: http, server, location + +头信息 +Syntax: proxy_set_header field value; +Default: proxy_set_header Host $proxy_host; #设置真实客户端地址 + proxy_set_header Connection close; +Context: http, server, location + +超时 +Syntax: proxy_connect_timeout time; +Default: proxy_connect_timeout 60s; #链接超时 +Context: http, server, location + +Syntax: proxy_read_timeout time; +Default: proxy_read_timeout 60s; +Context: http, server, location +``` + +启用 nginx proxy 代理: + +​ nginx-1 启动网站(内容)(作为网站服务器) + +​ nginx-2 启动代理程序 + +```shell +[root@nginx-server ~]# vim /etc/nginx/conf.d/default.conf +server { + listen 80; + server_name localhost; + + location / { + proxy_pass http://10.0.105.199:80; + proxy_redirect default; + proxy_set_header Host $http_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; + + proxy_connect_timeout 30; + proxy_send_timeout 60; + proxy_read_timeout 60; + + proxy_buffering on; + proxy_buffer_size 32k; + proxy_buffers 4 128k; + proxy_busy_buffers_size 256k; + proxy_max_temp_file_size 256k; + } +} +``` + +nginx proxy 具体配置详解: + +```shell +proxy_pass :真实服务器的地址,可以是ip也可以是域名和url地址 +proxy_redirect :如果真实服务器使用的是的真实 IP:非默认端口。则改成IP:默认端口。 +proxy_set_header:重新定义或者添加发往后端服务器的请求头 +proxy_set_header X-Real-IP :启用客户端真实地址(否则日志中显示的是代理在访问网站) +proxy_set_header X-Forwarded-For:记录代理地址 + +proxy_connect_timeout::后端服务器连接的超时时间发起三次握手等候响应超时时间 +proxy_send_timeout:后端服务器数据回传时间就是在规定时间之内后端服务器必须传完所有的数据 +proxy_read_timeout :nginx接收upstream(上游/真实) server数据超时, 默认60s, 如果连续的60s内没有收到1个字节, 连接关闭。像长连接 + +proxy_buffering on;开启缓存 +proxy_buffer_size:proxy_buffer_size只是响应头的缓冲区 +proxy_buffers 4 128k; 内容缓冲区域大小 +proxy_busy_buffers_size 256k; 从proxy_buffers划出一部分缓冲区来专门向客户端传送数据的地方 +proxy_max_temp_file_size 256k;超大的响应头存储成文件 +``` + +## 二:Nginx负载均衡 + +​ 随着网站、应用访问量的增加,一台服务器已经不能满足应用的需求,而需要多台服务器集群,这时就会用到负载均衡 + +#### 1.负载均衡配置 + +```shell +upstream testapp { + server 10.0.105.199:8081; + server 10.0.105.202:8081; + } + server { + .... + location / { + proxy_pass http://testapp; #请求转向 testapp 定义的服务器列表 + } + +upstream mysvr { + server http://10.0.105.199:8081; + server http://10.0.105.202:8081; + } + server { + .... + location / { + proxy_pass http://mysvr; #请求转向mysvr 定义的服务器列表 + } +``` + +#### 2.负载均衡算法 + +​ 轮询(默认):每个请求按时间顺序逐一分配到不同的后端服务器 + +​ ip_hash:每个请求按访问IP的hash结果分配,同一个IP客户端固定访问一个后端服务器 + +​ url_hash:按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器 + +​ fair:这是比上面两个更加智能的负载均衡算法。按后端服务器的响应时间来分配请求,响应时间短的优先分配 + +注意: + +​ Nginx本身是不支持 fair的,如果需要使用这种调度算法,必须下载Nginx的 upstream_fair模块 + +#### 3.配置实例 + +```shell +1)、热备:如果你有2台服务器,当一台服务器发生事故时,才启用第二台服务器给提供服务。服务器处理请求的顺序:AAAAAA突然A挂啦,BBBBBBBBBBBBBB..... +upstream myweb { + server 172.17.14.2:8080; + server 172.17.14.3:8080 backup; #热备 + } +2)、轮询:nginx默认就是轮询其权重都默认为1,服务器处理请求的顺序:ABABABABAB.... +upstream myweb { + server 172.17.14.2:8080; + server 172.17.14.3:8080; + } +3)、加权轮询:跟据配置的权重的大小而分发给不同服务器不同数量的请求。如果不设置,则默认为1。下面服务器的请求顺序为:BBABBABBABBABB.... +upstream myweb { + server 172.17.14.2:8080 weight=1; + server 172.17.14.3:8080 weight=2; +} +4、ip_hash:nginx会让相同的客户端ip请求相同的服务器。 +upstream myweb { + server 172.17.14.2:8080; + server 172.17.14.3:8080; + ip_hash; + } + +5)、nginx负载均衡配置状态参数 +• down,表示当前的server暂时不参与负载均衡。 + +• backup,预留的备份机器。当其他所有的非backup机器出现故障或者忙的时候,才会请求backup机器,因此这台机器的压力最轻。 + +• max_fails,允许请求失败的次数,默认为1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误。 + +• fail_timeout,在经历了max_fails次失败后,暂停服务的时间单位秒。max_fails可以和fail_timeout一起使用。 + upstream myweb { + server 172.17.14.2:8080 weight=2 max_fails=2 fail_timeout=2; + server 172.17.14.3:8080 weight=1 max_fails=2 fail_timeout=1; + } +``` + +#### 4.Nginx七层负载案例 + +![image-20221009215449110](https://xingdian-image.oss-cn-beijing.aliyuncs.com/xingdian-image/image-20221009215449110.png) + +## 三:Nginx会话保持 + +#### 1.实现方式 + +ip_hash: + +​ ip_hash使用源地址哈希算法,将同一客户端的请求总是发往同一个后端服务器,除非该服务器不可用 + +语法: + +```shell +upstream backend { + ip_hash; + server backend1.example.com; + server backend2.example.com; + server backend3.example.com; +} +``` + +ip_hash简单易用,但有如下问题: + +​ 当后端服务器宕机后,session会丢失 + +​ 来自同一局域网的客户端会被转发到同一个后端服务器,可能导致负载失衡 + +sticky_cookie_insert: + +​ 使用sticky_cookie_insert启用会话亲缘关系,这会导致来自同一客户端的请求被传递到一组服务器的同一台服务器 + +​ 与ip_hash不同之处在于,它不是基于IP来判断客户端的,而是基于cookie来判断 + +​ 因此可以避免上述ip_hash中来自同一局域网的客户端和前段代理导致负载失衡的情况 + +#### 2.部署 + +环境: + +```shell +一台服务器做负载均衡并且使用第三方模块sticky来做会话保持 + 192.168.182.130(sticky) + 两台服务器做web-server + 192.168.182.131(web-server-1) + 安装nginx并运行 自己创建一个测试界面,使用curl能否访问到内容,保证web-server-1可用。 + 192.168.182.132(web-server-2) + 安装nginx并运行 自己创建一个测试界面,使用curl能否访问到内容,保证web-server-2可用。 +``` + +下载插件: + +```shell +[root@xingdian ~]# wget https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/get/08a395c66e42.zip +``` + +下载源码包: + +```shell +[root@xingdian ~]# wget https://nginx.org/download/nginx-1.22.0.tar.gz +``` + +解压: + +```shell +[root@xingdian ~]# unzip 08a395c66e42.zip +[root@xingdian ~]# tar xf nginx-1.22.0.tar.gz +[root@xingdian ~]# mv nginx-goodies-nginx-sticky-module-ng-08a395c66e42/ nginx-sticky +``` + +配置: + +```shell +[root@xingdian nginx-1.22.0]# cd nginx-1.22.0 +[root@xingdian nginx-1.22.0]# ./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie' +``` + +编译安装: + +```shell +[root@xingdian nginx-1.22.0]# make && make install +``` + +配置负载均衡和会话保持: + +```shell +vim /etc/nginx/nginx.conf +以下只是要添加的内容: + upstream xingdian { + server 192.168.182.131; + server 192.168.182.132; + sticky ; + } + +vim /etc/nginx/conf.d/default.conf +以下为配置文件修改的内容: + location / { + proxy_pass http://xingdian; + } +``` + +重启服务: + +```shell +[root@xingdian nginx-1.22.0]# systemctl restart nginx +``` + +## 四:动静分离 + +#### 1.介绍 + +​ 一般来说,都需要将动态资源和静态资源分开,将静态资源部署在Nginx上,当一个请求来的时候,如果是静态资源的请求,就直接到nginx配置的静态资源目录下面获取资源,如果是动态资源的请求,nginx利用反向代理的原理,把请求转发给后台应用去处理,从而实现动静分离 + +处理静态的服务:nginx apache + +处理动态的服务:web容器/web中间件 php(php)tomcat(java) uwsgi(python) + +#### 2.实验部署 + +环境: + +| 服务器 | 要求 | +| :-------------: | :----------------: | +| 192.168.182.130 | 动静分离、upstream | +| 192.168.182.131 | static | +| 192.168.182.132 | php-server | + +配置代理: + +```shell +vim /etc/nginx/nginx.conf (只是写了修改的内容) +upstream static { + server 10.0.105.196:80 weight=1 max_fails=1 fail_timeout=60s; + } +upstream phpserver { + server 10.0.105.200:80 weight=1 max_fails=1 fail_timeout=60s; + } + +vim /etc/nginx/conf.d/default.conf (只是写了修改的内容) +#动态资源加载 + location ~ \.(php|jsp)$ { + proxy_pass http://phpserver; + proxy_set_header Host $host:$server_port; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } +#静态资源加载 + location ~ .*\.(html|gif|jpg|png|bmp|swf|css|js)$ { + proxy_pass http://static; + proxy_set_header Host $host:$server_port; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } +``` + +静态配置: + +```shell +1.安装nginx +2.配置nginx的配置文件,创建创展发布目录(略),写一个测试的静态网站(index.html)(略) +vim /etc/nginx/conf.d/default.conf (你要修改的配置) + + location ~ \.(html|jpg|png|js|css|gif|bmp|jpeg)$ { + root /qfedu; + index index.html; + } +3.启动服务(关闭selinux和firewalld) +``` + +动态配置: + +```shell +1.安装nginx(略),安装php +yum -y install php php-fpm php-mysql +2.修改配置文件 +vim /etc/nginx/conf.d/default.conf + +location / { + root /qfedu; + index index.php index.html; +} + +location ~ \.php$ { + root /qfedu; + fastcgi_pass 127.0.0.1:9000; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + include fastcgi_params; + +} +注意:删除注释,修改内容。 +3.创建网站目录(略),创建一个网站 +index.php (文件名) + + +4.关闭slinux关闭firewalld,重启服务 + +5.分别对静态和动态服务器单独测试,最后使用130的机器进行测试。 +``` + +#### 3.如何安装高版本php + +安装仓库: + +```shell +[root@xingdiancloud ~]# yum install http://rpms.remirepo.net/enterprise/remirelease-7.rpm +``` + +安装php: + +```shell +[root@xingdiancloud ~]# yum install yum-utils +[root@xingdiancloud ~]# yum-config-manager --enable remi-php72 +[root@xingdiancloud ~]# yum install httpd php php-gd php-json php-mysql phpcurl php-mbstring php-intl php-mcrypt php-imagick php-xml php-zip +``` + +## 五:防盗链 + +#### 1.介绍 + +​ 两个网站 A 和 B, A网站引用了B网站上的图片,这种行为就叫做盗链。 防盗链,就是要防止A引用B的图片 + +​ nginx防止网站资源被盗用模块:ngx_http_referer_module + +​ HTTP Referer是Header的一部分,当浏览器向Web服务器发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的,服务器借此可以获得一些信息用于处理,例如防止未经允许的网站盗链图片、文件等。因此HTTP Referer头信息是可以通过程序来伪装生成的,所以通过Referer信息防盗链并非100%可靠,但是,它能够限制大部分的盗链情况 + +#### 2.环境 + +​ 用来做图片服务器(防盗链的部署)192.168.182.131 (A) + +​ 盗链(测试防盗链是否成功) 192.168.182.132(B) + +#### 3.部署A + +​ 创建一个网站发布目录,上传一张图片,写一个index.html的文件 + +```shell +[root@a web]# vim index.html + + + + qf.com + + +
xingdian
+ + +``` + +​ 修改配置文件,修改的内容如下(部分) + +```shell + location / { + root /web; + index index.html index.htm; + } +``` + +#### 4.部署B + +​ 有一个网站发布目录,有index.html的测试网站(不需要有图片 图片直接从A盗用) + +```shell +[root@b qfedu]# vim index.html + + + + qf.com + + + //这个是你在盗用那台服务器的图片 + + +``` + +​ 修改配置nginx的配置文件(部分) + +```shell + location / { + root /qfedu; + index index.html index.htm; + } +``` + +#### 5.测试盗用 + +​ 当你访问B的时候,会获取到A的图片,这说明盗用成功了 + +#### 6.防盗配置A + +修改主配置文件 + +```shell +[root@a ~]# vim /etc/nginx/nginx.conf +# 日志格式添加"$http_referer",如果存在就不需要重复添加 +log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; +``` + +修改子配置文件 + +```shell +[root@a ~]# vim /etc/nginx/conf.d/default.conf (蓝色使我们要添加的关于防盗链的配置) + location ~ .*\.(gif|JPG|png|jpeg|jpg)$ { + root /web; + + valid_referers none blocked 192.168.1.10; + if ($invalid_referer) { + return 403; + } + } + location / { + root /web; + index index.html index.htm; + } +``` + +注意: + +none : 允许没有http_refer的请求访问资源 + +blocked : 允许不是http://开头的,不带协议的请求访问资源 + +server_names : 只允许指定ip/域名来的请求访问资源(白名单) + +重新启动服务 + +```shell +[root@a ~]# nginx -s reload +``` + +​ 访问B机器,如果B机器不在白名单,那么是访问不到内容,这样我们的防盗链就成功了,B机器在白名单内,是可以正常盗用的 + + + + + + + + + + + + + + + + + diff --git a/nginx-md/第二章:Nginx基础.md b/nginx-md/第二章:Nginx基础.md new file mode 100644 index 0000000..0db8bff --- /dev/null +++ b/nginx-md/第二章:Nginx基础.md @@ -0,0 +1,582 @@ +

Nginx基础

+ +**作者:行癫(盗版必究)** + +------ + +## 一:简介 + +![image-20221007123009328](https://xingdian-image.oss-cn-beijing.aliyuncs.com/xingdian-image/image-20221007123009328.png) + +Nginx的官方网站:www.nginx.org + +Nginx的最新稳定版本:1.22(截至时间为2022年10月) + +注意: + +​ Mainline version:主线版,即开发版 + +​ Stable version:最新稳定版,生产环境上建议使用的版本 + +​ Legacy versions:遗留的老版本的稳定版 + +#### 1.介绍 + +​ Nginx (engine x) 是一个高性能的开源的 HTTP 和 反向代理 服务,也是一个IMAP/POP3/SMTP服务。Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的,第一个公开版本0.1.0发布于2004年10月4日。其将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。2011年6月1日,nginx 1.0.4发布 + +​ Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等 + +​ 在高连接并发的情况下,Nginx是Apache服务器不错的替代品 + +​ Nginx的功能:WEB服务器、代理服务器、负载均衡器 + +​ Nginx由模块化组成,支持异步,非阻塞,可以支持高并发 + +伊戈尔·赛索耶夫 + +image-20221007124112815 + +#### 2.异步非阻塞 + +```shell +$ pstree |grep nginx + |-+= 81666 root nginx: master process nginx + | |--- 82500 nobody nginx: worker process + | \--- 82501 nobody nginx: worker process +``` + +​ 每进来一个request,会有一个worker进程去处理。但不是全程的处理,处理到什么程度呢?处理到可能发生阻塞的地方,比如向上游(后端)服务器转发request,并等待请求返回。那么,这个处理的worker不会这么一直等着,他会在发送完请求后,注册一个事件:“如果upstream返回了,告诉我一声,我再接着干”。于是他就休息去了。这就是异步。此时,如果再有request 进来,他就可以很快再按这种方式处理。这就是非阻塞和IO多路复用。而一旦上游服务器返回了,就会触发这个事件,worker才会来接手,这个request才会接着往下走。这就是异步回调 + +案例: + +​ 客户(发送方)向收款员(接收方)付款(发送请求)后在等待收款员找零的过程中,还可以做其他事情,比如打电话、聊天等;而收款员在等待收款机处理交易(IO操作)的过程中还可以帮助客户将商品打包,当收款机产生结果后,收款员给客户结账(响应请求)。在四种方式中,这种方式是发送方和接收方通信效率最高的一种 + +##### 同步异步 + +​ 同步与异步的重点在消息通知的方式上,也就是调用结果通知的方式 + +​ 同步:当一个同步调用发出去后,调用者要一直等待调用结果的通知后,才能进行后续的执行 + +​ 异步:当一个异步调用发出去后,调用者不能立即得到调用结果的返回 + +​ 异步调用,要想获得结果,一般有两种方式: + +​ 主动轮询异步调用的结果 + +​ 被调用方通过callback来通知调用方调用结果 + +案例: + +​ 同步取快递:小明收到快递将送达的短信,在楼下一直等到快递送达 + +​ 异步取快递:小明收到快递将送达的短信,快递到楼下后,小明再下楼去取 + +​ 异步取快递,小明知道快递到达楼下有两种方式: + +​ 不停的电话问快递小哥到了没有,即主动轮询 + +​ 快递小哥到楼下后,打电话通知小明,然后小明下楼取快递,即回调通知 + +##### 阻塞非阻塞 + +​ 阻塞与非阻塞在于进/线程等待消息时候的行为,也就是在等待消息的时候,当前进/线程是挂起还是非挂起状态 + +​ 阻塞:阻塞调用在发出去后,在消息返回之前,当前进/线程会被挂起,直到有消息返回,当前进/线程才会被激活 + +​ 非阻塞:非阻塞调用在发出去后,不会阻塞当前进/线程,而会立即返回 + +案例: + +​ 阻塞取快递:小明收到快递即将送达的信息后,什么事都不做,一直专门等快递 + +​ 非阻塞取快递:小明收到快递即将送达的信息后,等快递的时候,还一边敲代码、一边刷微信 + +##### 总结 + +​ 异步非阻塞:小明收到信息后,边刷着微博,边等快递员通知他取快递 + +##### I/O多路复用 + +​ Input/Output====I/O + +​ 三种模型:select、poll、epoll + +epoll(): + +​ epoll能更高效的检查大量fd,UNIX中提供了类似功能的kqueue调用 + +​ epoll可以理解为event poll,不同于忙轮询和无差别轮询,当连接有I/O流事件产生的时候,epoll就会去告诉进程哪个连接有I/O流事件产生,然后进程就去处理这个事件。此时我们对这些流的操作都是有意义的 + +案例: + +​ 小明家楼下有一个收发室,每次有快递到了,就先代收并做了标记;然后通知小明去取送给小明的快递 + +#### 3.Nginx内部架构 + +​ Nginx服务器,以其处理网络请求的高并发、高性能及高效率,获得了行业界的广泛认可,近年已稳居web服务器部署排名第二的位置,并被广泛用于反向代理和负载均衡 + +技术点: + +​ nginx启动时,会生成两种类型的进程,一个是主进程(Master),一个或多个工作进程(Worker)。主进程并不处理网络请求,主要负责调度工作进程,也就是:加载配置、启动工作进程及非停升级。所以,nginx启动以后,查看操作系统的进程列表,我们就能看到至少有两个nginx进程 + +​ 服务器实际处理网络请求及响应的是工作进程(worker),在类unix系统上,nginx可以配置多个worker,而每个worker进程都可以同时处理数以千计的网络请求 + +​ 模块化设计。nginx的worker,包括核心和功能性模块,核心模块负责维持一个运行循环(run-loop),执行网络请求处理的不同阶段的模块功能,如网络读写、存储读写、内容传输、外出过滤,以及将请求发往上游服务器等。而其代码的模块化设计,也使得我们可以根据需要对功能模块进行适当的选择和修改,编译成具有特定功能的服务器 + +​ 事件驱动、异步及非阻塞,可以说是nginx得以获得高并发、高性能的关键因素,同时也得益于对Linux、Solaris及类BSD等操作系统内核中事件通知及I/O性能增强功能的采用,如kqueue、epoll及event ports + +​ 代理(proxy)设计,可以说是nginx深入骨髓的设计,无论是对于HTTP,还是对于FastCGI、memcache、Redis等的网络请求或响应,本质上都采用了代理机制。所以,nginx天生就是高性能的代理服务器 + +## 二:Nginx安装部署 + +#### 1.Yum安装 + +方式一: + +​ 使用默认的yum仓库,epel仓库里是有关于nginx的rpm包 + +```shell +[root@master ~]# ls /etc/yum.repos.d/ +CentOS-Base.repo epel.repo +[root@master ~]# yum -y install nginx +``` + +方式二: + +​ 使用官方的yum仓库 + +获取nginx官方仓库: + +image-20221007214954698 + +image-20221007215023640 + +```shell +[root@master ~]# vim /etc/yum.repos.d/nginx.repo +[nginx-stable] +name=nginx stable repo +baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ +gpgcheck=1 +enabled=1 +gpgkey=https://nginx.org/keys/nginx_signing.key +module_hotfixes=true + +[nginx-mainline] +name=nginx mainline repo +baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/ +gpgcheck=1 +enabled=0 +gpgkey=https://nginx.org/keys/nginx_signing.key +module_hotfixes=true + +[root@master ~]# yum -y install nginx +``` + +获取安装版本信息: + +```shell +[root@xingdian ~]# nginx -V +nginx version: nginx/1.22.0 +built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) +built with OpenSSL 1.0.2k-fips 26 Jan 2017 +TLS SNI support enabled +configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie' +``` + +查看nginx版本: + +```shell +[root@xingdian ~]# nginx -v +nginx version: nginx/1.22.0 +``` + +关闭防火墙和selinux: + +```shell +[root@nginx-server ~]# sed -i '/^SELINUX=/c SELINUX=Disabled' /etc/selinux/config +[root@nginx-server ~]# setenforce 0 +[root@nginx-server ~]# systemctl stop firewalld +[root@nginx-server ~]# systemctl disable firewalld +``` + +启动并设置开机启动: + +```shell +[root@nginx-server ~]# systemctl start nginx +[root@nginx-server ~]# systemctl enable nginx +``` + +浏览器测试访问: + +![image-20221007221659305](https://xingdian-image.oss-cn-beijing.aliyuncs.com/xingdian-image/image-20221007221659305.png) + +#### 2.编译安装 + +准备编译安装环境: + +```shell +[root@xingdian ~]# yum -y install gcc gcc-c++ make ncurses ncurses-devel wget openssl* pcre* +``` + +获取编译安装包: + +image-20221007222135126 + +```shell +[root@xingdian ~]# wget http://nginx.org/download/nginx-1.22.0.tar.gz +[root@xingdian ~]# tar xf nginx-1.22.0.tar.gz +[root@xingdian ~]# cd nginx-1.22.0 +``` + +配置: + +```shell +[root@xingdian nginx-1.22.0]# ./configure --prefix=/usr/local/nginx --group=nginx --user=nginx --sbin-path=/usr/local/nginx/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/tmp/nginx/client_body --http-proxy-temp-path=/tmp/nginx/proxy --http-fastcgi-temp-path=/tmp/nginx/fastcgi --pid-path=/var/run/nginx.pid --lock-path=/var/lock/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-pcre --with-http_realip_module --with-stream +``` + +编译和安装: + +```shell +[root@xingdian nginx-1.22.0]# make && make install +``` + +创建管理用户: + +```shell +[root@xingdian sbin]# useradd -s /sbin/nologin -M nginx +``` + +启动报错及解决方案: + +```shell +[root@xingdian nginx-1.22.0]# cd /usr/local/nginx/sbin/ +[root@xingdian sbin]# ./nginx +nginx: [emerg] mkdir() "/tmp/nginx/client_body" failed (2: No such file or directory) +[root@xingdian sbin]# mkdir -pv /tmp/nginx/client_body +mkdir: created directory '/tmp/nginx' +mkdir: created directory '/tmp/nginx/client_body' +[root@xingdian sbin]# ./nginx +``` + +浏览器访问测试: + +![image-20221007223057836](https://xingdian-image.oss-cn-beijing.aliyuncs.com/xingdian-image/image-20221007223057836.png) + +nginx编译参数: + +​ 官方地址:http://nginx.org/en/docs/configure.html + +```shell +--prefix=/usr/local/nginx //指向安装目录 +--conf-path=/etc/nginx/nginx.conf //指定配置文件 +--http-log-path=/var/log/nginx/access.log //指定访问日志 +--error-log-path=/var/log/nginx/error.log //指定错误日志 +--lock-path=/var/lock/nginx.lock //指定lock文件 +--pid-path=/run/nginx.pid //指定pid文件 + +--http-client-body-temp-path=/var/lib/nginx/body //设定http客户端请求临时文件路径 +--http-fastcgi-temp-path=/var/lib/nginx/fastcgi //设定http fastcgi临时文件路径 +--http-proxy-temp-path=/var/lib/nginx/proxy //设定http代理临时文件路径 +--http-scgi-temp-path=/var/lib/nginx/scgi //设定http scgi临时文件路径 +--http-uwsgi-temp-path=/var/lib/nginx/uwsgi //设定http uwsgi临时文件路径 + +--with-debug //启用debug日志 +--with-pcre-jit //编译PCRE包含“just-in-time compilation” +--with-ipv6 //启用ipv6支持 +--with-http_ssl_module //启用ssl支持 +--with-http_stub_status_module //获取nginx自上次启动以来的状态 +--with-http_realip_module //允许从请求标头更改客户端的IP地址值,默认为关 +--with-http_auth_request_module //实现基于一个子请求的结果的客户端授权。如果该子请求返回的2xx响应代码,所述接入是允许的。如果它返回401或403中,访问被拒绝与相应的错误代码。由子请求返回的任何其他响应代码被认为是一个错误。 +--with-http_addition_module //作为一个输出过滤器,支持不完全缓冲,分部分响应请求 +--with-http_dav_module //增加PUT,DELETE,MKCOL:创建集合,COPY和MOVE方法 默认关闭,需编译开启 +--with-http_geoip_module //使用预编译的MaxMind数据库解析客户端IP地址,得到变量值 +--with-http_gunzip_module //它为不支持“gzip”编码方法的客户端解压具有“Content-Encoding: gzip”头的响应。 +--with-http_gzip_static_module //在线实时压缩输出数据流 +--with-http_image_filter_module //传输JPEG/GIF/PNG 图片的一个过滤器)(默认为不启用。gd库要用到) +--with-http_spdy_module //SPDY可以缩短网页的加载时间 +--with-http_sub_module //允许用一些其他文本替换nginx响应中的一些文本 +--with-http_xslt_module //过滤转换XML请求 +--with-mail //启用POP3/IMAP4/SMTP代理模块支持 +--with-mail_ssl_module //启用ngx_mail_ssl_module支持启用外部模块支持 +``` + +#### 3.Nginx配置文件详解 + +​ nginx.conf的组成:nginx.conf一共由三部分组成,分别为:全局块、events块、http块 + +​ 在http块中又包含http全局块、多个server块 + +​ 每个server块中又包含server全局块以及多个location块 + +```shell +# 全局参数设置 +worker_processes 4; #设置nginx启动进程的数量,一般设置成与逻辑cpu数量相同 +注意: +1.物理cpu数:主板上实际插入的cpu数量,可以数不重复的 physical id 有几个(physical id) +2.cpu核数:单块CPU上面能处理数据的芯片组的数量,如双核、四核等 (cpu cores) +3.逻辑cpu数:一般情况下,逻辑cpu=物理CPU个数×每颗核数 + +error_log logs/error.log; #指定错误日志 +worker_rlimit_nofile 102400; #设置一个nginx进程能打开的最大文件数 +pid /var/run/nginx.pid; +events { + worker_connections 1024; #设置一个进程的最大并发连接数 +} +# 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 /var/log/nginx/access.log main; #设置访问日志的位置和格式 + sendfile on; #是否调用sendfile函数输出文件,一般设置为on,若nginx是用来进行磁盘IO负载应用时,可以设置为off,降低系统负载 + gzip on; #是否开启gzip压缩,将注释去掉开启 + keepalive_timeout 65; #设置长连接的超时时间 +# 虚拟服务器的相关设置 + server { + listen 80; #设置监听的端口 + server_name localhost; #设置绑定的主机名、域名或ip地址 + charset koi8-r; # 设置编码字符 + location / { + root /var/www/nginx; #设置服务器默认网站的根目录位置,需要手动创建 + index index.html index.htm; #设置默认打开的文档 + } + error_page 500 502 503 504 /50x.html; #设置错误信息返回页面 + location = /50x.html { + root html; #这里的绝对位置是/usr/local/nginx/html + } + include /etc/nginx/conf.d/*.conf; 加载子配置文件 + + } + } + +检测nginx配置文件是否正确 +[root@localhost ~]# /usr/local/nginx/sbin/nginx -t +[root@localhost ~]# mkdir -p /tmp/nginx + +启动nginx服务 +[root@localhost ~]# /usr/local/nginx/sbin/nginx + +通过 nginx 命令控制 nginx 服务 + +nginx -c /path/nginx.conf # 以特定目录下的配置文件启动nginx: +nginx -s reload # 修改配置后重新加载生效 +nginx -s reopen # 重新打开日志文件 +nginx -s stop # 快速停止nginx +nginx -t # 测试当前配置文件是否正确 +nginx -t -c /usr/lcoal/nginx/conf/nginx.conf # 测试特定的nginx配置文件是否正确 +``` + +通过nginx命令控制nginx服务: + +```shell +nginx -c /path/nginx.conf # 以特定目录下的配置文件启动nginx: +nginx -s reload # 修改配置后重新加载生效 +nginx -s reopen # 重新打开日志文件 +nginx -s stop # 快速停止nginx +nginx -t # 测试当前配置文件是否正确 +nginx -t -c /usr/lcoal/nginx/conf/nginx.conf # 测试特定的nginx配置文件是否正确 +``` + +注意: + +nginx -s reload 命令加载修改后的配置文件,命令下达后发生如下事件: + +​ Nginx的master进程检查配置文件的正确性,若是错误返回错误信息,nginx继续采用原配置文件进行工作(因为worker未受到影响) + +​ Nginx启动新的worker进程,采用新的配置文件 + +​ Nginx将新的请求分配新的worker进程 + +​ Nginx等待以前的worker进程的全部请求已经都返回后,关闭相关worker进程 + +​ 重复上面过程,直到全部旧的worker进程都被关闭掉 + +## 三:Nginx虚拟主机 + +#### 1.什么是虚拟主机 + +​ 虚拟主机是一种特殊的软硬件技术,它可以将网络上的每一台计算机分成多个虚拟主机,每个虚拟主机可以独立对外提供www服务,这样就可以实现一台主机对外提供多个web服务,每个虚拟主机之间是独立的,互不影响 + +image-20221008205248566 + +#### 2.虚拟主机类型 + +​ 基于域名的虚拟主机 + +​ 基于ip的虚拟主机 + +​ 基于端口的虚拟主机 + +#### 3.基于域名的虚拟主机 + +​ 创建虚拟主机配置文件: + +```shell +[root@localhost ~]# cat /etc/nginx/conf.d/qfedu.conf (可以写到两个配置文件当中,也可以写到一个) +server { + listen 80; + server_name www.xingdiancloud.com; + location / { + root /web1; + index index.html index.htm; + } + } + +server { + listen 80; + server_name www.1000phone.com; + location / { + root /web2; + index index.html index.htm; + } + } +``` + +​ 创建网站发布目录,并且创建对应的网站: + +```shell +[root@localhost ~]# mkdir /web1 +[root@localhost ~]# mkdir /web2 +[root@localhost ~]#echo "web1" > /web1/index.html +[root@localhost ~]#echo "web2" > /web2/index.html +``` + +​ 重新加载配置文件: + +```shell +[root@localhost ~]# nginx -s reload +``` + +​ 客户端配置路由映射(本地域名解析): + +```shell +[root@localhost ~]# vim /etc/hosts +10.0.105.199 www.xingdiancloud.com +10.0.105.199 www.1000phone.com +``` + +​ 测试访问: + +```shell +[root@xingdian conf.d]# curl www.xingdiancloud.com +web1 +[root@xingdian conf.d]# curl www.1000phone.com +web2 +``` + +#### 4.基于域名的虚拟主机 + +​ 添加IP地址: + +```shell +[root@localhost ~]# ip a +1: lo: mtu 65536 qdisc noqueue state UNKNOWN qlen 1 + link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 + inet 127.0.0.1/8 scope host lo + valid_lft forever preferred_lft forever + inet6 ::1/128 scope host + valid_lft forever preferred_lft forever +2: ens33: mtu 1500 qdisc pfifo_fast state UP qlen 1000 + link/ether 00:0c:29:17:f1:af brd ff:ff:ff:ff:ff:ff + inet 10.0.105.199/24 brd 10.0.105.255 scope global dynamic ens33 + valid_lft 81438sec preferred_lft 81438sec + inet6 fe80::9d26:f3f0:db9c:c9be/64 scope link + valid_lft forever preferred_lft forever +[root@localhost ~]# ifconfig ens33:1 10.0.105.201/24 +[root@localhost ~]# ifconfig +ens33: flags=4163 mtu 1500 + inet 10.0.105.199 netmask 255.255.255.0 broadcast 10.0.105.255 + inet6 fe80::9d26:f3f0:db9c:c9be prefixlen 64 scopeid 0x20 + ether 00:0c:29:17:f1:af txqueuelen 1000 (Ethernet) + RX packets 9844 bytes 1052722 (1.0 MiB) + RX errors 0 dropped 0 overruns 0 frame 0 + TX packets 5567 bytes 886269 (865.4 KiB) + TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 + +ens33:1: flags=4163 mtu 1500 + inet 10.0.105.201 netmask 255.255.255.0 broadcast 10.0.105.255 + ether 00:0c:29:17:f1:af txqueuelen 1000 (Ethernet) +``` + +​ 配置通过ip区分的虚拟机: + +```shell +[root@localhost conf.d]# cat qfedu.conf +server { + listen 192.168.182.131:80; + server_name www.xingdiancloud.com; + location / { + root /web1; + index index.html index.htm; + } + } + +server { + listen 192.168.182.120:80; + server_name www.xingdiancloud.com; + location / { + root /web2; + index index.html index.htm; + } + } +``` + +​ 重新加载配置文件: + +```shell +[root@localhost ~]# nginx -s reload +``` + +​ 创建网站:略(以基于域名的虚拟主机为主) + +​ 测试访问: + +```shell +浏览器输入:http://192.168.182.120 +浏览器输入:http://192.168.182.131 +``` + +#### 5.基于端口的虚拟主机 + +​ 创建虚拟主机配置文件: + +```shell +[root@localhost ~]# cat /etc/nginx/conf.d/qfedu.conf + server { + listen 80; + server_name web.testpm.com; + location / { + root /var/www/nginx/; + index index.html index.htm; + } + + + server { + listen 8080; + server_name web.testpm.com; + location / { + root /1000phone/html/; + index index.html index.htm; + } + } +} +``` + +​ 创建网站:略(以基于域名的虚拟主机为主) + +​ 重新加载配置文件: + +```shell +[root@localhost ~]# nginx -s reload +``` + +​ 测试访问: + +```shell +[root@localhost ~]# curl web.testpm.com +web1 +[root@localhost ~]# curl web.testpm.com:8080 +web2 +``` diff --git a/nginx-md/第五章:Nginx地址重写.md b/nginx-md/第五章:Nginx地址重写.md new file mode 100644 index 0000000..dd1bab5 --- /dev/null +++ b/nginx-md/第五章:Nginx地址重写.md @@ -0,0 +1,420 @@ +

Nginx地址重写

+ +作者:行癫(盗版必究) + +------ + +## 一:地址重写 + +#### 1.rewrite简介 + +​ Rewrite对称URL Rewrite,即URL重写,就是把传入Web的请求重定向到其他URL的过程 + +​ URL Rewrite最常见的应用是URL伪静态化,是将动态页面显示为静态页面方式的一种技术 + +​ 从安全角度上讲,如果在URL中暴露太多的参数,无疑会造成一定量的信息泄漏,所以静态化的URL地址具有更高的安全性 + +​ 实现网站地址跳转,例如用户访问360buy.com,将其跳转到jd.com;当用户访问xingdian.com的80端口时,将其跳转到443端口 + +#### 2.rewrite指令 + +​ Nginx Rewrite 相关指令有 if、rewrite、set、return + +## 二:if语句 + +#### 1.应用环境 + +​ server,location + +#### 2.使用语法 + +```shell +if (condition) { … } +``` + +#### 3.判断符号 + +```shell +~ 正则匹配 (区分大小写) +~* 正则匹配 (不区分大小写) +!~ 正则不匹配 (区分大小写) +!~* 正则不匹配 (不区分大小写) +-f 和!-f 用来判断是否存在文件 +-d 和!-d 用来判断是否存在目录 +-e 和!-e 用来判断是否存在文件或目录 +-x 和!-x 用来判断文件是否可执行 +``` + +#### 4.全局变量 + +​ 在匹配过程中可以引用一些Nginx的全局变量 + +```shell +$args 请求中的参数; +$document_root 针对当前请求的根路径设置值; +$host 请求信息中的"Host",如果请求中没有Host行,则等于设置的服务器名; http://www.qf.com +$limit_rate 对连接速率的限制; +$request_method 请求的方法,比如"GET"、"POST"等; +$remote_addr 客户端地址; +$remote_port 客户端端口号; +$remote_user 客户端用户名,认证用; +$request_filename 当前请求的文件路径名(带网站的主目录/usr/local/nginx/html/images /a.jpg) +$request_uri 当前请求的文件路径名(不带网站的主目录/images/a.jpg) +$query_string 与$args相同; +$scheme 用的协议,比如http或者是https +$server_protocol 请求的协议版本,"HTTP/1.0"或"HTTP/1.1"; +$server_addr 服务器地址,如果没有用listen指明服务器地址,使用这个变量将发起一次系统调用以取得地址(造成资源浪费); +$server_name 请求到达的服务器名; +$document_uri 与$uri一样,URI地址; +$server_port 请求到达的服务器端口号; +``` + +#### 5.使用案例 + +​ 匹配访问的url地址是否是个目录 + +```shell +if (-d $request_filename) { 当前请求的文件路径名 +…; +} +``` + +​ 匹配访问的地址是否以www开头 + +```shell +if ( $host ~* ^www) { +…; +} +``` + +## 三:rewrite语句 + +#### 1.使用简介 + +​ rewrite 指令根据表达式来重定向URI,或者修改字符串。可以应用于server,location, if环境下每行rewrite指令最后跟一个flag标记 + +#### 2.标记 + +```shell +last 相当于Apache里的[L]标记,表示完成rewrite。默认为last +break 本条规则匹配完成后,终止匹配,不再匹配后面的规则 +redirect 返回302临时重定向,浏览器地址会显示跳转后的URL地址 +permanent 返回301永久重定向,浏览器地址会显示跳转后URL地址 +``` + +#### 3.使用案例 + +​ http://www.testpm.com/a/1.html ==> http://www.testpm.com/b/2.html + +```shell + location /a { + root /html; + index 1.html index.htm; + rewrite .* /b/2.html permanent; + } + location /b { + root /html; + index 2.html index.htm; + } +``` + +​ http://www.testpm.com/2019/a/1.html ==> http://www.testpm.com/2018/a/1.html + +```shell + location /2019/a { + root /var/www/html; + index 1.html index.hml; + rewrite ^/2019/(.*)$ /2018/$1 permanent; + } + location /2018/a { + root /var/www/html; + index 1.html index.htl; + } +``` + +​ 准备工作 + +![image-20230506222159398](https://xingdian-image.oss-cn-beijing.aliyuncs.com/xingdian-image/image-20230506222159398.png) + +​ http://www.qf.com/a/1.html ==> http://jd.com + +```shell +location /a { + root /html; + if ($host ~* qf.com ) { + rewrite .* http://jd.com permanent; + } + } +``` + +​ http://www.qf.com/a/1.html ==> http://jd.com/a/1.html + +```shell +location /a { + root /html; + if ( $host ~* qf.com ){ + rewrite .* http://jd.com$request_uri permanent; + } + } +``` + +​ 在访问目录后添加/ (如果目录后已有/,则不加/) + +```shell +# http://www.tianyun.com/a/b/c +# $1: /a/b +# $2: c +# http://$host$1$2/ +location /a/b/c { + root /usr/share/nginx/html; + index index.html index.hml; + if (-d $request_filename) { + rewrite ^(.*)([^/])$ http://$host$1$2/ permanent; + } + } +``` + +​ http://www.tianyun.com/login/tianyun.html ==> http://www.tianyun.com/reg/login.html?user=tianyun + +```shell + location /login { + root /usr/share/nginx/html; + rewrite ^/login/(.*)\.html$ http://$host/reg/login.html?user=$1; + } + location /reg { + root /usr/share/nginx/html; + index login.html; + + } +``` + +​ http://www.tianyun.com/qf/11-22-33/1.html ==> http://www.tianyun.com/qf/11/22/33/1.html + +```shell +location /qf { + rewrite ^/qf/([0-9]+)-([0-9]+)-([0-9]+)(.*)$ /qf/$1/$2/$3$4 permanent; + } + + location /qf/11/22/33 { + root /html; + index 1.html; + } +``` + +## 四:set指令 + +#### 1.简介 + +​ set 指令是用于定义一个变量,并且赋值 + +#### 2.应用环境 + +​ server,location,if + +#### 3.应用案例 + +​ http://alice.testpm.com ==> http://www.testpm.com/alice + +​ http://jack.testpm.com ==> http://www.testpm.com/jack + +准备工作: + +```shell +[root@nginx-server conf.d]# cd /usr/share/nginx/html/ +[root@nginx-server html]# mkdir jack alice +[root@nginx-server html]# echo "jack.." >> jack/index.html +[root@nginx-server html]# echo "alice.." >> alice/index.html + +本地解析域名host文件 +10.0.105.202 www.testpm.com +10.0.105.202 alice.testpm.com +10.0.105.202 jack.testpm.com +``` + +配置文件: + +```shell +server { + listen 80; + server_name www.testpm.com; + + location / { + root /usr/share/nginx/html; + index index.html index.htm; + if ( $host ~* www.testpm.com) { + break; + } + if ( $host ~* "^(.*)\.testpm\.com$" ) { + set $user $1; + rewrite .* http://www.testpm.com/$user permanent; + } + } + location /jack { + root /usr/share/nginx/html; + index index.html index.hml; + } + location /alice { + root /usr/share/nginx/html; + index index.html index.hml; + } +} +``` + +## 五:return指令 + +#### 1.简介 + +​ return指令用于返回状态码给客户端 + +#### 2.应用环境 + +​ server,location,if + +#### 3.应用案例 + +​ 如果访问的.sh结尾的文件则返回403操作拒绝错误 + +```shell +server { + listen 80; + server_name www.testpm.cn; + #access_log /var/log/nginx/http_access.log main; + + location / { + root /usr/share/nginx/html; + index index.html index.htm; + } + + location ~* \.sh$ { + return 403; + } +} +``` + +​ 80 ======> 443 :80转443端口 + +```shell +server { + listen 80; + server_name www.testpm.cn; + access_log /var/log/nginx/http_access.log main; + return 301 https://www.testpm.cn$request_uri; +} + +server { + listen 443 ssl; + server_name www.testpm.cn; + access_log /var/log/nginx/https_access.log main; + + #ssl on; + ssl_certificate /etc/nginx/cert/2447549_www.testpm.cn.pem; + ssl_certificate_key /etc/nginx/cert/2447549_www.testpm.cn.key; + ssl_session_timeout 5m; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP; + ssl_prefer_server_ciphers on; + + location / { + root /usr/share/nginx/html; + index index.html index.htm; + } +} +``` + +## 六:break和last + +#### 1.使用案例 + +```shell +[root@localhost test]# cat /etc/nginx/conf.d/last_break.conf +server { + listen 80; + server_name localhost; + access_log /var/log/nginx/last.access.log main; + + location / { + root /usr/share/nginx/html; + index index.html index.htm; + } + location /break/ { + root /usr/share/nginx/html; + rewrite .* /test/break.html break; + } + location /last/ { + root /usr/share/nginx/html; + rewrite .* /test/last.html last; + } + location /test/ { + root /usr/share/nginx/html; + rewrite .* /test/test.html break; + } + +} +[root@localhost conf.d]# cd /usr/share/nginx/html/ +[root@localhost html]# mkdir test +[root@localhost html]# echo "last" > test/last.html +[root@localhost html]# echo "break" > test/break.html +[root@localhost html]# echo "test" > test/test.html + +http://10.0.105.196/break/break.html +http://10.0.105.196/last/last.html +``` + +#### 2.案例总结 + +​ last 标记在本条 rewrite 规则执行完后,会对其所在的 server { … } 标签重新发起请求 + +​ break 标记则在本条规则匹配完成后,停止匹配,不再做后续的匹配 + +​ 使用 alias 指令时,必须使用 last + +​ 使用 proxy_pass 指令时,则必须使用break + +## 七:https案例 + +​ 使用rewrite的方式进行http转https + +```shell +server { + listen 80; + server_name *.vip9999.top vip9999.top; + + if ($host ~* "^www.vip9999.top$|^vip9999.top$" ) { + return 301 https://www.vip9999.top$request_uri; + } + + if ($host ~* "^(.*).vip9999.top$" ) { + set $user $1; + return 301 https://www.vip9999.top/$user; + } + + } + + # Settings for a TLS enabled server. + server { + listen 443 ssl; + server_name www.vip9999.top; + + location / { + root /usr/share/nginx/html; + index index.php index.html; + } + + #pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 + location ~ \.php$ { + root /usr/share/nginx/html; + fastcgi_pass 127.0.0.1:9000; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + include fastcgi_params; + } + ssl on; + ssl_certificate cert/214025315060640.pem; + ssl_certificate_key cert/214025315060640.key; + ssl_session_cache shared:SSL:1m; + ssl_session_timeout 10m; + ssl_ciphers HIGH:!aNULL:!MD5; + ssl_prefer_server_ciphers on; + } +``` + diff --git a/nginx-md/第六章:Nginx日志.md b/nginx-md/第六章:Nginx日志.md new file mode 100644 index 0000000..cfcc608 --- /dev/null +++ b/nginx-md/第六章:Nginx日志.md @@ -0,0 +1,261 @@ +

Nginx日志管理

+ +作者:行癫(盗版必究) + +------ + +## 一:日志介绍 + +#### 1.介绍 + +​ nginx有一个非常灵活的日志记录模式,每个级别的配置可以有各自独立的访问日志, 所需日志模块 ngx_http_log_module 的支持 + +​ 日志格式通过 log_format 命令来定义 + +​ 日志对于统计和排错是非常有利的 + +​ nginx 日志相关的配置 包括 access_log、log_format、open_log_file_cache、rewrite_log、error_log + +#### 2.总结 + +​ Nginx中通过access_log和error_log指令配置访问日志和错误日志,通过log_format我们可以自定义日志格式。如果日志文件路径中使用了变量,我们可以通过open_log_file_cache 指令来设置缓存,提升性能。其他的根据自己的使用场景定义。详细的日志配置信息可以参考Nginx官方文档 + +## 二:访问日志 + +#### 1.设置访问日志 + +```shell +access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]]; +``` + +​ path 指定日志的存放位置 + +​ format 指定日志的格式。默认使用预定义的combined + +​ buffer 用来指定日志写入时的缓存大小。默认是64k + +​ gzip 日志写入前先进行压缩。压缩率可以指定,从1到9数值越大压缩比越高,同时压缩的速度也越慢。默认是1 + +​ flush 设置缓存的有效时间。如果超过flush指定的时间,缓存中的内容将被清空 + +​ if 条件判断。如果指定的条件计算为0或空字符串,那么该请求不会写入日志 + +#### 2.关闭访问日志 + +```shell +access_log off; +``` + +#### 3.应用范围 + +​ 可以应用access_log指令的作用域分别有http,server,location等。也就是说,在这几个作用域外使用该指令,Nginx会报错 + +​ 指定日志的写入路径为/var/logs/nginx-access.log,日志格式使用默认的combined + +```shell +access_log /var/logs/nginx-access.log +``` + +​ 指定日志的写入路径为/var/logs/nginx-access.log,日志格式使用默认的combined,指定日志的缓存大小为 32k,日志写入前启用 gzip 进行压缩,压缩比使用默认值 1,缓存数据有效时间为1分钟 + +```shell +access_log /var/logs/nginx-access.log buffer=32k gzip flush=1m +``` + +#### 4.log_format 指令 + +​ Nginx 预定义了名为 combined 日志格式,如果没有明确指定日志格式默认使用该格式 + +​ 如果不想使用Nginx预定义的格式,可以通过log_format指令来自定义 + +```shell +log_format combined '$remote_addr - $remote_user [$time_local] ' + '"$request" $status $body_bytes_sent ' + '"$http_referer" "$http_user_agent"'; +``` + +语法: + +```shelll +log_format name [escape=default|json] string ...; +``` + +​ name 格式名称。在 access_log 指令中引用 + +​ escape 设置变量中的字符编码方式是json还是default,默认是default + +​ string 要定义的日志格式内容。该参数可以有多个;参数中可以使用Nginx变量 + +自定义日志格式的使用: + +```shell +access_log /var/logs/nginx-access.log main +log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; +``` + +​ 使用log_format指令定义了一个main的格式,并在access_log指令中引用了它 + +​ 假如客户端有发起请求:https://qf.com/,我们看一下我截取的一个请求的日志记录 + +```shell +10.0.105.207 - - [01/Jul/2019:10:44:36 +0800] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36" "-" +我们看到最终的日志记录中$remote_user、$http_referer、$http_x_forwarded_for都对应了一个-,这是因为这几个变量为空。 +``` + +## 三:错误日志 + +#### 1.简介 + +​ 错误日志在Nginx中是通过error_log指令实现的 + +​ 该指令记录服务器和请求处理过程中的错误信息 + +#### 2.语法 + +​ 配置错误日志文件的路径和日志级别 + +```shell +error_log file [level]; +Default: +error_log logs/error.log error; +``` + +​ file 参数指定日志的写入位置 + +​ level 参数指定日志的级别 + +注意: + +​ level可以是debug, info, notice, warn, error, crit, alert,emerg中的任意值。可以看到其取值范围是按紧急程度从低到高排列的。只有日志的错误级别等于或高于level指定的值才会写入错误日志中。默认值是error + +#### 3.基本用法 + +```shell +error_log /var/logs/nginx/nginx-error.log +``` + +​ 指定了错误日志的路径为:/var/logs/nginx/nginx-error.log,日志级别使用默认的 error + +#### 4.作用域 + +​ main, http, mail, stream, server, location + +## 四:日志文件描述符缓存 + +#### 1.简介 + +​ 每一条日志记录的写入都是先打开文件再写入记录,然后关闭日志文件 + +​ 如果你的日志文件路径中使用了变量,如 access_log /var/logs/$host/nginx-access.log + +​ 为提高性能,可以使用open_log_file_cache指令设置日志文件描述符的缓存 + +#### 2.语法 + +```shell +open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time]; +``` + +​ max 设置缓存中最多容纳的文件描述符数量,如果被占满,采用LRU算法将描述符关闭 + +​ inactive 设置缓存存活时间,默认是10s + +​ min_uses 在inactive时间段内,日志文件最少使用几次,该日志文件描述符记入缓存,默认是1次 + +​ valid:设置多久对日志文件名进行检查,看是否发生变化,默认是60s + +​ off:不使用缓存。默认为off + +#### 3.作用域 + +​ http、server、location + +#### 4.使用案例 + +```shell +open_log_file_cache max=1000 inactive=20s valid=1m min_uses=2; +``` + +​ 设置缓存最多缓存1000个日志文件描述符,20s内如果缓存中的日志文件描述符至少被被访问2次,才不会被缓存关闭。每隔1分钟检查缓存中的文件描述符的文件名是否还存在 + +## 五:地址重写日志 + +#### 1.简介 + +​ 由ngx_http_rewrite_module模块提供的 + +​ 用来记录重写日志的 + +​ 将在error log中记录notice级别的重写日志 + +#### 2.基本语法 + +```shell +rewrite_log on | off; +``` + +​ 默认值:off + +#### 3.作用域 + +​ http, server, location, if + +## 六:Nginx日志轮转 + +#### 1.轮转文件 + +```shell +[root@192 ~]# vim /etc/logrotate.d/nginx +/var/log/nginx/*.log { #指定需要轮转处理的日志文件 + daily #日志文件轮转周期,可用值为: daily/weekly/yearly + missingok # 忽略错误信息 + rotate 7 # 轮转次数,即最多存储7个归档日志,会删除最久的归档日志 + minsize 5M #限制条件,大于5M的日志文件才进行分割,否则不操作 + dateext # 以当前日期作为命名格式 + compress # 轮循结束后,已归档日志使用gzip进行压缩 + delaycompress # 与compress共用,最近的一次归档不要压缩 + notifempty # 日志文件为空,轮循不会继续执行 + create 640 nginx nginx #新日志文件的权限 + sharedscripts #有多个日志需要轮询时,只执行一次脚本 + postrotate # 将日志文件转储后执行的命令。以endscript结尾,命令需要单独成行 + if [ -f /var/run/nginx.pid ]; then #判断nginx的PID。# 默认logrotate会以root身份运行 + kill -USR1 `cat /var/run/nginx.pid` + fi + endscript +} +执行命令: +[root@192 nginx]# /usr/sbin/logrotate -f /etc/logrotate.conf +创建计划任务: +[root@192 nginx]# crontab -e +59 23 * * * /usr/sbin/logrotate -f /etc/logrotate.conf +``` + +注意: + +​ USR1停止接受新的连接,等待当前连接停止,重新载入配置文件,重新打开日志文件,重启服务器,实现相对平滑的不关机的更改 + +## 七:面试案例 + +#### 1.简介 + +​ nginx 的 access log 中可以记录很多有价值的信息,通过分析 access log,可以收集到很多指标 + +​ PV:PV(访问量): 即Page View, 即页面浏览量或点击量,用户每次刷新即被计算一次。 +​ UV:UV(独立访客):即Unique Visitor,访问您网站的一台电脑客户端为一个访客。00:00-24:00内相同的客户端只被计算一次 + +#### 2.案例 + +```shell +1.根据访问IP统计UV +awk '{print $1}' access.log|sort | uniq -c |wc -l +2.统计访问URL统计PV +awk '{print $7}' access.log|wc -l +3.查询访问最频繁的URL +awk '{print $7}' access.log|sort | uniq -c |sort -n -k 1 -r|more +4.查询访问最频繁的IP +awk '{print $1}' access.log|sort | uniq -c |sort -n -k 1 -r|more +5.查询访问最频繁的前10的IP +awk '{print $1}' access.log|sort | uniq -c |sort -n -k 1 -r|head -n 10 +``` \ No newline at end of file diff --git a/nginx-md/第四章:Nginx匹配.md b/nginx-md/第四章:Nginx匹配.md new file mode 100644 index 0000000..e84ed6c --- /dev/null +++ b/nginx-md/第四章:Nginx匹配.md @@ -0,0 +1,216 @@ +

Nginx匹配

+ +作者:行癫(盗版必究) + +------ + +## 一:Location匹配 + +#### 1.location简介 + +​ location 指令是 nginx 中最关键的指令之一,location 指令的功能是用来匹配不同的 URI 请求,进而对请求做不同的处理和响应 + +#### 2.location语法 + +​ location 是在 server 块中配置,根据不同的 URI 使用不同的配置,来处理不同的请求 + +​ location 是有顺序的,会被第一个匹配的location 处理 + +```shell +Nginx 的 HTTP 配置主要包括三个区块,结构如下: + +http { # 这个是协议级别 +  include mime.types; +  default_type application/octet-stream; +  keepalive_timeout 65; +  gzip on; +    server { # 这个是服务器级别 +      listen 80; +      server_name localhost; +        location / { # 这个是请求级别 +          root html; +          index index.html index.htm; +        } + location ~ \.(html|jpg)$ { + root /web; + } +      } +} +``` + +#### 3.前缀含义 + +```shell += 表示精确匹配,优先级也是最高的 +^~ 表示uri以某个常规字符串开头,理解为匹配url路径即可 +~ 表示区分大小写的正则匹配 +~* 表示不区分大小写的正则匹配 +!~ 表示区分大小写不匹配的正则 +!~* 表示不区分大小写不匹配的正则 +/ 通用匹配,任何请求都会匹配到 +``` + +#### 4.配置示例 + +```shell +1)、没有修饰符 表示:必须以指定模式开始 + + location / { + root /abc/location; (/abc/location目录下:有abc的目录,index.html) + index 2.html; + } + + +2)、=表示:必须与指定的模式精确匹配(创建一个网站发布目录,下面分别a.html和b.html) + location = / { + root /usr/share/nginx/html; + index b.html index.htm; + } + + location / { + root /usr/share/nginx/html; + index a.html index.htm; + } + + +3)、~ 表示:指定的正则表达式要区分大小写 +  location ~ \.(jpg|css)$ { +   root location; //要在location目录下有一个以.jpg结尾的文件 +  } + +4)、~* 表示:指定的正则表达式不区分大小写 +location ~* \.(JPG|css)$ { +  root location; //要在location目录下有一个以.jpg结尾的文件 +  } + + +5)、^~ :类似于无修饰符的行为,也是以指定模式开始,不同的是,如果模式匹配,那么就停止搜索其他模式了 +``` + +#### 5.优先级 + +​ 带有“=“的精确匹配优先 + +​ 没有修饰符的精确匹配 + +​ 正则表达式按照他们在配置文件中定义的顺序 + +​ 带有“^~”修饰符的,开头匹配 + +​ 带有“~” 或“~*” 修饰符的,如果正则表达式与URI匹配 + +​ 没有修饰符的,如果指定字符串与URI开头匹配 + +总结: + +​ 多个location配置的情况下匹配顺序为:首先匹配 =,其次匹配^~, 其次是按正则匹配,最后是交给 / 通用匹配。当有匹配成功时候,停止匹配,按当前匹配规则处理请求 + +```shell += 大于 ^~ 大于 ~|~*|!~|!~* 大于 / +``` + +#### 6.案例 + +image-20230425215743676 + + + +image-20230425215806679 + +#### 7.echo模块 + +获取nginx的安装版本: + +```shell +[root@192 ~]# nginx -v +``` + +上传或者下载一个相同版本的nginx包,并解压(略) + +下载echo模块的安装包,并解压到指定位置(略): + +```shell +[root@192 ~]# wget https://github.com/openresty/echo-nginx-module/archive/v0.61.tar.gz +``` + +安装编译所需软件: + +```shell +[root@192 local]# yum install -y pcre* openssl* gcc gcc-c++ make +``` + +获取源nginx的配置: + +```shell +[root@192 ~]# nginx -V +``` + +添加上原来已经有的参数和新添加的模块: + +```shell +[root@192 nginx-1.16.0]# ./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --add-module=/usr/local/echo-nginx-module-0.61 +``` + +重新编译: + +```shell +[root@192 nginx-1.16.0]# make +``` + +将原来的nignx备份: + +```shell +[root@192 nginx-1.16.0]# mv /usr/sbin/nginx /usr/sbin/nginx_bak +[root@192 nginx-1.16.0]# cp objs/nginx /usr/sbin/ +``` + +重新启动: + +``` +[root@192 nginx-1.16.0]# systemctl restart nginx +``` + +使用echo: + +```shell +配置 $foo=hello +[root@192 ~]# cd /etc/nginx/conf.d/ +[root@192 conf.d]# vim echo.conf +server { + listen 80; + server_name localhost; + location /test { + set $foo hello; + echo "foo: $foo"; + } +} + +[root@192 conf.d]# nginx -s reload +[root@192 conf.d]# curl localhost/test +foo: hello +``` + +#### 8.alias和root + +​ alias 是一个目录别名的定义 + +​ root 则是最上层目录的定义 + +​ 还有一个重要的区别是alias后面必须要用“/”结束,否则会找不到文件的,而root则可有可无 + +```shell +location /img/ { + alias /var/www/image/; +} +``` + +​ 若按照上述配置的话,则访问/img/目录里面的文件时,ningx会自动去/var/www/image/目录找文件 + +```shell +location /img/ { + root /var/www/image; +} +``` + +​ 若按照这种配置的话,则访问/img/目录下的文件时,nginx会去/var/www/image/img/目录下找文件 +