nodejs 异步非阻塞.js操作数据库会不会阻塞

最近看了一本书,其中,如果想要一个请求处理程序中耗时的操作不会阻塞对另一个请求作出立即响应,使用了Node.js的child_process模块的一个既简单又实用的非阻塞操作exec()。
下面模拟通过exec()中执行一个耗时操作,来测试非阻塞。
exec("sleep 6 && ls -lah", function(error, stdout, stderr){
response.writeHead(200, {"content-type":"text/plain"});
response.write(stdout);
response.end();
如果在一个请求响应中加上上面的代码则至少耗时6秒,显然是个阻塞操作,然后可以测试对于其他请求,查看是否立即响应。
此外,查看Node.js的:
child_process.exec(command[, options], callback)
需要注意的是,如果command的运行时间超过options中timeout的设定上限就会被kill掉。
本文已收录于以下专栏:
相关文章推荐
通过使用mongoose模块能够更为方便的对mongodb数据库进行操作,而在测试过程中使用mocha模块能够十分方便的模拟http请求的发送并很方便的测试对数据库的相应操作1.数据库连接和模型建立通...
child_process是nw.exe的一个内置模块,通过它可以实现创建多线程,并可实现主线程和子线程之间的通信。child_process模块中主要使用有两个方法spawn和exec,这两个方法都...
我们在使用child_process模块的exec方法时经常会遇到“未找到命令”错误,如下简单示例://test.js:
var exec = require('child_process').exe...
转自http://cnodejs.org/topic/4f50dda610b808a
今天.NET老师在课堂上吹捧多线程编程,我就想为单线程抱个不平,因为Node的单线程异步非阻塞I/O模型,演绎了单线程编程的神话。
阻塞I/O程序执行过程中必然要进行很多I/O操作,读写文件、输...
Node.js 回调函数
Node.js 异步编程的直接体现就是回调。
异步编程依托于回调来实现,但不能说使用了回调后程序就异步化了。
回调函数在完成任务后就会被调用,Node 使用...
Node.js 是以单线程的模式运行的,但它使用的是事件驱动来处理并发,这样有助于我们在多核 cpu 的系统上创建多个子进程,从而提高性能。每个子进程总是带有三个流对象:child.stdin, ch...
使用Mocha进行Node.js的单元测试
今天要介绍的两个模块分别是assert和vm,下面我们就分别介绍。
  使用assert做测试
  node中,我们可以使用assert模块来测试代码。equal()和notEqual()...
安装 mongoskin方法很简单 
在cmd中,进入nodejs目录,输入 npm install mongoskin回车即可安装成功
var mongoskin = require...
他的最新文章
讲师:刘文志
讲师:陈伟
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)在 SegmentFault,解决技术问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
一线的工程师、著名开源项目的作者们,都在这里:
获取验证码
已有账号?
问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
因为我之前用php,都是每次查询的时候才连接,查询完了就关闭的,但是用nodejs,我发现其实压根没必要每次查询都连接-关闭啊,启动node app的时候连接,然后保持连接,怎么查询都没看出有什么不好的地方啊,想问一下到底我这个做法对不对?还是说不同需求有不同做法?
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
两种方式解决
1、你可以配置mysql的连接池
var mysql = require('mysql');
var pool = mysql.createPool({
host: 'localhost',
user: 'nodejs',
password: 'nodejs',
database: 'nodejs',
port: 3306
var selectSQL = 'select * from t_user limit 10';
pool.getConnection(function (err, conn) {
if (err) console.log("POOL ==& " + err);
conn.query(selectSQL,function(err,rows){
if (err) console.log(err);
console.log("SELECT ==& ");
for (var i in rows) {
console.log(rows[i]);
conn.release();
2、你可以使用断线重连的方式来解决
var mysql = require('mysql');
function handleError () {
conn = mysql.createConnection({
host: 'localhost',
user: 'nodejs',
password: 'nodejs',
database: 'nodejs',
port: 3306
//连接错误,2秒重试
conn.connect(function (err) {
if (err) {
console.log('error when connecting to db:', err);
setTimeout(handleError , 2000);
conn.on('error', function (err) {
console.log('db error', err);
// 如果是连接断开,自动重新连接
if (err.code === 'PROTOCOL_CONNECTION_LOST') {
handleError();
handleError();
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
mysql是有连接池的 并发大的情况下 如果你之前的连接不关闭 连接池满了 请求无法处理 程序就会阻塞 因此是用完是需要释放的
同步到新浪微博
分享到微博?
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:node.js 操作 postgresql 数据库
这篇node.js操作postgresql,采用的是两个文件的方式实现,一个文件相当于客户端,实现连接数据库,调用相应的函数,而另一个文件是具体实现函数的。
在你安装了node.js,postgre(不一定是本机)和相应的模块的基础上,在数据库中建表teacher。并插入几条测试数据,这儿插入的测试数据为:
create table teacher(id varchar(10),name varchar(20),pwd varchar(10)); &
insert into teacher values('1','aaa','111'); &
insert into teacher values('2','bbb','222'); &
insert into teacher values('3','ccc','333'); &
insert into teacher values('4','ddd','444'); &
1) client.js
var f = require('./function'); &
var pg = require('pg'); &
var conString = &tcp://postgres:postgres@localhost/my&; &
var client = new pg.Client(conString); &
var value = ['10','fillp','abc']; &
insertSQLString = 'insert into teacher values($1,$2,$3)'; &
selectSQLString = 'select * from teacher'; &
updateSQLString = &update teacher set NAME='ipone' where ID='4'&; &
deleteSQLString = &delete from teacher where ID='10'&; &
client.connect(function(error, results) { &
& & if(error){ &
& & & & console.log('ClientConnectionReady Error: ' + error.message); &
& & & & client.end(); &
& & console.log('Connecting to postgres...'); &
& & console.log('Connected to postgres automatically.'); &
& & console.log('connection success...\n'); &
& & f._select(client,selectSQLString); &
& & f._insert(client,insertSQLString,value); &
& & f._select(client,selectSQLString); &
& & f._delete(client,deleteSQLString); &
2) function.js
&span style=&font-size:14&&&span style=&font-size:12&&function _insert(client,insertSQLString,value) &
& & console.log(&insert beginning&); &
& & client.query(insertSQLString, value, &function(error, results) &
& & & & if(error) &
& & & & { &
& & & & & & console.log(&ClientReady Error: & + error.message), &
& & & & & & client.end(); &
& & & & & & &
& & & & } &
& & & & console.log('Inserted: ' + results.affectedRows + ' row.'), &
& & & & console.log('insert success...\n'); &
& & console.log(&insert end\n&); &
function _select(client,selectSQLString) &
& & console.log(&select beginning&); &
& & client.query(selectSQLString, &function selectCb(error, results, fields) &
& & & & console.log(&in select callback function&); &
& & & & if (error) &
& & & & { &
& & & & & & console.log('GetData Error: ' + error.message), &
& & & & & & client.end(); &
& & & & & & &
& & & & } &
& & & & if(results.rowCount & 0) &
& & & & { &
& & & & & & var firstResult, &
& & & & & & resultSet = ''; &
& & & & & & for(var i = 0, len = results.rowC i & i++) &
& & & & & & { &
& & & & & & & & firstResult = results.rows[i]; &&
& & & & & & & & resultSet += 'id:' + firstResult['id'] + ' ' + 'name:' + firstResult['name'] + ' ' + &&
& & & & & & & & & & & & & & &'pwd:' + firstResult['pwd'] + '\n'; &&
& & & & & & } &
& & & & } &
& & & & console.log(resultSet); &
& & & & /* 添加功能:使查询结果集返回到客户端并保证此函数的通用性. */ &
& & console.log(&select end\n&); &
function _update(client,updateSQLString) &
& & console.log(&update beginning&); &
& & client.query(updateSQLString,function(error, results) &
& & & & if(error) &
& & & & { &
& & & & & & console.log(&ClientReady Error: & + error.message), &
& & & & & & client.end(); &
& & & & & & &
& & & & } &
& & & & console.log('update success...\n'); &
& & console.log(&update end\n&); &
function _delete(client,deleteSQLString) &
& & console.log(&delete beginning&); &
& & client.query(deleteSQLString, &function(error, results) &
& & & & if(error) &
& & & & { &
& & & & & & console.log(&ClientReady Error: & + error.message), &
& & & & & & client.end(); &
& & & & & & &
& & & & } &
& & & & console.log('delete success...\n'); &
& & console.log(&delete end\n&); &
exports._insert = _ &
exports._select = _ &
exports._update = _ &
exports._delete = _&/span& &
3) 运行node client.js,结果如下:
Connecting to postgres...
Connected to postgres automatically.
connection success...
select beginning
select end
insert beginning
insert end
select beginning
select end
delete beginning
delete end
in select callback function
id:1 name:aaa pwd:111
id:2 name:bbb pwd:222
id:3 name:ccc pwd:333
id:4 name:ddd pwd:444
Inserted: undefined row.
insert success...
in select callback function
id:1 name:aaa pwd:111
id:2 name:bbb pwd:222
id:3 name:ccc pwd:333
id:4 name:ddd pwd:444
id:10 name:fillp pwd:abc
delete success...
在函数实现里面,我们采用了回调函数的形式实现,根据输出信息可以很号的看出node.js的主要特性:非阻塞博客分类:
NoteJS简介
NodeJS是一个使用了Google高性能V8引擎的服务器端JavaScript实现。它提供了一个(几乎)完全非阻塞I/O栈,与JavaScript提供的闭包和匿名函数相结合,使之成为编写高吞吐量网络服务程序的优秀平台。
NoteJS特性
1. 单线程
这说明它只能用一个CPU,在多核CPU上没有优势;不过可以通过以下方式实现多核CPU的利用:
a) 使用软件负载均衡:为每个处理器单独启动一个NodeJS进程,每个进程都运行HTTP服务并绑定到不同的端口。这样需要一个负载均衡软件,将客户端请求转发到各进程,这个软件知道每个服务进程的端口。
b) 使用操作系统内核做负载均衡:在node-v0.1.98中 ,雅虎贡献了一个用于传递和重用文件描述符的核心补丁,允许如Connect和multi-node等HTTP框架使用多个进程同时提供HTTP服务,而且不需要修改原有的程序代码和配置。
c) 使用NodeJS转发请求:需要node-v0.1.100或更高版本以及node-webworker。可以认为Web Worker是一个独立的执行上下文(类似进程),它可以由JavaScript代码生成并来回传递数据。
2. 非阻塞IO
nodejs通过libev事件得到IO执行状态,而不是轮询,提高了CPU利用率。
虽然nodejs是单线程的,但它的IO操作是多线程的,多个IO请求会创建多个libeio线程(最多4个),使通常情况的IO操作性能得到提高。
但是当IO操作情况比较复杂的时候,有可能造成线程竞争状态,导致IO性能降低;而且libeio最多创建4个线程,当同时有大量IO请求时,实际性能有 待测量。另外,由于每个IO请求对应一个libeio的数据结构,当同时有大量IO操作驻留在系统中时候,会增加内存开销。
Libeio为了实现异步IO功能,带来了额外的管理,当IO数据量比较小的时候,整体性能不一定比同步IO好。
3. Google V8
C++编写,解释JS更快,性能更好。
测试结果表明,nodeJS性能远超php\python\ruby。
4. 事件驱动
传统的web server多为基于线程模型。你启动Apache或者什么server,它开始等待接受连接。当收到一个连接,server保持连接连通直到页面或者什么事务请求完成。如果他需要花几微妙时间去读取磁盘或者访问数据库,web server就阻塞了IO操作(这也被称之为阻塞式IO).想提高这样的web server的性能就只有启动更多的server实例。
相反的,NodeJS使用事件驱动模型,当web server接收到请求,就把它关闭然后进行处理,然后去服务下一个web请求。当这个请求完成,它被放回处理队列,当到达队列开头,这个结果被返回给用户。这个模型非常高效可扩展性非常强,因为webserver一直接受请求而不等待任何读写操作。(这也被称之为非阻塞式IO或者事件驱动IO)
运行NodeJS
nodeJS可以运行在各个平台上:windows\mac\linux。安装方法也是下载双击便可安装,无需配置,一步到位。
以下是hello world例子:
1. 编写hello_world.js
var http = require('http');
http.createServer(function (req, res) {
& res.writeHead(200, {'Content-Type': 'text/plain'});
& res.end('Hello World\n');
}).listen(1337, "127.0.0.1");
console.log('Server running at http://127.0.0.1:1337/');
2. 运行:node hello_world.js
Server running at http://127.0.0.1:1337/
3. 访问:http://127.0.0.1:1337/
像apache一样,nodeJS是模块化的,可以通过安装npm来安装任何模块:
$ npm install MODULE
然后通过:require(‘MODULE’)引进你想要的任何模块。社区相当丰富,模块也相当多,基本上能找到你想要的任何模块:web framework/database/templating/css engines/build and deployment/smtp/rpc/tcp\ip等等。
比较出色的web框架有express,国人更是在此基础上开发出性能更高的rrestjs web框架,性能堪比nginx!express再配合出色的jade view engine,就可以实现复杂的MVC开发模式。
NodeJS带来的改变
对于前端开发者,有了一个非常好的机会切入后端开发或者尝试后端开发,而无需重新学习一门新的语言和语法。前端开发者学习一些基本的服务器端知识,无需依赖额外的资源,就可以靠自己快速开发出一个功能完整的原型,这是以前无法想象的。
对于后端开发者,NodeJS提供一种全新的开发思路和性能更好的动态语言。作为追求性能的后端开发者,在动态语言选择中,NodeJS是非常有性能优势的。前后端代码复用不再是幻想。例如,表单输入有效性判断的业务逻辑代码可以很有地复用。更重要的是让前后端开发者的思维相互交叉渗透,会萌发出更多创新火花。
NodeJS现况与应用场景
目前NodeJS主要还是应用在一些中小型的Web项目,以及特定的开发平台中,更多的还是一些应用逻辑层面的开发,对于NodeJS自身性能和功能的挖掘还停留在一个比较浅的层次上。
目前国内大中型的系统中实际应用NodeJS作为线上业务系统还不多见。淘宝内目前有一些大中型项目已经在线运行,如NodeFox(分布式Mysql查询与管理服务)、Itier(异构数据源的中间层数据服务)、淘宝指数。
然而,微软、雅虎、LinkedIn、eBay都在使用,并且拥有目前最火爆的开源社区,以及最频繁更新和贡献的第三方模块支持,这是一个高速飞奔的生态系统。
由于NodeJS天生的异步非阻塞,单线程特色,对于大量的io依赖性应用,如中间层、应用服务器、代理服务等是非常适合的场景。由于NodeJS技术社区很给力,提供了大量的功能模块,对于快速开发中小型的Web项目很合适
NodeJS开发注意
1. 注意思维方式的转换,不要用串行系统的思路进行NodeJS系统的设计。
2. 注意ECMA Script 5的新特性对于代码和程序运行效率的影响。
3. 单线程模式中的资源共享给系统设计带来变化。
4. 异步模式下的异常处理。
NodeJS相关资源网站
官网:http://www.nodejs.org
nodeJS模块:/joyent/node/wiki/modules
国内社区:http://cnodejs.org/
Express官网:/guide.html
Jade官网:/
浏览: 599340 次
来自: 广州
第二种方式错误无法添加;
感谢楼主分享!!我遇到的问题:本地word转html 两个编码 ...
文档编号显示不对,读出来全是1和1.1,我的文档是1,1.1, ...
世界太小了,统一移动平台的jrebel插件是不是就是你搞的,今 ...
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'

我要回帖

更多关于 node.js非阻塞 的文章

 

随机推荐