-
玩转Nginx分布式架构:
- 1.学习Nginx 详细介绍(负载均衡、全局异常、跨域、封禁IP、路径匹配、地址重定向、Websocket反向代理、缓存、压缩)
- 2.使用Nginx配置域名
- 3.使用Nginx配置HTTPS传输协议
- 4.Nginx整合OpenResty+Lua (黑名单控制、内网访问限制、资源下载限速、日志分析、漏桶原理、令牌桶原理)
- 5.Nginx高可用解决方案LVS+KeepAlived
- 6.Nginx高可用后配置HTTPS传输协议
Nginx整合OpenResty+Lua (黑名单控制、内网访问限制、资源下载限速、日志分析、漏桶原理、令牌桶原理)
一、Nginx的第三⽅利器OpenResty+Lua介绍
1、什么是OpenResty, 为什么要⽤OpenResty?
由章亦春发起,是基于Ngnix和Lua的⾼性能web平台,内部集成精良的Lua库、第三⽅模块、依赖, 开发者可以⽅便搭建能够处理⾼并发、扩展性极⾼的动态web应⽤、web服务、动态⽹关。
OpenResty将Nginx核⼼、LuaJIT、许多有⽤的Lua库和Nginx第三⽅模块打包在⼀起
Nginx是C语⾔开发,如果要⼆次扩展是很麻烦的,⽽基于OpenResty,开发⼈员可以使⽤ Lua 编程语⾔对 Nginx核⼼模块进⾏⼆次开发拓展性能强⼤,OpenResty可以快速构造出1万以上并发连接响应的超⾼性能Web应⽤系统
1.官网:https://openresty.org/cn/
2.阿⾥、腾讯、新浪、酷狗⾳乐等都是 OpenResty 的深度⽤户
3.拓展
让Web 服务直接跑在 Nginx 服务内部,充分利⽤ Nginx的⾮阻塞 I/O 模型,不仅仅对 HTTP 客户端请求,甚⾄于对远程后端诸如 MySQL, Memcaches 以及 Redis 等都进⾏⼀致的⾼性能响应。所以对于⼀些⾼性能的服务来说,可以直接使⽤ OpenResty 访问 Mysql或Redis等,⽽不需要通过第三⽅语⾔(PHP、Python、Ruby)等来访问数据库再返回,这⼤⼤提⾼了应⽤的性能
2、什么是ngx_lua?
ngx_lua是Nginx的⼀个模块,将Lua嵌⼊到Nginx中,从⽽可以使⽤Lua来编写脚本,部署到Nginx中运⾏,即Nginx变成了⼀个Web容器;开发⼈员就可以使⽤Lua语⾔开发⾼性能Web应⽤了。
3、OpenResty提供了常⽤的ngx_lua开发模块
lua-resty-memcached
lua-resty-mysql
lua-resty-redis
lua-resty-dns
lua-resty-limit-traffic
通过上述的模块,可以⽤来操作 mysql数据库、redis、memcached等,也可以⾃定义模块满⾜其他业务需求,很多经典的应⽤,⽐如开发缓存前置、数据过滤、API请求聚合、AB测试、灰度发布、降级、监控、限流、防⽕墙、⿊⽩名单等。
二、OpenResty + Lua相关环境准备
1、OpenResty安装
下载:https://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
#查看版本
openresty -v
2、启动Nginx
cd /usr/local/openresty/nginx/sbin/
./nginx
本地访问云服务:http://59.110.68.26/’
三、Nginx+OpenRestry开发
nginx.conf 配置
# 编辑:/usr/local/openresty/nginx/conf/nginx.conf
http {
# 虚拟机主机块,还需要配置lua⽂件扫描路径
lua_package_path "$prefix/lualib/?.lua;;";
lua_package_cpath "$prefix/lualib/?.so;;";
server {
# 监听端⼝
listen 80;
server_name localhost;
# 配置请求的路由
location / {
root html;
index index.html index.htm;
}
location /block {
default_type text/html;
# content_by_lua_block是一个指令,用于定义一个Lua代码块
content_by_lua_block{
# ngx.say是OpenResty提供的一个函数,用于向客户端返回响应
ngx.say("hello world OpenResty!");
}
}
location /file {
default_type text/html;
# content_by_lua_file是一个指令,用于指定Lua代码文件的路径
content_by_lua_file /usr/local/openresty/lua/hello.lua;
}
}
# 重启Nginx
cd /usr/local/openresty/nginx/sbin/
./nginx
hello.lua 文件
-- hello.lua
-- 定义一个处理函数
local function handle_request()
-- 返回 "Hello, World!"
ngx.say("Hello, World OpenResty!")
end
-- 调用处理函数
handle_request()
访问:http://59.110.68.26/block
访问:http://59.110.68.26/file
Linux服务器里有多个Nginx版本解决方案
1.杀进程
ps -ef | grep nginx
kill -9 进程ID
2.指定nginx.conf文件目录
./nginx -c /usr/local/openresty/nginx/conf/nginx.conf
四、Nginx内置变量 和OpenResty请求阶段划分
讲解NginxOpenRestry常⻅基础知识
nginx内置变量
1.提供丰富的内置变量, openresty⾥⾯使⽤参考下⾯的⽂档
2.https://github.com/openresty/lua-nginx-module#ngxvarvariable
3.部分变量是可以被修改的,部分是不给修改
名称 | 说明 |
---|---|
$arg_name | 请求中的name参数 |
$args | 请求中的参数 |
$content_length | HTTP请求信息⾥的"Content-Length" |
$content_type | 请求信息⾥的"Content-Type" |
$host | 请求信息中的"Host",如果请求中没有Host⾏,则等于设置的服务器名 |
$hostname | 机器名使⽤ gethostname系统调⽤的值 |
$http_cookie | cookie 信息 |
$http_referer | 引⽤地址 |
$http_user_agent | 客户端代理信息 |
$http_via | 最后⼀个访问服务器的Ip地址。 |
$http_x_forwarded_for | 相当于⽹络访问路径 |
$is_args | 如果请求⾏带有参数,返回“?”,否则返回空 |
$limit_rate | 对连接速率的限制 |
$nginx_version | 当前运⾏的nginx版本号 |
$pid | worker进程的PID |
$query_string | 与$args相同 |
$remote_addr | 客户端IP地址 |
$remote_port | 客户端端⼝号 |
$request | ⽤户请求 |
$request_method | 请求的⽅法,⽐如"GET"、"POST"等 |
$request_uri | 请求的URI,带参数 |
$scheme | 所⽤的协议,⽐如http或者是https |
$server_name | 请求到达的服务器名 |
$server_port | 请求到达的服务器端⼝号 |
$server_protocol | 请求的协议版本,“HTTP/1.0"或"HTTP/1.1” |
$uri | 请求的URI,可能和最初的值有不同,⽐如经 |
nginx对于请求的处理分多个阶段,Nginx , 从⽽让第三⽅模块通过挂载⾏为在不同的阶段来控制, ⼤致如下:
1.初始化阶段(Initialization Phase)
# 在Nginx工作进程启动时执行Lua代码,用于进行全局初始化操作。
init_by_lua_file
# 在Nginx工作进程启动后,每个工作进程执行一次的Lua代码,用于进行工作进程级别的初始化操作。
init_worker_by_lua_file
2.重写与访问阶段(Rewrite / Access Phase)
# 在请求重写阶段执行Lua代码,用于修改请求URI或其他请求参数。
rewrite_by_lua_file
# 在访问控制阶段执行Lua代码,用于进行访问控制、权限验证等操作。
access_by_lua_file
3.内容⽣成阶段(Content Phase)
# 在内容生成阶段执行Lua代码,用于生成响应内容。
content_by_lua_file
4.⽇志记录阶段(Log Phase)
# 在日志记录阶段,Nginx将请求的访问日志写入日志文件
/usr/local/openresty/nginx/logs
这些阶段允许开发者通过编写Lua代码来控制请求的处理过程,实现自定义的功能和逻辑。通过挂载Lua代码到相应的阶段,第三方模块可以在不同的阶段中介入请求处理,实现更灵活和定制化的功能。
五、Nginx+OpenResty+Lua开发内网访问限制
1、开发内网访问限制
1.⽣产环境-管理后台⼀般需要指定的⽹络才可以访问,⽹段/ip等
2.Nginx+OpenRestry+Lua开发
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;;";
upstream lbs {
server 59.110.68.26:8080;
server 59.110.68.26:8081;
}
server {
location / {
root html;
index index.html index.htm;
}
location /api {
access_by_lua_file /usr/local/openresty/lua/black_ip_list.lua;
proxy_pass http://lbs;
}
}
}
/usr/local/openresty/lua/black_ip_list.lua
-- 定义了一个名为black_ips的本地变量,它是一个表(table)类型的数据结构。该表用于存储黑名单中的IP地址。
local black_ips = {["221.223.102.234"]=true}
-- 获取了客户端的IP地址,并将其赋值给变量ip
local ip = ngx.var.remote_addr
-- 使用if条件语句判断black_ips[ip]是否为true。这里使用了表的索引操作符[]来访问表中的元素,如果ip在black_ips表中存在,则返回true,否则返回nil。如果条件成立(即true == black_ips[ip]),则执行ngx.exit(ngx.HTTP_FORBIDDEN)语句,该语句会中断当前请求,并返回HTTP 403 Forbidden状态码给客户端。如果条件不成立,则继续执行后续的请求处理
if true == black_ips[ip] then
ngx.exit(ngx.HTTP_FORBIDDEN)
return;
end
访问:http://59.110.68.26/api/demo/1 本机地址:221.223.102.234
2、拓展:如何做⼀个动态⿊名单控制?
1.使用Logstach分析日志
Logstach作用:将access.log日志文件转换成JSON对象,方便解析。
2.使用Lua脚本,将转换后的日志数据发送到消息队列(如RabbitMQ、Kafka等)中。
3.Elasticsearch集群:将消息队列中的日志数据发送到Elasticsearch集群中进行存储和索引。使用Elasticsearch的API或客户端库来将日志数据写入到集群中的索引中。这样,您可以使用强大的搜索和分析功能来查询和分析日志数据。
4.大数据流式处理:使用流式处理框架(如Apache Flink、Apache Spark Streaming等),对大量的日志数据进行实时处理和分析。
5.Redis:Redis是一个高性能的内存数据库,可以用于缓存、存储临时数据和实时计算结果。使用流式处理框架的计算结果存储到Redis中,以供其他应用程序或服务使用。
六、Nginx+OpenResty实现资源下载限速
1、 限速限流应用场景:
下载限速:保护带宽及服务器的IO资源
请求限流:防止恶意攻击,保护服务器及资源安全
I.限制某个用户在一个给定的时间段内能够产生的HTTP请求数量。
II.限制用在保护上游应用服务器不被在同一时刻的大量用户访问。
2、 openResty下载限速案例实操
Nginx 有⼀个 $limit_rate,这个反映的是当前请求每秒能响应的字节数, 该字节数默认为配置⽂件中 limit_rate 指令的设值
#当前请求的响应上限是 每秒 300K 字节
location /uploads {
access_by_lua_block {
ngx.var.limit_rate = "30K"
}
alias /usr/local/uploads;
}
# 重启Nginx
cd /usr/local/openresty/nginx/sbin/
./nginx -s reload
随便上传个压缩包
访问:http://59.110.68.26/uploads/apache-maven-3.9.3-bin.tar.gz
七、⽹盘静态资源下载限速实现原理
简介:讲解常⻅的资源下载限速实现原理
下载限速实现原理:
⽬的:限制下载速度
常⽤的是漏桶原理和令牌桶原理
漏桶原理(Leaky Bucket)
漏桶原理基于一个类比,将网络传输比作一个漏桶,数据以恒定的速率从桶中流出。当数据到达时,如果桶已满,则数据被丢弃或延迟发送,以保持恒定的传输速率。这种方式可以平滑传输速率,但可能会导致数据包的延迟。
令牌桶原理(Token Bucket)
令牌桶原理基于一个类比,将网络传输比作一个令牌桶,令牌以恒定的速率被放入桶中。当数据到达时,如果有足够的令牌,则数据被发送出去,并从桶中消耗相应数量的令牌。如果桶中没有足够的令牌,则数据被丢弃或延迟发送,直到有足够的令牌为止。这种方式可以精确控制传输速率,并且不会引入额外的延迟。
在实际应用中,下载限速可以通过在网络设备、服务器或应用程序中实现漏桶或令牌桶算法来实现。例如,在服务器端,可以使用流量控制模块或限速模块来实现下载限速。这些模块会根据漏桶或令牌桶原理对传输的数据进行控制,以限制传输速率。
需要注意的是,下载限速通常是在网络设备或服务器端实现的,而不是在客户端浏览器中实现。客户端浏览器可以通过接收限速的数据来实现下载速度的限制,但实际的限速控制是由服务器端或网络设备来完成的。