PHP实战开发25-电商网站系统缓存设计方案系统讲述

news2025/2/23 22:37:20

文章目录

  • 一、前言-缓存的作用
    • 1.1 提高性能
    • 1.2 减轻服务端压力
    • 1.3 减少网络流量
    • 1.4 改善用户体验
    • 1.5 支持离线访问
    • 1.6 降低数据传输成本
  • 二、浏览器缓存
    • 2.1 强缓存
    • 2.2 协商缓存
  • 三、CDN 缓存
    • 3.1 使用CDN缓存的好处
      • 3.1.1 加速网站加载时间
      • 3.1.2 节省服务器带宽
      • 3.1.3 提高可用性和可靠性
    • 3.2 使用CDN的场景
  • 四、Nginx缓存
    • 4.1 关于Nginx缓存
    • 4.2 关于配置和使用Nginx缓存
      • 4.2.1 配置缓存路径
      • 4.2.1 开启缓存
  • 五、接口缓存
    • 5.1 关于接口缓存
    • 5.2 使用接口缓存
  • 六、数据库缓存
    • 6.1 Memcached
    • 6.2 Redis
  • 七、内存及全局变量缓存
    • 7.1 内存缓存
    • 7.2 全局变量缓存
  • 八、总结


一、前言-缓存的作用

本文已收录于PHP全栈系列专栏:PHP快速入门与实战

Web 开发中常见的缓存有浏览器缓存、CDN 缓存、数据库缓存和应用程序缓存。每种缓存都有各自的优化方法,以提高 Web 应用的性能和用户体验。缓存在我们系统设计中起到了举足轻重的作用。利用好缓存设计既能够提升我们的网站访问速度,也能够提升开发人员的技术水平。

在这里插入图片描述
缓存在web应用中起到以下几个作用:

1.1 提高性能

缓存可以减少对数据库或其他资源的频繁访问,从而加快响应时间和提高系统的吞吐量。

1.2 减轻服务端压力

通过缓存静态内容(如HTML、CSS、JavaScript文件),可以减少服务器的负载,提高应用的可扩展性和稳定性。

1.3 减少网络流量

通过缓存页面或资源,可以减少重复请求和响应,从而减小网络带宽的使用。

1.4 改善用户体验

缓存可以使用户更快地加载页面或资源,提供更好的使用体验,尤其是在低网络速度或高延迟的情况下。

1.5 支持离线访问

将页面或资源缓存在本地,用户可以在没有网络连接的情况下访问已缓存的内容。

1.6 降低数据传输成本

通过缓存常用的数据或结果,可以减少数据传输的成本,尤其是在跨地区或跨网络边界的场景中。

今天本文就来详细讲解在一些流量较大的网站用,缓存是如何使用的,主要有下面一些缓存的设计。

二、浏览器缓存

浏览器缓存是指在用户访问网站后,浏览器会将一些静态资源(如图片、CSS、JavaScript
文件)保存在本地,在下次访问该网站时直接从本地加载,而不是再次向服务器请求。这样可以减少网络传输,提高加载速度。
可以通过 Expires、Cache-Control、ETag 和 Last-Modified 等来控制缓存的有效期和验证机制。同时,对于动态内容,可以使用版本号或摘要进行更新。

当用户访问一个网页时,浏览器会检查该页面的缓存是否存在,如果存在并且未过期,则直接从缓存中加载资源,而不是重新下载。浏览器缓存有两种类型:强缓存协商缓存

2.1 强缓存

当用户第一次访问网页时,服务器会返回一个响应头字段"Cache-Control""Expires",用来指示该资源在多长时间内可以被缓存。之后,用户再次访问该资源时,浏览器会根据此信息判断是否使用缓存。例如,响应头中包含"Cache-Control:max-age=3600"表示该资源可以在一小时内被缓存。

2.2 协商缓存

如果资源的缓存已过期或无效,浏览器会向服务器发送一个请求,服务器会返回一个响应头字段"Last-Modified"和一个唯一的标识符。之后,用户再次访问资源时,浏览器会发送一个请求头字段"If-Modified-Since",将上次获取资源时的"Last-Modified"值传递给服务器。如果资源未发生变化,服务器会返回一个状态码"304 Not Modified",浏览器则从缓存中加载资源;否则,服务器会返回更新的资源。

下面举一个例子来说明如何使用浏览器缓存:

  • 用户第一次访问一个网站的首页时,服务器返回以下响应头:
   Cache-Control:max-age=3600

此时,浏览器会将该网页的HTML、CSS和JavaScript文件等缓存一小时。

  • 用户再次访问该网站的首页时,浏览器会检查缓存是否过期。如果在一小时内,浏览器会从缓存中加载资源,提升加载速度。

  • 如果用户点击了网页中的链接,访问了其他页面。当用户返回到首页时,浏览器会直接从缓存中加载资源,而不需要重新下载。

  • 如果用户在一小时后再次访问首页,此时缓存已过期,浏览器会向服务器发送请求,服务器返回新的首页资源并更新缓存。

通过使用浏览器缓存,可以节省带宽,加快网页加载速度,并提供更好的用户体验。

三、CDN 缓存

CDN(Content Delivery Network)缓存是一种网络技术,用于加速访问网站或应用程序的内容。它通过将静态内容(如图片CSSJavaScript文件)缓存在位于全球各地的服务器上,从而使用户能够更快地获取到这些内容。

在这里插入图片描述

3.1 使用CDN缓存的好处

3.1.1 加速网站加载时间

当用户请求内容时,CDN会根据用户的地理位置将内容传输到离用户最近的服务器,减少了网络延迟,从而提高网站加载速度。

3.1.2 节省服务器带宽

CDN服务器可以缓存并服务大部分静态内容,这样可以减轻源服务器的负载,节省服务器带宽,提高整体性能。

3.1.3 提高可用性和可靠性

CDN通常具有冗余架构,即使某个服务器出现故障,其他服务器仍然能够提供内容。

3.2 使用CDN的场景

假设你拥有一个电子商务网站,在全球范围内有许多用户。你的网站包含大量的产品图片。使用CDN缓存,你可以将这些图片上传到CDN服务器上,并配置CDN,使其根据用户的地理位置提供这些图片。

当用户访问你的网站时,他们的浏览器会从CDN服务器中获取图片,而不是从源服务器。由于CDN服务器通常位于用户附近,所以图片可以更快地加载到用户的设备上,提供更好的用户体验。

另外,由于图片已经缓存在CDN服务器上,当其他用户也需要相同的图片时,CDN服务器可以直接提供,而不必再次从源服务器获取,从而减少了源服务器的压力和带宽消耗。

CDN缓存通过在全球范围内分布服务器并缓存静态内容,提供了更快速、可靠和高效的内容交付方式。这对于大型网站、电子商务平台和流媒体服务等特别有用。

四、Nginx缓存

4.1 关于Nginx缓存

Nginx缓存是一种功能强大的工具,能够帮助提高网站的性能和响应速度。它通过在服务器和客户端之间保存已经访问过的页面、图片、文件等内容,以便在下次访问时快速地响应请求,而无需再次从源服务器获取数据。

在这里插入图片描述

使用Nginx缓存可以减少对源服务器的请求,减轻其负载,提高网站的并发能力。另外,缓存还能有效地减少网络流量,并且对于移动设备和慢网络连接的用户来说,使用缓存可以显著提升页面加载速度和用户体验。

4.2 关于配置和使用Nginx缓存

下面是一个简单的示例,说明如何在Nginx中配置和使用缓存:

4.2.1 配置缓存路径

在Nginx的配置文件中,添加以下代码配置缓存路径和相关选项:

http {
	...
	   proxy_cache_path /path/to/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;
    ...
}
  • /path/to/cache 是缓存路径,这里可以根据需要指定一个合适的目录。
  • levels=1:2 指定缓存路径的层级结构。
  • keys_zone=my_cache:10m 定义了缓存区域的名称和内存大小。
  • max_size=10g 指定缓存的最大大小。
  • inactive=60m 设置缓存文件在指定时间内未被访问时将被删除。
  • use_temp_path=off 禁用使用临时路径。

4.2.1 开启缓存

在需要开启缓存的地方,例如反向代理服务器或者静态文件服务器的配置中,添加以下代码:

location / {
  ...
  proxy_cache my_cache;
  proxy_cache_valid 200 302 10m;
  proxy_cache_valid 404 1m;
  ...
}
  • proxy_cache my_cache; 启用缓存,将请求结果保存到名为 my_cache 的缓存区域中。
  • proxy_cache_valid 200 302 10m; 设置当响应状态码为200或302时缓存的有效期为10分钟。
  • proxy_cache_valid 404 1m; 设置当响应状态码为404时缓存的有效期为1分钟。

通过以上配置,Nginx将会根据请求的URL和相关选项来查找和提供缓存内容。如果缓存中存在对应的内容,则直接返回给客户端;否则,Nginx将从源服务器获取内容,并将其存储在缓存中供下次使用。

通过合理地配置Nginx缓存,你可以显著提高网站的性能和用户体验。

五、接口缓存

5.1 关于接口缓存

接口缓存是指将接口的响应数据缓存起来,以便在后续请求同一个接口时可以直接从缓存中获取数据,而不必再次向后端发起请求。这样可以提高接口的响应速度和降低后端服务器的负载。
在这里插入图片描述

5.2 使用接口缓存

在PHP中,可以通过以下步骤实现一个简单的文件接口缓存:

  • 定义一个用于判断缓存是否过期的时间阈值,例如5分钟:
$cacheExpiration = 300; // 5 minutes in seconds
  • 在调用接口之前,先检查缓存文件是否存在以及是否过期:
$cacheFile = 'cache/api_response.cache'; // 缓存文件路径
if (file_exists($cacheFile) && time() - filemtime($cacheFile) < $cacheExpiration) {
    // 从缓存文件中读取数据
    $response = file_get_contents($cacheFile);
} else {
    // 发起请求获取数据
    $response = makeApiRequest();

    // 将数据保存到缓存文件
    file_put_contents($cacheFile, $response);
}
  • 缓存文件的名称可以根据接口的URL进行哈希或其他处理生成,以确保每个接口都有唯一的缓存文件。

这只是一个简单的文件接口缓存的实现示例,实际应用中还需要考虑缓存的管理、更新策略、缓存失效的处理等问题。另外,接口缓存对于一些需要即时更新的数据,如用户信息等,并不适用。因此,在实际应用中需要根据具体场景进行综合考虑和使用。

六、数据库缓存

Web数据缓存是一种常用的优化技术,它可以减少数据库查询和网络请求,提高网站的响应速度。在Web开发中,可以使用各种工具和技术来实现数据缓存。

在这里插入图片描述

6.1 Memcached

Memcached是一个内存对象缓存系统,它可以将数据存储在内存中,以提高访问速度。使用Memcached扩展库,可以通过简单的键值对操作来存储和获取数据。

$memcached = new Memcached();
$memcached->addServer('localhost', 11211);

$data = $memcached->get('data'); // 从缓存中获取数据
if(empty($data)) {
   // 如果缓存数据为空,从数据库查询数据并写入缓存
   $data = fetchDataFromDB();
   $memcached->set('data', $data);
}

// 使用缓存数据进行操作

6.2 Redis

Redis是一个基于内存的键值对存储系统,类似于Memcached,但提供了更丰富的数据结构和功能。使用Redis扩展库可以方便地进行缓存操作。

$redis = new Redis();
$redis->connect('localhost', 6379);

$data = $redis->get('data'); // 从缓存中获取数据
if(empty($data)) {
   // 如果缓存数据为空,从数据库查询数据并写入缓存
   $data = fetchDataFromDB();
   $redis->set('data', $data);
}

// 使用缓存数据进行操作

七、内存及全局变量缓存

在PHP中,内存和全局变量缓存是两种不同的概念。

7.1 内存缓存

PHP中的内存缓存是通过使用内存来存储数据以提高读取和操作数据的速度。这可以通过使用一些扩展库(如Memcached、Redis等)或者PHP自带的函数(如apcu、shmop等)来实现。

下面是一个使用APCu扩展库来实现内存缓存的示例代码:

// 存储数据到内存缓存中
apcu_store('key', 'value');

// 从内存缓存中读取数据
$data = apcu_fetch('key');
if ($data === false) {
    // 缓存中不存在数据,需要重新获取数据并存储到缓存中
    $data = getDataFromDatabase();
    apcu_store('key', $data);
}

// 删除内存缓存中的数据
apcu_delete('key');

7.2 全局变量缓存

全局变量缓存是指将经常使用的数据存储在全局变量中,以减少对数据库或其他外部资源的访问次数,提高程序的性能。

下面是一个使用全局变量缓存的示例代码:

// 定义一个全局变量,并初始化为null
global $cachedData;
$cachedData = null;

function getData() {
    // 判断全局变量是否已缓存数据
    global $cachedData;
    if ($cachedData !== null) {
        return $cachedData;
    }
    
    // 从数据库中获取数据
    $data = getDataFromDatabase();
    
    // 将数据存储到全局变量中
    global $cachedData;
    $cachedData = $data;
    
    return $data;
}

// 使用缓存的数据
$data = getData();

在上述代码中,全局变量$cachedData被用来缓存数据,当需要获取数据时,首先检查全局变量是否已经缓存了数据。如果是,则直接返回缓存的数据;否则,从数据库中获取数据并存储到全局变量中,以供后续使用。

需要注意的是,在使用全局变量缓存时,需要注意并发访问的问题,例如使用互斥锁(如flock()函数)来避免多个进程同时修改全局变量。此外,也需要注意及时更新缓存的数据,以保证数据的准确性。

八、总结

本文系统的讲述了在大流量如电商网站中,缓存的一些分类及如何应用的,但是再实际的项目过程中,面临的业务问题可能更加复杂,技术挑战更大,需要我们不断学习,总结经验,把这些缓存技术用好。

本文已收录于PHP全栈系列专栏:PHP快速入门与实战 很多精彩内容收录其中,欢迎大家关注。

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

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

相关文章

快速计算多项式相乘系数 FFT快速傅里叶变换

快速计算多项式相乘系数 FFT快速傅里叶变换 快速傅里叶变换(FFT)——有史以来最巧妙的算法&#xff1f; 正常求两个多项式乘积 A ( x ) ∑ i 0 n A i x i , B ( x ) ∑ i 0 n B i x i C ( x ) ∑ i 0 n ∑ j 0 n A i B j x i j A(x)\sum_{i0}^{n}{A_ix^i},B(x)\sum_{…

Java多线程基础-11:工厂模式及代码案例之线程池

在Java中&#xff0c;xx池的概念是很常见的&#xff0c;比如之前遇到过的常量池、数据库连接池等等。 线程池是一种常用的多线程处理方式&#xff0c;它可以重复利用已创建的线程&#xff0c;从而减少线程的创建和销毁开销&#xff0c;并提高程序的性能。 通俗来说&#xff…

【Windows】Redis集群部署

集群是如何进行工作的 Redis采用哈希槽来处理数据与节点之间的映射关系&#xff0c;一个集群共有16384 个哈希槽&#xff0c;每个key通过 CRC16算法计算出一个16bit的值&#xff0c;再对16384取模&#xff0c;得到对应的哈希槽&#xff0c;集群通过维护哈希槽与节点的关系来得…

flutter聊天界面-Text富文本表情emoji、url、号码展示

flutter聊天界面-Text富文本表情emoji、url、号码展示 Text富文本表情emoji展示&#xff0c;主要通过实现Text.rich展示文本、emoji、自定义表情、URL等 一、Text及TextSpan Text用于显示简单样式文本 TextSpan它代表文本的一个“片段”&#xff0c;不同“片段”可按照不同的…

Verilog学习笔记2:反相器

代码&#xff1a; //反相器 timescale 1ns/10ps module inv( A,y); input A; output y; assign y~A; endmodule //testbench module inv_tb;reg A; wire YY;inv inv(.A(A),.y(YY));initial beginA<0;#10 A<1;#10 A<0; #10 A<1;#10 A<0; #10 A<1;#10 A<0;…

从小白到大神之路之学习运维第54天--------ELK日志收集分析

第三阶段基础 时 间&#xff1a;2023年7月6日 地 点&#xff1a;2304教室 授课人&#xff1a;李凤海 参加人&#xff1a;全班人员 内 容&#xff1a; ELK技术堆栈 目录 服务器设置&#xff1a; 部署elasticsearch集群&#xff1a; 配置elasticsearch集群&#xff…

怎样寻找SEO服务商,需要注意那些问题?

网上提供SEO服务的公司或个人多如牛毛&#xff0c;随便在搜索引擎上搜索一下&#xff0c;成千上万的公司就在眼前。大部分网站设计公司也兼职SEO服务&#xff0c;寻找合适的SEO服务商并不简单&#xff0c;鉴别合格的SEO服务商是关键。 1、确定外包任务 如果没有SEO团队&…

C++类相关概念

1. 函数形参默认值 &#xff08;1&#xff09; 建议函数&#xff08;不仅仅是构造函数&#xff09;形参默认值只在函数声明中指定&#xff1b; &#xff08;函数声明和定义写在同一个文件中&#xff0c;则函数声明、定义两者之一或两者都可指定形参默认值&#xff0c;两者都指定…

mybati执行流程源码分析

MyBatis执行流程源码分析 前言 由于之前写过关于mybatis源码的文章,但是感觉还是不够细致,不够完善.没有把一些具体的流程应用写下来,至此又写了一篇.内容可能比较长,希望大家可以打开源码跟着这篇文章一起看源码保证可以收获许多. 1.mybatis基础开发流程 1.引入mybatis相关…

短视频去水印小帮手微信小程序源码带后台

短视频去水印小帮手微信​小程序源码​带后台&#xff0c;短视频去水印系列教程服务端源码。 php版&#xff0c;这里不过多介绍&#xff0c;我假设您有基本的编码基础&#xff0c;并熟悉php语言及laravel框架。

Topaz Gigapixel AI v6 人工智能图像放大

其他软件或插件依赖于插值算法来放大图像&#xff0c;Topaz Gigapixel AI 则与众不同&#xff0c;它使用最先进的深度学习技术来扩大和增强图像。 它通过神经网络分析了数百万张照片&#xff0c;从而了解了不同的照片在放大时细节是如何损失的&#xff0c;以及如何为图像增强和…

四十三、贪心——Huffman树、排序不等式

算法主要内容 一、Huffman树1、题目内容——合并果子2、算法思路&#xff08;1&#xff09;“合并果子”中的Huffman树&#xff08;2&#xff09;算法步骤&#xff08;3&#xff09;状态转移 3、题解 二、排序不等式1、题目内容——排队打水2、算法思路&#xff08;1&#xff0…

【MySQL】数据库基础概念

文章目录 前言连接服务器什么是数据库&#xff1f;MySQL和MySQLdLinux中如何看到数据库文件SQL语句分类存储引擎 前言 今天继续讲解MySQL相关内容&#xff0c;本期主要讲解数据库的基础概念&#xff0c;方便后续学习数据库。 连接服务器 mysql -h [ip] -P [port] -u [root] …

IRIS在Linux下通过JDBC操作其他数据库

以前都是在Windows上用cache的SqlGateway通过odbc创建连接操作其他数据库。现在都用Linux了&#xff0c;那么和其他数据进行调用咋办呢。 可以看到是可以创建JDBC的连接的&#xff0c;而Java是跨平台的&#xff0c;所以可以用JDBC操作其他数据库&#xff0c;这次以mysql为例。…

浅谈Node.js中的npm和yarn

官方文档&#xff1a; npmhttps://www.npmjs.cn/ yarnhttps://yarn.bootcss.com/ npm和yarn的作用 yarn和npm都是构建和打包javascript代码的工具 区别 npm&#xff1a; 1npm使得js开发者易于分享其为解决特定问题而编写的代码&#xff0c;且可供其他开发者在他们自己的应…

【阶段学习小总结】

串口通信和CAN总线通信的区别 can总线和串口是两种不同的通信模式&#xff0c;注意CAN总线数据传输所用的虽然是DB9串口线&#xff0c;但它完全不是串口&#xff0c;这一点容易出错。 CAN总线通信是高速&#xff0c;可靠&#xff0c;灵活的一种通信协议。作为一种分布式通信方…

天梯赛注意事项

格式错误 有的时候题目隐含的条件是要你输出两行的&#xff0c;即使第二行什么也没有&#xff0c;也得输出。 答案错误可能涉及特殊值的处理 或者 题意与你本身的思维不一致 map定义在main外面 键自动赋值 it->first it->second mp自动按照下标排序 . 模拟出栈入栈操…

使用GTK创建简易计算器

使用GTK创建简易计算器 本文将介绍如何使用GTK&#xff08;GIMP Toolkit&#xff09;创建一个简单的计算器应用程序。通过这个例子&#xff0c;你将学习如何构建基本的图形用户界面&#xff0c;并了解GTK的一些常用组件和回调函数的使用。 准备工作 首先&#xff0c;确保你已…

Django之中间件

一、中间件介绍 官方的说法&#xff1a;中间件是一个用来处理Django的请求和响应的框架级别的钩子。它是一个轻量、低级别的插件系统&#xff0c;用于在全局范围内改变Django的输入和输出。每个中间件组件都负责做一些特定的功能。 但是由于其影响的是全局&#xff0c;所以需要…

Vivado2020.1 vitis使用:创建hello world项目

前言 之前网上的教程都是基于Vivado2018的&#xff0c;后来接手一个未完工的项目&#xff0c;是使用Vivado2020.1创建的&#xff0c;非常尴尬&#xff0c;只能打开&#xff0c;不能编辑。千辛万苦把2020.1安装好&#xff0c;当然此时不仅仅是Vivado2020.1了&#xff0c;而是vi…