以前还在学校的时候就听说过实验室在做一些服务器端javascript解释器应用的研究,由于自己对js前段了解很有限,也没有去关注,现在看来node.js项目真是非常棒。采用Google V8 Javascript引擎,通过更改连接方式,每个连接发射一个在Node引擎的进程中运行的事件,而不是为每个连接生成一个新的OS线程(和一些配套内存),能够支持数万个并发连接,性能很好。已经有了很多企业级的应用。虽然对js不够熟悉,也还是想尝试一下node服务,感受它的非阻塞IO的魅力,下面是一组官方教程的示例程序。
简单的Hello World(访问8124端口就能看到结果,这比用libevent的http库实现一个Hello World要简单得多了,呵呵)
var http = require('http');
http.createServer(function(request, response){
response.writeHead(200,{'Content-Type':'text/plain'});
response.end('Hello World\n');
}).listen(8124);
console.log('Server is running');
随机数生成(运行 node example.js ,访问http://127.0.0.1:8124/?number=35
var http = require('http');
var url = require('url');
http.createServer(function(request, response){
response.writeHead(200,{'Content-Type':'text/plain'});
var params = url.parse(request.url, true).query;
var input = params.number;
var numInput = new Number(input);
var numOutput = new Number(Math.random() * numInput).toFixed(0);
response.write(numOutput);
response.end();
}).listen(8124);
console.log('Random Number Generator');
nodejs还提供https server的库,同样可以轻松创建一个https服务,而且官方网站上已经有超过一万个可用的第三方模块,可见nodejs的社区多么活跃啊。
我们再来看看nodejs和数据库的交互效果,异步的IO模型一般都是在并发操作数据库读写的时候才能体现出优势来,所以如何能做到数据库操作非阻塞才是最重要的。我们现有的后台php,perl等脚本语言在操作数据库上面都存在很大的性能瓶颈,无怪乎催生了这么多的nosql产品。但是它们都没有从根本上解决数据库读写的阻塞问题,闲话少说,我们来看看nodejs如何操作数据库的。首先用npm(nodejs package manager)安装mysql模块(npm开可以用于发布提交自己的模块,安装新模块时也会自动安装所依赖的模块)
root$npm install mysql
或者在github上下载
https://github.com/felixge/node-mysql(不一定是最好用的mysql模块,只做测试学习用)
编写脚本如下:
var mysql = require('mysql');
var TEST_DATABASE = 'nodejs_db';
var TEST_TABLE = 'test';
//创建连接
var client = mysql.createClient({
user: 'root',
password: 'rainbow',
});
//创建数据库
client.query('CREATE DATABASE '+TEST_DATABASE, function(err) {
if (err && err.number != mysql.ERROR_DB_CREATE_EXISTS) {
throw err;
}
});
//不指定回调函数,如果出错,则体现为客户端错误
client.query('USE '+TEST_DATABASE);
//创建表格,插入数据
client.query(
'CREATE TABLE '+TEST_TABLE+
'(id INT(11) AUTO_INCREMENT, '+
'name VARCHAR(255), '+
'PRIMARY KEY (id))'
);
client.query(
'INSERT INTO '+TEST_TABLE+' '+
'SET name = ?',
['nodejs1']
);
var query = client.query(
'INSERT INTO '+TEST_TABLE+' '+
'SET name = ?',
['nodejs2']
);
//查询,并设置回调函数
client.query(
'SELECT * FROM '+TEST_TABLE,
function selectCb(err, results, fields) {
if (err) {
throw err;
}
console.log(results);
console.log(fields);
client.end();
}
);
执行脚本后我们再查询数据库
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| daxue |
| mysql |
| nodejs_db |
+--------------------+
4 rows in set (0.00 sec)
mysql> show tables;
+---------------------+
| Tables_in_nodejs_db |
+---------------------+
| test |
+---------------------+
1 row in set (0.00 sec)
mysql> select * from test;
+----+---------+
| id | name |
+----+---------+
| 1 | nodejs1 |
| 2 | nodejs2 |
+----+---------+
2 rows in set (0.00 sec)
功能虽然很简单,我们用php,c也能很轻易实现。但是正如nodejs所宣扬的那样,它是提供非阻塞IO的数据库操作,单进程便能处理高并发的访问。
不同的操作系统平台提供的非阻塞编程的机制是不同的,而nodejs的出现很好地统一了各个平台,对于一些轻量级的业务可以考虑直接用nodejs来处理,javascript作为一个函数式语言也有很多灵活的特性(闭包,函数即变量)我们在前台已经见识过它强大的业务处理能力。那就再期待它在服务器端的表现吧,看来我也要花点时间学习js了,亚历山大。