nginx反向代理缓存

news2024/11/18 0:44:25

背景

nginx 一般用来做反向代理和负载均衡,将客户端请求发送到后端的 jetty,并将 jetty 的响应发送给客户端。后端的 jetty 通常不止一个,nginx 根据配置来选择其中一个 jetty,比较常见的选择策略是轮询。示意图如下

启动缓存支持以后,nginx 在将请求转发到 jetty 之前会在缓存里查找结果,如果缓存里存在匹配客户端请求的结果,则直接返回给客户端,不会将请求发送给 jetty;如果缓存没有命中,才会将请求发送给 jetty,接收到 jetty 返回的结果后,会将结果进行缓存以备客户端下次的请求。示意图如下:
在这里插入图片描述

缓存命中

在这里插入图片描述

缓存未命中

在这里插入图片描述

最简单的缓存设置

web 程序

首先我们有个简单的 web 程序,返回当前时间,如下

@Controller
public class TestController {

    @ResponseBody
    @RequestMapping("time.do")
    public Map<String, Long> time() {
        Map<String, Long> map = new HashMap<String, Long>();
        map.put("time", System.currentTimeMillis());
        return map;
    }
}

这个接口会返回当前时间,精确到毫秒,正常情况下每次刷新返回的值都应该是不一样的

nginx 配置

现在配置 nginx 的缓存,首先在 http 小节添加如下配置

http {
    ...

    # 设置缓存的路径和其他参数
    # proxy_cache_path path [levels=levels] keys_zone=name:size [inactive=time] [max_size=size] [loader_files=number] [loader_sleep=time] [loader_threshold=time];
    # 缓存路径 /data/nginx/cache 缓存结构为 2 层,即该路径下会有 2 层子目录,缓存文件会保存在最下层子目录
    # 缓存的 key 会保存在名为 web_cache 的内存区域,该内存区域大小为 50 m
    # 10 分钟内缓存没有被访问就会过期
    # 缓存文件最多占用 1g 空间
    proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=web_cache:50m inactive=10m max_size=1g;

    # proxy_cache_path 指令必须在 include 指令之前
    include vhosts/*.conf;

    ...
}

接下来在 server 小节 的 location / 小节添加如下配置

location / {
    proxy_store off;
    proxy_redirect off;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $http_host;
    proxy_pass http://my-server/;

    # 缓存使用前面定义的内存区域
    proxy_cache web_cache;
    # 这个貌似没啥用
    proxy_ignore_headers   Expires Set-Cookie;
    # 对于 200 和 304 的响应码进行缓存,过期时间为 2 分钟,这会覆盖前面定义的 10 分钟过期时间
    proxy_cache_valid 200 304 2m;
    # 设置缓存的 key,这里用到了 nginx 的内嵌变量,表示用整个 url 作 key
    proxy_cache_key  $scheme$proxy_host$request_uri;
    # 在返回的响应里添加响应头 X-Proxy-Cache,其值表示是否命中了缓存,貌似没啥用
    add_header X-Proxy-Cache $upstream_cache_status;
    # 返回的响应头里,设置过期时间为 10 分,貌似没啥用
    expires 10m;
    # 貌似没啥用
    add_header Access-Control-Allow-Origin "http://myserver.net";
    # 貌似没啥用
    add_header Access-Control-Allow-Credentials true;

}

缓存特定的参数

有的参数每个客户端都不一样,而且该参数的值并不影响返回的结果,如果我们用整个 url 作为缓存的 key,那么 key 的数量就太多了,导致缓存的命中率非常低。
例如,用户手机的 imei 是唯一的,如果 key 包括了 imei,那就会导致每个用户都有一个缓存,这显然不是我们需要的
那么,能不能把某些参数排除在 key 之外呢?答案是肯定滴,看看下面这个 web 程序

@ResponseBody
@RequestMapping("/test/user.do")
public Map<String, String> user(String imei, String sn, String phone, String name) {
    Map<String, String> map = new HashMap<String, String>();
    map.put("imei", imei);
    map.put("sn", sn);
    map.put("phone", phone);
    map.put("name", name);
    return map;
}

只用 phone 和 name 参数来构造缓存的 key,可以如下配置

location / {
    proxy_store off;
    proxy_redirect off;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $http_host;
    proxy_pass http://my-server/;

    # 缓存使用前面定义的内存区域
    proxy_cache web_cache;
    # 对于 200 和 304 的响应码进行缓存,过期时间为 2 分钟,这会覆盖前面定义的 10 分钟过期时间
    proxy_cache_valid 200 304 2m;
    # 设置缓存的 key,只用 phone 和 name 构造 key
    proxy_cache_key  $host$uri$is_args$arg_phone&$arg_name;

}

这次把貌似没用的配置都移除了,要指定某些参数来构造缓存的 key,关键是以下的内嵌变量

  • $is_args
  • $arg_{name}

缓存特定的接口

有时候不是所有接口都需要被 nginx 缓存,或者缓存的 key 采用不同的规则,可以通过不同的 location 来配置
例如,下面的配置就只对以 /test/ 开头的接口做缓存

location / {
    proxy_store off;
    proxy_redirect off;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $http_host;
    proxy_pass http://my-server/;

    # 不缓存 proxy_cache 默认值就是 off,所以也可以省略这一行
    proxy_cache off
}
location /test/ {
    proxy_store off;
    proxy_redirect off;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $http_host;
    proxy_pass http://my-server/test/;

    # 缓存使用前面定义的内存区域
    proxy_cache web_cache;
    # 对于 200 和 304 的响应码进行缓存,过期时间为 2 分钟,这会覆盖前面定义的 10 分钟过期时间
    proxy_cache_valid 200 304 2m;
    # 设置缓存的 key,只用 phone 和 name 构造 key
    proxy_cache_key  $host$uri$is_args$arg_phone&$arg_name;

}

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

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

相关文章

oracle19c介绍和安装

目录 一、版本 &#xff08;1&#xff09;历史 &#xff08;2&#xff09;11g和12c管理方式区别 11g 12C &#xff08;3&#xff09;各个版本对操作系统要求 二、分类 &#xff08;1&#xff09;分为桌面类和服务器类 &#xff08;2&#xff09;分为企业版和标准版 三…

基于遗传算法的BP神经网络优化算法(matlab实现)

1 理论基础 1.1 BP神经网络概述 BP网络是一类多层的前馈神经网络。它的名字源于在网络训练的过程中&#xff0c;调整网络的权值的算法是误差的反向传播的学习算法&#xff0c;即为BP学习算法。BP算法是Rumelhart等人在1986年提出来的。由于它的结构简单&#xff0c;可调整的…

个人网站实现微信扫码登录

⭐个人网站实现微信扫码登录 &#x1f948;效果图 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kzSrNgiv-1685034480658)(https://img.ggball.top/picGo/动画.gif)] &#x1f4d7;开发背景 为什么想用微信扫码登录呢&#xff1f; 起因是自己开发…

【CH32】| 02——常用外设 | GPIO

系列文章目录 【CH32】| 00——开发环境搭建 【CH32】| 01——新建工程 | 下载 | 运行 |调试 【CH32】| 02——常用外设 | GPIO 失败了也挺可爱&#xff0c;成功了就超帅。 文章目录 前言1. GPIO简介2. IO口的内部结构框图保护二极管上下拉电阻施密特触发器两个MOS管输出寄存器…

chatgpt赋能python:Python加速循环的执行方法详解

Python 加速循环的执行方法详解 Python是一门非常流行的编程语言&#xff0c;它可以在很多领域应用&#xff0c;比如Web开发、数据分析、机器学习等等。然而&#xff0c;Python执行速度较慢&#xff0c;特别是在循环语句中&#xff0c;代码执行效率会大打折扣。在本文中&#…

【基于ROS Melodic环境安装rosserial arduino】

【基于ROS Melodic环境安装rosserial arduino】 1. 简介2. 安装2.1 Ubuntu下的Arduino IDE安装2.2 Ubuntu下rosserial arduino软件安装2.3 安装ros_lib到Arduino IDE开发环境 3. 将ros_lib配置到 Arduino 环境库中4. 使用helloword5. 实验验证6.总结 1. 简介 这个教程展示如何…

Linux系统初始化命令的备忘单,Linux运维工程师收藏!

在管理和维护Linux系统时&#xff0c;有一些常用的命令可以帮助您进行系统初始化和配置。这些命令涵盖了各种任务&#xff0c;包括系统设置、用户管理、软件安装和网络配置等。 本文将为您提供一个Linux系统初始化命令的备忘单&#xff0c;以便在需要时方便查阅和使用。 系统设…

chatgpt赋能python:Python动画制作指南:从入门到精通

Python动画制作指南&#xff1a;从入门到精通 Python作为一种易学易用的编程语言&#xff0c;在数据分析、机器学习等领域已经得到广泛应用。但是你知道吗&#xff1f;Python还可以用来制作动画&#xff01;本文将为你介绍如何用Python制作动画&#xff0c;从入门到精通&#…

chatgpt赋能python:Python写计算器:从入门到精通

Python写计算器&#xff1a;从入门到精通 简介 计算器无疑是计算机编程中最基本且实用的工具之一。Python 作为一门易于学习且功能强大的编程语言&#xff0c;能够轻松实现计算器的功能。在本文中&#xff0c;我们将介绍如何使用 Python 编写一个简单的计算器。 如何实现&am…

chatgpt赋能python:Python的封装:提高代码的可维护性和可复用性

Python的封装&#xff1a;提高代码的可维护性和可复用性 在软件开发领域中&#xff0c;封装是一种重要的概念。它被用于隐藏程序的实现细节&#xff0c;使得程序的功能变得更加易于使用和维护。在Python编程中&#xff0c;封装是一种被广泛使用的技术&#xff0c;可以帮助你提…

Linux 信号知识点总结

对于 Linux来说&#xff0c;实际信号是软中断&#xff0c;许多重要的程序都需要处理信号。信号&#xff0c;为 Linux提供了一种处理异步事件的方法。比如&#xff0c;终端用户输入了 ctrlc 来中断程序&#xff0c;会通过信号机制停止一个程序。信号概述 1.信号的名字和编号: 每…

JavaSE_day38(异常分类,自定义异常,File介绍,方法使用,相对路径与绝对路径概念以及注意的点)

1 A.java * 异常的分类&#xff1a; 运行时期异常:RuntimeException的子类就是运行时期异常&#xff0c;在编译时期可以自由选择处理或者不处理 编译时期异常:是Exception的子类&#xff0c;非RuntimeExcpetion的子类&#xff0c;在编译时期必须处理 public c…

注意力机制(一)SE模块(Squeeze-and-Excitation Networks)

Squeeze-and-Excitation Networks&#xff08;压缩和激励网络&#xff09; 论文地址&#xff1a;Squeeze-and-Excitation Networks 论文中文版&#xff1a;Squeeze-and-Excitation Networks_中文版 代码地址&#xff1a;GitHub - hujie-frank/SENet: Squeeze-and-Excitation Ne…

chatgpt赋能python:Python内置:优化SEO的利器?

Python 内置&#xff1a;优化SEO的利器&#xff1f; Python是一种广泛使用的高级编程语言&#xff0c;拥有丰富的标准库和第三方库&#xff0c;能够适用于很多领域。其中&#xff0c;Python内置的一些功能&#xff0c;比如字符串操作和网络请求&#xff0c;可以帮助我们进行SE…

web前端综合案例——小兔鲜首页(html+css)

前言&#xff1a;我这里只使用了html和css&#xff0c;js没有使用 项目源代码&#xff1a;https://pan.baidu.com/s/1alnekYEu5F9XwHTW7dO5RA?pwdqjhd 页面效果&#xff1a; 项目准备阶段&#xff1a; 1.准备项目相应的图片素材&#xff0c;设计稿。 2.创建项目: 2.1 项目…

用反射设计通用的实例化对象方案

需求 对象的相关信息存储在javabean.properties文件中&#xff0c;通过读取properties文件中的信息&#xff0c;实例化对象&#xff0c;要求程序不能硬编码&#xff0c;即程序可以通用&#xff0c;针对不同的对象&#xff0c;都可以实例化。仅需修改配置文件&#xff0c;不需要…

网络基础初识

目录 网络发展 时代背景 计算机内部 协议 协议的创立 什么是协议&#xff1f; 网络协议 OSI七层模型 TCP/IP五层(或四层)模型 硬件方面 -- 补充 路由器 协议的分层 网络传输基本流程 1.协议报头 2.局域网 查询自己的MAC地址 局域网通信的原理 跨路由器传递数…

以太网协议详解

文章目录 前言一、MAC地址二、以太网协议1. 以太网数据格式2. MAC地址表 前言 假设有这样一张网络拓扑图&#xff1a; 在拓扑图中有A、B、C三台计算机&#xff0c;并且它们三个是通过中间的路由器连接的。这时候计算机A要向计算机C发送一条数据&#xff0c;那么数据是怎么样到…

nvm教程

介绍 这个东西&#xff0c;是nodejs官网有个链接里面有很多列表&#xff0c;这是其中一个 下载 https://github.com/coreybutler/nvm-windows/releases 安装 安装前&#xff0c;将.npmrc文件删除&#xff1b;文件位置&#xff1a; C:\Users{User}\AppData\Roaming\npm C:\…

chatgpt赋能python:Python单行for:如何简化你的代码

Python单行for&#xff1a;如何简化你的代码 在Python编程中&#xff0c;for循环是必不可少的一部分&#xff0c;它可以用于遍历列表、元组和字典等各种数据类型。而Python单行for则是一种更加简单、更加紧凑的语法形式&#xff0c;可以让你更加高效地遍历和处理数据。 什么是…