Node.js 中的并发安全问题
Node.js 中的并发安全问题
简介
Node.js 采用非阻塞异步IO的方式来处理请求。基于 Libuv 的事件循环机制,node 得以通过单线程来处理高并发的请求。一般情况下,如果采用多线程的方式来处理并发的请求时,我们需要考虑多个线程在访问共享的数据时的线程安全问题。对应的方式一般会提供一些同步机制或锁的能力来方便开发人员解决并发问题。
那么对于单线程的 Node.js 应用,并不存在多线程的问题,是否就不需要考虑并发安全问题了呢?答案可能是否定的。
事件循环的并发安全
在 node 中,一个事件循环中的执行是可以保证并发安全的,不会被其他操作打断,所以如果能保证代码中的需要保证并发安全的业务都在一个事件循环中被处理,那么是不存在问题的。但是实际情况下,这并不容易做到,通常业务中的异步逻辑会在多个事件循环中被执行,从而存在并发时的数据不一致问题。 可以来看一个简单的例子。
// 将 redis 中的 k 乘 2
const double = async () => {
const val = await .get('k')
await redis.set('k', val * 2)
const main = async () => {
// 初始化 k, redis 是一个 redis 客户端
await redis.set('k', 1)
// 模拟并发的请求
await Promise.all([double(), double()])