2

我有一个场景,我的 node.js 应用程序位于负载平衡 HAProxy 后面,该 HAProxy 将 HTTP 和 HTTPS 流量转发到我的节点服务器上的端口 8000。

不幸的是,这让我陷入了一个棘手的境地:我需要为我的 http 和 https 服务器使用相同的端口。如果在某种程度上更容易的话,我也会很满意仅仅将 http 重定向到 https。

但是,现在,我处于被迫选择 HTTP -- 或 -- HTTPS 的位置

为了包含代码...

https.createServer(api.credentials, api.server).listen(8000);
http.createServer(api.server).listen(8000); // ERR ADDR IN USE
4

2 回答 2

4

您不能将多个服务器绑定到同一个端口,但您可以打开一个 TCP 服务器并将流量代理到相关的 HTTP 实现。

httpx.js

'use strict';
let net = require('net');
let http = require('http');
let https = require('https');

exports.createServer = (opts, handler) => {

    let server = net.createServer(socket => {
        socket.once('data', buffer => {
            // Pause the socket
            socket.pause();

            // Determine if this is an HTTP(s) request
            let byte = buffer[0];

            let protocol;
            if (byte === 22) {
                protocol = 'https';
            } else if (32 < byte && byte < 127) {
                protocol = 'http';
            }

            let proxy = server[protocol];
            if (proxy) {
                // Push the buffer back onto the front of the data stream
                socket.unshift(buffer);

                // Emit the socket to the HTTP(s) server
                proxy.emit('connection', socket);
            }
            
            // As of NodeJS 10.x the socket must be 
            // resumed asynchronously or the socket
            // connection hangs, potentially crashing
            // the process. Prior to NodeJS 10.x
            // the socket may be resumed synchronously.
            process.nextTick(() => socket.resume()); 
        });
    });

    server.http = http.createServer(handler);
    server.https = https.createServer(opts, handler);
    return server;
};

例子.js

'use strict';
let express = require('express');
let fs = require('fs');
let io =  require('socket.io');

let httpx = require('./httpx');

let opts = {
    key: fs.readFileSync('./server.key'),
    cert: fs.readFileSync('./server.cert')
};

let app = express();
app.use(express.static('public'));

let server = httpx.createServer(opts, app);
let ws = io(server.http);
let wss = io(server.https);
server.listen(8080, () => console.log('Server started'));

于 2017-02-03T08:21:20.963 回答
1

您不能让两个任务在同一个端口上侦听。HTTP 在默认端口 80 上侦听,HTTPS 在默认端口 443 上侦听。您将需要管理 HAProxy 程序以进行相应的转发。

我发现这个漂亮的页面建议你像这样设置你的配置:

全球的
  stats socket ./haproxy.stats 级别管理员

前端 ft_http
    绑定:80
    模式http
    default_backend bk_http

前端 ft_https
    绑定:443
    模式 tcp
    default_backend bk_https

后端 bk_http
    模式http
    平衡循环
    坚持 src 表 bk_https
    默认服务器间 1s
    服务器 s1 192.168.1.1:80 检查 id 1
    服务器 s2 192.168.1.2:80 检查 id 2

后端 bk_https
    模式 tcp
    平衡循环
    stick-table 类型 ip 大小 200k 过期 30m
    坚持src
    默认服务器间 1s
    服务器 s1 192.168.1.1:443 检查 id 1
    服务器 s2 192.168.1.2:443 检查 id 2

请注意上面的配置如何将 Node.js 端口设置为 80 和 443。由于 Node.js 没有管理员权限,您可能需要编辑端口以使其像这样工作:

后端 bk_http
    模式http
    平衡循环
    坚持 src 表 bk_https
    默认服务器间 1s
    服务器 s1 192.168.1.1:8000 检查 id 1
    服务器 s2 192.168.1.2:8000 检查 id 2

后端 bk_https
    模式 tcp
    平衡循环
    stick-table 类型 ip 大小 200k 过期 30m
    坚持src
    默认服务器间 1s
    服务器 s1 192.168.1.1:8001 检查 id 1
    服务器 s2 192.168.1.2:8001 检查 id 2

您还需要将 Node.js 代码更改为:

https.createServer(api.credentials, api.server).listen(8001);
http.createServer(api.server).listen(8000);

我不熟悉 HAProxy,所以我可能会离开。

于 2013-03-16T01:21:28.280 回答