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;定级定薪、员工培训、工作安排、绩…

学生课程信息管理系统

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

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

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

路由

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

昇思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

【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;主要用于与…

Cyber Weekly #12

赛博新闻 1、Anthropic发布Claude 3.5 Sonnet 本周五&#xff08;6月21日&#xff09;凌晨&#xff0c;Anthropic宣布推出其最新的语言模型Claude 3.5 Sonnet&#xff0c;距离上次发布Claude3才过去3个月。Claude3.5拥有20万token的长上下文窗口&#xff0c;目前已经在Claude…

HCIA 19 结束 企业总部-分支综合实验(下)

3.6出口NAT配置可以访问互联网 配置NAT使内网可以访问公网8.8.8.8&#xff0c;当前总部PC1 PING不通公网地址8.8.8.8。 3.6.1总部配置NAT访问互联网 步骤1&#xff1a;配置NAT acl number 2000 rule 5 permit source 192.168.0.0 0.0.255.255 # interface GigabitEthern…

Redis预备知识

一.预备知识 1.基本全局命令 set key value 将key的值设置成value get key 得到key的值 keys [pattern] 查看匹配pattern的所有key 比如h?llo匹配hallo&#xff0c;hbllo&#xff0c;hcllo……只要用一个符号将&#xff1f;代替即可 比如h*llo匹配hllo&#xff0c;heeeello…

【图像识别系统】昆虫识别Python+卷积神经网络算法+人工智能+深度学习+机器学习+TensorFlow+ResNet50

一、介绍 昆虫识别系统&#xff0c;使用Python作为主要开发语言。通过TensorFlow搭建ResNet50卷积神经网络算法&#xff08;CNN&#xff09;模型。通过对10种常见的昆虫图片数据集&#xff08;‘蜜蜂’, ‘甲虫’, ‘蝴蝶’, ‘蝉’, ‘蜻蜓’, ‘蚱蜢’, ‘蛾’, ‘蝎子’, ‘…

02_ESP32+MicroPython 点亮LED灯

书接第1篇《01_ESP32 MicroPython开发环境搭建_eps32开发板-CSDN博客》 想要让一个引脚输出高电平&#xff0c;只需要找到对应的GPIO然后通过on()或者value(1)操作就可以&#xff0c;同理如果想要输出低电平让LED灯灭&#xff0c;只需要调用off()或者value(0)就行。 一、点亮…

【ACM出版】2024人工智能与自然语言处理国际学术会议(AINLP 2024,7月19-21)

2024人工智能与自然语言处理国际学术会议&#xff08;AINLP 2024&#xff09;将于2024年7月19-21日在中国珠海召开&#xff0c;该会议作为第四届人工智能、自动化与高性能计算国际会议&#xff08;AIAHPC 2024&#xff09;分会场召开。 本次会议主要围绕“人工智能与自然语言处…

【网络安全的神秘世界】SQL注入漏洞

&#x1f31d;博客主页&#xff1a;泥菩萨 &#x1f496;专栏&#xff1a;Linux探索之旅 | 网络安全的神秘世界 | 专接本 | 每天学会一个渗透测试工具 本章知识使用的靶场&#xff1a;DVWA 一、漏洞简介 SQL&#xff1a;结构化查询语言&#xff0c;是一种特殊的编程语言&#…

智能风控(原理、算法与工程实践)项目一

本文介绍该书第一章的项目&#xff1a;运用CART树进行规则挖掘&#xff0c;具体代码如下 #!/usr/bin/env python # coding: utf-8 # In[1]: import pandas as pd import numpy as np import os # In[2]: data pd.read_excel( ./data_for_tree.xlsx) # In[3]: data.h…