Nginx-深度学习篇
一、Nginx动静分离
1、动态请求与静态请求的概念:
-
概念:通过中间件将动态请求和静态请求分离。
-
为什么要动静分离呢?
- 分离资源,从服务端而言要减少一些不必要的请求消耗,减少请求延时。
-
动态请求图解:
- 客户端先请求中间件
- 中间件请求后端的框架
- 后端的框架中的逻辑
- 请求数据库,返回资源给客户端
-
静态请求的图解:
-
客户端请求中间件,只需要再硬盘中,获取数据就可以了,不需要走程序框架之后的。
2、什么是动态请求?什么是静态请求?图解:
- 客户端请求Nginx代理服务器的时候,如果是动态请求的话jsp 会请求Tomcat(应用服务器),如果是静态请求的话会去找静态资源。
-
动态请求,静态请求配置语法:
pstream python_api{ server 127.0.0.1:8000; # 后端服务器的端口 } server { listen 80; server_name localhost; #charset koi8-r; access_log /var/log/nginx/log/host.access.log; root /opt/app/code; # 因为我动态请求的跟静态请求的文件都放在了这个目录中 location ~ \.jsp$ { # 请求.jsp结尾的就是动态请求 proxy_pass http://python_api; index index.html index.htm; } location ~ \.(jpg|png|gif)$ { # 请求.jpg|png|gif 结尾的就是静态请求 expires 1h; gzip on; } }
二、Nginx的rewrite规则:
- 概念:实现url的重写,跟匹配url的重定向。
匹配依赖于正则表达式。
1、场景:
1)URL访问跳转,支持开发设计
- 页面跳转,兼容性支持,展示效果等
2)SEO优化;
3)维护:
- 后端的维护、流量转发等
4)安全:
- 可以实践伪静态
2、rewrite配置语法:
- 语法:
- Syntax:rewrite regex replacement [flag];
- Default:-
- Context:server , location, if
- 配置实例:
- `rewrite^(.*)$/pages/maintain.html break;
- 当网站需要维护的时候,不管怎么请求,都会到pages/maintain.html这个
维护页面
下。
3、正则表达式:
. | 匹配除了换行符以外的任意字符 |
---|---|
? | 重复0次或者1次 |
+ | 重复1次或者更多次 |
* | 最少链接数,那个机器链接数少就分发,贪婪匹配有多少就匹配多少 |
\d | 匹配数字 |
^ | 匹配字符串的开始 |
$ | 匹配字串的结束 |
{n} | 重复n次 |
{n, } | 重复n次或者更多次 |
[c] | 匹配单个字符c |
[a-z] | 匹配小写字母a-z的任意一个 |
\ | 转义字符(匹配一些特殊符号的时候,就需要转译字符) |
( ) | 用于匹配括号之间的内容,通过$1,$2 |
- 比如:rewrite index
\
.php$\pages\maintain.html break;想匹配到index.php ,因为.
是属于任意字符, 所以再前面\
转义字符才可以匹配到index.php。
4、rewrite-flag:
last | 停止rewrite检测 |
---|---|
break | 停止rewrite检测 |
redirect | 返回302临时重定向,地址栏会显示跳转后的地址 |
permanent | 返回301永久重定向,地址栏会显示跳转后的地址 |
1)break检测与last检测的区别:
-
创建一个配置项:
server { listen 80; server_name 192.168.37.192; access_log /var/log/nginx/log/host.access.log; root /opt/app/code; location ~ ^/break { rewrite ^/break /test/ break; } location ~ ^/last { rewrite ^/last /test/ last; } location /test/ { default_type application/json; return 200 '{"status":"success"}'; } }
-
首先当你访问192.168.37.192/test/的时候会出现’{“status”:“success”}'的页面。说明你访问成功,下面就说说last跟break的区别:
- 访问192.168.37.192
/break/
会返回404 NOT FOUND
的页面,说明了,再rewrite ^/break /test/ break
这步的时候,会去root
下面的/opt/app/code/ 的文件路径下面找test
文件,没有该文件它就会报404/ - 访问192.168.37.192/
last
的时候,rewrite ^/last /test/ last;
也会去该root /opt/app/code
;下面的找test
,没找到文件,它就会把它当作一次请求的路径
来执行, 就会继续往下走, 到了,location /test/进行匹配,所以返回’{“status”:“success”}'页面。
- 访问192.168.37.192
2)redirect临时重定向与permanent永久重定向的区别:
-
创建一个配置项:
server { listen 80; server_name 192.168.37.192; access_log /var/log/nginx/log/host.access.log; root /opt/app/code; location ~ ^/break { rewrite ^/break /test/ break; } location ~ ^/last { rewrite ^/last /test/ last; } location /test/ { default_type application/json; return 200 '{"status":"success"}'; } location ~ ^/lh9/ { rewrite ^/lh9 http://www.baidu.com/ redirect; #rewrite ^/lh9 http://www.baidu.com/ permanent; } }
- 首先rewrite 开启
redirect
这个是临时重定向,开启的时候把访问日志也开启,这样有助于查看信息,当访问192.168.37.192/lh9/ 的时候 会跳转到www .baidu.com的页面,但是看日志的时候会发现,返回了俩个状态,一个是200状态, 一个是304状态。意思就是每回请求这个地址的时候,都要去请求一次Nginx服务器,这就是临时的重定向。 - rewrite 开启
permanent
这个是永久重定向, 也把请求日志开启,当访问192.168.37.192/lh9/ 跳转到www .baidu.com,但是你会发现请求只有200状态, 当你下次再继续请求的时候,就直接到www baidu.com的页面。
- 首先rewrite 开启
5、rewrite规则:
-
场景1:比如我的静态文件放在了,很多级的目录中/opt/app/code/course/11/22/lh9.html 很多级。
-
配置语法:
rewrite ^/course-(\d+)-(\d+)-(\d+)\.html$ /course/$1/$2/course_$3.html break; # 配置的内容就是 192.168.37.192/course-11-22-33.html 就会访问到/course/11/22/lh9.html 这个html文件, (\d+)就是数字 $1 就是匹配第一个() 里面的内容 $2就是匹配第二个() 里面的内容 中间有 - 进行连接 以course开头 .html结尾
-
-
场景2:或者指定允许什么样式的浏览器来访问我这个html。
-
配置语法:
if ($http_user_agent ~* Chrome) { rewrite ^/nginx http://www.baidu.com redirect; } # 配置内容就是192.168.37.192/nginx 访问这个地址的时候,前提你必须得是Chrome浏览器, 会帮你临# 时重定向到 www.baidu.com 页面上
-
-
场景3:请求的文件名的路径是否存在。如果不存在的话就redirect。
!-f
判断路径是否存在用的。!
的意思是取反。-
配置语法:
if (!-f $request_filename) { rewrite ^/(.*)$ http://www.baidu.com/$1 redirect; } # 配置内容就是192.168.37.192/xxxx(文件名) 判断请求的文件名的路径是否存在,如果不存在就跳转到www.baidu.com/xxx 文件名
-
6、rewrite规则优先级:
-
优先级最高的
执行server块的rewrite指令
→其次执行location匹配
→再其次执行选定location中的rewrite匹配
-
rewrite规则书写:
server { listen 80; server_name localhost nginx.org; if ($http_host = nginx.org) { rewrite (.*) http://www.nginx.org$1 } ..... }
-
rewrite优雅的规则书写
:server { listen 80; server_name nginx.org; rewrite ^http://www.nginx.org$request_uil?; }
三、Nginx高级模块:
1、secure_link_module(安全链接)模块:
-
作用:
- 一、制定并允许检查请求的链接的真实性以及保护资源免遭未经授权的访问。
- 二、限制链接生效周期,下载链接的有效时间,防止资源被无限的下载。
-
配置语法1:
- Syntax:secure_link expression;
- Default:-
- Context:http, server, location
-
配置语法2:
- Syntax:secure_link_md5 expression;
- Default:—
- Context:http,server,location
-
secure_link_module验证图示:
-
大体流程图:
- 点击下载链接→去请求服务器→会返回给客户端一段md5加密字符串跟过期时间→客户端拿的服务器返回的字符串再次请求服务器进行校验→通过了就有下载资源,没有通过就直接返回。
-
服务器返回给客户端字符串的详图:
-
配置项:
location / { secure_link $arg_md5,$arg_expires; # $arg是参数名(加密验证)(过期校验) secure_link_md5 "$secure_link_expires$uri fe_cow"; # fe_cow 是我自定义的加密串 # fe_cow 再后端的时候,也需要按照规格进行加密 if ($secure_link = "") { return 403; } if ($secure_link = "0") { return 410; } }
-
2、geoip_module模块
-
概念:基于IP地址匹配MaxMind GeoIP 二进制文件,读取IP所在地域信息。
-
场景:
- 一、区别国内外做HTTP访问规则。
- 二、区别国内城市地域作HTTP访问规则。
-
场景的演示:
geoip_country /etc/nginx/geoip/GeoIP.dat; # 国家的地域信息 geoip_city /etc/nginx/geoip/GeoLiteCity.dat; # 国家城市信息 把包都放在了etc/nginx/geoip/下面,怎么安装可以百度查找 server { listen 80; server_name 192.168.37.129; #charset koi8-r; #access_log /var/log/nginx/log/host.access.log main; location / { if ($geoip_country_code != CN) { # 如果国家代码不是CN的话,直接返回403,就是只能中国IP才可以访问 return 403; } root /usr/share/nginx/html; index index.html index.htm; } location /myip { # 访问192.168.37.129/myip 的时候就会出现 IP地址和相对应的国家 default_type text/plain; return 200 "$remote_addr $geoip_country_name $geoip_country_code $geoip_city"; }
四、HTTPS服务:
1、HTTPS协议原理:
- 一、为什么需要HTTPS?
- 原因:HTTP 不安全。
- 1.传输数据被中间人盗用,信息泄露。
- 2.数据内容易被劫持,篡改。
- 原因:HTTP 不安全。
2、HTTPS协议的实现:
-
对传输内容进行加密以及身份验证。
-
对称加密和非对称加密:
-
对称加密图解:
加密密钥跟 解密密钥是一样的,只是传输的过程中用的是密文而已。
- 对称加密的优点:连接快捷,减少连接性能上的损耗。
- 对称加密的缺点:没有非对称加密安全可靠
-
非对称加密图解:
是两串不同的密钥,发送方是进行公钥加密, 服务端保存的是私钥,这就是非对称加密
- 非对称加密的优点:安全可靠
- 缺点:连接较为复杂,消耗连接的时性能的损耗。
-
3、HTTPS加密协议原理:
-
图解如下:
-
首先客户端 发起SSL连接到服务器的时候,到服务器把公钥给客户端的过程,这是
非对称加密
,然后再发送对称密码给服务器,这时候建立的就是对称加密
。 -
总体来说,客户端跟服务器第一次进行了建立连接,得到非对称加密,以后的再连接时,就是对称加密。
-
中间人伪造客户端和服务端:
-
图解:
-
这时,中间人可以扮演客户端的角色请求服务端,也可以扮演服务端像客户端返回响应,这时候上面的加密协议就是有漏洞的。
-
-
解决中间人伪造客户端和服务端:
-
图解如下:
-
客户端对数字证书进行CA校验:
- 1.如果校验成功利用公钥加密。
- 2.如果校验失败停止会话。
-
4、证书签名生成CA证书:
一、生成密钥和CA证书:
- 首先确定系统是否安装:**#openssl | version **
- OpenSSL 1.0.1-fips 11 Feb 2013
- 再确定Nginx -V:
- –with-http_ssl_module
- 安装完:
- 步骤一:生成key密钥
- 步骤二:生成证书签名请求文件(csr文件)
- 步骤三:生成证书签名文件(CA文件)
5、HTTPS服务优化:
1、方法一:激活keeplive长连接:
keepalive_timeout 100;
2、方法二:设置ssl session缓存:
ssl on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
#ssl_certificate /etc/nginx/ssl_key/jesonc.crt;
ssl_certificate /etc/nginx/ssl_key/jesonc_apple.crt;
ssl_certificate_key /etc/nginx/ssl_key/jesonc.key;
#ssl_certificate_key /etc/nginx/ssl_key/jesonc_nopass.key;
五、Nginx 与 Lua开发:
1、Lua及基础语法:
-
Lua:是一个简洁、轻量、可扩展的脚本语言。
-
安装:
-
如果是ubuntu系统的话:
-
1、apt install lua5.1
-
2、输入lua就会进入交互环境:
root@ubuntu:/opt/work# lua Lua 5.1.5 Copyright (C) 1994-2012 Lua.org, PUC-Rio >
-
3、或者自己写个lua的脚本文件。比如:test.lua
#!/usr/bin/lua print("your_name")
-
-
-
注释:
- —行注释
- –[[ 块注释 – ]]
-
变量:
- a = ‘alo\n123’
- a = 'alo\n123 \ ’
- a = ‘\97lo\10\04923’
- a = [[alo123]]
- 布尔类型只有nil和false 是 false, 数字0 “空字符串(”\0")都是true"
- lua中的变量如果没有特殊说明,全是全局变量
-
while循环语句:
sum = 0 num = 1 while num <= 100 do sum = sum + num num = num + 1 end print("sum = ", sum)
- 注意:lua没有 + + 或是+=这样的操作
-
for 循环:
sum = 0 for i = 1, 100 do sum = sum + i end
-
if - else判断语句:
if age == 40 and sex == 'Male' print('等于40男人') elseif age > 60 and sex ~= 'Female' -~=- 代表的是不等于 print('非女人而且大于60') else local age = io.read() -io.read- 表示的是从屏幕的终端读取用户的输入信息 io.read是读取输出信息 print('Your age') end
2、Nginx与Lua环境:
-
Nginx + Lua 优势:
- 充分的结合Nginx的并发处理epoll优势和Lua的轻量实现简单的功能切高并发的场景。
-
首先下载:
- 1:LuaJIT
- 2:ngx_devel_kit和lua-nginx-module
- 3:重新编译Nginx
- 可以参考http://www.imooc.com/article/19597 文章
-
Nginx调用lua模块指令:
-
Nginx的可插拔模块化加载执行,共11个处理阶段。
set_by_lua 设置Nginx变量,可以实现复杂的赋值逻辑 set_by_lua_file 同上… 执行的是脚本文件 上面执行的是单行 access_by_lua 请求访问阶段处理,用于访问控制 access_by_lua_file 同上… 执行的是脚本文件 上面执行的是单行 content_by_lua 内容处理器,接收请求处理并输出响应 content_by_lua)_file 同上… 执行的是脚本文件 上面执行的是单行
-
-
Nginx Lua API:
ngx.var nginx变量 ngx.req.get_headers 获取请求头 ngx.req.get_uri_args 获取url请求参数 ngx.redirect 重定向 ngx.print 输出响应内容体 ngx.say 通ngx.print,但是会最后输出一个换行符 ngx.header 输出响应头
3、场景:
- 用Nginx结合Lua实现代码的灰度发布。
-
灰度发布:
- 按照一定的关系区别,分部分的代码进行上线,使代码的发布能平滑过渡上线。
- 1、用户的信息cookie等信息区别。
- 2、根据用户IP地址。
-
灰度发布图解:
-