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. 批处理 进行svn代码拉取,vs编译,dotfuscator混淆

    Dotfuscator的使用:https://www.cnblogs.com/aitong/p/10684004.html 从拉取代码,编译到最后的混淆步骤很多.这时就可以使用批处理来进行自动化. 用 ...

  2. IE8 placeholder不支持的兼容性处理

    引入 <script type="text/javascript" src="<%=path%>/common/js/jquery/jquery.min ...

  3. 《The Python Standard Library》——http模块阅读笔记3

    http.cookies — HTTP state management http.cookies模块定义了一系列类来抽象cookies这个概念,一个HTTP状态管理机制.该模块支持string-on ...

  4. APP的功能分类及打包与发布的分类方式

    智能手机的出现改变了我们的生活,同时各种各样的APP充斥在我们的手机当中.那么我先现在在来熟悉一下APP的分类及其用途:工具类.社交类.信息类.娱乐类.生活类等几大类.我么了解了APP的用途分类,那么 ...

  5. java实现多线程的4种方式

    1.继承Thread类 看jdk源码可以发现,Thread类其实是实现了Runnable接口的一个实例,继承Thread类后需要重写run方法并通过start方法启动线程. 继承Thread类耦合性太 ...

  6. (转)Cobbler自动化部署最佳实践

    原文:http://www.xuliangwei.com/xubusi/446.html 运维自动化在生产环境中占据着举足轻重的地位,尤其是面对几百台,几千台甚至几万台的服务器时,仅仅是安装操作系统, ...

  7. MySQL 的数据库、表基本操作

    1.链接数据库 mysql -u root -ppassword 2创建数据库 create database mr_book; 3选择数据库 use mr_book; 4 创建表 create ta ...

  8. ADT安装Genymotion的eclipse插件安装及错误解决办法

    接触安卓开发也有很长一段时间了,但是一直使用的真机测试程序,因为感觉android模拟器实在是太不方便,运行慢,而且经常出错.最近听人介绍说Genymotion这款Android模拟器相当不错,于是打 ...

  9. js 递归树结构数据查找父级

    1.json树数据查找所有父级--完成 json:树结构数据 var arrData = [{ "label": "中国", "City": ...

  10. fzu 2136 取糖果 好几种方法解决。

    Problem 2136 取糖果 Accept: 39    Submit: 101 Time Limit: 1000 mSec    Memory Limit : 32768 KB Problem ...