作者:侯贵聪_680 | 来源:互联网 | 2023-05-21 18:55
我一直在使用phantomjs在服务器端dom
环境中为我做一些繁重的工作.直到现在我一直把数据结构放在内存中(即对它们没什么特别的),一切都很好.但最近在一些用例中我开始遇到以下问题:
内存使用率变得太高,导致交换启动并严重影响我的性能.
无法从上一个保存点恢复,因为内存中的数据结构不是持久的(显然)
这迫使我寻找一个用于幻像的数据库解决方案,但在决定解决方案时我又遇到了问题:
我不希望我的表演太受影响.
它必须是持久的和可查询的
我怎么能从幻像脚本里面连接数据库.
谁能引导我找到满意的解决方案?
注意:我几乎已经决定,sqlite
但从幻影连接到它仍然是一个问题.Nodejs提供sqlite3
节点模块,我正在尝试browserify
使用幻像.
注意注意: Browserify没有用!回到地面零!:-(
Thanx提前!
1> 小智..:
Phantomjs的文件系统API允许您读取和写入二进制文件:
buf = fs.read(FILENAME, 'b') and
fs.write(FILENAME, buf, 'b')
sql.js(https://github.com/kripken/sql.js/)为您提供了一个可以在phantomjs中运行的Javascript SQLite实现.
结合2,您就拥有了一个快速,持久,可查询的SQL数据库.
示例演练
获取Javascript SQLite实现(保存到/tmp/sql.js)
$ wget https://raw.githubusercontent.com/kripken/sql.js/master/js/sql.js -O /tmp/sql.js
使用命令行sqlite3应用程序创建一个测试SQLite数据库(显示它是持久的并且在phantomjs应用程序外部).
sqlite3 /tmp/eg.db
sqlite> CREATE TABLE IF NOT EXISTS test(id INTEGER PRIMARY KEY AUTOINCREMENT,创建INTEGER NOT NULL DEFAULT CURRENT_TIMESTAMP);
sqlite> .quit
保存此测试phantomjs脚本以将条目添加到测试数据库并验证行为.
$ cat /tmp/eg.js
var fs = require('fs'),
sqlite3 = require('./sql.js'),
dbfile = '/tmp/eg.db',
sql = 'INSERT INTO test(id) VALUES (NULL)',
// fs.read returns binary 'string' (not 'String' or 'Uint8Array')
read = fs.read(dbfile, 'b'),
// Database argument must be a 'string' (binary) not 'Uint8Array'
db = new sqlite3.Database(read),
write,
uint8array;
try {
db.run(sql);
} catch (e) {
console.error('ERROR: ' + e);
phantom.exit();
}
// db.export() returns 'Uint8Array' but we must pass binary 'string' to write
uint8array = db.export();
write = String.fromCharCode.apply(null, Array.prototype.slice.apply(uint8array));
fs.write(dbfile, write, 'b');
db.close();
phantom.exit();
运行phantomjs脚本进行测试
$ /usr/local/phantomjs-2.0.0-macosx/bin/phantomjs /tmp/eg.js
使用外部工具验证更改是否持久.
sqlite3 /tmp/eg.db
sqlite> SELECT*FROM test;
id已创建
1 2015-03-28 10:21:09
sqlite的>
要注意的一些事项:
仅当您调用fs.write时,才会在磁盘上修改数据库.在您调用fs.write之前,您所做的任何更改对访问同一SQLite数据库文件的外部程序都是不可见的.
使用fs.read将整个数据库读入内存.您可能希望为不同的表(或表的版本)提供不同的OS文件,具体取决于您的应用程序和表中的数据量,以满足您提到的内存要求.
将sqlite3.export()返回的内容传递给fs.write会破坏磁盘上的SQLite数据库文件(它将不再是有效的SQLite数据库文件).Uint8Array不是fs.write参数的正确类型.