log.js 文件实现了一个用于打印日志的函数 log() ,它可以支持 console.log() 一样的用法,并且自动在输出前面加上当前的日期和时间,方便我们浏览日志 reverseProxy() 函数入口使用 assert 模块来进行基本的参数检查,如果参数格式不符合要求即抛出异常,保证可以第一时间让开发者知道,而不是在运行期间发生各种 不可预测 的错误 getTarget() 函数用于循环返回一个目标服务器地址 bindError() 函数用于监听 error 事件,避免整个程序因为没有捕捉网络异常而崩溃,同时可以统一返回出错信息给客户端 为了测试我们的代码运行的效果,我编写了一个简单的程序,文件 server.js : const http = require("http"); const log = require("./log"); const reverseProxy = require("./proxy"); // 创建反向代理服务器 function startProxyServer(port) { return new Promise((resolve, reject) => { const server = http.createServer( reverseProxy({ servers: ["127.0.0.1:3001", "127.0.0.1:3002", "127.0.0.1:3003"] }) ); server.listen(port, () => { log("反向代理服务器已启动: %s", port); resolve(server); }); server.on("error", reject); }); } // 创建演示服务器 function startExampleServer(port) { return new Promise((resolve, reject) => { const server = http.createServer(function(req, res) { const chunks = []; req.on("data", chunk => chunks.push(chunk)); req.on("end", () => { const buf = Buffer.concat(chunks); res.end(`${port}: ${req.method} ${req.url} ${buf.toString()}`.trim()); }); }); server.listen(port, () => { log("服务器已启动: %s", port); resolve(server); }); server.on("error", reject); }); } (async function() { await startExampleServer(3001); await startExampleServer(3002); await startExampleServer(3003); await startProxyServer(3000); })(); 执行以下命令启动: node server.js 然后可以通过 curl 命令来查看返回的结果: curl :3000/hello/world 连续执行多次该命令,如无意外输出结果应该是这样的(输出内容端口部分按照顺序循环): 3001: GET /hello/world 3002: GET /hello/world 3003: GET /hello/world 3001: GET /hello/world 3002: GET /hello/world 3003: GET /hello/world 注意:如果使用浏览器来打开该网址,看到的结果顺序可能是不一样的,因为浏览器会自动尝试请求 /favicon ,这样刷新一次页面实际上是发送了两次请求。 单元测试 (责任编辑:admin) |