| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 系统运维 -> Nginx实战详解 -> 正文阅读 |
|
[系统运维]Nginx实战详解 |
目录 4.9 使用nginx的rewrite(重定向)来配置防盗接 7.1 ?Nginx的第三方利?OpenResty+Lua介绍 7.3 高并发利?-Nginx+OpenResty第一个例子 .4 ?Nginx内置全局变量 和 OpenResty 请求阶段划分讲解 7.5 OpenResty开发内网访问限制或者端口访问限制(类似ECS安全组) 7.6 -Nginx+OpenResty实现请求限流和资源下载限速 第8章 Ngnix高可用解决方案LVS+KeepAlived 第2集 业界主流的高可用方案 Linux虚拟服务?LVS 讲解 第6集Nginx+LVS+KeepAlived高可用方案(主备模式)实战 第7集Nginx+LVS+KeepAlived高可用方案(双主模式)实战 第一章正向代理和反向代理1.1代理在Java设计模式中,代理模式是这样定义的:给某个对象提供一个代理对象,并由代理对象控制原对象的引用。 可能大家不太明白这句话,在举一个现实生活中的例子:比如我们要买一间二手房,虽然我们可以自己去找房源,但是这太花费时间精力了,而且房屋质量检测以及房屋过户等一系列手续也都得我们去办,再说现在这个社会,等我们找到房源,说不定房子都已经涨价了,那么怎么办呢?最简单快捷的方法就是找二手房中介公司(为什么?别人那里房源多啊),于是我们就委托中介公司来给我找合适的房子,以及后续的质量检测过户等操作,我们只需要选好自己想要的房子,然后交钱就行了。 代理简单来说,就是如果我们想做什么,但又不想直接去做,那么这时候就找另外一个人帮我们去做。那么这个例子里面的中介公司就是给我们做代理服务的,我们委托中介公司帮我们找房子。 Nginx 主要能够代理如下几种协议,其中用到的最多的就是做Http代理服务器。 1.2正向代理(VPN)弄清楚什么是代理了,那么什么又是正向代理呢 这里的 VPN 就是做正向代理的。正向代理服务器位于客户端和服务器之间,为了向服务器获取数据,客户端要向代理服务器发送一个请求,并指定目标服务器,代理服务器将目标服务器返回的数据转交给客户端。这里客户端是要进行一些正向代理的设置的。 核心:用户知道自己访问的目标服务?的地址也知道正向代理服务器的地址 使用场景:、访问原来无法访问的网站,VPN 1.3反向代理(Nginx等)反向代理和正向代理的区别就是:正向代理服务器代理的是客户端(客户是指客户端浏览器),反向代理服务器代理的是服务器(客户是Web网站)。 核心:客户端不知道要访问的目标服务?的地址,但是知道反向代理服务器的地址,反向代理服务器会根据一定的策略选择一个真实的服务?进行请求 反向代理,其实客户端对代理是无感知的,因为客户端不需要任何配置就可以访问,我们只需要将请求发送到反向代理服务器,由反向代理服务器去自己选择目标服务器获取数据后(我们要在反向代理服务器配置自己要用的目标服务器),在返回给客户端,此时反向代理服务器和目标服务器对外就是一个服务器,暴露的是代理服务器地址,隐藏了真实服务器IP地址。 理解这两种代理的关键在于代理服务器所代理的对象是什么,正向代理代理的是客户端,我们需要在客户端进行一些代理的设置。而反向代理代理的是服务器,作为客户端的我们是无法感知到服务器的真实存在的。 总结起来还是一句话:正向代理代理客户端,反向代理代理服务器。 1.4(域名请求的流程解析)线上访问服务?应用流程解析1一个通过域名访问的http请求的基本流程 客户端通过发起域名资源请求 -> DNS解析获得IP -> 寻找服务?获得资源 2 域名和ip的关系, 一个ip地址可以对应多个域名,但是一个域名只有一个ip地址 3 DNS作用 DNS:Domain Name Server 域名服务? 域名虽然便于人们记忆,但网络中的计算机之间只能互相认识IP地址,它们之间的转换工作称为域名解析,域名解析需要由专门的域名解析服务?来完成,DNS 就是进行域名解析的服务? 4 什么是cname和a记录 a记录(常用) 用户可以在此设置域名并指向到自己的目标主机ip地址上,从而实现通过域名找到服务?(也叫ip指向域名配置)aabbcc.com -> 120.24.216.117 cname 别名指向,可以为一个主机设置别名。比如设置open1024.com,用来指向一个主机 xdclass.net 那么以后就可以用open1024.com来代替访问xdclass.net 了? ,可以直接输入xdclass.net去访问 www.xdclass.net --> xdclass.net 第二章 Nginx的部署的本地域名映射1 使用dokcer部署docker run --name xdclass-nginx -d -p 80:80 -v /tmp/nginx/log:/var/log/nginx -v /tmp/nginx/conf/nginx.conf:/etc/nginx/nginx.conf -v /tmp/nginx/html:/usr/share/nginx/html?? -v /tmp/nginx/conf/deny.conf:/etc/nginx/deny.conf????? 08b152afcfae 2 本地域名映射当我们没有公网域名时,可以使用本地域名来模拟 使用SwitchHosts工具去做本地域名映射 比如此时虚拟机的IP为 192.168.43.180? 我们做了域名映射后,在浏览器中访问图中的xxrtest.com就是访问192.168.43.180 第三章 Nginx目录以及配置文件的详解3.1 Nginx目录在docker安装的Nginx中 1 配置文件目录在 /etc/nginx 目录中 里面有default.conf(模板配置文件)以及Nginx.conf(正式配置文件,里面会包含在模板配置文件进行的配置) 2 默认站点目录在 /usr/share/nginx/html中 里面有50x.html #错误页面(服务器报错页面)index.html #默认首页 3 日志目录/var/log/nginx 里面有access.log? error.log 3.2 Nginx 配置文件详解打开nginx配置文件Nginx后,我们可以很明显的将 nginx.conf 配置文件分为三部分: 1 全局块,2 events块 3http块 # 每个配置项由配置指令和指令参数 2 个部分构成 user? nginx; worker_processes? auto; error_log? /var/log/nginx/error.log notice; pid??????? /var/run/nginx.pid; events { ??? worker_connections? 1024; } http { ??? include?????? /etc/nginx/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; ??? #tcp_nopush???? on; ??? keepalive_timeout? 65; ??? #gzip? on; ??? include /etc/nginx/conf.d/*.conf; } 3.2.1全局块? (配置全局指令) 从配置文件开始到 events 块之间的内容,主要会设置一些影响nginx 服务器整体运行的配置指令,主要包括配置运行 Nginx 服务器的用户(组)、允许生成的 worker process 数,进程 PID 存放路径、错误日志存放路径和类型以及配置文件的引入等。 user? nginx; # 指定Nginx Worker进程运行以及用户组 比如上面第二行配置的:
这是 Nginx 服务器并发处理服务的关键配置,worker_processes 值越大,可以支持的并发处理量也越多,但是会受到硬件、软件等设备的制约,这个后面会详细介绍。推荐与CPU的核数保持一致 error_log? /var/log/nginx/error.log notice; 表示错误日志存放目录 ?? pid ???/var/run/nginx.pid; # 进程PID存放路径 3.2.2events 块(事件模块指令) 比如上面的配置:
events 块涉及的指令主要影响 Nginx 服务器的性能与用户的网络连接数,常用的设置包括是否开启对多 work process 下的网络连接进行序列化,是否允许同时接收多个网络连接,选取哪种事件驱动模型来处理连接请求(如epoll 异步非阻塞,线上一般用这个),每个 word process 可以同时支持的最大连接数等。 上述例子就表示每个 work process 支持的最大连接数为 1024. # 定义Nginx每个进程的最大连接数, ?作为(静态资源)服务?(不与后端联系的话)来说最大并发为: worker_connections * worker_processes, # 作为反向代理服器器来说,最大并发数量应该是 worker_connections * worker_processes/2。 因为反向代理服务?,每个并发会建立与客户端的连接和与后端服务的连接,会占用两个连接 这部分的配置对 Nginx 的性能影响较大,在实际中应该灵活配置。
#Nginx默认初始配置中时没有的我们可以加上以提高性能 3.2.3http 块 ?http全局块配置的指令包括文件引入、MIME-TYPE(枚举类型) 自定义accesslog的日志格式、连接超时时间、单链接请求数上限等。 http { ??? include?????? /etc/nginx/mime.types; #枚举类型 default_type? application/octet-stream; #内容类型 #用户访问日志accesslog的格式(后期我们肯定要修改) ??? 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;? # access_log的地址 ??? sendfile??????? on;? #开启高效传输 ??? #tcp_nopush???? on; #减少网络报文的数量 ??? keepalive_timeout? 65; #客户端连接超时时间 #gzip? on; #压缩(压缩客户端发送的文件,可以减少带宽) server { ??????? listen 9001; #虚拟主机监听的端口 ??????? server_name 118.31.13.73 xxrtest.com; #虚拟主机的名称可以是Ip也可以是域名,可以在这里写多个,空格隔开,一般是写多个域名 ? ???????access_log? /var/log/nginx/ gateway_access.log? main;? #每个server也可以有自己的access_log的地址 # Location主要是用来匹配(拦截)Nginx? 服务器接收到的请求uri,匹配成功则反向代理到指定的服务器当中去(可以写正则表达式) ??????? location / { ???? ????proxy_pass http://gateway/;#被代理服务器的地址 ???????? root html; //存储路径可以是绝对路径也可以是相对路径,用来做静态文件服务器的 ???????? index? index.html index.html; 如果匹配路径/后面没有写东西则进入这个页面 (即默认的首页) ???????? } ???? } ??? include /etc/nginx/conf.d/*.conf; } 3.2.3.1 ?upstream 块(请求转发块)(包含在http 全局块中) 假设Nginx只能代理一台服务器的话,那它也不可能像今天这么火。Nginx能够配置代理多台服务器。当一台服务器宕机之后。仍能保持系统可用。 使用nginx的upstream块可以让nginx代理多台服务器,当请求到nginx的upstream块之后,upstream块会按照轮询(默认)方式进行负载均衡的反向代理 如??? upstream nacos { ????? ? server 192.168.152.1:8849; ????? ? server 192.168.152.1:8850; ????? ? server 192.168.152.1:8851; ????? } ????? upstream redisLock { ????? ? server 192.168.43.98:8080 weight=1; ????? ? server 192.168.43.98:8081 weight=1; ????? } 3.2.3.2 ?server 块(虚拟主机块)(包含在http 全局块中)(可以有多个server) 这块和虚拟主机有密切关系,虚拟主机从用户角度看,和一台独立的硬件主机是完全一样的,该技术的产生是为了节省互联网服务器硬件成本。后面会详细介绍虚拟主机的概念。 每个 http 块可以包括多个 server 块,而每个 server 块就相当于一个虚拟主机,每一个虚拟主机块server可以监听一个端口。不同的server他们监听的端口可以是一样的但是 server_name即虚拟主机的名称一定不一样 而每个 server 块也分为全局 server 块,以及可以同时包含多个 locaton 块。 1、全局 server 块 最常见的配置是本虚拟机主机的监听配置和本虚拟主机的名称或IP配置。
3.2.3.2.1 location 块(路径拦截器块)(包含在server 块中) 一个 server 块可以配置多个 location 块。 ? Location主要是用来匹配Nginx? 服务器接收到的请求uri的(不是URL),当匹配成功时Nginx?会做出应答给客户端(反向代理到某个地址,或者直接到Nginx配置的页面当中去,或者直接获取存储路径中的静态资源)(可以写正则表达式去匹配收到的请求uri的) location /redisLock/{ ?????????? ?proxy_pass http://redisLock/;???? ???? ???????root html; //存储路径可以是绝对路径也可以是相对路径,用来做静态文件服务器的(一般都是单独写) ??? ??????????index? index.html index.html; ???? }? 2.1 proxy_pass该指令用于设置被代理服务器的真实地址。可以是主机名称、IP地址加端口号的形式,也可以是upstream块的名称(因为我们往往会让nginx同时代理多台服务器)。 (注意这里的proxy_pass地址后面一定要加/,否则真正要用的uri无法反向代理到我们真实的服务器中 这里请求的url如果是 http://localhost/redislock/test1,则uri/redislock/test1那么uri只有后面部分会反向代理到我们真实服务器192.168.43.98:808x中(location的匹配路径并不会反向代理过去) ?这样真实的请求(方向代理请求)就变成了192.168.43.98:808x/ test1, 如果不加/,那么反向代理的请求就变成 http:// 192.168.43.98:808x /redislock/test1,肯定是404 ) 2 .2 root 这里指的是存储路径可以是绝对路径也可以是相对路经(使用root时就是用Nginx做静态资源服务器) ?? location /static/{ ??? root?? /usr/share/nginx/html; ??? } 3 index? 如果匹配路径/后面没有写东西则进入这个首页页面(即默认的首页) ,如果找不到index.html则返回404 3.2.3.2.2 location块的拦截顺序问题 注意:当有多个location块时我们要考虑顺序问题,在前面的优先拦截,我们一般吧?? location / {? 这个放在末尾以防影响其他的location,因为它什么请求都会拦截 } 3 .3 access.log日志用处1 统计站点访问ip来源、某个时间段的访问频率 2 查看访问最频的页面、Http响应状态码、 3 接口性能接口秒级访问量、分钟访问量、小时和天访问量 4 查看PV 等参数指标 #用户访问日志accesslog的格式(后期我们肯定要修改) ??log_format? main? '$remote_addr - $remote_user [$time_local] "$request" ' ????????????????????? '$status $body_bytes_sent "$http_referer" ' ????????????????????? '"$http_user_agent" "$http_x_forwarded_for"'; 注意:这些数据都在一行中,且各自都是空格隔开,我们可以使用awk命令去按列提取(切割) 这样方便对access.log进行数据分析 实例 122.70.148.18 - - [04/Aug/2020:14:46:48+0800] "GET /user/api/v1/product/order/query_state? product_id=1&token=xdclasseyJhbGciOJE HTTP/1.1" 200 48 "https://xdclass.net/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36" 常见属性的解析 1 $remote_addr 对应的是真实日志里的122.70.148.18, 即客户端的IP。 2 $remote_user 对应的是第二个中杠“-”,没有远程用户, 所以用“-”填充。 3 [$time_local]对应的是[04/Aug/2020:14:46:48+0800]。 请求的时间 4 “$request”对应的是 请求类型和请求Uri(用来统一最热门的接口) 5 $status对应的是200状态码,200表示正常访问。 6 $body_bytes_sent对应的是48字节,即响应body的大小。 7 $http_referer” 对应的即请求的来源即是”https://xdclass.net/“,若是直接打开域名浏览的时,referer就会没有值,为”-“。(可以用来设置防盗链) 8 “$http_user_agent” 指用户的代理信息如用户是通过什么系统访问win,mac,安卓等,什么浏览器访问(可以用来防爬虫,爬虫的话,这个地方一般都是为空的) 对应的是 ”Mozilla/5.0(Macintosh; Intel Mac OS X 10.12; rv:56.0) Gecko/20100101 Firefox/56.0”。 9 “$http_x_forwarded_for” 对应的是”-“或者空。(只有配置了这个,后端才能直接获取用户的真实IP) 3.3.1通过access.log获取访问最频繁的前100个IP awk '{print $1}' access_temp.log | sort |uniq -c | sort -rn | head -n 100 (命令逻辑:先切割日志中第一列的数据出来,进行排序一下,在使用uniq 去除重复出现的行列, -c 在每列旁边显示该行重复,这样此时就有两列数据,再sort –rn按第一列的数值大小(即重复数)进行倒序,再取前100条数据) 命令解析 awk 是文本处理工具,默认按照空格切分,默认按列切割(提取)数据,$N 是切割第N列的数据 sort命令用于将文本文件内容加以排序,-n 按照数值排,- r 按照倒序来排 案例的sort -n 是按照第一列的数值大小进行排序,从 小到大,倒序就是 sort -rn uniq 去除重复出现的行列, -c 在每列旁边显示该行重复 出现的次数。 head –n 取前多少行的数据 3.3.2 通过access.log获取访问最多的url(接口)前20名 awk '{print $7}' access_temp.log | sort | uniq -c|sort -rn|head -n 20 最简单的写法,但是由于URI的参数会不同(如token不同),实际项目中不能这么写 /pub/api/v1/web/user_info?token=xdclasssdfsdf2sseyJhbGciOiJIUzI1NiJ9.eyJzd 线上的写法 awk '{print $7}' access_temp.log|awk -F"?" '{print $1}'|sort|uniq -c|sort -rn|head -n 20 (我们还要把URL参数给去掉,再统计) (第二次awk是根据?号去分割数据) 结果是这种 4574 /user/api/v1/product/order/query_state ? ?1165 /pub/api/v1/web/user_info ??? 684 /order/api/v1/video/xdcloud_play_url ??? 610 /pub/api/v1/web/product/find_list_by_type ??? 428 /pub/api/v1/web/all_category ??? 357 /pub/api/v1/web/video_detail ??? 346 /user/api/v1/order/query_state ??? 264 /pub/api/v1/web/index_card ??? 224 /pub/api/v1/web/find_ad_by_id ??? 190 /pub/api/v1/web/page_video ??? 174 /pub/api/v1/web/list_buyer ??? 143 /pub/api/v1/web/relative_video ??? 140 /pub/api/v1/web/funny_lang_list ??? 134 /user/api/v1/order/find_orders ??? 126 /pub/api/v1/web/is_favorite ??? 119 /user/api/v1/video_record/page ??? 111 /pub/api/v1/web/search ???? 53 /pub/api/v1/web/web_login ???? 26 /pub/api/v1/web/get_free_online_note ???? 15 /pub/api/v1/web/tool/page_all_tools 3.3.3自定义access.log日志统计接口性能 使用单纯的jmeter测出的接口的响应时间,可能不是实际线上的接口响应时间,我们就可能无法找到瓶颈,我们可以使用Nginx的access.log日志来分析最准确的接口响应时间 步骤:日志格式的最后增加 $request_time $request_time:从接受用户请求的第一个字节到发送完响应数据的时间,即 包括接收请求数据时间、程序响应时间、输出响应数据时间,用它来描述用户对接口的性能是最好的 $upstream_response_time:指从Nginx向后端建立连接开始到接受完数据然后关闭连接为止的时间用它来描述纯后端接口的性能是最好的 $request_time一般会比upstream_response_time 大,因为用户网络较差,或者传递数据较大时,前者会耗时大很多 实例:统计耗时接口,列出传输时间超过 2秒的接口和其次数,显示前5条 cat time_temp.log|awk '($NF > 2){print$7}'|sort -n|uniq -c|sort -nr|head -5 $NF 表示最后一列 (当然这里也没有处理接口的参数问题) 完善的后的接口,处理接口参数后 awk '($NF>2){print $7}' access_temp.log|awk -F"?" '{print $1}'|sort|uniq -c|sort -rn|head -n 20 3.3.4 根据access.log获取pv(访问量)和uv(用户量)数据 PV(访问量):即Page View, 即页面浏览量或点击量,用户每次刷新即被计算一次。 UV(独立访客)(用户量):即Unique Visitor,访问您网站的一台电脑客户端为一个访客。00:00-24:00内相同的客户端只被计算一次。 1 我们可以根据accesslog中访问的uri(接口)数量(次数)去统计PV(访问量) awk '{print $7}' access_temp.log|awk -F"?" '{print $1}'|sort|uniq -c|sort -rn| wc -l 2 我们可以根据accesslog中的访问的ip数量去统计PV(用户量) awk '{print $1}' access_temp.log | wc –l ?? 3 获取日志中所有每分钟请求的数量 ?cat access.log? | awk '{print substr($4,14,5)}' | uniq -c | awk '{print $2","$1}' > access.txt 第四章Nginx的常见应用4.1 Nginx搭建静态资源服务器(动静分离)完整配置 user? nginx; worker_processes? auto; error_log? /var/log/nginx/error.log notice; pid??????? /var/run/nginx.pid; events { ??? worker_connections? 1024; } http { ??? include?????? /etc/nginx/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; ??? #tcp_nopush???? on; ??? keepalive_timeout? 65; ??? server { ??? listen? 80; ??? server_name xxrtest.com; ??? proxy_cache_path /root/cache levels=1:2 keys_zone=xd_mystatic:30h max_size=1g inactive=30h use_temp_path=off; ???? location /static/ { #使用Nginx的客户端缓存(浏览器缓存)缓存静态资源数据 expires 30d; ?? ???root? /usr/share/nginx/html;? #静态资源存储在这个目录中,我们一般给这个目录做一个文件挂载 # 当我们请求是http://xxrtest.com/static/css/base.css 等(还有JS,img)的时候时会去获取/usr/share/nginx/html/static/css/base.css 目录中的css文件,注意这个目录路径在创建时中一定要带static否则会出现找不到文件的情况, ????? } ???? location / {? #因为要考虑路径拦截的顺序问题所以将 /放在后面 ????? root? /usr/share/nginx/html; ????? index? index.html; ???? } ??? #gzip? on; ??? include /etc/nginx/conf.d/*.conf; } 4.2 Nginx同时代理多台不同域名的(网站)服务器1 利用虚拟主机server块把多个不同域名的网站部署在同一台服务?上,节省了服务?硬件成本和相关的维护费用。 方式1 : 使用多个server块,每个server块的 server_name 不同 ?server { ??? listen? 80; ??? server_name xxrtest.com; ???? location /static/ { ????? root? /usr/share/nginx/html; ????? ????? } ???? ??? ???? location / { ????? root? /usr/share/nginx/html; ????? index? index.html; ???? } ??? ?? } ?? ??? server { ??? listen? 80; ??? server_name xdclass.com; ???? location /static/ { ????? root? /usr/share/nginx/html; ????? } ???? location / { ????? root? /usr/share/nginx/html; ????? index? xdclassindex.html; ???? } ?? } 4.3 负载均衡与常见的负载均衡策略(重点)4.1 Nginx负载均衡实例代码 ? upstream gateway { ??? server 172.30.193.38:9088; ??? server 172.30.193.38:9089; ??? } ??? server { ??????? listen 9001; ??????? server_name 118.31.13.73; ??????? location / { ??????? #设置被代理服务器的真实地址 ???????? proxy_pass http://gateway/; ?? ???????? } ???? } 4.2 Nginx常见的负载均衡策略 4.2.1节点轮询(默认)(使用的少) 简介:每个请求按顺序分配到不同的后端服务? (使用的比较少) 场景:会造成可靠性低(一旦轮询到的那个节点挂了)和负载分配不均衡(由于机器性能的差异),适合静态文件服务? 4.2.2 Weight权重配置(使用的多) 简介:weight和访问比率成正比,数字越大,分配得到的流量越高 场景:服务?性能差异大的情况使用 upstream gateway { ??? server 172.30.193.38:9088 weight=5; ??? server 172.30.193.38:9089 weight=10; } 4.2.3 ip_hash(固定分发)(使用本地缓存的项目必须使用这个) 简介:根据用户请求的访问ip的hash结果分配(进行负载君合),这样每个用户就可以固定访问一个后端服务? 场景:服务?业务分区、业务缓存(本地缓存)、Session需要单点的情况, 注意:当我们的业务使用本地缓存时,我们必须使用这个,不然在集群情况下本地缓存失效,和本地缓存数据不一致的概率非常大。 Upstream gateway { ip_hash;? ? ??server 172.30.193.38:9088; ??? server 172.30.193.38:9089; } 4.2.4 upstream还可以为每个节点设置状态值 down 表示当前的server暂时不参与负载 server 192.168.159.133:8080 down; backup 其它所有的非backup机?down的时候,会请求backup机?,这台机?压力会最轻,配置也会相对低,这是一个备用的服务器,我们一般都会设置 server 192.168.159.133:8080 backup; 4.4 Nginx探测后端节点可用性和配置实操(重点)如果某个应用节点挂了,请求不应该继续分发到这个应用节点中 max_fails 允许请求失败的次数,默认为1.当超过最大次数时就暂时不会请求该节点的应用 fail_timeout : max_fails次失败后,暂停请求某节点的时间,默认:fail_timeout为10s,过了这个时间只会,会继续进行尝试请求(与熔断策略很像)如果成功的话就复活该节点 参数解释 max_fails=N 设定Nginx与后端节点通信的尝试失败的次数。 在fail_timeout参数定义的时间内,如果失败的次数达到此值,这个节点就暂时不可用在定义的时间内。在下一个fail_timeout时间段到来前,这个节点服务?不会再被尝试。 失败的尝试次数默认是1,如果设为0就会停止统计尝试次数,认为服务?是一直可用的。 具体什么是nginx认为的失败呢 可以通过指令proxy_next_upstream来配置什么是失败。 注意默认配置时,http_404状态,不会被认为是请求失败的。 proxy_next_upstream error timeout http_500 http_503 http_404;? //注意:实际项目中为防止他人恶意攻击导致(错落的请求路径,但是我们的服务器却是好的)我们全部的节点不可用,一般不设置 http_404 upstream gateway { ip_hash;? server 192.168.0.106:8080 max_fails=2 fail_timeout=60s ; server 192.168.0.106:8081 max_fails=2 fail_timeout=60s; } location / { proxy_pass http://gateway/; proxy_next_upstream error timeout http_500 http_503 http_404; } 案例实操 暂停一个后节点,然后访问接口大于10次,Nginx会把 这个节点剔除 重启这个节点,在fail_timeout周期里面不会再获取流 量 4.5 Nginx-全局异常兜底数据返回简介:Nginx自定义全局异常json数据 任何接口都是可能出错,4xx、5xx等 如果业务没有做好统一的错误管理,直接暴露给用户,无疑是看不懂,不过实际项目中500的错误,后端基本全部会做好统一的错误管理,但是400的错误如404,403等却没法统一做 所以假如后端某个业务出错,nginx层也需要进行转换,让前端知道Http响应是200,其实是将错误的状态码定向至200,返回了全局兜底数据(不管后端出什么错误,最终用户见到的都是200的响应,但是在4xx时,5xx会有错误提示) server { ??? listen? 80; ??? server_name xdclass.com; ??? location / { ?????? proxy_pass http://gateway/; ##开启错误拦截配置,一定要开启 ?? ????proxy_intercept_errors on; ?? } # 我们还可以设置多种错误状态码的不同返回 ?? ?error_page 403 =200? /defaultError403Api; ?? location = /defaultError403Api { ?? default_type application/json; ?? return 200 '{"code":"-1","msg":"请求的资源不允许访问,没有对应的权限 "}'; ? } ?? error_page 404 =200? /defaultError404Api; ??? location = /defaultError404Api { ???? default_type application/json; ??? return 200 '{"code":"-1","msg":"页面不存在或接口不存在请检查请求路径 "}'; ?? } } 4.6? nginx热加载配置,不中断服务1 docker 安装的nginx 进行热加载 docker exec -it 683ca3c9abe0 bash -c 'nginx -s reload' 2 源码编译安装的nginx ./nginx -s reload 4.7 Nginx封禁恶意IP网络攻击时有发生, TCP洪水攻击、注入攻击、DOS等比较难防的有DDOS等 数据安全,防止对手爬虫恶意爬取, 解决方法:一般就是封禁ip linux server的层面封IP:iptables nginx的层面封IP方式多种 (但 req还是会打进来, 让nginx 返回 403, 占用资源) Nginx作为网关,可以有效的封禁ip 4.7.1Nginx手动封禁IP 单独网站屏蔽IP的方法,把deny放在server{}语句块,虚拟主机块 所有网站屏蔽IP的方法,把deny {}放在http语句块。 如deny 192.168.159.2; 也可以使用配置参数在location中 ??????? location { ??????????? ... ??????????? #限制每ip每秒不超过20个请求,漏桶数burst为5 ??????????? #brust的意思就是当每秒超过20个请求时,5个以内的请求会被延迟访问,超过5个的直接返回503 ??????????? #nodelay,设置该选项,将严格使用平均速率限制请求数,超过请求频率的直接返回503 ?????? ?????limit_req zone=happy burst=5 nodelay; ?????? ??????? } 4.7.2拓展-Nginx自动化封禁ip思路和实现脚本 编写shell脚本 AWK统计access.log,记录每分钟访问超过60次的ip要结合日志切割,然后配合nginx或者iptables进行封禁 crontab定时跑脚本 脚本如下 #!/bin/bash #AWK统计access.log,记录每分钟访问超过60次的ip到deny.conf配置文件中deny.conf配置文件已经包含在nginx.conf中了 #(输入形式是 deny ip ;) awk '{print $1}' access.log | sort |uniq -c | sort -rn | awk '{if($1>60) print "deny "$2";"}'>>/tmp/nginx/conf/deny.conf #nginx日志路径(定义变量) logs_path=/tmp/nginx/log lastminute=$(date -d 'yesterday' +%Y-%m-%d+%H:%M) #移动日志并以日期改名 #${变量名}—表示使用变量 mv ${logs_path}/access.log ${logs_path}/accesslog_dir/access_${lastminute}.log mv ${logs_path}/error.log ${logs_path}/errorlog_dir/error_${lastminute}.log #向nginx主进程发送信号,重新生成日志文件(因为日志文件被我们改名移动了,nginx不会自己生成日志文件,所以我们要向nginx主进程发送信号(即向主进程PID发信号即可),重新生成日志文件,不然会丢失日志信息-- nginx.pid与Nginx主进程pid一模一样) # ps -ef |grep nginx #查看nignx进程 kill -USR1 $(ps -ef |grep nginx |awk 'NR==1 {print $2}') #热加载Nginx docker exec -it? xdclass-nginx? bash -c 'nginx -s reload' 使用定时任务(每分钟执行) 4.8 Nginx如何配置浏览?跨域跨域:浏览?同源策略 1995年,同源政策由 Netscape 公司引入浏览?。目前,所有浏览?都实行这个政策。 最初,它的含义是指,A网页设置的 Cookie,B网页不能打开,除非这两个网页"同源"。所谓"同源"指的是"三个相同" 1 协议相同 http https 2 域名(ip)相同 www.xdclass.net 3 端口相同? 80? 81 一句话:浏览?从一个域名的网页去请求另一个域名的资源 时,域名(ip)、端口、协议任一不同,都是跨域(跨域在默认情况下会无法访问) 浏览?控制台跨域提示: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. 解决方法 1 JSONP 2 Http响应头配置允许跨域(使用的多) nginx层配置(更加方便统一) 程序代码(JAVA)中处理通过拦截?配置 Nginx开启跨域配置,location下配置(当然有时候我们是有些接口允许跨域有些不允许(即在有些location上配置跨域有些不配置即可),但是对于微服务项目,网关是唯一请求入口,所以是统一做跨域处理,静态资源一般不做跨域处理) location / { # 允许跨域的源? * 代表所有 若考虑到安全性,也可以指定访问来源请求的域 add_header 'Access-Control-Allow- Origin' $http_origin; # 是否允许发送cookie add_header 'Access-Control-Allow- Credentials' 'true'; #允许携带的请求头 add_header'Access-Control-Allow-Headers''DNT,web-token,token,Token,app-token,Authorization,Accept,Origin,Keep-Alive,User-Agent,X-Mx-ReqToken,X-Data-Type,X-Auth-Token,X-Requested-With,If- Modified-Since,Cache-Control,Content- Type,Range'; #允许跨域的请求方法 add_header Access-Control-Allow- Methods 'GET,POST,OPTIONS,DELETE'; #如果预检请求则返回成功,不需要转发到后端 if ($request_method = 'OPTIONS') #注意=两边都有一个空格 { add_header 'Access-Control-Max-Age' 1728000; add_header 'Content-Type' 'text/plain; charset=utf-8'; add_header 'Content-Length' 0; return 200; } } #允许跨域请求的域,* 代表所有 add_header 'Access-Control-Allow-Origin' *; #允许请求的header add_header 'Access-Control-Allow-Headers' *; #允许带上cookie请求 add_header 'Access-Control-Allow-Credentials' 'true'; #允许请求的方法,比如 GET,POST,PUT,DELETE add_header 'Access-Control-Allow-Methods' *;
4.9 使用nginx的rewrite(重定向)来配置防盗接Nginx配置重定向的应用场景 1非法访问跳转,防盗站、(防止其他人盗用我们己网站的链接,或者静态资源,显示到他的网站上去,如果被盗的话消耗还是我们自己的资源)(用的多) 2 更换新域名(还是可以输入老域名,但是会重定向到新域名中来)(用的多) 3 http跳转https(用的多) 4 不同地址访问同一个虚拟主机的资源 Nginx重写-重定向的概念 rewrite 地址重定向,实现URL重定向的重要指令,他根据regex(正则表达式)来匹配内容跳转 语法 rewrite regex replacement[flag] rewrite ^/(.*) https://xdclass.net/$1 ????????????permanent? (即我们访问任务地址都会跳转到任何https://xdclass.net中去) # 这是一个正则表达式,匹配完整的域名和后面的路径地址 # replacement部分是https://xdclass.net/$1,$1 是取自regex部分()里的内容 [flag]是指重定向的形式 常用正则表达式
rewrite 最后一项flag参数
location / { ? #是指请求的来源,如果我们直接打开域名浏览的时就重定向到首页(防止别人知道了我们资源的链接就来盗取资源,只有从首页去访问域名时才会正常跳转,nginx不支持else,如浏览器直接访问https://xdclass.net/#/coursedetail?video_id=50没有用还是会重定向到https://xdclass.net这样别人无法直接使用我们的资源了) ? ?if ($http_referer = '-') ?? {? rewrite ^/(.*) https://xdclass.net/$1 permanent; ?? } ?? if ($http_referer = ' https://xdclass.net') ?? { ??proxy_pass http://gateway/; ?? } ?rewrite ^/(.*) https://xdclass.net/$1 permanent; } 4.10 Nginx的locatioin匹配规则应用正则 ^ 以什么开始 $ 以什么结束 ^/api/user$? #表示用以/api开头? 以user结尾。 location 路径匹配? 语法 location [ = | ~ | ~* | ^~ ] uri {??? } 1 location = /uri??? =表示精准匹配,只要完全匹配上才能生效(一般不用) 2 location /uri??? 不带任何修饰符,表示前缀匹配(用的最多,也是默认使用的) 3 location ^~ /uri/ ??匹配任何已 /uri/开头的任何查询并且停止搜索 4 location /? 通用匹配,任何未匹配到其他location的请求都会匹配到(为了不影响其他location我们会把它放在最后面) 5 正则匹配 区分大小写匹配(~) 不区分大小写匹配(~*)放在最前面 如~^/api/pub$ 匹配规则的优先级(不要写复杂,容易出问题和遗忘) 精准匹配 > 字符串匹配(前缀匹配)(若有多个匹配项匹配成功,那么选择匹配长的并记录) > 正则匹配 (注意: 1 当有多个相同语法的location时,会先匹配放在前面的location,每个请求最多匹配一个location 2 ?当然为了开发方便一个项目中最好只使用一种匹配语法 ) 案例 server { server_name xdclass.net; location ~^/api/pub$ { } } ^/api/pub$这个正则表达式表示uri字符串必须以/开始,以b结束不能多加一个/在最后,中间必须是/api/pub,后面可以加参数 ?http://xdclass.net/api/v1 匹配(完全匹配) ?http://xdclass.net/API/PUB 不匹配,大小写?感 http://xdclass.net/api/pub?key1=value1 匹配 http://xdclass.net/api/pub/ 不匹配 http://xdclass.net/api/public 不匹配,不能匹配正则表达式 测试 location = /img/test.png { return 1; } location /img/test.png { return 2; } location ^~/img/ { return 3; } location = / { return 4; } location = / { return 4; } 4.11 Nginx端缓存前置简介:讲解Nginx 端缓存核心配置 常见的开发人员控制的缓存分类 1 数据库缓存 2 应用程序缓存 –分布式缓存,本地缓存 3 Nginx网关缓存 (性能比Redis更好甚至比后端本地缓存更好,因为更靠近用户,速度会更快) 4前端缓存 注意: 1 Nginx缓存让后端结果缓存离用户更进一步(会有比redis更好的效果) 2 默认情况下GET请求及HEAD请求会被缓存,而POST请求不会被缓存,并非全部都要缓存,可以过滤部分路径不用缓存 3 ?Nginx 是一个缓存热点数据且不易改变数据的最好选择,但是呢对数据一致性较高的数据,或者经常改变的数据不要使用这个(一般就是那一些一成不变的数据,或者如果要改变但是改变的频率不高的数据),因为Nginx不方便更新缓存,Nginx缓存的时间尽量不要太长。当缓存的数据是后端接口的数据尽量使用proxy_cache_valid这个去设置缓存过期时间不要使用Inactive它容易造成数据不一致,当缓存的数据是静态文件数据时可以使用Inactive 使用场景:通常对于静态资源,即较少经常更新的资源,如图片,css或js等进行缓存,从而在每次刷新浏览器的时候,不用重新请求,而是从缓存里面读取(因为这些静态资源数据基本固定不变,我们 往往可以使用更进一步的Nginx客户端缓存expires,这样配置起来更方便),这样就可以减轻服务器的压力,此外那些获取固定数据的接口,还有获取首页图片,分类数据的接口也可以使用Nginx缓存,注意不应是所有的接口都做Nginx缓存。 核心配置 1 /root/cache 本地路径,用来设置Nginx缓存资源的存放地址 2 levels=1:2 默认所有缓存文件都放在上面指定的根路径中,可能影响缓存的性能,推荐指定为 2 级目录来存储缓存文件;1和2表示用1位和2位16进制来命名目录名称。第一级目录用1位16进制命名,如a;第二级目录用2位16进制命名,如3a。所以此例中一级目录有16个,二级目录有16*16=256个,总目录数为16 * 256=4096个。 当levels=1:1:1时,表示是三级目录,且每级目录数均为16个 3 key_zone? (key空间)(设置key空间和其大小) 在共享内存中定义一块存储区域来存放缓存的 key和 metadata(缓存的使用次数,过期时间等) 4 max_size(推荐1G) 最大缓存空间,如果不指定会使用掉所有磁盘空间。当达到disk上限后,会删除最少使用的cache 5 Inactive(类似于缓存过期时间,但是如果在指定时间内访问了,就会重新计时,如果超过这个时间还没有进行访问,则将会从缓存中删除)(为了数据的一致性考虑一般不使用这个) 某个缓存在inactive指定的时间内如果不访问,将会从缓存中删除 6 proxy_cache_valid (缓存的过期时间)(优先级低于Inactive) 配置nginx cache中的缓存文件的缓存时间 ,proxy_cache_valid 200 304 2m 对于响应状态为200 和304的请求缓存文件的缓存时间是2分钟 nginx缓存过期影响的优先级进行排序为:inactvie >(浏览器缓存)源服务?端Expires/max-age > proxy_cache_valid 7use_temp_path? (使用临时文件夹)建议为 off,则 nginx会将缓存文件直接写入指定的cache 文件中 8 proxy_cache 启用proxy cache,并指定key_zone,如果proxy_cache off表示关闭掉缓存 如proxy_cache xd_cache 9 add_header Nging-Cache "$upstream_cache_status" (可以用于统计Nginx缓存是否命中的) 用于前端判断是否是缓存,miss(不命中)、hit(命中)、expired(缓存过期)、updating(更新,使用旧的应答)) 10 proxy_cache_min_uses 指定请求至少被发送了多少次以上时才缓存,可以防止低频请求被缓存。 proxy_cache_path /root/cache levels=1:2 keys_zone=xd_cache:2m max_size=1g inactive=1m use_temp_path=off; 实例 server { location /{ ... proxy_cache xd_cache; proxy_cache_valid 200 304 1m; proxy_cache_valid 404 1m; proxy_cache_key $host$uri$is_args$args; #缓存key的规则这里写的是主机+uri+参数 proxy_cache_min_uses 3 #请求至少被发送了多少次以上时才缓存,可以防止低频请求被缓存 add_header Nginx-Cache ????"$upstream_cache_status"; } } 还原nginx配置,只保留upstream模块 配置实操 请求后端json接口,通过控制台日志判断是否有到后端服务 注意: 1 nginx缓存过期影响的优先级进行排序为:inactvie >源服务?端Expires/max-age > proxy_cache_valid 2 如果出现 Permission denied 修改nginx.conf,将第一行修改为 user root(提高Nginx的权限) 3? 默认情况下GET请求及HEAD请求会被缓存,而POST请求不会被缓存,并非全部都要缓存,可以过滤部分路径不用缓存 proxy_cache_path /root/cache levels=1:2 keys_zone=xd_cache:2m max_size=1g inactive=1m use_temp_path=off; server { location /{ ... ?//注意实际开发项目中我们不可能对所有的Get请求都去做Nginx缓存,只有部分接口做Nginx缓存 ? 所有就要定制化设计 ?if ($uri = '/api/getdata') #//只有/api/getdata接口做缓存 { ?? proxy_cache xd_cache; proxy_cache_valid 200 304 1m; proxy_cache_valid 404 1m; proxy_cache_key $host$uri$is_args$args; #缓存key的规则这里写的是主机+uri+参数? #$is_args ?表示请求中的URL是否带参数,如果带参数,$is_args值为"?"。如果不带参数,则是空字符串? $args HTTP请求中的完整参数(包括所有参数) add_header Nginx-Cache ????"$upstream_cache_status"; proxy_pass http://gateway/; ??} } } 缓存清空 1直接rm删除 2 ngx_cache_purge 缓存命中率统计方式 1 前端打点日志上报 2 Nginx access.log日志模板增加信息$upstream_cache_status 然后利用AWK获取所有的hit的请求,并统计数 Nginx的expires(Nginx的客户端缓存) nginx缓存的设置可以提高网站性能,对于网站的图片,尤其是新闻网站,图片一旦发布,改动的可能是非常小的,为了减小对服务器请求的压力,提高用户浏览速度,我们可以通过设置nginx中的expires(Nginx的客户端缓存比Nginx的proxy_cache距离用户更近更快),让用户访问一次后,将图片缓存在用户的浏览器中,且时间比较长的缓存。 原理:当nginx设置了expires后,例如设置为:expires 10d;? 那么,所在的location或if的内容,用户在10天内请求的时候,都只会访问浏览器中的缓存,而不会去请求nginx。 注:需要注意的是,这种缓存方式只能在用户不对浏览器强制刷新的情况下生效,如果用户通过url来进行访问,是可以访问到缓存的。 举例查看网站图片的缓存时间: server{ location /static{ expires 30d; root? /usr/share/nginx/html; } 简介:讲解Nginx的压缩配置和实操 对文本、js和css,文件等进行压缩(已经压缩过了的图片如 gif,jpg 等是没有效果的),一般是压缩后的大小是原始大小的25%, 压缩后的内容可以获得更快的网络传输速度(减少了带宽消耗),响应时间是得到了优化 常用的压缩配置 #开启gzip,减少我们发送的数据量 gzip on; # 文件最小为1k才会进行压缩 gzip_min_length 1k; #4个单位为16k的内存作为压缩结果流缓存 gzip_buffers 4 16k; #gzip压缩比,可在1~9中设置,1压缩比最小,速度最快,9压缩比最大,速度最慢,消耗CPU gzip_comp_level 4; #压缩的类型 注意对已经压缩过了的图片如 gif,jpg 等是没有效果的, gzip_types application/javascript text/plain text/css application/json application/xml text/javascript image/jpeg?image/gif?image/png; #给代理服务?用的,有的浏览?支持压缩,有的不支持,所以避免浪费不支持的也压缩,所以根据客户端的HTTP头来判断,是否需要压缩 gzip_vary on; #禁用IE6以下的gzip压缩,IE某些版本对gzip的压缩支持很不好 gzip_disable "MSIE [1-6]."; 压缩前后区别(上传js文件进行验证)
面试题:压缩是时间换空间,还是空间换时间? web层主要涉及浏览?和服务?的网络交互,而网络交互显然是耗费时间的, 我们要尽量减少交互次数,降低每次请求或响应数据量。 开启压缩 在服务端是时间换空间的策略,Nginx服务端需要牺牲时间进行压缩以减小响应数据大小 在客户端的角度:压缩后的内容可以获得更快的网络传输速度(减少了带宽消耗),响应时间是得到了优化 所以是双向的(时间) 第五章 Nginx线上实战完整配置user? root; #默认情况下是user? nginx 在某些情况下因为权限问题会报错,故要修改 worker_processes? auto; error_log? /var/log/nginx/error.log notice; pid??????? /var/run/nginx.pid; events { ?? use epoll; #默认初始配置中时没有的我们可以加上以提高性能,使用epoll事件模型 worker_connections? 1024; #每个工作进程的最大连接数(生产环境中建议设置超过9000) } http { ??? include ??????/etc/nginx/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" "$request_time” '; ??? access_log? /var/log/nginx/access.log? main; #可以指定具体使用哪个文件去存储日志信息 ??? sendfile??????? on; ??? #tcp_nopush???? on; keepalive_timeout? 65; upstream gateway { ? ip_hash; ??? server 172.30.193.38:9088 max_fails=2 fail_timeout=60s ;; ??? server 172.30.193.38:9089 max_fails=2 fail_timeout=60s ;; ?? }? #开启gzip,减少我们发送的数据量 gzip on; # 文件最小为1k才会进行压缩 gzip_min_length 1k; #4个单位为16k的内存作为压缩结果流缓存 gzip_buffers 4 16k; #gzip压缩比,可在1~9中设置,1压缩比最小,速度最快,9压缩比最大,速度最慢,消耗CPU gzip_comp_level 4; ?????? #压缩的类型 注意对已经压缩过了的图片如 gif,jpg 等是没有效果的, gzip_types application/javascript text/plain text/css application/json application/xml text/javascript image/jpeg?image/gif?image/png; #给代理服务?用的,有的浏览?支持压缩,有的不支持,所以避免浪费不支持的也压缩,所以根据客户端的HTTP头来判断,是否需要压缩 gzip_vary on; #禁用IE6以下的gzip压缩,IE某些版本对gzip的压缩支持很不好 gzip_disable "MSIE [1-6]."; ??? server { ??? listen? 80; ??? server_name xxrtest.com; ???? location /static/ { ????? root? /usr/share/nginx/html; ????? } proxy_cache_path /root/cache levels=1:2 keys_zone=xd_cache:1m max_size=1g? use_temp_path=off; ???? location / { #Nginx端缓存的配置 proxy_cache xd_cache; proxy_cache_valid 200 304 30s; proxy_cache_valid 404 1m; proxy_cache_key $host$uri$is_args$args; #缓存key的规则这里写的是主机+uri+参数? #$is_args ?表示请求中的URL是否带参数,如果带参数,$is_args值为"?"。如果不带参数,则是空字符串? $args HTTP请求中的#完整参数(包括所有参数) proxy_cache_min_uses 3 #请求至少被发送了多少次以上时才缓存,可以防止低频请求被缓存 add_header Nginx-Cache ????"$upstream_cache_status"; ?????? proxy_pass http://gateway/; # 存放用户的真实ip,这样后端才可以获取到用户的真实Ip ip proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; ??????? # 设置什么才是请求失败 ?????????? proxy_next_upstream error timeout http_500 http_503; #开启错误拦截配置,一定要开启 proxy_intercept_errors on; #允许跨域请求的域,* 代表所有 add_header 'Access-Control-Allow-Origin' *; #允许请求的header add_header 'Access-Control-Allow-Headers' *; #允许带上cookie请求 add_header 'Access-Control-Allow-Credentials' 'true'; #允许请求的方法,比如 GET,POST,PUT,DELETE add_header 'Access-Control-Allow-Methods' *; #如果预检请求则返回成功,不需要转发到后端 I f ($request_method = 'OPTIONS') #注意=两边都有一个空格 { add_header 'Access-Control-Max-Age' 1728000; add_header 'Content-Type' 'text/plain; charset=utf-8'; add_header 'Content-Length' 0; return 200; ?} ???? } # 我们还可以设置多种错误状态码的不同返回 ? error_page ?403 =200? /defaultError403Api; ? location = /defaultError403Api { default_type application/json; return 200 '{"code":"-1","msg":"请求的资源不允许访问,没有对应的权限 "}'; ??? } ? ?error_page ?404? =200? /defaultError404Api; ??? location = /defaultError404Api { default_type application/json; return 200 '{"code":"-1","msg":"页面不存在或接口不存在请检查请求路径 "}'; ??? } ?? } ??? #gzip? on; ??? include /etc/nginx/conf.d/*.conf; } 第1集 大话新一代传输协议Https简介: 介绍什么是https,使用的好处 什么是Https,和http的区别 HTTPS (Secure Hypertext Transfer Protocol)安全超文本传输协议,是身披SSL外壳的HTTP HTTPS是一种通过计算机网络进行安全通信的传输协 议,经由HTTP进行通信,利用SSL/TLS建立安全信道,加 密数据包。 为什么要用呢 HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传 输、身份认证的网络协议,要比 HTTP 协议安全,可防止数据在传输过程中被窃取、改变,确保数据的完整性 但是不是百分百安全的 加密流程
1 客户端(浏览器)向服务器发送请求,2服务端会生成公钥和私钥,3把SSL证书和公钥返回客户端(浏览器) 4 浏览器验证SSL证书是否有效,如果无效,则浏览器会提示该网站有风险,如果验证成功,则会生成随机的对称秘钥(一把公钥,一把私钥), 5客户端使用对称秘钥中的公钥把服务端返回的公钥进行加密并传输给服务端 6服务端使用自己生成的秘钥对第5步的数据进行解密,从而拿到对称秘钥(公钥的)明文 7 服务端响应数据时,会把客户端公钥的明文返回。 8 客户端使用客户端私钥检测第7步返回的客户端秘钥是否正确。 核心:这样服务端与客户端就交换了自己的公钥,这样服务端就可以对客户端发来的数据进行检查,是否被篡改,客户端也能检查副段响应的数据是否被篡改 第七章Nginx整合OpenResty7.1 ?Nginx的第三方利?OpenResty+Lua介绍简介: 介绍Nginx的扩展 整合框架OpenResty 7.1.1什么是OpenResty, 为什么要用OpenResty? OpenResty:是基于Ngnix和Lua的高性能web平台(使用OpenResty就能使用Nginx中的所有功能(里面内嵌了Nginx),但是它比Nginx更加强大,集成了非常多的功能),内部集成精良的LUa库、第三方模块、依赖, 开发者可以方便搭建能够处理高并发、扩展性极高的动态web应用、web服务、动态网关。 OpenResty将Nginx核心、LuaJIT、许多有用的Lua库和Nginx第三方模块打包在一起 为什么要用OpenResty? 1 Nginx是C语言开发,如果要二次扩展是很麻烦的(因为C语言难度高),而基于OpenResty,开发人员可以使用 Lua 编程语言对 Nginx 核心模块进行二次开发拓展 2 性能强大,OpenResty可以快速构造出1万以上并发连接响应的超高性能Web应用系统(性能超过Ngixn) 阿里、腾讯、新浪、酷狗音乐等都是 OpenResty 的深度用户 7.1.2 OpenResty拓展 让Web 服务直接跑在 Nginx 服务内部,充分利用 Nginx 的非阻塞 I/O 模型,不仅仅对 HTTP 客户端请求,甚至于对远程后端诸如 MySQL, Memcaches 以及 Redis 等都进行一致的高性能响应。所以对于一些高性能的服务来说,可以直接使用 OpenResty 访问 Mysql或Redis等,而不需要通过第三方语言(JAVA,PHP、Python、Ruby)等来访问数据库再返回,这大大提高了应用的性能 7.1.3 Lua脚本介绍 官网:http://www.lua.org/start.html Lua 由标准 C 编写而成,没有提供强大的库,但可以很容易的被 C/C++ 代码调用,也可以反过来调用 C/C++ 的函数。 在应用程序中可以被广泛应用,不过Lua是一种脚本/动态语言,不适合业务逻辑比较重的场景(如电商平台,因为没有强大的类库),适合小巧的应用场景,代码行数保持在几十行到几千行。 LuaJIT 是采用 C 和汇编语言编写的 Lua 解释?与即时编译?。(快速的执行lua脚本) 7.1.4什么是ngx_lua ngx_lua是Nginx的一个模块,将Lua嵌入到Nginx中,从而可以使用Lua来编写脚本,并且部署到Nginx中运行, 即Nginx变成了一个Web容?;开发人员可以在nginx中使用Lua语言开发高性能Web应用了。 OpenResty提供了常用的ngx_lua开发模块 lua-resty-memcached lua-resty-mysql(在Nginx中直接访问mysql) lua-resty-redis(在Nginx中直接访问redis) lua-resty-dns? lua-resty-limit-traffic (对Nginx进行限流) 通过上述的模块,可以用来操作 mysql数据库、redis、memcached等,也可以自定义模块满足其他业务需求, 很多经典的应用,比如开发缓存前置、数据过滤、API请求聚合、AB测试、灰度发布、降级、监控、限流、防火墙、黑白名单等 7.2 OpenResty + Lua相关环境准备7.2.1 简介:OpenResty和Lua相关环境准备 当我们安装好OpenResty之后我们可以发现,OpenResty就是一个Nginx但是里面集成了Lua和一些相关模块和依赖 OpenResty安装 下载:http://openresty.org/en/linux-packages.html #centos # add the yum repo: wget https://openresty.org/package/centos/openresty. repo sudo mv openresty.repo /etc/yum.repos.d/ # update the yum index: sudo yum check-update sudo yum install openresty #安装命令行工具 sudo yum install openresty-resty # 列出所有 openresty 仓库里的软件包 sudo yum --disablerepo="*" -- enablerepo="openresty" list available #查看版本 resty –V docker安装OpenResty 1 docker pull openresty/openresty 2 docker run -idt --name openresty -p 80:80 openresty/openresty 3 mkdir -p /data/openresty/conf 4 docker cp openresty:/usr/local/openresty/nginx/conf/nginx.conf /data/openresty/conf 5 docker rm –f openresty 6 docker run -itd -p 80:80 --name openresty --restart always -v /data/openresty/conf/nginx.conf:/usr/local/openresty/nginx/conf/nginx.conf -v /etc/localtime:/etc/localtime -v /data/openresty/html:/usr/local/openresty/nginx/html 28ccc9f564cd 7.3 高并发利?-Nginx+OpenResty第一个例子简介:?? 讲解Nginx+OpenRestry开发第一个例子 Nginx+OpenRestry开发 在Nginx中使用Lua打印输出一段话 方式1 使用LUA代码块的方式(不方便一旦Lua代码多一点)content_by_lua_block server{ # 监听端口 listen 80; # 配置请求的路由 location /{ default_type text/html; content_by_lua_block{ ngx.say("hello world; xdclass.net 小滴课堂"); } } 方式2 使用lua文件的方式(一般使用这种,把Lua脚本写在一个文件中)content_by_lua_file #使用其他方式http { 还需要配置lua文件扫描路径 lua_package_path "$prefix/lualib/?.lua;;"; lua_package_cpath "$prefix/lualib/?.so;;"; server{ # 监听端口 listen 80; # 配置请求的路由 location /{ default_type text/html; content_by_lua_file lua/xdclass.lua; } .4 ?Nginx内置全局变量 和 OpenResty 请求阶段划分讲解简介:?? 讲解Nginx+OpenRestry常见基础知识 7.4.1 nginx内置全局变量 nginx提供丰富的内置变量, openresty里面使用参考下面的文档 https://github.com/openresty/lua-nginx-module#n gxvarvariable 部分变量是可以被修改的,部分是不给修改 如果openresty的lua中使用nginx内置全局变量则是 ngx.var.全局变量名(不加$)
7.4.2Nginx 请求阶段划分 nginx对于请求的处理分多个阶段,从而让第三方模块(lua)通过挂载行为在不同的阶段来控制请求的处理, 大致如下,以及相关指令 1 初始化阶段(Initialization Phase)(初始化一些参数) init_by_lua_file init_worker_by_lua_file 2 重写与访问阶段(Rewrite / Access Phase)(用于限流,黑名单,防火墙等)(业务中用的多) ???? rewrite_by_lua_file access_by_lua_file 文件访问 3 内容生成阶段(Content Phase)(业务中用的多) content_by_lua_file 4 日志记录阶段(Log Phase) 7.5 OpenResty开发内网访问限制或者端口访问限制(类似ECS安全组)简介:?? 讲解Nginx+OpenRestry开发网络访问限制 1 生产环境-管理后台一般需要指定的网络才可以访问,网 段/ip等(为了安全不是所有的人都可以访问管理后台,只有部分人可以访问,指定部分的IP可以访问即可) 2 ECS安全组:只有指定的端口的才可以访问 http{ # 这里设置为 off,是为了避免每次修改之后都要重新reload 的麻烦。 # 在生产环境上需要 lua_code_cache 设置成 on。 lua_code_cache off; # lua_package_path可以配置openresty的文件寻址路径, $PREFIX 为openresty安装路径 # 文件名使用“?”作为通配符,多个路径使用“;”分隔,默认的查找路径用“;;” # 设置纯 Lua 扩展库的搜寻路径 lua_package_path "$prefix/lualib/?.lua;;"; # 设置 C 编写的 Lua 扩展模块的搜寻路径(也可以用 ';;') lua_package_cpath "$prefix/lualib/?.so;;"; server { location / { access_by_lua_file lua/white_ip_list.lua; proxy_pass http://lbs; } } 内网访问限制和ECS安全组的lua代码 设置访问黑名单 lua/ black _ip_list.lua local black_ips = {["127.0.0.1"]=true} local ip = ngx.var.remote_addr if true == black_ips[ip] then ngx.exit(ngx.HTTP_FORBIDDEN) return; end 线上写我们肯定是指定只有部分IP可以访问 local white_ips = {["127.0.0.1","192.168.43.98"]=true} local ip = ngx.var.remote_addr if false== black_ips[ip] then ?ngx.exit(ngx.HTTP_FORBIDDEN) return; end 阿里云ECS安全组 local white_port = {["430","8080"]=true} local port = ngx.var.remote_ port if false== black_ips[port] then ?ngx.exit(ngx.HTTP_FORBIDDEN) return; end 7.6 -Nginx+OpenResty实现请求限流和资源下载限速简介:?? 讲解Nginx+OpenRestry开发下载限速 限速限流应用场景 下载限速:保护带宽及服务?的IO资源(以及带宽) 请求限流:防止恶意攻击,保护服务?及资源安全 (在Nginx端同时配置请求限流和恶意Ip封禁能够极大的避免恶意攻击) 限制某个用户在一个给定时间段内能够产生的HTTP 请求数 限流用在保护上游应用服务?不被在同一时刻的大量用户访问(这个功能与Sentinel类似) openResty下载限速案例实操 Nginx 有一个 $limit_rate ,这个反映的是当前请求每秒能响应的字节数, 该字节数默认为配置文件中limit_rate指令的设值 #当前请求的响应上限是 每秒 300K 字节 location /download { access_by_lua_block { ngx.var.limit_rate = "300K" } ? #映射到这个路径下 alias /usr/local/software/app; } 请求限流实操(重点) (在Nginx端同时配置请求限流和恶意Ip封禁能够极大的避免恶意攻击) nginx可以使用 首先,在nginx.conf文件中的
说明:
burst :是缓冲队列的长度,(当请求超过 nodelay?:表示不延时,比如rate=5r/s,burst=10 那么来了15个请求,能一次搞定,但是如果超过了rate+ burst会报503错误,否则,就是此秒只能搞定5个请求。一般都是不延期的设置(即设置后严格执行limit_req_zone)。 limit_req_zone $binary_remote_addr zone=commonper:10m rate=1r/s; location /test { ????? limit_req zone=commonper burst=5 nodelay; ??? ??default_type text/html; ??? ??content_by_lua_block{ ????? ngx.say("hello world; xdclass.net 小滴课堂"); ??? } error_page ?503 =200? /defaultError403Api; ? location = /defaultError503Api { default_type application/json; return 200 '{"code":"-1","msg":"请求的太频繁"}'; ??? } ?? ? 7.7 【面试题】网盘静态资源下载限速实现原理下载限速实现原理 目的:限制下载速度,用的是漏桶原理和令牌桶原理 什么是漏桶算法 备注:如果是请求限流,请求先进入到漏桶里,漏桶以固定的速度出水,也就是处理请求,当水加的过快也就是请求过多,桶就会直接溢出,也就是请求被丢弃拒绝了,所以漏桶算法能强行限制数据的传输速率或请求数。限流的大小(漏桶漏洞的大小)决定出水速度( 处理速度永远都是固定的) 什么是令牌桶算法,(一般使用这种) 备注:只要突发并发量不高于桶里面存储的令牌数据, 就可以充分利用好机?网络资源,比漏桶算法更加能够利用好资源。(不仅实现限流,还能最大可能的利用好网络资源,并发大的时候能够利用好全部资源,请求小的时候,不多浪费资源,处理速度能快能慢) 如果桶内令牌数量小于被请求消耗的量,则产生的令牌的速度就是均匀(限流)处理请求的速度 第8章 Ngnix高可用解决方案LVS+KeepAlived第1集 全链路高可用之Nginx基础架构问题分析简介:讲解Nginx单点问题剖析 全链路高可用之Nginx反向代理单点故障分析 dns轮训多个ip,假如某个nginx挂了,怎么办 Nginx集群架构(vip Virtual IP虚拟IP 虚拟IP和 ip漂移技术实现Nginx的高可用,LVS会虚拟出一个IP,用户以后直接去访问这个虚拟IP,这样多台Nginx机器,相对于用户而言就只有一台服务器) 至少需要两台机器+一台做LVS和Keepalived的主节点,一台做备用节点,主节点提供服务,一但主节 点挂了就备用节点提供服务(VIP 虚拟IP会漂移到备用节点上)(如果之后主节点又恢复使用了,则还是主节点提供服务)。Vip默认指向的是主节点,默认当我们访问VIP时,也就是访问主节点下的realServer(如 Nginx),所以以后就外部直接使用VIP不使用real ip Nginx高可用解决方案-基础 国际标准化组织(ISO)制定的一个用于计算机或通信系统间 互联的标准体系。从低到高分别是: 物理层、数据链路层、网络层、传输层、会话层、表示层和 应用层(http层) 四层工作在OSI第四层 也就是传输层 七层工作在最高层,也就是应用层 F5、LVS(第四层负载 tcp) 用虚拟ip+port接收请求,再转发到对应的真实机? HAproxy、Nginx(第七层负载) 用虚拟的url或主机名接收请求,再转向相应的处理服务? 第2集 业界主流的高可用方案 Linux虚拟服务?LVS 讲解简介:讲解业界主流高可用方案Linux虚拟服务? LVS讲解 什么是LVS LVS是Linux Virtual Server,Linux虚拟服务?,是一个虚拟的服务?集群系统 Linux2.4 内核以后,LVS 已经是 Linux 标准内核的一部分(无需安装) LVS软件负载:解决的两个核心问题是:选谁、转发 (vip Virtual IP虚拟IP 虚拟IP漂移技术实现Nginx的高可用,LVS会虚拟出一个IP,用户以后直接去访问这个虚拟IP,这样多台Nginx机器,相对于用户而言就只有一台服务器) 至少需要两台机器+一台做LVS和Keepalived的主节点,一台最备用节点,主节点提供服务,一但主节 点挂了就备用节点提高工服务? Vip默认指向的是主节点
三种负载均衡转发技术(一般只使用NAT或者DR,使用Docker进行不同数值端口映射时(如81:80)会出现无响应的状态,故此时使用端口映射时尽量相同如80:80) NAT:数据进出都通过 LVS, LVS的Master既要处理客户端发起的请求,又要处理后台RealServer的响应信息,将RealServer响应的信息再转发给客户端, 容易成为整个集群系统性能的瓶颈; (支持任意系统且可以实现端口映射)。 DR: (直接路由)移花接木,最高效的负载均衡规则,前端的Master只处理客户端的请求,将请求转发给(Nginx集群),由后台的(Nginx集群)直接响应客户端,不再经过LVS的Master, 性能要优于LVS-NAT; 需要LVS和(Nginx)集群绑定同一个VIP(支持多数系统,不可以实现端口映射)。??? ????????? TUNL:隧道技术,LVS的Master只处理客户端的请 求,将请求转发给(Nginx集群),然后由后台的Nginx集群直接响应客户端,不再经过Master;(支持少数系统,不可以实现端口映射)。 第3集 业界主流的高可用方案 keepalived讲解简介:讲解业界主流高可用方案keepalived讲解 什么是keepalived 核心:监控并管理 LVS 集群系统中各个服务节点的状态 keepalived是一个类似于交换机制的软件,核心作用是检测服务?的状态,如果有一台web服务?工作出现故障, Keepalived将检测到并将有故障的服务?从系统中剔除,使用其他服务?代替该服务?的工作,当有故障服务?工作正常后Keepalived自动将服务?加入到服务?群中,这些工作全部自动完成。 后来加入了vrrp(虚拟路由?冗余协议),除了为lvs提供高可用还可以为其他服务?提供高可用比如Nginx,Mysql、Haproxy等软件提供高可用 方案 docker安装keepalived https://blog.csdn.net/weixin_41438870/article/details/10555814 yum安装? yum install -y keepalived #安装路径 cd /etc/keepalived 启动和查看命令 service keepalived start #停止 service keepalived stop #查看状态 service keepalived status #重启 service keepalived restart #停止防火墙 systemctl stop firewalld.service 注意: 如果有缺少依赖可以执行下面的命令
注意: 如果有缺少依赖可以执行下面的命令
第4集 Keepalived核心配置讲解简介:Keepalived核心配置讲解 配置/etc/keepalived/keepalived.conf 分为3大模块。第一全局变量定义global_defs,2 vrrp_script主要用于健康检查及节点失败后执行的动作。3#配置对外提供服务的VIP vrrp_instance配置 ! Configuration File for keepalived global_defs { router_id LVS_DEVEL # 设置lvs的id,主备节点在一个网络内应该是唯一的 enable_script_security #允许执行外部脚本 } #配置vrrp_script,主要用于健康检查及节点失败后执行的动作。 vrrp_script chk_real_server { #健康检查脚本,当脚本返回值不为0时认为失败script"/usr/local/software/conf/chk_server.sh" #检查频率,以下配置每2秒检查1次 interval 2 #当检查失败后,将vrrp_instance的priority减小5 ?weight -5 #连续监测失败3次,才认为真的健康检查失败。并调整优先级 fall 3 #连续监测2次成功,就认为成功。但不调整优先级rise 2 user root } #配置对外提供服务的VIP vrrp_instance配置 vrrp_instance VI_1 { #指定vrrp_instance的状态,是MASTER还是BACKUP主要还是看优先级(备用节点要改)。 state MASTER #指定vrrp_instance绑定的网卡,最终通过指定的网卡绑定VIP interface ens33 #相当于VRID,用于在一个网内区分组播,需要组播域内内唯一。 virtual_router_id 51 #本机的优先级,VRID相同的机?中,优先级最高的会被选举为MASTER(备用节点要改) priority 100 #心跳间隔检查,默认为1s,MASTER会每隔1秒发送一个报文告知组内其他机?自己还活着。 advert_int 1 ?? #密码鉴权(防止有人恶意加入我们的VIP集群) authentication { auth_type PASS auth_pass 1111 } #定义虚拟IP(VIP)为192.168.159.100,可多设,每行一个 virtual_ipaddress { 192.168.159.100 } #本vrrp_instance所引用的脚本配置,名称就是vrrp_script 定义的容?名 track_script { ?chk_real_server } } # 定义对外提供服务的LVS的VIP以及port virtual_server 192.168.159.100 80 { # 设置健康检查时间,单位是秒 delay_loop 6 # 设置负载调度的算法为rr轮询? ?; lb_algo rr # 设置LVS实现负载的机制,有NAT、TUN、DR三个模式 lb_kind NAT # 会话保持时间 persistence_timeout 50 #指定转发协议类型(TCP、UDP) ? protocol TCP # 指定real server1(Nginx)的IP地址 ???? (备用节点要改real_server 的ip) real_server 192.168.43.98 81 { # 配置节点权值,数字越大权重越高weight 1 ?????? # 健康检查方式 TCP_CHECK { connect_timeout 10?????????????????????????????????????????????????????????? retry 3??????????????????????????????????????????????????????????????????????????????????? #重试次数 delay_before_retry 3???????????????????????????????????????????????????????? #重试间隔 connect_port 80????????????????????????????????????????????????????????????????? #连接端口????????????????? } } } 配置注意 router_id后面跟的自定义的ID在同一个网络下主备节点是一致的 state后跟的MASTER和BACKUP必须是大写;否则会造成配置无法生效的问题 interface 网卡ID;要根据自己的实际情况来看,可以使用以下方式ifconfig 在BACKUP(备用节点)上,其keepalived.conf与Master上基本一致,修改state为BACKUP,priority值改小还有修改real_server 的ip即可,但是注意在双主模式下 virtual_router_id? VRID也是不同的 authentication主备之间的认证方式,一般使用PASS即可;主备的配置必须一致,不能超过8位 第 5 集 Keepalived常用命令
第6集Nginx+LVS+KeepAlived高可用方案(主备模式)实战简介:Nginx+Lvs+KeepAlive高可用方案实施《上》 根据需求配置多个节点演示 两种情况 1 (LVS节点挂了但是RealServer存活) 如果其中主keepalived挂了,那就会vip就会分发(漂移)到另外一个keepalived节点(备用),响应正常 2? (RealServer节点挂了但是LVS存活) 如果主节点中的realServer挂了,比如是Nginx挂了,那对应keepalived节点存活依旧可以转发过去,但是响应失败 解决问题 如果某个realServer挂了,比如是Nginx挂了,那对应 keepalived节点存活依旧可以转发过去,但是响应失败 #配置vrrp_script,主要用于realServer健康检查及realServer检查失败后执行的动作。 其实原理就是,当我们的realServer挂了以后,我们把它对应的Keepalived关掉,这样就会产生VIP漂移,此时请求就分发到另外的keepalived节点,响应正常 #配置vrrp_script,主要用于健康检查及检查失败后执行的动作。 vrrp_script chk_real_server { #健康检查脚本,当脚本返回值不为0时认为失败 ??? script "/usr/local/software/conf/chk_server.sh" #检查频率,以下配置每2秒检查1次 ??? interval 2 #当检查失败后,将vrrp_instance的priority减小5 ??? weight -5 #连续监测失败3次,才认为真的健康检查失败。并调整优先级 ??? fall 3 #连续监测2次成功,就认为成功。但不调整优先级 ??? rise 2 ? ??? user root } chk_server.sh脚本内容(需要 chmod +x chk_server.sh) #!/bin/bash #检查nginx进程是否存在 counter=$(ps aux | grep -v grep | grep nginx | wc -l) if [ "${counter}" -eq "0" ]; then ??? service keepalived stop ??? echo 'nginx server is died.......' fi? 配置的常见问题 vip能ping通,vip监听的端口不通: 第一个原因:nginx1和nginx2两台服务器的服务没有正常启动 ? vip ping不通: 核对是否出现裂脑,常见原因为防火墙配置所致导致多播心跳失败,核对keepalived的配置是否正确 1 特别注意: (不管是双主还是主备模式)一定需要关闭selinux,不然sh脚本可能不生效 getenforce 查看 setenforce 0 关闭? 用于关闭selinux防火墙,但重启后失效,所以要永久关闭 永久关闭 修改selinux的配置文件,重启后生效。 打开 selinux 配置文件 vim /etc/selinux/config 修改 selinux 配置文件 将SELINUX=enforcing改为SELINUX=disabled,保存后退出 生产环境问题(有些云服务器不支持VIP) VIP : 阿里云(LBS)(支持)、华为云(支持)、腾讯云、AWS 第7集Nginx+LVS+KeepAlived高可用方案(双主模式)实战nginx+keepalived主备模式,始终有一台服务器处于空闲状态。为了更好地利用服务器,可以把它们设置为双主模式,另一台为这一台的备份,同时它又是另外一个VIP的主服务器,两台同时对外提供不同服务,同时接收用户的请求。(线上一般使用这种)(然后最外层再弄一个DNS轮询,用户可以轮询访问两台主服务器了) 1 特别注意: (不管是双主还是主备模式)一定需要关闭selinux,不然sh脚本可能不生效 ? ? 参考文献 https://www.cnblogs.com/guantou1992/p/12724794.html 管理与维护 1 keepalived主配置文件必须设置不同的VRRP名称,同时优先级和VIP也不相同 配置如下(有时候启动不成功的话,重启即可) 192.168.43.180机器的配置 ! Configuration File for keepalived global_defs { ?? router_id LVS_DEVEL # 设置lvs的id,在一个网络内应该是唯一的 ?? enable_script_security #允许执行外部脚本 } #配置vrrp_script,主要用于健康检查及检查失败后执行的动作。 vrrp_script chk_real_server { #健康检查脚本,当脚本返回值不为0时认为失败 ??? script "/usr/local/software/conf/chk_server.sh" #检查频率,以下配置每2秒检查1次 ??? interval 2 #当检查失败后,将vrrp_instance的priority减小5 ??? weight -5 #连续监测失败3次,才认为真的健康检查失败。并调整优先级 ??? fall 3 #连续监测2次成功,就认为成功。但不调整优先级 ??? rise 2 ??? user root } #配置对外提供服务的VIP vrrp_instance配置 vrrp_instance VI_1 { #指定vrrp_instance的状态,是MASTER还是BACKUP主要还是看优先级。 ??? state MASTER #指定vrrp_instance绑定的网卡,最终通过指定的网卡绑定VIP ??? interface ens33 #相当于VRID,用于在一个网内区分组播,需要组播域内内唯一。 ??? virtual_router_id 51 #本机的优先级,VRID相同的机器中,优先级最高的会被选举为MASTER ??? priority 100 #心跳间隔检查,默认为1s,MASTER会每隔1秒发送一个报文告知组内其他机器自己还活着。 ??? advert_int 1 ??? authentication { ??????? auth_type PASS ??????? auth_pass 1111 ??? } #定义虚拟IP(VIP)为192.168.159.100,可多设,每行一个 ??? virtual_ipaddress { ??????? 192.168.159.100 ??? } ??? #本vrrp_instance所引用的脚本配置,名称就是vrrp_script 定义的容器名 ? track_script { ????? chk_real_server ??? } } # 定义对外提供服务的LVS的VIP以及port virtual_server 192.168.159.100 80 { ??? # 设置健康检查时间,单位是秒 ??? delay_loop 6 ??? # 设置负载调度的算法为rr ??? lb_algo rr ??? # 设置LVS实现负载的机制,有NAT、TUN、DR三个模式 ??? lb_kind NAT ??? # 会话保持时间 ??? persistence_timeout 50 ?? #指定转发协议类型(TCP、UDP) ??? protocol TCP ??? # 指定real server1的IP地址 ??? real_server 192.168.43.180 80 { ??????? # 配置节点权值,数字越大权重越高 ??????? weight 1 ??????? # 健康检查方式 ??????? TCP_CHECK {????????????????? # 健康检查方式 ??????????? connect_timeout 10?????? # 连接超时 ??????????? retry 3?????????? # 重试次数 ??????????? delay_before_retry 3???? # 重试间隔 ??????????? connect_port 80????????? # 检查时连接的端口 ??????? } ??? } #配置对外提供服务的VIP vrrp_instance配置 vrrp_instance VI_2 { #指定vrrp_instance的状态,是MASTER还是BACKUP主要还是看优先级。 ??? state BACKUP #指定vrrp_instance绑定的网卡,最终通过指定的网卡绑定VIP ??? interface ens33 #相当于VRID,用于在一个网内区分组播,需要组播域内内唯一。 ??? virtual_router_id 48 #本机的优先级,VRID相同的机器中,优先级最高的会被选举为MASTER ??? priority 85 #心跳间隔检查,默认为1s,MASTER会每隔1秒发送一个报文告知组内其他机器自己还活着。 ??? advert_int 1 ??? authentication { ??????? auth_type PASS ??????? auth_pass 222 ??? } #定义虚拟IP(VIP)为192.168.159.99,可多设,每行一个 ??? virtual_ipaddress { ??????? 192.168.159.99 ??? } ??? #本vrrp_instance所引用的脚本配置,名称就是vrrp_script 定义的容器名 ? track_script { ????? chk_real_server ??? } } # 定义对外提供服务的LVS的VIP以及port virtual_server 192.168.159.99 80 { ??? # 设置健康检查时间,单位是秒 ??? delay_loop 6 ??? # 设置负载调度的算法为rr ??? lb_algo rr ??? # 设置LVS实现负载的机制,有NAT、TUN、DR三个模式 ??? lb_kind NAT ??? # 会话保持时间 ??? persistence_timeout 50 ?? #指定转发协议类型(TCP、UDP) ??? protocol TCP ??? # 指定real server1的IP地址 ??? real_server 192.168.43.180 80 { ??????? # 配置节点权值,数字越大权重越高 ??????? weight 1 ??????? # 健康检查方式 ??????? TCP_CHECK {????????????????? # 健康检查方式 ??????????? connect_timeout 10?????? # 连接超时 ??????????? retry 3?????????? # 重试次数 ??????????? delay_before_retry 3???? # 重试间隔 ??????????? connect_port 80????????? # 检查时连接的端口 ??????? } ??? } } 192.168.43.189 ! Configuration File for keepalived global_defs { ?? router_id LVS_DEVEL # 设置lvs的id,在一个网络内应该是唯一的 ?? enable_script_security #允许执行外部脚本 } #配置vrrp_script,主要用于健康检查及检查失败后执行的动作。 vrrp_script chk_real_server { #健康检查脚本,当脚本返回值不为0时认为失败 ??? script "/usr/local/software/conf/chk_server.sh" #检查频率,以下配置每2秒检查1次 ??? interval 2 #当检查失败后,将vrrp_instance的priority减小5 ??? weight -5 #连续监测失败3次,才认为真的健康检查失败。并调整优先级 ??? fall 3 #连续监测2次成功,就认为成功。但不调整优先级 ??? rise 2 ??? user root } #配置对外提供服务的VIP vrrp_instance配置 vrrp_instance VI_1 { #指定vrrp_instance的状态,是MASTER还是BACKUP主要还是看优先级。 ??? state BACKUP #指定vrrp_instance绑定的网卡,最终通过指定的网卡绑定VIP ??? interface ens33 #相当于VRID,用于在一个网内区分组播,需要组播域内内唯一。 ??? virtual_router_id 51 #本机的优先级,VRID相同的机器中,优先级最高的会被选举为MASTER ??? priority 84 #心跳间隔检查,默认为1s,MASTER会每隔1秒发送一个报文告知组内其他机器自己还活着。 ??? advert_int 1 ??? authentication { ??????? auth_type PASS ??????? auth_pass 1111 ??? } #定义虚拟IP(VIP)为192.168.159.100,可多设,每行一个 ??? virtual_ipaddress { ??????? 192.168.159.100 ??? } ??? #本vrrp_instance所引用的脚本配置,名称就是vrrp_script 定义的容器名 ? track_script { ????? chk_real_server ??? } } # 定义对外提供服务的LVS的VIP以及port virtual_server 192.168.159.100 80 { ??? # 设置健康检查时间,单位是秒 ??? delay_loop 6 ??? # 设置负载调度的算法为rr ??? lb_algo rr ??? # 设置LVS实现负载的机制,有NAT、TUN、DR三个模式 ??? lb_kind NAT ??? # 会话保持时间 ??? persistence_timeout 50 ?? #指定转发协议类型(TCP、UDP) ??? protocol TCP ??? # 指定real server1的IP地址 ??? real_server 192.168.43.189 80 { ??????? # 配置节点权值,数字越大权重越高 ??????? weight 1 ??????? # 健康检查方式 ??????? TCP_CHECK {????????????????? # 健康检查方式 ??????????? connect_timeout 10?????? # 连接超时 ??????????? retry 3?????????? # 重试次数 ??????????? delay_before_retry 3???? # 重试间隔 ??????????? connect_port 80????????? # 检查时连接的端口 ??????? } ??? } } #配置对外提供服务的VIP vrrp_instance配置 vrrp_instance VI_2 { #指定vrrp_instance的状态,是MASTER还是BACKUP主要还是看优先级。 ??? state MASTER #指定vrrp_instance绑定的网卡,最终通过指定的网卡绑定VIP ??? interface ens33 #相当于VRID,用于在一个网内区分组播,需要组播域内内唯一。 ??? virtual_router_id 48 #本机的优先级,VRID相同的机器中,优先级最高的会被选举为MASTER ??? priority 90 #心跳间隔检查,默认为1s,MASTER会每隔1秒发送一个报文告知组内其他机器自己还活着。 ??? advert_int 1 ??? authentication { ??????? auth_type PASS ??????? auth_pass 222 ??? } #定义虚拟IP(VIP)为192.168.159.99,可多设,每行一个 ??? virtual_ipaddress { ??????? 192.168.159.99 ??? } ??? #本vrrp_instance所引用的脚本配置,名称就是vrrp_script 定义的容器名 ? track_script { ????? chk_real_server ??? } } # 定义对外提供服务的LVS的VIP以及port virtual_server 192.168.159.99 80 { ??? # 设置健康检查时间,单位是秒 ??? delay_loop 6 ??? # 设置负载调度的算法为rr ??? lb_algo rr ??? # 设置LVS实现负载的机制,有NAT、TUN、DR三个模式 ??? lb_kind NAT ??? # 会话保持时间 ??? persistence_timeout 50 ?? #指定转发协议类型(TCP、UDP) ??? protocol TCP ??? # 指定real server1的IP地址 ??? real_server 192.168.43.189 80 { ??????? # 配置节点权值,数字越大权重越高 ??????? weight 1 ??????? # 健康检查方式 ??????? TCP_CHECK {????????????????? # 健康检查方式 ??????????? connect_timeout 10?????? # 连接超时 ??????????? retry 3?????????? # 重试次数 ??????????? delay_before_retry 3???? # 重试间隔 ??????????? connect_port 80????????? # 检查时连接的端口 ??????? } ??? } } 第九章 Nginx高性能原理和课程总结第1集 Nginx基础架构master-worker进程剖析 简介:Nginx基础架构模型剖析
高性能原理 nginx 通过 多进程 + io多路复用(epoll) 实现了高并发
拓展:linux I/O多路复用有select,poll,epoll I/O模式一般分为同步IO和异步IO。 同步IO会阻塞进程,异步IO不会阻塞进程。 目前linux上大部分用的是同步IO,异步IO在linux上还不太成熟(有部分) 同步IO又分为阻塞IO,非阻塞IO,IO多路复用, 很多人对这个就有疑问了???? 同步IO会阻塞进程,为什么也包括非阻塞IO? 因为非阻塞IO虽然在请求数据时不阻塞,但真正数据来临时,也就是内核数据拷贝到用户数据时,此时进程是阻塞的(大部分时间是不阻塞的,小部分时间是阻塞的所以我们说它是非阻塞的)。 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年2日历 | -2025/2/22 2:46:02- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |