Article details

Node.js实现一个数据缓存服务器

nano71.com
2024/11/25 13:34:21
0 comments
43 views

需求场景
公司的数据服务器每次更新部署时,会有一个服务不可用的时间以及服务重新启动的时间,但如果恰巧这段时间有用户进行访问。。。当然,这只适应于非即时性的数据

实现思路
先搭建http服务器监听post请求,用请求头的url和body创建一个hash值,作缓存的键,再检测数据服务器是否在线,如果是离线状态则用hash键去查询是否有已缓存的数据,如果数据服务器是在线状态,则将请求头和body原封不动的转发给数据服务器,返回的数据将根据该hash键进行缓存,同时返回给客户端本次转发请求的数据

需要用到的
后端是用JavaScript写的,所以围绕Node.js展开

  1. axios:负责请求数据服务器
  2. express:搭建http服务器
  3. NodeCache:一个简单的缓存模块,类似Map
  4. node:net:Socket在Node.js上的实现
  5. json-stable-stringify:字符串化json
  6. crypto:创建hash

代码实现
先创建express服务器,以及使用一些中间件:

const app = express()
app.use(cors())
app.use(express.json())
const cache = new NodeCache({stdTTL: 0}) // stdTTL为0则永不过期

一个检查指定端口是否可用的函数:

async function checkServerStatus(url) {
    try {
        await axios.get(url, { timeout: 100 })
        return true
    } catch {
        return false
    }
}

接着还需要一个hash生成函数:

const stableStringify = require('json-stable-stringify');

function generateHashKey(request) {
    const url = request.url;
    const body = stableStringify(request.body || {});

    return crypto.createHash('sha256')
        .update(url + body) // 用url以及body进行hash生成
        .digest('hex');
}

接受post请求,请求数据服务器:

app.post('*', async (req, res) => {
    const url = req.url
    const key = generateHashKey(req)
    const cachedData = cache.get(key)

    if (!await checkServerStatus()) { // 数据服务器离线
        if (cachedData) { // 有缓存就返回缓存的数据
            return res.json(cachedData)
        } 
        // 找不到缓存的话也可以直接返回50x
        // 或者忽略这个else,让后续的axios再请求一次以模拟真实情况
    }

    let response
    try {
        response = await axios.post("http://127.0.0.1:3000" + url, req.body, {
            headers: req.headers,
        })
        cache.set(key, response.data) // 正常返回就根据key来更新缓存
    } catch (error) {
        if (cachedData) {
            return res.json(cachedData)
        }
        response = error.response
    }

    res.status(response.status) // 状态
    Object.entries(response.headers).forEach(([key, value]) => {
        res.setHeader(key, value)
    }) // 将response原封不动的copy到res响应头中
    res.send(response.data) // 返回
})

延迟说明
多一层服务器中转,是会增加一定的延迟的,我开发机和服务器都是同一局域网,6kb的数据 总时长 下面这个是直接请求数据服务器的,且不返回数据的 image.png 对比起来,差不多会多一份数据下载延迟的增加,基本无感

nano71.com
2024/11/25 13:34:21
0 comments
43 views
Welcome to myBlog-site
Recent
Category
Guestbook
2026/3/10 16:11:31

解决 Dify 数据库插件连接 SQL Server 2008/2012 报错 DB-Lib error message 20002, severity 9

(pymssql.exceptions.OperationalError) (20002, b'DB-Lib error message 20002, severity 9:\nAdaptive Server connection failed (192.168.0.223)\nDB-Lib error message 20002, severity 9:\nAdaptive Server connection failed (192.168.0.223)\n') (Background on this error at: https://sqlalche.me/e/20/e3q8)

view
coverImage
2025/8/21 15:53:02

代码还原 Pinia 官网上的那个可以互动的小菠萝

眨眼 眼球跟随鼠标 一定时间鼠标不移动眼球归位

view
coverImage
2025/5/20 13:58:34

JDBC速成

JDBC(Java Database Connectivity)是 Java 官方提供的一套 API,集成在 java.sql 和 javax.sql 包中 JDBC 允许 Java 程序连接和操作各种关系型数据库,如 MySQL、Oracle、PostgreSQL、SQL Server 等

view
coverImage
2024/11/25 13:34:21

Node.js实现一个数据缓存服务器

需求场景 公司的数据服务器每次更新部署时,会有一个服务不可用的时间以及服务重新启动的时间,但如果恰巧这段时间有用户进行访问。。。当然,这只适应于非即时性的数据

view
coverImage
2024/7/18 19:30:34

Go的高并发实现:多协程和任务队列设计

前言 随着大学生活的结束,我入职了浙江的一家属于电气制造业的公司,岗位是数据分析,我算是暂时脱离了互联网这一行业,以后可能就很少接触Web开发了;把曾经对Web电子邮件系统中的性能优化的一部分抽出来记录下,也算在表达我对Web后端开发的一种敬意了

view
coverImage
2024/4/25 18:07:59

针对SPA网站的SEO方式探索-2

前言 针对SPA网站,本文将使用Nginx+Express+Puppeteer实现一个高效的SEO工具,大致的实现思路为:Nginx判断UA再进行代理转发,Express负责监听转发的请求,Puppeteer接到Express命令后启动一个无用户界面的Chrome对目标页面进行访问,等待目标SPA页面加载完成后,再返回完整的HTML给爬虫

view
coverImage
loading-GIF