nodejs + redis/mysql 连接池问题

需不需要连接池

连接池的作用主要是较少每次临时建立连接所带来的开销。初步一看,nodejs运行单线程上,它不能同时使用多个连接,乍一看是不需要连接池的。但是这只是我们初步下意识的感觉,下面我们详细分析来看看这个结论对是不对。

先从简单的redis开始。
redis服务器也是运行在单线程上的。俩都是单线程,看起来更加坚定不需要连接池的结论了。
从详细的图像来看看nodejs 连接 redis用连接池有没有意义。
 
上图中,nodejs共有俩连接,分别发送查询请求到redis服务器上。因为redis是单线程作业,不管两个查询任务是由一个连接发来还是多个连接发来,也不管任务是串行一前一后先后发送到服务器,还是并行的同时发送到服务器上,redis都将他们一个个按顺序执行,并通过当前连接返回给客户端(这里是nodejs)。nodejs接受到redis的返回后,也管不了并行不并行,都得等他nodejs的主线程空闲的时候才能来一个个处理服务器返回的数据。
 
所以单从上面结论来看,nodejs + redis只需要公用一个连接就可以了,所以是不需要用连接池的。
 
再来看看nodejs + mysql下的情况
 
不同的是mysql不是单线程服务的,也就是它可以并行处理多个查询请求。
如上图所示,mysql会为每个连接创建一个单独的线程来查询。不同于redis数据基本都在内存中,因为mysql会有大量的读取磁盘的IO操作,所以多个线程一起工作会比一个个查询要快。
 
但是nodejs又是单线程的,它能不能同时发送多个请求到mysql服务器上呢?
这里要理解nodejs的运作,虽然nodejs是一个主线程,但是它调用的IO指令等是通过另外的线程去做的,IO指令完成后就给主线程一个小任务片,也就是回调函数了。
这里有个很关键的点就是,nodejs主线程一个,但是IO线程会有多个。
因此如果用nodejs + mysql只用单个连接的话那么就利用不到mysql能同时服务多个查询的优势了。应该使用类似下图的运作方式,nodejs 使用多个连接来连接mysql。多连接是需要连接池的,有连接池就避免了每次连接都要去创建销毁的消耗了。
 
所以我们第一步的感觉认为Nodejs是单线程而不是需要连接池是错误的,使用不使用连接池,不光看客户端,还要看数据库服务器等。要全盘理解整个系统的运作模式才能下结论。了解服务器的运作模式,有没有阻塞操作,是否是多线程等。我想redis设计成单线程主要原因在于它的数据基本都在内存中,查询数据过程总不会产生阻塞过程,cpu也不会处于空闲状态。
 

全局连接断开重连问题

到这里还没完。综上面的分析,nodejs + mysql用线程池是没什么问题的。nodejs + redis只用单个连接就够。不过也还是有人建议需要连接池。为了说明问题得从代码着手。我们使用node-redis这个包来做例子。
 
例如新建了一个db.js
var redis = require("redis"),
client = redis.createClient(6379, "127.0.0.1");
module.exports = client;

上面的连接会在程序启动载入完后就连接上了。使用它的时候引入它就可以使用全局唯一的连接。

var db = require("db.js");

exports.add = function(req, res, next) {

    db.get("keyName", function() {
res.send("ok");
});
}
这里于是有这样的问题存在。
但此处全局只有一个连接,并且这个连接是程序启动的时候创建的。它不同于连接池中的连接那样运行时候动态创建。如果某个时候唯一的连接断掉了,程序又不会动态去创建连接,岂不是需要重新启动服务器才行。
 
看是来挺可怕,但好在这个问题是不存在的。因为redis的客户端会自动重新连接,所以不需要重新启动服务器。
但是因为连接断开那一小段时间,应用服务器不能正常对外服务,但是连接自动重连是需要一定的时间间隔的。例如一秒之后,所以这一秒之内系统是处在不能服务状态。
 
也正是基于上面这样的原因,于是就有连接redis使用连接池的做法。如果使用连接池来管理,当连接不可用的时候立即手动去创建新连接。和自动重连相比,一个是手动立即重连,一个是等到一定间隔重连。相对来说手动重连的时间更短,也就是说系统那1秒中不能服务的状态或许可以缩短成0.5秒。于是就有了使用连接池管理redis连接的做法。严格来说这个不能算是连接池,而是一个连接管理模块。 
 
到这里最后的结论nodejs + mysql使用连接池更好, nodejs + redis可以使用也可以不用。
 

nodejs + redis/mysql 连接池问题的更多相关文章

  1. redis mysql 连接池 之 golang 实现

    1 mysql 连接池代码 package lib import ( "database/sql" "fmt" "strconv" &quo ...

  2. nodejs使用MYSQL连接池,断线重连

    两种方式解决1.你可以配置mysql的连接池 var mysql = require('mysql'); var pool = mysql.createPool({ host: 'localhost' ...

  3. nodejs 封装mysql连接池

    写在前面的 在nodejs后台代码中,我们总是会和数据库打交道 然而,每次都要写数据库的配置以及连接和断开,不胜其烦 我就封装了一个连接池模块,不足之处还请多多批评 上代码 一下是写在mysqls.j ...

  4. Nodejs与mysql连接池的应用(pool)

    /* * 连接池 连接和缓存的技术 * */ var mysql = require('mysql'); var pool = mysql.createPool({ connectionLimit:2 ...

  5. 解决Mysql连接池被关闭 ,hibernate尝试连接不能连接的问题。 (默认mysql连接池可以访问的时间为8小时,如果超过8小时没有连接,mysql会自动关闭连接池。系统发布第二天访问链接关闭问题。

    解决Mysql连接池被关闭  ,hibernate尝试连接不能连接的问题. (默认MySQL连接池可以访问的时间为8小时,如果超过8小时没有连接,mysql会自动关闭连接池. 所以系统发布第二天访问会 ...

  6. Java Mysql连接池配置和案例分析--超时异常和处理

    前言: 最近在开发服务的时候, 发现服务只要一段时间不用, 下次首次访问总是失败. 该问题影响虽不大, 但终究影响用户体验. 观察日志后发现, mysql连接因长时间空闲而被关闭, 使用时没有死链检测 ...

  7. MySQL连接池

    1. using System; using System.Collections; using MySql.Data.MySqlClient; namespace Helper { /// < ...

  8. redis运用连接池报错解决

    redis使用连接池报错解决redis使用十几小时就一直报异常 redis.clients.jedis.exceptions.JedisConnectionException: Could not g ...

  9. tomcat中使用mysql连接池的配置

    1.下载相应的jar包,添加到工程中 需要下载的包主要有commons-pool2-2.2 commons-dbcp2-2.0.1-src commons-dbcp2-2.0.1  commons-c ...

随机推荐

  1. Oracle 创建数据库卡死在85%

    Oracle 创建数据库卡死在85%处理方法 1.首先用改工具,删除数据库 2.对应的目录 3.重启服务器(本次尝试有重启,在有其他数据库在跑的情况下,可以试试不重启)

  2. 使用try-with-resource遇到的问题

    JDK1.7增加了try-with-source语法.在try中声明一个或者多个资源,在try块代码执行完成后自动关闭流,不用再写close()进行手动关闭. try(Resource res = x ...

  3. 用hashmap实现redis有什么问题

    1.容量问题 hashmap是有最大容量的 2.时效问题 redis可以持久化,也可以定时时间 hashmap不可以持久化 3.线程并发问题 hashmap不是线程安全的(并且:多线程同时调用hash ...

  4. numpy多维矩阵,取出第一行或者第一列,方法和df一样

    # 定义一个多维矩阵 arr = np.array([[1,2,3], [4,5,6], [7,8,9]]) # 取出第一行 arr[0,:] # 取出第一列 arr[:,0]

  5. 基于JQuery easyui,gson的批量新增/修改和删除-servlet版

    最近项目需要用到在页面进行批量操作,做了一些这方面的学习,参照网上的资料写了个小例子,记录一下: 准备 引入gson-2.6.2.jar,这里使用gson而不使用json-lib,原因是json-li ...

  6. java实现HTTP请求的三种方式

    目前JAVA实现HTTP请求的方法用的最多的有两种:一种是通过HTTPClient这种第三方的开源框架去实现.HTTPClient对HTTP的封装性比较不错,通过它基本上能够满足我们大部分的需求,Ht ...

  7. XAMPP中Apache和Mysql启动失败问题总结

    一.Apache启动失败 xampp启动时显示的错误为: 9:52:41  [Apache]  Attempting to start Apache app... 9:52:41  [Apache]  ...

  8. ssh 端口转发实现外网 80 端口映射到内网 80 端口

    开发中经常需要外网服务映射到本机内网服务的需要,便于调试. 以前都是同事帮着配,这两天自己也看了一下 ssh 端口转发. 同事分分钟钟搞定的事情,自己折腾了 2 天, 真是弱爆了. 最初老想不明白一件 ...

  9. ArrayList、Vector和LinkedList等的差别与用法(基础回顾)

    ArrayList 和Vector是采取数组体式格式存储数据,此数组元素数大于实际存储的数据以便增长和插入元素,都容许直接序号索引元素,然则插入数据要设计到数组元素移动等内存操纵,所以索引数据快插入数 ...

  10. 【Css】Layout布局(一)

    看下图: css框模型(Box Model),也有叫做盒模型的.规定了元素框处理元素内容.内边距.边框 和 外边距 的方式. element元素,也是内容的主体: padding内边距,也右称为填充的 ...