使用Nginx OpenResty与Redis实现高效IP黑白名单管理

1、引言

在当今数字化时代,网络安全已成为企业和个人用户关注的焦点。IP黑白名单作为一种有效的网络安全策略,允许我们精确控制对Web资源的访问权限。通过白名单,我们可以确保只有可信的IP地址能够访问敏感资源;而黑名单则可以阻止恶意IP的访问,从而减少安全风险。

选择Nginx OpenResty与Redis作为实现黑白名单的解决方案,是基于以下几个原因:

  • 高性能:Nginx以其轻量级和高性能著称,适合处理高并发请求。
  • 灵活性:OpenResty通过集成Lua脚本,提供了强大的定制能力。
  • 可扩展性:Redis作为一个内存数据结构存储,支持数据的快速读写,适合实现动态的黑白名单管理。

2、简介

1、什么是OpenResty?

OpenResty是一个基于Nginx的全功能Web平台,它集成了一系列精心设计的Lua库、第三方模块和一个基于LuaJIT的轻量级Web框架。OpenResty的核心是Nginx,但它通过Lua语言扩展了Nginx的功能,使其能够构建能够处理超高并发的动态Web应用。

2、OpenResty与Nginx的关系

OpenResty是在Nginx的基础上构建的,它保留了Nginx的所有功能,并通过Lua语言扩展了其能力。这意味着你可以使用OpenResty来实现Nginx的所有功能,同时还能够利用Lua脚本来实现更复杂的业务逻辑。

3、环境安装

1、环境版本

centos 7 
redis 7.2
nginx version: openresty/1.25.3.1

2、环境安装

1、添加OpenResty仓库

# 由于公共库中找不到openresty,所以需要添加openresty的源仓库
yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo# 注意,如果上面命令提示不存在,那就先安装一下
yum install -y yum-utils
  1. 安装OpenResty
# 安装openresty
yum install -y openresty
# 安装OpenResty管理工具,帮助我们安装第三方的Lua模块
yum install -y openresty-opm

3、目录结构
​ 默认安装在/usr/local/openresty
在这里插入图片描述
看到里面有一个nginx目录,进去可以看到跟我们平常用的nginx是一模一样的,OpenResty就是在Nginx基础上集成了一些Lua模块

到这里我们就安装好了

4、启动和运行
OpenResty底层是基于Nginx的,查看OpenResty目录的nginx目录,结构与windows中安装的nginx基本一致

5、安装配置redis

sudo yum install redis -y

Redis配置主要包括设置持久化选项、网络配置、安全性设置等。以下是一个基本的配置示例:

# redis.conf
port 6379
bind 127.0.0.1
protected-mode yes
requirepass "yourpassword"

4、白名单实现

在这里插入图片描述

图例说明:

  • 客户端:发送HTTP请求的用户或应用。
  • Nginx (OpenResty):处理和管理HTTP请求,执行Lua脚本进行访问控制。
  • Lua脚本:在Nginx中运行,负责从Redis获取白名单并进行IP检查。
  • Redis:存储白名单数据,用于快速查询。
交互流程:
  1. 客户端发送请求到Nginx。
  2. Nginx调用Lua脚本进行访问控制。
  3. Lua脚本连接Redis,并查询IP是否在白名单中。
  4. Lua脚本返回查询结果给Nginx。
  5. Nginx根据结果决定是否允许请求,并返回响应给客户端

定义白名单的作用与重要性

白名单是一种安全策略,用于定义一组被信任的IP地址或实体,它们被允许访问特定的资源或服务。在Web应用中,白名单的作用尤为显著:

  • 安全性增强:限制访问权限,仅允许特定的IP地址访问敏感资源。
  • 防止滥用:减少恶意用户或爬虫对服务的滥用。
  • 流量管理:通过控制访问源,更有效地管理网络流量。

通过OpenResty Lua脚本实现白名单逻辑

在OpenResty中,我们可以使用Lua脚本来实现白名单逻辑。Lua脚本可以在Nginx的配置文件中直接编写,或者存储在外部文件中,并在配置文件中引用。

Lua脚本实现步骤:

  1. 定义白名单:在Redis中存储白名单IP地址。
  2. 访问控制:在Nginx配置中使用access_by_lua_blockaccess_by_lua_file指令调用Lua脚本。
  3. 脚本逻辑:检查请求的IP地址是否在白名单中,如果不在,则拒绝访问。

案例演示

jenkins.ownit.top.conf
这个是nginx的配置文件
最主要内容:access_by_lua_file /opt/nginx/lua_script/white.lua;

upstream jenkins-uat {server 192.168.102.20:91;
}
server {listen       80;server_name  jenkins.ownit.top;#白名单 或者 黑名单#include /opt/nginx/whitelist/corporation.conf;location / {rewrite ^/(.*)$ https://$host/$1 permanent;}access_log  /www/wwwlogs/dns.ownit.top.log;error_log  /www/wwwlogs/dns.ownit.top.error.log;}
server {listen       443 ssl;server_name  jenkins.ownit.top;#白名单 或者 黑名单#include /opt/nginx/whitelist/corporation.conf;#ssl                   on;ssl_certificate      /opt/nginx/ssl/ownit.top.crt;ssl_certificate_key  /opt/nginx/ssl/ownit.top.key;include ssl.conf;location / {access_by_lua_file /opt/nginx/lua_script/white.lua; # nginx的lua脚本proxy_pass  http://jenkins-uat;include https_proxy.conf;}access_log  /www/wwwlogs/dns.ownit.top.log;error_log  /www/wwwlogs/dns.ownit.top.error.log;}

white.lua文件

通过使用Lua脚本,在接收到HTTP请求时检查请求的IP地址是否在Redis存储的白名单中。如果IP不在白名单中,则拒绝访问。

思路

  1. 获取客户端IP和请求路径:在Lua脚本中获取客户端的IP地址和请求路径。
  2. 连接Redis:使用resty.redis模块连接Redis数据库。
  3. 权限校验:对连接的Redis进行认证。
  4. 检查IP是否在白名单中:从Redis中检查IP是否存在于白名单集合中。
  5. 返回结果:如果IP在白名单中,允许访问;否则,返回403 Forbidden状态码,拒绝访问。
  6. 释放Redis连接:将Redis连接返回到连接池中,以便复用。
-- 获取客户端IP和请求路径
local client_ip = ngx.var.remote_addr
local path = ngx.var.uri-- Redis相关配置
local redis_key_white_list = "map_request_white_list"-- 连接Redis
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, "Redis连接失败: ", err)return ngx.exit(500)
end-- 权限校验
local res, err = red:auth("123456")
if not res thenngx.say("failed to authenticate: ", err)return
end-- 检查IP是否在白名单中
local is_in_whitelist, err = red:sismember(redis_key_white_list, client_ip)
if is_in_whitelist == 1 thenngx.log(ngx.INFO, "IP在白名单中: ", client_ip)
elsengx.status = ngx.HTTP_FORBIDDENngx.say("Access Denied")return ngx.exit(ngx.HTTP_FORBIDDEN)
end-- 返还redis连接到连接池
local ok, err = red:set_keepalive(10000, 100)
if not ok thenngx.log(ngx.ERR, "设置keepalive失败: ", err)
end

详细解释

  1. 获取客户端IP和请求路径

    local client_ip = ngx.var.remote_addr
    local path = ngx.var.uri
    

    这两行代码从Nginx变量中获取客户端的IP地址和请求路径,client_ip用于后续的白名单检查。

  2. Redis相关配置

    local redis_key_white_list = "map_request_white_list"
    

    定义存储白名单的Redis键。

  3. 连接Redis

    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, "Redis连接失败: ", err)return ngx.exit(500)
    end
    

    使用resty.redis模块创建Redis连接对象,并设置连接超时时间。尝试连接到Redis服务器,如果连接失败,记录错误日志并返回500错误。

  4. 权限校验

local res, err = red:auth("123456")
if not res thenngx.say("failed to authenticate: ", err)return
end

对Redis进行认证,如果认证失败,输出错误信息并停止执行。

  1. 检查IP是否在白名单中
local is_in_whitelist, err = red:sismember(redis_key_white_list, client_ip)
if is_in_whitelist == 1 thenngx.log(ngx.INFO, "IP在白名单中: ", client_ip)
elsengx.status = ngx.HTTP_FORBIDDENngx.say("Access Denied")return ngx.exit(ngx.HTTP_FORBIDDEN)
end

使用SISMEMBER命令检查IP是否在Redis的白名单集合中。如果IP在白名单中,记录信息日志;否则,返回403 Forbidden状态码并拒绝访问。

  1. 释放Redis连接
local ok, err = red:set_keepalive(10000, 100)
if not ok thenngx.log(ngx.ERR, "设置keepalive失败: ", err)
end

将Redis连接返回到连接池中,以便后续请求复用该连接。如果设置失败,记录错误日志。

在Nginx中配置Lua脚本

在Nginx的location配置中,使用access_by_lua_file指令来调用上述Lua脚本:

nginx复制代码http {```lua
http {server {listen 80;server_name example.com;location / {access_by_lua_file /opt/nginx/lua_script/white.lua;proxy_pass http://backend;}}
}

上述配置在接收到HTTP请求时,会首先执行/opt/nginx/lua_script/white.lua脚本进行白名单检查。如果通过检查,则继续将请求转发到后端服务器。

在这里插入图片描述
成功访问:
在这里插入图片描述
禁止访问:
在这里插入图片描述

5、黑名单实现

黑名单的作用与场景

黑名单是一种网络安全机制,用于识别并阻止恶意IP地址对服务器资源的访问。它在多种场景中发挥着重要作用:

  • 防止恶意攻击:通过封禁已知的攻击者IP,减少服务器遭受的恶意攻击。
  • 打击爬虫滥用:限制爬虫对网站资源的过度访问,保护数据不被滥用。
  • 减轻服务器负载:通过限制特定IP的访问频率,减轻服务器压力,提高服务稳定性。
  • DDoS防御:快速响应DDoS攻击,封禁攻击源IP,保护服务可用性。

使用Lua脚本与Redis实现动态IP封禁

OpenResty结合Redis可以实现一个高效的动态IP封禁系统。以下是实现的关键步骤:

  1. 环境配置:确保Nginx OpenResty和Redis环境准备就绪。
  2. Lua脚本编写:编写Lua脚本来动态查询和更新Redis中的黑名单状态。
  3. Nginx配置整合:在Nginx配置文件中集成Lua脚本,实现访问控制。

在这里插入图片描述

案例演示

通过使用Lua脚本,在接收到HTTP请求时检查请求的IP地址是否在黑名单中,或控制IP的访问频率,并进行相应的处理。

思路

  1. 获取客户端IP:在Lua脚本中获取客户端的IP地址。
  2. 连接Redis:使用resty.redis模块连接Redis数据库。
  3. 权限校验:对连接的Redis进行认证。
  4. 检查IP是否在黑名单中:从Redis中检查IP是否存在于黑名单集合中。
  5. 访问频次控制:对每个IP的访问频次进行限制,如果超过指定的频次,则将IP加入黑名单。
  6. 返回结果:如果IP在黑名单中,返回403 Forbidden状态码,拒绝访问;否则,允许请求继续。

Nginx 配置文件

upstream jms-uat {server 192.168.82.105:81;
}
server {listen 80;server_name jms.ownit.top;# 白名单 或者 黑名单# include /opt/nginx/whitelist/corporation.conf;rewrite ^/(.*)$ https://$host/$1 permanent;access_log /www/wwwlogs/dns.ownit.top.log;error_log /www/wwwlogs/dns.ownit.top.error.log;
}
server {listen 443 ssl;server_name jms.ownit.top;# 白名单 或者 黑名单# include /opt/nginx/whitelist/corporation.conf;ssl_certificate /opt/nginx/ssl/ownit.top.crt;ssl_certificate_key /opt/nginx/ssl/ownit.top.key;include ssl.conf;location = /core/auth/login/ {access_by_lua_file /opt/nginx/lua_script/login.lua;proxy_pass http://jms-uat;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "upgrade";}location / {if ($request_uri !~ \.(html|htm|jpg|png|ico|js|css)$) {access_by_lua_file /opt/nginx/lua_script/rule.lua;}proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "upgrade";proxy_pass http://jms-uat;include https_proxy.conf;client_max_body_size 0;}access_log /www/wwwlogs/dns.ownit.top.log;error_log /www/wwwlogs/dns.ownit.top.error.log;
}

location = /core/auth/login/

location = /core/auth/login/ {access_by_lua_file /opt/nginx/lua_script/login.lua;proxy_pass http://jms-uat;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "upgrade";
}
解释
  • location = /core/auth/login/
    • 这是一个精确匹配的location块,仅对请求路径严格等于/core/auth/login/的请求生效。
  • access_by_lua_file /opt/nginx/lua_script/login.lua;
    • 使用OpenResty的Lua模块,指定在访问控制阶段执行/opt/nginx/lua_script/login.lua脚本。这个脚本通常用于执行认证、权限检查或其他预处理逻辑。
  • proxy_pass http://jms-uat;
    • 将匹配到的请求代理到上游服务器http://jms-uat
  • proxy_set_header Upgrade $http_upgrade;
    • 设置Upgrade请求头,支持WebSocket等协议升级。$http_upgrade变量包含原始请求中的Upgrade头字段的值。
  • proxy_set_header Connection "upgrade";
    • 设置Connection请求头为upgrade,通常与Upgrade头一起使用,以确保连接升级。

location /

location / {# 如果该location 下存在静态资源文件可以做一个判断 if ($request_uri !~ \.(html|htm|jpg|png|ico|js|css)$) {access_by_lua_file /opt/nginx/lua_script/rule.lua; 加上了这条配置,则会根据 rule.lua 的规则进行限流}proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "upgrade";proxy_pass http://jms-uat;include https_proxy.conf;client_max_body_size 0;
}
解释
  • location /
    • 这是一个通配符匹配的location块,表示所有路径的请求都会匹配到这个块,除非有其他更精确的匹配块。
  • if ($request_uri !~ \.(html|htm|jpg|png|ico|js|css)$)
    • 使用if指令对请求路径进行检查。仅在请求路径不匹配指定的静态资源文件扩展名(如.html, .htm, .jpg, .png, .ico, .js, .css)时,执行后续的Lua脚本。这种检查有助于将动态资源与静态资源区分开来。
  • access_by_lua_file /opt/nginx/lua_script/rule.lua;
    • 使用OpenResty的Lua模块,指定在访问控制阶段执行/opt/nginx/lua_script/rule.lua脚本。这个脚本通常用于实现限流、防火墙或其他动态访问控制逻辑。
  • proxy_set_header Upgrade $http_upgrade;
    • 设置Upgrade请求头,支持WebSocket等协议升级。$http_upgrade变量包含原始请求中的Upgrade头字段的值。
  • proxy_set_header Connection "upgrade";
    • 设置Connection请求头为upgrade,通常与Upgrade头一起使用,以确保连接升级。
  • proxy_pass http://jms-uat;
    • 将匹配到的请求代理到上游服务器http://jms-uat
  • include https_proxy.conf;
    • 包含额外的配置文件https_proxy.conf,该文件可能包含HTTPS代理相关的其他配置项。
  • client_max_body_size 0;
    • 设置客户端请求体的最大大小为0,表示不限制请求体的大小。

这两个location块主要用于处理不同路径的请求,并在访问控制阶段使用Lua脚本进行相应的逻辑处理。精确匹配的/core/auth/login/路径专用于特定的认证或预处理,而通配符匹配的/路径则处理所有其他请求,并进行动态访问控制逻辑。两者共同确保了Nginx服务器的灵活性和安全性。

Lua脚本 (rule.lua)

-- 连接池超时回收毫秒
local pool_max_idle_time = 10000
-- 连接池大小
local pool_size = 100
-- redis 连接超时时间
local redis_connection_timeout = 100
-- redis host
local redis_host = "192.168.102.20"
-- redis port
local redis_port = "6379"
-- redis auth
local redis_auth = "123456"
-- 封禁IP时间(秒)
local ip_block_time = 120
-- 指定ip访问频率时间段(秒)
local ip_time_out = 10
-- 指定ip访问频率计数最大值(次)
local ip_max_count = 60-- 错误日志记录
local function errlog(msg, ex)ngx.log(ngx.ERR, msg, ex)
end-- 释放连接池
local function close_redis(red)if not red thenreturnendlocal ok, err = red:set_keepalive(pool_max_idle_time, pool_size)if not ok thenngx.say("redis connct err:", err)return red:close()end
end-- 连接redis
local redis = require "resty.redis"
local client = redis:new()
local ok, err = client:connect(redis_host, redis_port)
-- 连接失败返回服务器错误
if not ok thenreturn
end
-- 设置超时时间
client:set_timeout(redis_connection_timeout)-- 优化验证密码操作
local connCount, err = client:get_reused_times()
-- 新建连接,需要认证密码
if 0 == connCount thenlocal ok, err = client:auth(redis_auth)if not ok thenerrlog("failed to auth: ", err)returnend
elseif err thenerrlog("failed to get reused times: ", err)return
end-- 获取请求ip
local function getIp()local clientIP = ngx.req.get_headers()["X-Real-IP"]if clientIP == nil thenclientIP = ngx.req.get_headers()["x_forwarded_for"]endif clientIP == nil thenclientIP = ngx.var.remote_addrendreturn clientIP
endlocal clientIp = getIp()local incrKey = "limit:all:count:" .. clientIp
local blockKey = "limit:all:block:" .. clientIp-- 查询ip是否被禁止访问,如果存在则返回403错误代码
local is_block, err = client:get(blockKey)
if tonumber(is_block) == 1 thenngx.exit(ngx.HTTP_FORBIDDEN)close_redis(client)
endlocal ip_count, err = client:incr(incrKey)
if tonumber(ip_count) == 1 thenclient:expire(incrKey, ip_time_out)
end
-- 如果超过单位时间限制的访问次数,则添加限制访问标识,限制时间为ip_block_time
if tonumber(ip_count) > tonumber(ip_max_count) thenclient:set(blockKey, 1)client:expire(blockKey, ip_block_time)
endclose_redis(client)

在这里插入图片描述
成功访问:
在这里插入图片描述

失败访问:
在这里插入图片描述

参考文档:
https://www.cnblogs.com/KingArmy/p/18019489
https://blog.csdn.net/qq_45503196/article/details/134648292

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

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

相关文章

嵌入式人工智能(2-树莓派4B开发板硬件环境搭建)

1.硬件开发环境(T型板) 树莓派4B开发板需要搭配面包板,T型板将40个GPIO口引出,再将T型板插到面包板上面。这个地方需要注意插接的方向,由于插树莓派引脚的排线没有防呆设计,因此,请注意方向&am…

第二证券:电影暑期档持续升温 农机自动驾驶驶入快车道

农机自动驾驶打开驶入快车道 得益于农机补贴、土地流通、高标准农田制造等方针引导,叠加技术突围和用户降本增效的内生需求,我国正处于农业2.0向农业3.0的过渡阶段。其间农机自动驾驶系统是结束农业3.0(即自动化)的要害并迎来快速…

PyCharm软件初始化配置

安装完pycharm后,需要对其进行个性化设置,分别设置方法如下 目录 一、修改主题二、修改默认字体和大小三、设置拖动滚轮改变字体大小四、常见快捷键 一、修改主题 1、界面右上角点击红框的内容 2、选择Theme选项 3、选择对应的主题 第一二个是白色主题…

电池技术的未来:BMS的创新与应用

目录 一、什么是BMS? 二、BMS的核心功能 三、为什么BMS如此重要? 四、应用领域 五、未来展望 随着电动汽车、储能系统以及各种便携式设备的普及,电池技术的发展变得至关重要。而在这一领域中,电池管理系统(BMS&am…

直播美颜工具开发教学:视频美颜SDK集成详解

本篇文章,笔者将详细介绍如何在直播应用中集成视频美颜SDK,让你的直播画面焕然一新。 一、什么是视频美颜SDK? 视频美颜SDK是一种软件开发工具包,提供了视频处理和图像增强功能。通过集成视频美颜SDK,开发者可以轻松…

可视化作品集(14)智慧旅游和智慧景区,洞悉一切。

智慧旅游和智慧景区的可视化大屏可以带来以下几个方面的好处: 1. 提升游客体验: 通过可视化大屏,游客可以方便地获取到景区地图、交通信息、景点介绍、活动安排等信息,帮助游客更好地规划行程,提升游览体验。 2. 提供…

超越99%动画!我测试了Luma AI视频的首尾帧,流畅度NO.1?

关键帧通常用于控制动画中的运动、形状变化、颜色变化、透明度等属性,以及视频和音频编辑中的剪辑、效果和音频级别。 最近一段时间,玩可灵AI玩得比较多(国产免费速度快),luma上回写了一篇文章后就没有接着使用(排队生…

2024年上半年信息系统项目管理师——综合知识真题题目及答案(第1批次)(2)

2024年上半年信息系统项目管理师 ——综合知识真题题目及答案(第1批次)(2) 第21题:在一个大型信息系统项目中,项目经理发现尽管已经建立了沟通机制,但团队间的沟通依然不畅,项目风险…

【python模块】Selenium

声明:本文档或演示材料仅供教育和教学目的使用,任何个人或组织使用本文档中的信息进行非法活动,均与本文档的作者或发布者无关。 文章目录 Selenium库功能介绍环境准备示例代码 Selenium库 Selenium库是一个强大的Web自动化工具,…

【vue教程】一. 环境搭建与代码规范配置

目录 引言Vue 框架概述起源与设计理念核心特性优势 Vue 开发环境搭建环境要求安装 Vue CLI创建 Vue 项目项目结构介绍运行与构建 组件实例基础模板响应式更新 代码规范为什么要使用代码规范在 Vue 项目中使用 ESLint 、PrettierESLint配置 ESLintrules 自定义错误级别 Prettier…

推理的判定定理三种验证方式

1. 真值表技术 2. 公式转换法 3. 主析取范式法 参考:离散数学-电子科技大学

LLM-阿里 DashVector + langchain self-querying retriever 优化 RAG 实践【Query 优化】

文章目录 前言self querying 简介代码实现总结 前言 现在比较流行的 RAG 检索就是通过大模型 embedding 算法将数据嵌入向量数据库中,然后在将用户的查询向量化,从向量数据库中召回相似性数据,构造成 context template, 放到 LLM 中进行查询…

python如何判断变量是否可迭代

python如何判断变量是否可迭代?方法如下: 方法一: 适用于python2和python3 >>> from collections import Iterable >>> isinstance("str", Iterable) True 方法二: 适用于python3 s "hello …

InterSystems IRIS使用python pyodbc连接 windows环境,odbc驱动安装,DSN配置,数据源配置

一、创建的数据库和数据 SELECT 1SELECT $ZVERSIONCREATE TABLE MyApp.Person ( ID INT PRIMARY KEY, Name VARCHAR(100) NOT NULL, Age INT, Gender CHAR(1) );CREATE TABLE MyApp.Person2 ( ID INT PRIMARY KEY, Name VARCHAR(100) NOT NULL, Age INT, Gender CHA…

Gil-Pelaez inversion

一、特征函数 A.随即变量的特征函数定义与性质 B.特征函数与PDF的关系 傅里叶变换:C.特征函数与矩函数关系 二、Gil-Pelaez反演定理 输入功率 P i n P_{in}

MYSQL 四、mysql进阶 9(数据库的设计规范)

一、为什么需要数据库设计 二、范 式 2.1 范式简介 在关系型数据库中,关于数据表设计的基本原则、规则就称为范式。 可以理解为,一张数据表的设计结 构需要满足的某种设计标准的 级别 。要想设计一个结构合理的关系型数据库,必须满足一定的…

13 IP层协议-网际控制报文协议ICMP

计算机网络资料下载:CSDNhttps://mp.csdn.net/mp_blog/creation/editor/140148186 为了更有效的转发IP数据报和提高交付成果的机会,在网际层使用了网际控制报文协议ICMP。ICMP允许主机或路由器报告差错情况和提供有关异常情况的报告。ICMP不是高层协议数…

Java面试八股之Redis集群Cluster

Redis集群Cluster Redis Cluster是一种基于数据分片(Sharding)的分布式缓存和存储系统,它实现了数据的水平扩展、高可用性和自动故障转移。以下是对Redis Cluster模式详细实现流程的描述: 1. 初始化与配置 部署节点&#xff1a…

C++ //练习 15.15 定义你自己的Disc_quote和Bulk_quote。

C Primer(第5版) 练习 15.15 练习 15.15 定义你自己的Disc_quote和Bulk_quote。 环境:Linux Ubuntu(云服务器) 工具:vim 代码块 /******************************************************************…

Python酷库之旅-第三方库Pandas(026)

目录 一、用法精讲 65、pandas.bdate_range函数 65-1、语法 65-2、参数 65-3、功能 65-4、返回值 65-5、说明 65-6、用法 65-6-1、数据准备 65-6-2、代码示例 65-6-3、结果输出 66、pandas.period_range函数 66-1、语法 66-2、参数 66-3、功能 66-4、返回值 6…