以前还在学校的时候就听说过实验室在做一些服务器端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了,亚历山大。