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展开
- axios:负责请求数据服务器
- express:搭建http服务器
- NodeCache:一个简单的缓存模块,类似Map
- node:net:Socket在Node.js上的实现
- json-stable-stringify:字符串化json
- 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的数据
下面这个是直接请求数据服务器的,且不返回数据的
对比起来,差不多会多一份数据下载延迟的增加,基本无感
nano71.com
2024/11/25 13:34:21
0 comments
43 views





