基于 Nginx 的 CDN 基础实现
概览
本文是对基于Nginx的CDN网络的学习笔记,阅读的代码为:https://github.com/leandromoreira/cdn-up-and-running
其中,先确定CDN中的一些基础概念:
- Balancer:负载均衡,即请求数据的流量最开始打到Balancer,由负载均衡算法确定流量导到后续Edge节点,即缓存边缘节点
- Edge:边缘节点,即具有数据缓存,能够更快响应数据给回客户端的节点,在负载均衡和后端服务之间
- Backend:后端节点,即实际存储数据的节点
本文阅读学习的仓库,通过Nginx构建所有节点,用到了以下属性
- vhost_traffic_status:记录并存储每个节点的网络情况,包括处理状态码、处理时间
- proxy_cache:缓存交互处理,包括缓存路径、过期时间、中断处理、缓存键值存储区域(共享内存)
- nginx:使用nginx的基础功能,包括 server、location、proxy_pass、upstream 等
- openresty:配合lua引擎使用的nginx扩展,包括脚本增强、set_by_lua、access_by_lua、balancer_by_lua、content_by_lua 等能力
另外,还是用到 prometheus 作为监控各节点的工具,使用 grafana 作为时间序列数据的可视化工具
实现
Balancer
# vi:syntax=nginx
events {worker_connections 1024;
}error_log stderr;http {resolver 127.0.0.11 ipv6=off;include generic_conf/setup_logging.conf;include generic_conf/lua_path_setup.conf;# 本节点的统计信息,请求时长、status状态等include generic_conf/basic_vts_setup.conf;# 缓存相关设置include generic_conf/setup_cache.conf;init_by_lua_block {loadbalancer = require "loadbalancer"loadbalancer.setup_server_list()}upstream backend {server 0.0.0.1;# 进行流量负载均衡,选定 edge 节点balancer_by_lua_block {loadbalancer.set_proper_server()}keepalive 60;}server {listen 8080;location / {# access 阶段解析dns,并获取 edge 列表,后续在本文件的 backend 进行负载均衡access_by_lua_block {loadbalancer.resolve_name_for_upstream()}# 代理到本文件的backend,进行负载均衡到 edge 节点proxy_pass http://backend;add_header X-Edge LoadBalancer;}# 可通过 /status 接口获取本节点的统计信息include generic_conf/basic_vts_location.conf;}
}
generic_conf/setup_cache.conf 缓存设置如下:
# /cache/ 指定缓存文件存储目录,levels定义缓存目录结构,key_zone 定义存储缓存的键的共享内存区域
# max_size 为缓存最大大小,inactive表示缓存被视为非活的时间,use_temp_path表示不使用临时路径,用缓存目录
# 最终实现:zone_1 共享内存中,存储缓存的键key与数据对应的路径(/cache/中),数据则实际缓存到本机 /cache/ 中
proxy_cache_path /cache/ levels=2:2 keys_zone=zone_1:10m max_size=10m inactive=10m use_temp_path=off;
# 多个请求尝试缓存同一资源,在 lock_timeout 时间窗口内只请求backend一次,其余请求等待资源
proxy_cache_lock_timeout 2s;
# 缓存数据过期或backend失效,允许使用过期的缓存数据
proxy_cache_use_stale error timeout updating;
# 请求backend的超时时间,超过则关闭nginx连接
proxy_read_timeout 2s;
# nginx 向客户端发送数据的超时时间,超过则关闭连接
proxy_send_timeout 2s;
# 如果客户端中止连接,nginx 将继续与后端完成数据获取与缓存本地
proxy_ignore_client_abort on;
Edge实现
# vi:syntax=nginx
events {worker_connections 1024;
}error_log stderr;http {resolver 127.0.0.11 ipv6=off;include generic_conf/setup_logging.conf;include generic_conf/lua_path_setup.conf;# 本节点的统计信息,请求时长、status状态等include generic_conf/basic_vts_setup.conf;# 设置缓存交互策略include generic_conf/setup_cache.conf;# 数据后端,即从哪获取数据缓存到 edge 节点upstream backend {server backend:8080;server backend1:8080;keepalive 10; # connection pool}server {listen 8080;location / {# 将参数 cache_key 设置为 uriset_by_lua_block $cache_key {return ngx.var.uri}# access 阶段模拟 edge 节点延时access_by_lua_block {local edge = require "edge"edge.simulate_load()}# 获取实际数据的后端 backend 服务器proxy_pass http://backend;# edge 节点缓存处理策略,根据 cache_key 参数获取缓存include generic_conf/define_cache.conf;add_header X-Edge Server;}# 获取当前节点统计信息的接口include generic_conf/basic_vts_location.conf;}
}
edge节点具体实现了缓存策略,根据请求uri作为缓存key,划定某个文件路径存储实际数据value,使用共享内存记录key和缓存路径的映射,利用nginx实现缓存功能
generic_conf/define_cache.conf 缓存处理策略实现:
# 启用名为 zone_1 的共享缓存区域,来存储和检索缓存键key和实际数据的路径映射
proxy_cache zone_1;
# 设置缓存的键为 cache_key 变量
proxy_cache_key $cache_key;
# 启用缓存锁定。当多个请求同时尝试获取同一资源时,只有一个请求会去后端服务器获取数据,其他请求将等待该请求完成
proxy_cache_lock on;
# 设置与后端服务器的 HTTP 协议版本为 1.1,这通常用于启用持久连接
proxy_http_version 1.1;
# 清空 Connection 头
proxy_set_header Connection "";
# 启用代理缓冲。这意味着 Nginx 会在发送响应给客户端之前,先将后端服务器的响应全部接收并缓冲
proxy_buffering on;
# 设置用于缓冲响应的缓冲区数量和大小
proxy_buffers 16 16k;
# 添加一个参数到Header,表示是否命中缓存、正在更新
add_header X-Cache-Status $upstream_cache_status;
Backend
# vi:syntax=nginx
events {worker_connections 1024;
}error_log stderr;http {include generic_conf/setup_logging.conf;include generic_conf/lua_path_setup.conf;# 本节点的统计信息,请求时长、status状态等include generic_conf/basic_vts_setup.conf;server {listen 8080;location / {# 获取数据,模拟延时并返回数据、过期时间、数据键keycontent_by_lua_block {local backend = require "backend"backend.generate_content()}}# 可通过 /status 接口获取本节点的统计信息include generic_conf/basic_vts_location.conf;}
}
backend.generate_content() 后端节点的具体实现:
local simulations = require "simulations"
local backend = {}backend.generate_content = function()-- 模拟 backend 节点延时simulations.for_work_longtail(simulations.profiles.backend)-- 返回数据头,根据 max_age 参数设置过期时间ngx.header['Content-Type'] = 'application/json'ngx.header['Cache-Control'] = 'public, max-age=' .. (ngx.var.arg_max_age or 10)-- 返回数据,记录了 key,即请求 uringx.say('{"service": "api", "value": 42, "request": "' .. ngx.var.uri .. '"}')
endreturn backend
总结
利用Nginx特性实现简易CDN模型,简明概要了CND各个重要模块的主要功能
相关文章:
基于 Nginx 的 CDN 基础实现
概览 本文是对基于Nginx的CDN网络的学习笔记,阅读的代码为:https://github.com/leandromoreira/cdn-up-and-running 其中,先确定CDN中的一些基础概念: Balancer:负载均衡,即请求数据的流量最开始打到Bal…...
讲人话的理解ai学习原理
通过把各种东西打上分数标签存起来。ai不花算力是不可能的,需要巨大的算力,需要要大量gpu芯片,如果大大降低成本,就需要蒸馏别人成果,把这些参数偷偷弄过来。 比如”猫睡在石头上感觉很凉快,很舒服&#x…...
Spring boot整合quartz方法
目录 1.定时任务 1.quartz说明 2.Quartz提供了不同的数据存储策略以管理作业调度信息: 1.Quartz引入依赖 2.开发定时任务 (1)更新定时任务 (2)停止定时任务 (3)唤醒定时任务 ÿ…...
网站改HTTPS方法
默认的网站建设好后打开的样子那看起来像是钓鱼网站,现在的浏览器特别只能,就是你新买来的电脑默认的浏览器同样也会出现这样“不安全”提示。 传输协议启动了向全球用户安全传输网页内容的流程。然而,随着HTTPS的推出,传输协议通…...
数据中台是什么?:架构演进、业务整合、方向演进
文章目录 1. 引言2. 数据中台的概念与沿革2.1 概念定义2.2 历史沿革 3. 数据中台的架构组成与关键技术要素解析3.1 架构组成3.2 关键技术要素 4. 数据中台与其他平台的对比详细解析 5. 综合案例:金融行业数据中台落地实践5.1 背景5.2 解决方案5.3 成果与价值 6. 方向…...
Java Stream API:高效数据处理的利器引言
Java Stream API:高效数据处理的利器引言 在 Java 编程中,数据处理是一项极为常见且关键的任务。传统的 for 循环在处理数据集合时,往往会导致代码变得冗长、复杂,这不仅增加了代码的编写难度,还降低了代码的可读性和…...
qml之Text 组件显示当前时间
在 QML 中,显示时间的常用组件是 Text,结合 JavaScript 时间函数或者 Qt 的时间模块来实现动态时间显示。虽然 QML 没有专门用于显示时间的组件,但可以通过 Text 来显示格式化后的时间信息。 1. 使用 Text 组件显示当前时间 示例代码: import QtQuick 2.15 import QtQui…...
两栏布局、三栏布局、水平垂直居中
文章目录 1 两栏布局1.1 浮动 margin1.2 浮动 BFC1.3 flex布局1.4 左绝父相 margin1.5 右绝父相 方向定位 2 三栏布局2.1 子绝父相 margin2.2 flex布局2.3 浮动 margin2.4 圣杯布局2.5 双飞翼布局 3 水平垂直居中3.1 绝对定位 translate3.2 绝对定位 margin3.3 绝对定位…...
Hanoi ( 2022 ICPC Southeastern Europe Regional Contest )
Hanoi ( 2022 ICPC Southeastern Europe Regional Contest ) The original problem “Towers of Hanoi” is about moving n n n circular disks of distinct sizes between 3 3 3 rods. In one move, the player can move only the top disk from on…...
Matplotlib基础01( 基本绘图函数/多图布局/图形嵌套/绘图属性)
Matplotlib基础 Matplotlib是一个用于绘制静态、动态和交互式图表的Python库,广泛应用于数据可视化领域。它是Python中最常用的绘图库之一,提供了多种功能,可以生成高质量的图表。 Matplotlib是数据分析、机器学习等领域数据可视化的重要工…...
SMU寒假训练第二周周报
训练情况 本周是第二周,训练情况比第一周好一点点,也仅仅是好一点点,经过春节以及后遗症,牛客更是打的稀烂,还不如去年,都不知道自己在干嘛,训练赛情况也非常糟糕,还要去搞社会实践…...
解锁全新视界:一键畅享 360 度全景图与多格式转换
软件介绍 各位朋友,大家好!今天要给大家引荐一款超实用的全景图转换“神器”——Pano2VR Pro 的最新版本。在当今这个追求极致视觉体验的时代,它宛如一把神奇的钥匙,能够解锁全新的视觉领域,将平平无奇的不同角度图像…...
python:面向对象案例烤鸡翅
自助烤鸡翅的需求: 1.烤鸡翅的时间和对应的状态: 0-4min :生的 4-7min:半生不熟 7-12min:熟了 12min以上:烤糊了 2.添加调料: 客户根据自己的需求添加 定义烤鸡翅的类、属性和方法,显示对象的信息 …...
游戏外挂原理解析:逆向分析与DLL注入实战(植物大战僵尸
目录 1.前言2.外挂类型3.前置知识4.CE查找基质4.1 逐步分析4.2 暴力搜索5.实现数值外挂6.dll导入表注入7.实现行为外挂(无敌类型)8.源码下载与外挂进阶本篇原文为:游戏外挂原理解析:逆向分析与DLL注入实战(植物大战僵尸)。 更多C++进阶、rust、python、逆向等等教程,可…...
【10.10】队列-设计自助结算系统
一、题目 请设计一个自助结账系统,该系统需要通过一个队列来模拟顾客通过购物车的结算过程,需要实现的功能有: get_max():获取结算商品中的最高价格,如果队列为空,则返回 -1add(value):将价格为…...
android的ViewModel和LiveData 简介
ViewModel ViewModel 的优势 ViewModel 的替代方案是保存要在界面中显示的数据的普通类。在 activity 或 Navigation 目的地之间导航时,这可能会造成问题。此时,如果您不利用保存实例状态机制存储相应数据,系统便会销毁相应数据。ViewModel…...
Linux系统之free命令的基本使用
Linux系统之free命令的基本使用 一、free命令介绍二、free命令的使用帮助2.1 free命令的帮助信息2.2 free命令帮助解释 三、free命令的基本使用3.1 显示内存使用情况3.2 新增总计条目3.3 显示内存详细信息 四、注意事项 一、free命令介绍 free 命令是 Linux 系统中用于显示系统…...
大模型赋能网络安全整体应用流程概述
一、四个阶段概述 安全大模型的应用大致可以分为四个阶段: 阶段一主要基于开源基础模型训练安全垂直领域的模型; 阶段二主要基于阶段一训练出来的安全大模型开展推理优化、蒸馏等工序,从而打造出不同安全场景的专家模型,比如数据安全领域、安全运营领域、调用邮件识别领…...
SpringCloud - Nacos注册/配置中心
前言 该博客为Nacos学习笔记,主要目的是为了帮助后期快速复习使用 学习视频:7小快速通关SpringCloud 辅助文档:SpringCloud快速通关 一、简介 Nacos官网:https://nacos.io/docs/next/quickstart/quick-start/ Nacos /nɑ:kəʊ…...
面试准备——Java理论高级【笔试,面试的核心重点】
集合框架 Java集合框架是面试中的重中之重,尤其是对List、Set、Map的实现类及其底层原理的考察。 1. List ArrayList: 底层是动态数组,支持随机访问(通过索引),时间复杂度为O(1)。插入和删除元素时&#…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...
cf2117E
原题链接:https://codeforces.com/contest/2117/problem/E 题目背景: 给定两个数组a,b,可以执行多次以下操作:选择 i (1 < i < n - 1),并设置 或,也可以在执行上述操作前执行一次删除任意 和 。求…...
如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
OD 算法题 B卷【正整数到Excel编号之间的转换】
文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的:a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...
安卓基础(Java 和 Gradle 版本)
1. 设置项目的 JDK 版本 方法1:通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分,设置 Gradle JDK 方法2:通过 Settings File → Settings... (或 CtrlAltS)…...
Java数组Arrays操作全攻略
Arrays类的概述 Java中的Arrays类位于java.util包中,提供了一系列静态方法用于操作数组(如排序、搜索、填充、比较等)。这些方法适用于基本类型数组和对象数组。 常用成员方法及代码示例 排序(sort) 对数组进行升序…...
数据分析六部曲?
引言 上一章我们说到了数据分析六部曲,何谓六部曲呢? 其实啊,数据分析没那么难,只要掌握了下面这六个步骤,也就是数据分析六部曲,就算你是个啥都不懂的小白,也能慢慢上手做数据分析啦。 第一…...
深度解析:etcd 在 Milvus 向量数据库中的关键作用
目录 🚀 深度解析:etcd 在 Milvus 向量数据库中的关键作用 💡 什么是 etcd? 🧠 Milvus 架构简介 📦 etcd 在 Milvus 中的核心作用 🔧 实际工作流程示意 ⚠️ 如果 etcd 出现问题会怎样&am…...
Copilot for Xcode (iOS的 AI辅助编程)
Copilot for Xcode 简介Copilot下载与安装 体验环境要求下载最新的安装包安装登录系统权限设置 AI辅助编程生成注释代码补全简单需求代码生成辅助编程行间代码生成注释联想 代码生成 总结 简介 尝试使用了Copilot,它能根据上下文补全代码,快速生成常用…...
