NGINX 结合 lua 动态修改upstream

Nginx负载均衡之动态更新upstream 由于该指令只支持 worker 级别的操作,为使得 Nginx 的所有 worker 都生效,此处通过编写 Lua 脚本与 lua-resty-upstream-healthcheck 模块做了简单的集成,利用 lua-resty-upstream-healthcheck 模块的共享内存机制将节点状态同步给其他工作进程,实现对 upstream 的节点状态的控制。在 Nginx 的商业版本中,提供了 ngx_http_api_module 模块,可以通过 API 动态添加或移除上游服务器组中的节点。 阅读详情

具体思路是: 

1 > 利用lua中 "lua_shared_dict" 指令开辟一个共享内存空间;

2> 通过API动态根据key值&参数修改 upstream  (这里使用 host 作为key);

3> 利用 proxy_pass 可使用变量特性及lua指令 "set_by_lua" 动态修改当前 upstream 变量即可;


以下是利用 qq.com 作为示例:

http {
	lua_shared_dict _ups_zone 64m; # 定义upstream共享内存空间
	...
	upstream qq_backend{
		server 14.17.42.40;
		server 14.17.32.211;
		server 59.37.96.63;
	}

	server {
		listen       80;
		server_name  www.qq.com *.qq.com;
		access_log  off;

		# 更新 upstream API 接口
		location = /ups_update {
			content_by_lua '
				local ups = ngx.req.get_uri_args()["ups"]
				if ups == nil then
					ngx.say("usage: /ups_update?ups=x.x.x.x")
					return
				end
				local host = ngx.var.http_host
				local ups_from = ngx.shared._ups_zone:get(host);
				ngx.log(ngx.WARN, host, " update upstream from ", ups_from, " to ", ups)
				ngx.shared._ups_zone:set(host, ups);
				ngx.say(host, " update upstream from ", ups_from, " to ", ups)
			';
		}
		location / {
			# 动态设置当前 upstream, 未设置则使用默认 upstream
			set_by_lua $cur_ups '
				local ups = ngx.shared._ups_zone:get(ngx.var.http_host)
				if ups ~= nil then
					ngx.log(ngx.ERR, "get [", ups, "] from ngx.shared._ups_zone")
					return ups
				end
				--ngx.log(ngx.INFO, "use default upstream");
				return "qq_backend";
			'
			proxy_next_upstream off;
			proxy_set_header    Host $host;
			proxy_http_version  1.1;
			proxy_set_header    Connection  "";
			proxy_pass $scheme://$cur_ups;
		}
	}
}

测试:

cur -x 127.0.0.1:80 www.qq.com  # 使用默认upstream
# 修改为140.206.160.207 & 61.135.157.156
curl -x 127.0.0.1:80 www.qq.com/ups_update?ups=140.206.160.207
curl -x 127.0.0.1:80 www.qq.com/ups_update?ups=61.135.157.156

这里只是一个简单的思路,并未考虑到 upstream 持久化,如需要可参考以下这篇文章, 使用 redis 来实现:

Dynamic nginx upstreams with Lua and Redis 


【后端】Nginx+lua+OpenResty高性能实践 证书可以明确的记录证书颁发机构的信息,证书使用者的相。关信息,从而接受者接收到证书,对证书信息通过公钥进行。可以对身份进行验证,密钥对存在漏洞,黑客可以伪装。第三方证书,证书通过加密算法对内容进行加密,并且。为发送者,生成密钥对,发送给接受者。验证,能够识别真实的发布者身份。指定加密后的文件的存放位置。自动插入一个随机数到文件中。指定要加密的文件的路径。# 根据生成对应公钥。 阅读详情

相关推荐

基于Luaupstream管理和健康检查模块Lua-Resty-Checkups.zip

Lua-Resty-Checkups是一个基于luaupstream管理和健康检查模块,由又拍云开源。特点:支持周期性upstream服务管理操作支持管理和健康检查支持upstream动态更新有利于加权轮询或哈希平衡支持 Nginx C upstream同步操作可使用级别和键值实现集群使用简介:-- config.lua _M = {} _M.global = {     checkup_timer_interval = 15,     checkup_shd_sync_enable = true,     shd_config_timer_interval = 1, } _M.ups1 = {     cluster = {         {             servers = {                 {host="127.0.0.1", port=4444, weight=10, max_fails=3, fail_timeout=10},             }         },     }, }lua_package_path "/path/to/lua-resty-checkups/lib/checkups/?.lua;/path/to/config.lua;;"; lua_shared_dict state 10m; lua_shared_dict mutex 1m; lua_shared_dict locks 1m; lua_shared_dict config 10m; server {     listen 12350;     return 200 12350; } server {     listen 12351;     return 200 12351; } init_worker_by_lua_block {     local config = require "config"     local checkups = require "resty.checkups.api"     checkups.prepare_checker(config)     checkups.create_checker() } server {     location = /12350 {         proxy_pass http://127.0.0.1:12350/;     }     location = /12351 {         proxy_pass http://127.0.0.1:12351/;     }     location = /t {         content_by_lua_block {             local checkups = require "resty.checkups.api"             local callback = function(host, port)                 local res = ngx.location.capture("/" .. port)                 ngx.say(res.body)                 return 1             end             local ok, err             -- connect to a dead server, no upstream available             ok, err = checkups.ready_ok("ups1", callback)             if err then ngx.say(err) end             -- add server to ups1             ok, err = checkups.update_upstream("ups1", {                     {                         servers = {                             {host="127.0.0.1", port=12350, weight=10, max_fails=3, fail_timeout=10},                         }                     },                 })             if err then ngx.say(err) end             ngx.sleep(1)             ok, err = checkups.ready_ok("ups1", callback)             if err then ngx.say(err) end             ok, err = checkups.ready_ok("ups1", callback)             if err then ngx.say(err) end             -- add server to new upstream             ok, err = checkups.update_upstream("ups2", {                     {                         servers = {                             {host="127.0.0.1", port=12351},                         }                     },                 })             if err then ngx.say(err) end             ngx.sleep(1)             ok, err = checkups.ready_ok("ups2", callback)             if err then ngx.say(err) end             -- add server to ups2, reset rr state             ok, err = checkups.update_upstream("ups2", {                     {                         servers = {                             {host="127.0.0.1", port=12350, weight=10, max_fails=3, fail_timeout=10},                             {host="127.0.0.1", port=12351, weight=10, max_fails=3, fail_timeout=10},                         }                     },                 })             if err then ngx.say(err) end             ngx.sleep(1)             ok, err = checkups.ready_ok("ups2", callback)             if err then ngx.say(err) end             ok, err = checkups.ready_ok("ups2", callback)             if err then ngx.say(err) end     } }Lua 配置示例:_M = {} -- Here is the global part _M.global = {     checkup_timer_interval = 15,     checkup_timer_overtime = 60,     default_heartbeat_enable = true,     checkup_shd_sync_enable = true,     shd_config_timer_interval = 1, } -- The rests parts are cluster configurations _M.redis = {     enable = true,     typ = "redis",     timeout = 2,     read_timeout = 15,     send_timeout = 15,     protected = true,     cluster = {         {   -- level 1             try = 2,             servers = {                 { host = "192.168.0.1", port = 6379, weight=10, max_fails=3, fail_timeout=10 },                 { host = "192.168.0.2", port = 6379, weight=10, max_fails=3, fail_timeout=10 },             }         },         {   -- level 2             servers = {                 { host = "192.168.0.3", port = 6379, weight=10, max_fails=3, fail_timeout=10 },             }         },     }, } _M.api = {     enable = false,     typ = "http",     http_opts = {         query = "GET /status HTTP/1.1\r\nHost: localhost\r\n\r\n",         statuses = {             [500] = false,             [502] = false,             [503] = false,             [504] = false,         },     },     mode = "hash",     cluster = {         dc1 = {             servers = {                 { host = "192.168.1.1", port = 1234, weight=10, max_fails=3, fail_timeout=10 },             }         },         dc2 = {             servers = {                 { host = "192.168.1.2", port = 1234, weight=10, max_fails=3, fail_timeout=10 },             }         }     } } _M.ups_from_nginx = {     timeout = 2,     cluster = {         {   -- level 1             upstream = "api.com",         },         {   -- level 2             upstream = "api.com",             upstream_only_backup = true,         },     }, } return _M

nginx-通过lua动态更改upstream

最近我们搭了一个consul服务,开发同学想要把supervisor的web管理集成到consul中,需要根据url中给定的ip地址动态的加载该机器上的supervisor管理界面,因为服务端机器都在VPC内部,办公网网络不可达,因此不能简单的rewrite url或者做个重定向来解决,因此需要通过反向代理的方式将请求转发给后端机器,并且要实现反向代理服...

weixin_33994444的博客 2657

DRAM内存模拟持久化设备的方法

由于持久化内存介质NVM技术的发展,越来越多的科研工作者投身到NVM相关的研究当中。但由于目前工业界并没有推出广泛使用的NVM介质设备,所以科研工作都需要自己以现有的条件,模拟NVM设备使用场景。一个简单的方法是:通过修改DRAM模拟器,达到模拟NVM的目的(可以参考:DRAMSim2模拟器分析与应用)。更高端的方式是:在真实系统中,将内存划分出一块儿,用来模拟NVM设备(类似于传统的ramdis

酷炫人笨笨熊 1870

nginx dyups动态修改upstream说明

dynamic upstream 使用tengine dyups模块(https://github.com/yzprofile/ngx_http_dyups_module) 实现upstream更新,减少tengine reload操作。 修改项 1.更新upstream check 模块(https://github.com/yzprofile/nginx_upstream_check_module)支持tengine dyups module。 2.upstream check module

focus on security 4662

Nginx + Lua + 共享内存实现动态查询(简单例子)

Nginx 配置。 lua_package_path "/usr/local/share/luajit-2.0.2/jit?.lua;;"; lua_shared_dict devicedb 45m; location /query { default_type 'text/plain'; content_by_lua

苏湘的专栏 1万+

通过分析nginx upstream源码来看动态配置upstream模块

upstream回源处理流程 代码围绕着ngx_http_upstream.c展开,该模块主要为创建mainconf函数: static void * ngx_http_upstream_create_main_conf(ngx_conf_t *cf) { ... //创建main conf umcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_main_conf_t)); //创建upstream数组,每一个ngx_http_u

focus on security 2150

运维36讲第04课:入口网关服务注册发现-Openresty 动态 upstream

本课时,我将带你一起了解入口网关服务的注册发现,并使用OpenResty 实现一套动态Upstream。课前学习提示基于本课时我们将要学习的内容,我建议你课前先了解一下 Nginx 的基础,同时熟悉基础的 Lua 语言语法,另外再回顾一下 HTTP 的请求过程,对于 Nginx 的负载均衡基本原理也要有基础的了解,掌握这些对我们学习此课时能起到一定的帮助。

sucaiwa的博客 795

Nginx 动态负载 upstream 三种方案

基于Nginx dyups模块的动态上下线基于以上这些情况, 我计划实现一个工具,这个工具首先解决站点上下线和动态扩容问题,也就是说在不需要重启nginx的情况下,并且在保证请求不丢失的情况下来更新站点。 同时带有部分服务治理功能。服务上线在一个新服务上线的时候,一般会提前申请几台机器, 运维会在nginx上新增server,...

qianghong000的博客 2963

Nginxupstream动态修改

nginx_http_dyups_module是第三方开源软件,它提供API动态修改upstream的配置,并且支持Nginx的ip_hash、keepalive等与upstream有关的配置。安装nginx_http_dyups_module。

爱琴孩的博客 793

探索 Lua-Upstream-Nginx-Module: 提升 Nginx 反向代理性能的新篇章

探索 Lua-Upstream-Nginx-Module: 提升 Nginx 反向代理性能的新篇章 在现代 Web 应用架构中,Nginx 以其高效、轻量级和强大的反向代理能力,被广泛应用于服务端负载均衡和流量控制。而 是一个增强版的上游模块,它允许你在 Nginx 中使用 Lua 脚本动态配置上游服务器,进一步扩展了 Nginx 的功能和灵活性。 项目简介 Lua-Upstream-Nginx...

gitblog_00051的博客 925

玩玩 Nginx 2-----给Nginx添加第三方模块(动态更新upstream

接上一篇,我们在初始化安装的时候添加了nginx_lua模块,然后了解到nginx不可以动态加载模块,所以当你安装第三方模块的时候需要覆盖nginx文件.接下来一起看看如何安装nginx第三模块吧! 1.我们先看看 目前nginx的配置 [root@localhost src]# cd /usr/local/nginx/ [root@localhost n...

aizhuan9418的博客 1950

nginx 返回动态Html,Nginx负载均衡 -Nginx动态更新upstream

Nginx 的配置是启动时一次性加载到内存中的,在实际的使用中,对 Nginx 服务器上游服务器组中节点的添加或移除仍需要重启或热加载 Nginx 进程。在 Nginx 的商业版本中,提供了 ngx_http_api_module 模块,可以通过 API 动态添加或移除上游服务器组中的节点。对于 Nginx 开源版本,通过 Nginx 的扩展版 OpenResty 及 Lua 脚本也可以实现上游服...

weixin_39862697的博客 723

iframe的src动态修改并刷新_入口网关服务发现-Openresty动态upstream

提示在本文前,我建议你先了解一下 Nginx 的基础,同时熟悉基础的 Lua 语言语法,另外再回顾一下 HTTP 的请求过程,对于 Nginx 的负载均衡基本原理也要有基础的了解,掌握这些对我们看本文时能起到一定的帮助。动态 Upstream 场景首先,我们来看第一部分内容,也就是动态 Upstream 的场景。我们先来看一下这样一个典型的场景,整体了解动态 Upstream 的作用。从图中流量的...

weixin_39898248的博客 602

nginx 设置网关时间_入口网关服务发现-Openresty动态upstream

提示在本文前,我建议你先了解一下 Nginx 的基础,同时熟悉基础的 Lua 语言语法,另外再回顾一下 HTTP 的请求过程,对于 Nginx 的负载均衡基本原理也要有基础的了解,掌握这些对我们看本文时能起到一定的帮助。动态 Upstream 场景首先,我们来看第一部分内容,也就是动态 Upstream 的场景。我们先来看一下这样一个典型的场景,整体了解动态 Upstream 的作用。从图中流量的...

weixin_39711721的博客 416

推荐文章:lua-resty-upstream - 动态负载均衡与故障转移的神器

推荐文章:lua-resty-upstream - 动态负载均衡与故障转移的神器 在微服务架构和高并发场景下,如何实现高效的后端服务调用成为了开发者的痛点之一。今天,我们要探讨的是一个开源库 —— lua-resty-upstream,它为OpenResty用户提供了一套灵活且强大的上游连接管理解决方案,专为解决负载均衡和故障恢复问题而生。 项目介绍 lua-resty-upstream是一个针对...

gitblog_00393的博客 708

Nginx迁移OpenResty+Lua,实现负载动态上下线

1.尝试过ngx_http_dyups_module模块,感觉不太好用,OpenResty完全兼容nginx果断采用OpenResty方案。1. 配置文件:/usr/local/openresty/nginx/conf/nginx.conf。所有 Nginx 配置直接复制到 OpenResty 100% 能用。淘宝团队(章亦春)基于官方 Nginx 打包的发行版。OpenResty 底层就是原汁原味 Nginx,2.迁移最好是找个新机器,测试没问题再切流量。完全兼容所有 Nginx 配置。

qq_20170923的博客 256

Nginx + UpSync + Consul 实现 Dynamic Upstream

Nginx 是一款开源、高性能、高可靠的 Web 和反向代理服务器,性能是 Nginx 最重要的考量,其占用内存少、并发能力强。 Nginx 最常见的使用场景就是反向代理,Nginx 接收客户端的请求并通过相应的负载均衡算法将流量转发给后端的多台应用服务器。 传统做法 通常我们先会配置一个 upstream 地址池,包含后端的多台应用服务器,然后通过 proxy_pass 将流量分发给 upstream 中的成员。 http { upstream upstream_server{

cr7258的博客 754
上一篇: Mozilla Apache/Nginx/Lighttpd/HAProxy SSL 配置生成器
下一篇: linux 下分离 debuginfo 到独立文件.
功名半纸
功名半纸 领域专家: 操作系统技术领域 领域专家: 操作系统技术领域
博客等级 码龄26年 1137粉丝 282原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值