Nginx+Lua+Redis 实现Nginx301跳转配置管理

在这里插入图片描述

业务场景需求


long long ago:

在项目的运维过程中有一次SEO团队提出 网页的URL 中如果可以带上关键字,那么网页在各大搜索引擎中收录和排名有非常重大的突出优势(~~SEO团队到底专不专业 ~~,此处不做置评),遂业务方决定,项目的CMS系统中增加修改页面URL的功能(不是什么大事,甲方爸爸要求了就加了)。
功能增加后,业务人员笃信此内容有效果,一天增删改好几遍,对于搜索引擎收录后的页面修改URL后要求增加301或302跳转,确保对搜索引擎友好。(虽然一天改那么多遍,到底友好在哪儿 我也不知道,不予置评)

因为项目架构涉及到多层级CDN分发,网站内容静态化管理,流量资源控制等情况,采用的是将变更URL的301映射定期存储在配置文件中进行reload的方式,为确保系统稳定,选择了每日更新的情况。

now :
外来的运维团队对实时性情况要求逐渐提升,要求立马生效,遂寻求了此解决方案。

在这个业务场景的解决问题上,我是在mac本地进行的流程验证和测试,旨为梳理思路和流程。在其他平台,也可以找到对应的方式。(官方文档和教程中都有我就不赘述了)

OpenResty = Nginx+Lua


因为web服务器一直使用的是Nginx,在项目中也有对Nginx源码的改造需求在,所以在此解决方案中选择了OpenResty。

https://openresty.org/

OpenResty是通过Lua 扩展Nginx 实现的可伸缩的Web平台。可以理解为Web服务核心是Nginx,但是通过Lua的方式增加了很多的扩展功能,还是很Nice的。

Nginx 早年间推出了njs 模块,支持使用javascript的部分子集进行扩展,也是不错的方式,但是在Nginx的许多场景中NJS的扩展使用生态没有Lua的好一些,在解决问题和功能扩展上不如Lua容易,感谢社区和开源的大佬。

MacOS下安装 :

brew install openresty/brew/openresty

在这里插入图片描述

需要注意

brew install openresty #采用此命令是安装不了的,会说找不到

安装后需要添加环境变量,以便Nginx 命令启动可以找到
在这里插入图片描述

brew安装后的地址(macOS)可以参考以下,其他的可能在/usr/local/openresty(这是默认地址)

PATH=/opt/homebrew/Cellar/openresty/1.25.3.1_1/nginx/sbin:$PATH
export PATH

之后创建Web服务所需的工作区

mkdir www logs conf

在这里插入图片描述

创建工作区这一步是因为我在全新的环境终验证流程所需,在已有的项目中,可以依据自身的情况进行配置即可,后续的命令是在nginx-lua-redis目录下执行的,如果切换到了别的目录,注意一些命令中所需的文件路径的变更。

在conf文件夹下新建一个示例配置Nginx.conf

worker_processes 1; 
error_log logs/error.log; 
events { worker_connections 1024; 
} 
http {server {listen 8080; location / {default_type text/html; content_by_lua_block {ngx.say("<p>hello, world</p>") } } } 
}

然后启动Nginx 服务:

nginx -p `pwd`/ -c conf/nginx.conf

如果说找不到文件,就检查一下自己所在路径是否正确。

测试:

curl http://localhost:8080/

结果:

<p>hello, world</p>

此时在nginx-lua-redis目录下会自动生成其他web服务所需的相关文件,可以不必理会。

此时Nginx+Lua环境就可以使用了,这里得益于OpenResty项目的集成,如果采用Nginx + Lua模块及其他扩展的安装会稍显麻烦,毕竟还有许多依赖和听都没听过得许多模块要学习和了解…… OpenResty本身已经集成了大多是扩展所需,Nice +1.

Redis 支持


为什么这个方案中用Redis?因为官网说它快……

在这里插入图片描述

Redis在mac上安装也是相对简单

brew install redis
brew services start redis
redis-server

在这里插入图片描述

Ok,Redis 的简单实例就搭好了

新开终端窗口测试链接:

redis-cli -h 127.0.0.1 -p 6379

因为是流程验证和测试,不想写为Redis写什么代码,直接从官网下载了支持Mac的免费客户端 :
RedisInsight https://redis.io/insight/
完全傻瓜化的操作,而且界面也很好看

在这里插入图片描述

在这里我尝试创建了两组页面跳转的实例,最终选择了HASH的模式.在自带的终端中创建了百度和知乎的跳转键值对用作后续的测试。

Redis中不同的数据类型操作方式不同,选择不同的数据类型在Lua脚本调用时需要进行调整。
Lua调用Redis中数据匹配跳转规则时,传入的URL数据是从"/"开始的,这也是为什么截图中有两组数据的原因(第一组我忘记这个事儿了,所以失败了,然后才想起来😭)

配置文件案例


Nginx + Lua脚本的实现是比较轻松地,只要了解了语法写起来就很轻松。这个实例的核心就是Nginx 在 匹配的URL 规则时,通过Lua脚本 调用后端Redis 中存储的301跳转规则,而不是之前写在配置文件中固定规则。通过对Redis的操作,来实时进行规则内容的更新。

worker_processes  1;
error_log logs/error.log;
events {worker_connections 1024;
}
http {lua_shared_dict redirects_cache 3m; # 分配1MB共享内存用于缓存server {listen 8080;location / {access_by_lua_block {local redis = require "resty.redis"local red = redis:new()red:set_timeout(1000) -- 设置超时时间local ok, err = red:connect("127.0.0.1", 6379)if not ok thenngx.log(ngx.ERR, "failed to connect to redis: ", err)return ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)end-- 尝试从缓存中获取跳转规则local cached_redirect = ngx.shared.redirects_cache:get(ngx.var.uri)if cached_redirect thenngx.redirect(cached_redirect, 301)returnend-- 查询Redislocal new_url = red:hget("redirects", ngx.var.uri)if type(new_url)=="string" then-- 缓存结果以加速后续请求ngx.shared.redirects_cache:set(ngx.var.uri, new_url, 600) -- 缓存600秒red:close() -- 关闭连接ngx.redirect(new_url, 301)returnendred:close()}default_type text/html;content_by_lua_block {ngx.say("<p>hello, world. nginx-lua-Redis</p>")}}}
}

redirects_cache:设置一个缓存区,毕竟每次都去查Redis也是要消耗的,缓存之后消耗会少一些,缓存多大要看项目中需要的301规则有多少。

通过访问预设的地址都可以正常跳转

localhost:8080/test1.shtml -> 正确的去了百度
localhost:8080/test2.shtml -> 正确的去了知乎

在对Redis 中数据进行更新后,跳转效果也可以实时生效。

后记:


关于Nginx 热加载 reload

Nginx本身是提供热加载的 :

nginx -s reload

这也是我们之前自动化所采用的方式。在实际使用中,大流量或者长链接保持情况下,reload的方式式经常会出现一些意外情况,比如服务中断,reload失败等等。所以在早期的方案中我们实际是高可用集群切换来保障自动更新的效果。但是目前业务方热衷于频繁修改URL跳转规则,并要求在短时间内立马生效。采用 Reload的方式对 平台业务服务的稳定性增加了较多隐患,可能这次集群Reload还没结束,下次又开始了,对于系统消耗和稳定性的考虑才决定尝试验证Nginx+Lua+Redis的方案。

方案的局限性
这个方案的产生和测试,都是基于在手的一个项目业务情况和环境需求所产生的,并不是说这是一个非常完善或者普适性的方案,它只解决我所处情况的问题,这里做的总结只是做一个思路梳理和验证,实际的项目中要依据自身情况进行。如有更好的方法和意见,欢迎批评指正。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/858293.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

超详细!想进华为od的请疯狂看我!

三分钟带你全面了解华为OD 【合同及管理】签约方为科锐国际/外企德科&#xff08;人力服务公司&#xff09;&#xff0c;劳动合同期为4年&#xff0c;试用期6个月。员工关系合同管理、五险一金、考勤发薪由科锐国际/外企德科负责&#xff1b;定级定薪、员工培训、工作安排、绩…

vuex的配置主要内容

1、state 作用&#xff1a;负责存储数据&#xff1b; 2、getters 作用&#xff1a;state计算属性(有缓存)&#xff1b; 3、mutaions 作用&#xff1a;负责同步更新state数据 mutaions是唯一可以修改state数据的方式&#xff1b; 4、actions 作用&#xff1a;负责异步操作&a…

mysql数据库入门手册

数据库 常见的数据库查看当前用户及其权限创建用户授权用户访问数据库撤销用户权限修改用户密码删除用户增创建一个数据库创建表表中插入数据表中添加字段&#xff08;三种方式&#xff09; 删删除表记录删除表字段删除表&#xff08;三种方式&#xff09;删除数据库 改修改表名…

学生课程信息管理系统

摘 要 目前&#xff0c;随着科学经济的不断发展&#xff0c;高校规模不断扩大&#xff0c;所招收的学生人数越来越 多&#xff1b;所开设的课程也越来越多。随之而来的是高校需要管理更多的事务。对于日益增 长的学生相关专业的课程也在不断增多&#xff0c;高校对其管理具有一…

Linux Kernel入门到精通系列讲解(RV-Kernel 篇) 5.6 在kernel 中实现系统复位和系统关机驱动

1. 概述 上一章节Qemu篇我们已经实现了我们SOC的power reset和 power down 寄存器,本章节我们就在Linux driver中去实现它。 2. Linux kernel 访问其他节点 Linux kernel中有一种机制,就是在driver中访问其它设备树节点的信息,了解设备树的应该都知道,每个设备节点都有一…

【java问答小知识19】一些Java基础的知识,用于想学习Java的小伙伴们建立一些简单的认知以及已经有经验的小伙伴的复习知识点

Java中的"java.util.concurrent.locks.StampedLock"的"tryConvertToReadLock()"方法如何工作&#xff1f; 回答&#xff1a;尝试将当前的写锁转换为读锁&#xff0c;并返回一个表示锁定状态的戳记。 Java中的"java.util.concurrent.locks.StampedLock…

计算机网络:应用层 - 万维网 HTTP协议

计算机网络&#xff1a;应用层 - 万维网 & HTTP协议 万维网 WWW统一资源定位符 URL 超文本传输协议 HTTP非持续连接持续连接非流水线流水线 代理服务器HTTP报文 万维网 WWW 万维网是一个大规模的、联机式的信息储藏所。万维网用链接的方法能非常方便地从互联网上的一个站点…

通信系统网络架构_4.存储网络架构

1.计算机访问磁盘存储有3种方式 一般来说&#xff0c;计算机访问磁盘存储有3种方式&#xff1a; &#xff08;1&#xff09;直连式存储&#xff08;Direct Attached Storage&#xff0c;DAS&#xff09;&#xff1a;计算机通过I/O端口直接访问存储设备的方式。 &#xff08;…

路由

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 客户端&#xff08;例如浏览器&#xff09;把请求发送给 Web 服务器&#xff0c;Web 服务器再把请求发送给 Flask程序实例。程序实例需要知道对每个U…

Kafka 最佳实践:构建高性能、可靠的数据管道

目录 1. 部署最佳实践 1.1 硬件配置 1.2 集群配置 1.3 ZooKeeper 配置 2. 主题和分区设计 2.1 分区设计 2.2 数据保留策略 3. 生产者最佳实践 3.1 生产确认机制 3.2 重试机制 3.3 批量发送 4. 消费者最佳实践 4.1 消费组管理 4.2 并行处理 4.3 错误处理 5. 安全…

昇思25天学习打卡营第5天|网络构建

一、简介&#xff1a; 神经网络模型是由神经网络层和Tensor操作构成的&#xff0c;mindspore.nn提供了常见神经网络层的实现&#xff0c;在MindSpore中&#xff0c;Cell类是构建所有网络的基类&#xff08;这个类和pytorch中的modul类是一样的作用&#xff09;&#xff0c;也是…

std::bind与std::ref配合使用时要注意的几个问题

目录 1 假如输入函数的变量是左值非常量引用&#xff0c;则该变量在std::bind中只能用std::ref修饰&#xff0c;不能用cref&#xff0c;否则编译失败&#xff1a; 2 假如输入函数的变量是左值常量引用&#xff0c;则该变量在std::bind中既可以用std::ref修饰&#xff0c;也可…

Mathtype7在Word2016中闪退(安装过6)

安装教程&#xff1a;https://blog.csdn.net/Little_pudding10/article/details/135465291 Mathtype7在Word2016中闪退是因为安装过Mathtype6&#xff0c;MathPage.wll和MathType Comm***.dotm)&#xff0c;不会随着Mathtype的删除自动删除&#xff0c;而新版的Mathtype中的文件…

Inpaint软件最新版下载【安装详细图文教程】

​根据使用者情况表明在今天的数字时代&#xff0c;我们经常会遇到需要处理图形的情况&#xff0c;然而&#xff0c;当我们遇到水印在图形上&#xff0c;我们就需要寻找一个有效的方式来去除它&#xff0c;Inpaint软件就是一个非常实用的工具&#xff0c;它能够帮助我们去除水印…

小柴带你学AutoSar系列一、基础知识篇(6)车规级MCU入门RH850

flechazohttps://www.zhihu.com/people/jiu_sheng 小柴带你学AutoSar总目录https://blog.csdn.net/qiansh

自动化开发任务:在PHP框架中实现自定义命令

在现代Web开发中&#xff0c;自动化是提高开发效率和减少重复工作的关键。PHP框架&#xff0c;如Laravel、Symfony等&#xff0c;提供了强大的自定义命令功能&#xff0c;允许开发者创建自己的artisan命令来执行各种自动化任务。本文将详细介绍如何在PHP框架中实现自定义命令&a…

【web2】jquary,bootstrap,vue

文章目录 1.jquary&#xff1a;选择器1.1 jquery框架引入&#xff1a;$("mydiv") 当成id选择器1.2 jquery版本/对象&#xff1a;$(js对象) -> jquery对象1.3 jquery的页面加载事件&#xff1a;$ 想象成 window.onload 1.4 jquery的基本选择器&#xff1a;$()里内容…

GIM: Learning Generalizable Image Matcher From Internet Videos

【引用格式】&#xff1a;Shen X, Yin W, Mller M, et al. GIM: Learning Generalizable Image Matcher From Internet Videos[C]//The Twelfth International Conference on Learning Representations. 2023. 【网址】&#xff1a;https://arxiv.org/pdf/2402.11095 【开源代…

Linux_软硬链接

目录 1、软链接 2、软链接的使用方式 3、软链接的删除 4、硬链接 5、硬链接的使用方式 6、软硬链接的使用场景 7、软硬链接的区别 结语 前言&#xff1a; 在Linux操作系统中&#xff0c;有软链接和硬链接&#xff0c;他们是一种特殊的文件引用&#xff0c;主要用于与…

mysql索引以及优化

索引的作用 在数据库表中对字段建立索引可以大大提高查询速度 mysql索引类型 普通索引唯一索引&#xff1a; 唯一索引列的值必须唯一允许有空值&#xff0c;如果是组合索引&#xff0c;则列值的组合必须唯一create unique index indexName on mytable(username(length))修改表结…