百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 博客教程 > 正文

七爪源码:如何使用 Redis 和 Node.js 缓存 API 请求

connygpt 2024-11-08 10:34 9 浏览

查询数据时减少响应时间的初学者指南

我们生活在即时的时代,时间已经比金钱更有价值。那个时代,再加上互联网的活力,让我们的观众每天都要求更高。

你网站的内容可能很棒,但如果加载速度不好,人们会等着看吗?

根据多项研究,一半的用户等待时间不超过三秒。这对于电子商务等网站来说是一个挑战,如果页面几乎没有立即加载,用户可能会放弃页面并失去潜在销售。

缓存您的 Web 应用程序数据对于解决此问题并在您扩展时提供高性能收益可能至关重要。

近年来,Redis 已成为最流行的缓存数据库,因为它允许网站通过在几毫秒内访问数据来显着提高性能并更顺畅地工作。


什么是 Redis?

远程词典服务器(Redis)是一个高性能的开源 NoSQL 数据库,主要用作各类应用程序的缓存解决方案。

Redis 基于哈希表结构,其中每个键都有一个关联的值。与其他 Key-Value 数据库相比,Redis 允许使用更复杂、更灵活的结构,为不同的业务应用程序需求开辟了多种可能性。

当访问速度和响应时间对业务解决方案至关重要时,强烈建议使用 Redis。在处理需要快速访问数据以缩短响应时间的实时应用程序时,也表明了它的使用。在我们可以找到的最常见的用例中:

  • 聊天和消息系统
  • 最新项目列表
  • 实时计数器和统计使用情况
  • 在线购物车管理和管理
  • 在应用程序中存储用户会话
  • 支持缓存网页


什么是缓存?

缓存是将数据副本存储在内存中以允许应用程序更快地访问和检索数据的过程。

缓存的目标是比数据库或远程服务器所允许的更好地加速数据访问操作。对于成本高昂(及时)的操作尤其如此。

例如,如果我们的查询需要多个操作,例如从数据库中检索数据、执行计算、从其他服务中检索其他数据等,我们可以使用缓存。

这样,我们只处理一次数据,将其存储在缓存中,然后直接从缓存中检索它,而无需执行所有这些昂贵的操作。然后我们会定期刷新缓存,以便用户可以看到更新的信息。

使用 Node.js 和 Redis 进行缓存

现在我们将从开发我们的应用程序开始,我们希望在本教程中实现的是对外部 API 执行查询并测量响应时间。

之后,我们将在我们的应用程序中实现 Redis,将查询结果存储在缓存中。有了这个,我们将能够比较 Redis 之前和 Redis 之后的响应时间。


构建 Node.js 应用程序

像这样为 Node.js 应用程序设置初始样板。 我们创建一个 app.js 文件,并在其中添加以下行:

const express = require('express')
const responseTime = require('response-time')
const redis = require('redis')
const axios = require('axios')const app = express()app.listen(process.env.PORT || 3000, () => {
    console.log("Node server started")
})

如果我们执行命令,现在我们已经创建了 Express 服务器。

npm run dev

我们将在控制台中看到消息“节点服务器已启动”


从外部 API 检索数据

在我们的教程中,我们将使用 The Rick and Morty API 的 REST 版本,它为我们提供了以下端点:

{
"characters": "https://rickandmortyapi.com/api/character",
"locations": "https://rickandmortyapi.com/api/location",
"episodes": "https://rickandmortyapi.com/api/episode"
}

现在我们将使用 axios 向 /characterendpoint 发出请求。

const express = require('express')
const responseTime = require('response-time')
const redis = require('redis')
const axios = require('axios')
const app = express()
app.use(responseTime())app.get("/character", async (req, res) => {
  try {
    const response = await axios.get('https://rickandmortyapi.com/api/character')   
   
    await client.set('characters', JSON.stringify(response.data))       
    return res.status(200).json(response.data) 
  } catch (err) {   
    return res.status(err.response.status).json({ mmessage: err.mmessage }) 
  
  }
});
app.listen(process.env.PORT || 3000, () => { console.log("Node server started")})

通过我们发出的这个请求,API 会返回一个包含所有字符的对象,而我们感兴趣的是这个请求所花费的响应时间。

使用我们作为中间件添加的响应时间,我们将能够在请求的标头中看到一个名为 X-Response-Time 的新标头,它将指示我们更多的时间。

此请求花费了 663.662 毫秒。


为我们的端点实现 Redis 缓存

现在,让我们看看如何通过缓存来提高应用程序的性能。

首先,我们需要通过我们的应用程序连接到 Redis 服务器。 我们使用已安装的 Redis 包来完成此任务。

默认情况下,redis.createClient() 将分别使用 127.0.0.1 和 6379 作为主机名和端口。 如果您有不同的主机/端口,您可以像这样提供它们:

const client = redis.createClient(port, host)
const runApp = async () => {  
  
  const client = redis.createClient()
  
  client.on('error', (err) => console.log('Redis Client Error', err))
  
  await client.connect()
  
  console.log('Redis connected!')
}
runApp()

现在我们将向 API 发出相同的请求,并使用 Redis 客户端的 set() 方法缓存响应,该方法接收我们要保存的密钥的名称作为第一个参数。 作为第二个参数,这个键的值,我们必须将其保存为字符串,因此我们必须将 JSON 解析为字符串。

const runApp = async () => {
  app.get('/character', async (req, res) => {
    
    try {
      const response = await axios.get('https://rickandmortyapi.com/api/character')
      await client.set('characters', JSON.stringify(response.data))
    
      return res.status(200).json(response.data)   
    
    } catch (err) {   
      return res.status(err.response.status).json({ mmessage: err.mmessage })  
    }
  })
}
runApp()

一旦我们重新加载我们的应用程序并返回查询结果,我们就已经缓存了答案。

为了验证这一点,我们将使用 Redis-commander。 Redis-commander 允许我们通过 Web 界面查看我们的 Redis 数据库。 我们使用以下命令安装它:

npm install -g redis-commander

这个包将为我们提供一个 redis-commandercommand,当执行时,它将在端口 127.0.0.1:8081 上执行数据库 Web 界面。

当我们输入 redis-commander 时,我们会看到对 /characterrequest 的响应已经以我们分配给它的名称存储。

使用 Redis 进行缓存的过程非常简单。 当我们收到用户的请求时,我们首先检查请求的数据是否已经被缓存。 如果是这样,我们可以快速从 Redis 中检索数据并发送响应。

但是,如果数据没有被缓存,我们称之为缓存未命中,我们必须首先从数据库或外部 API 中检索数据并将其发送给客户端。 我们还确保将检索到的数据存储在缓存中,以便下次收到相同的请求时,我们可以简单地将缓存的数据更快地发送给用户。

const runApp = async () => {
  app.get('/character', async (req, res) => {
      
    try {      
      const cacheCharacters = await             client.get('characters')
        
      if (cacheCharacters) {
        return res.json(JSON.parse(cacheCharacters))
      }      
        
      const response = await axios.get('https://rickandmortyapi.com/api/character')      
       await  client.set('characters', JSON.stringify(response.data))
      
      return res.status(200).json(response.data)    
    } catch (err) {      
      return res.status(err.response.status)
             .json({ mmessage: err.mmessage })
    }
  })
}
runApp()

现在我们正在从缓存中检索信息,响应时间已大幅下降到 1,569 毫秒。

需要注意的是,我们在本教程中只触及了表面,Redis 提供的内容远不止这些。 我强烈建议查阅其官方文档。

这是完整的脚本,其中还有一个端点接收参数的示例:

const express = require('express')
const responseTime = require('response-time')
const redis = require('redis')
const axios = require('axios')

const runApp = async () => {

  // connect to redis
  const client = redis.createClient()
  client.on('error', (err) => console.log('Redis Client Error', err));
  await client.connect();
  console.log('Redis connected!')

  
  const app = express()
  // add response-time to requests
  app.use(responseTime())

  app.get('/character', async (req, res) => {

    try {

      // check if the request is already stored in the cache, if so, return the response
      const cacheCharacters = await client.get('characters')
      if (cacheCharacters) {
        return res.json(JSON.parse(cacheCharacters))
      }

      // makes the request to the API
      const response = await axios.get('https://rickandmortyapi.com/api/character')

      /* Another way to save the data is to save it with the name of the requets url, with the property
       req.originalUrl which would be the same as '/character'
       await client.set(req.originalUrl, JSON.stringify(response.data))
      */

      // save the response in the cache
      await client.set('characters', JSON.stringify(response.data))
      return res.status(200).json(response.data)

    } catch (err) {
      return res.status(err.response.status).json({ mmessage: err.mmessage })
    }

  })

  app.get('/characters/:id', async (req, res) => {

    try {

      const cacheCharacter = await client.get('cacheCharacter' + req.params.id)
      if (cacheCharacter) {
        return res.json(JSON.parse(cacheCharacter))
      }

      const response = await axios.get('https://rickandmortyapi.com/api/character/' + req.params.id)

      await client.set('cacheCharacter' + req.params.id, JSON.stringify(response.data))
      return res.json(response.data)

    } catch (err) {
      return res.status(err.response.status)
        .json({ message: err.message })
    }

  })

  app.listen(process.env.PORT || 3000, () => {
    console.log(`server on port 3000`)
  })

}

runApp()


结论

在本教程中,我们快速介绍了 Redis,并使用它为 Node.js 应用程序创建了一个简单的缓存。

您现在可以使用 Redis 在应用程序中缓存频繁查询的数据,从而显着提升性能,尤其是在每秒处理大量请求的项目中,Redis 提供的性能变得非常重要。


关注七爪网,获取更多APP/小程序/网站源码资源!

相关推荐

3分钟让你的项目支持AI问答模块,完全开源!

hello,大家好,我是徐小夕。之前和大家分享了很多可视化,零代码和前端工程化的最佳实践,今天继续分享一下最近开源的Next-Admin的最新更新。最近对这个项目做了一些优化,并集成了大家比较关注...

干货|程序员的副业挂,12个平台分享

1、D2adminD2Admin是一个完全开源免费的企业中后台产品前端集成方案,使用最新的前端技术栈,小于60kb的本地首屏js加载,已经做好大部分项目前期准备工作,并且带有大量示例代码,助...

Github标星超200K,这10个可视化面板你知道几个

在Github上有很多开源免费的后台控制面板可以选择,但是哪些才是最好、最受欢迎的可视化控制面板呢?今天就和大家推荐Github上10个好看又流行的可视化面板:1.AdminLTEAdminLTE是...

开箱即用的炫酷中后台前端开源框架第二篇

#头条创作挑战赛#1、SoybeanAdmin(1)介绍:SoybeanAdmin是一个基于Vue3、Vite3、TypeScript、NaiveUI、Pinia和UnoCSS的清新优...

搭建React+AntDeign的开发环境和框架

搭建React+AntDeign的开发环境和框架随着前端技术的不断发展,React和AntDesign已经成为越来越多Web应用程序的首选开发框架。React是一个用于构建用户界面的JavaScrip...

基于.NET 5实现的开源通用权限管理平台

??大家好,我是为广大程序员兄弟操碎了心的小编,每天推荐一个小工具/源码,装满你的收藏夹,每天分享一个小技巧,让你轻松节省开发效率,实现不加班不熬夜不掉头发,是我的目标!??今天小编推荐一款基于.NE...

StreamPark - 大数据流计算引擎

使用Docker完成StreamPark的部署??1.基于h2和docker-compose进行StreamPark部署wgethttps://raw.githubusercontent.com/a...

教你使用UmiJS框架开发React

1、什么是Umi.js?umi,中文可发音为乌米,是一个可插拔的企业级react应用框架。你可以将它简单地理解为一个专注性能的类next.js前端框架,并通过约定、自动生成和解析代码等方式来辅助...

简单在线流程图工具在用例设计中的运用

敏捷模式下,测试团队的用例逐渐简化以适应快速的发版节奏,大家很早就开始运用思维导图工具比如xmind来编写测试方法、测试点。如今不少已经不少利用开源的思维导图组件(如百度脑图...)来构建测试测试...

【开源分享】神奇的大数据实时平台框架,让Flink&Spark开发更简单

这是一个神奇的框架,让Flink|Spark开发更简单,一站式大数据实时平台!他就是StreamX!什么是StreamX大数据技术如今发展的如火如荼,已经呈现百花齐放欣欣向荣的景象,实时处理流域...

聊聊规则引擎的调研及实现全过程

摘要本期主要以规则引擎业务实现为例,陈述在陌生业务前如何进行业务深入、调研、技术选型、设计及实现全过程分析,如果你对规则引擎不感冒、也可以从中了解一些抽象实现过程。诉求从硬件采集到的数据提供的形式多种...

【开源推荐】Diboot 2.0.5 发布,自动化开发助理

一、前言Diboot2.0.5版本已于近日发布,在此次发布中,我们新增了file-starter组件,完善了iam-starter组件,对core核心进行了相关优化,让devtools也支持对IAM...

微软推出Copilot Actions,使用人工智能自动执行重复性任务

IT之家11月19日消息,微软在今天举办的Ignite大会上宣布了一系列新功能,旨在进一步提升Microsoft365Copilot的智能化水平。其中最引人注目的是Copilot...

Electron 使用Selenium和WebDriver

本节我们来学习如何在Electron下使用Selenium和WebDriver。SeleniumSelenium是ThoughtWorks提供的一个强大的基于浏览器的开源自动化测试工具...

Quick 'n Easy Web Builder 11.1.0设计和构建功能齐全的网页的工具

一个实用而有效的应用程序,能够让您轻松构建、创建和设计个人的HTML网站。Quick'nEasyWebBuilder是一款全面且轻巧的软件,为用户提供了一种简单的方式来创建、编辑...