简体   繁体   English

使用socket.io / socket.io-redis / rediscloud / node.js在Heroku上的2个测功机出错

[英]Errors going to 2 dynos on Heroku with socket.io / socket.io-redis / rediscloud / node.js

I have a node.js / socket.io app running on Heroku. 我在Heroku上运行了一个node.js / socket.io应用程序。 I am using socket.io-redis with RedisCloud to allow users who connect to different dynos to communicate, as described here . 我使用socket.io,Redis的与RedisCloud允许谁连接到不同的DYNOS用户沟通,描述在这里

From my app.js: 从我的app.js中:

var express = require('express'),
app = express(),
http = require('http'),
server = http.createServer(app),
io = require('socket.io').listen(server),
redis = require('redis'),
ioredis = require('socket.io-redis'),
url = require('url'),
redisURL = url.parse(process.env.REDISCLOUD_URL),

And later in app.js ... 后来在app.js中...

var sub1 = redis.createClient(redisURL.port, redisURL.hostname, {
    no_ready_check: true,
    return_buffers: true
});
sub1.auth(redisURL.auth.split(":")[1]);
var pub1 = redis.createClient(redisURL.port, redisURL.hostname, {
    no_ready_check: true,
    return_buffers: true
});
pub1.auth(redisURL.auth.split(":")[1]);
var redisOptions = {
    pubClient: pub1,
    subClient: sub1,
    host: redisURL.hostname,
    port: redisURL.port
};
if (io.adapter) {
    io.adapter(ioredis(redisOptions));
    console.log("mylog: io.adapter found");
}

It is kind of working -- communication is succeeding between dynos. 这是一种工作-测功机之间的交流正在成功。

Three issues that happen with 2 dynos but not with 1 dyno: 2 dynos发生三个问题,而1 dyno则没有:

1) There is a login prompt which comes up and works reliably with 1 dyno but is hit-and-miss with 2 dynos -- may not come up and may not work if it does come up. 1)出现一个登录提示,该提示可与1个dyno一起可靠地工作,但与2个dyno一起可反复操作-可能不会出现,如果出现,则可能会不起作用。 It is (or should be) triggered by the io.sockets.on('connection') event. 它是(或应该)由io.sockets.on('connection')事件触发的。

2) I'm seeing a lot of disconnects in the server log. 2)我在服务器日志中看到很多断开连接。

3) Also lots of errors in the client console on Chrome, for example: 3)Chrome的客户端控制台中还存在很多错误,例如:

socket.io.js:5039 WebSocket connection to 'ws://example.mydomain.com/socket.io/?EIO=3&transport=websocket&sid=F8babuJrLI6AYdXZAAAI' failed: Error during WebSocket handshake: Unexpected response code: 503

socket.io.js:2739 POST http://example.mydomain.com/socket.io/?EIO=3&transport=polling&t=1419624845433-63&sid=dkFE9mUbvKfl_fiPAAAJ net::ERR_INCOMPLETE_CHUNKED_ENCODING

socket.io.js:2739 GET http://example.mydomain.com/socket.io/?EIO=3&transport=polling&t=1419624842679-54&sid=Og2ZhJtreOG0wnt8AAAQ 400 (Bad Request)

socket.io.js:3318 WebSocket connection to 'ws://example.mydomain.com/socket.io/?EIO=3&transport=websocket&sid=ITYEPePvxQgs0tcDAAAM' failed: WebSocket is closed before the connection is established.

Any thoughts or suggestions would be welcome. 任何想法或建议都将受到欢迎。

Yes, like generalhenry said, the issue is that Socket.io requires sticky sessions (meaning that requests from a given user always go to the same dyno), and Heroku doesn't support that. 是的,就像generalhenry所说的那样,问题在于Socket.io需要粘性会话(这意味着来自给定用户的请求始终使用相同的dyno),而Heroku不支持。

(It works with 1 dyno because when there's only 1 then all requests go to it.) (它与1个dyno一起使用,因为只有1个dyno时,所有请求都发送给它。)

https://github.com/Automattic/engine.io/issues/261 has a lot more good info, apparently web sockets don't really require sticky sessions, but long-polling does. https://github.com/Automattic/engine.io/issues/261有很多很好的信息,显然Web套接字确实不需要粘性会话,但长轮询却需要。 It also mentions a couple of potential work-arounds: 它还提到了一些潜在的解决方法:

  • Roll back to socket.io version 0.9.17, which tries websockets first 回滚到socket.io版本0.9.17,该版本首先尝试使用websockets
  • Only use SSL connections which, makes websockets more reliable (because ISP's and corporate proxies and whatnot can't tinker with the connection as easily.) 仅使用SSL连接,这会使websocket更加可靠(因为ISP和公司的代理以及诸如此类的东西都无法像以前那样轻易地修改连接。)

You might get the best results from combining both of those. 结合使用这两种方法,可能会获得最佳结果。

  • You could also spin up your own load balancer that adds sticky session support, but by that point, you're fighting against Heroku and might be better off on a different host. 您还可以启动自己的负载平衡器,以增加粘性会话支持,但是到那时,您正在与Heroku作战,在其他主机上可能会更好。

RE: your other question about the Node.js cluster module: it wouldn't really help here. RE:关于Node.js集群模块的另一个问题:在这里并没有真正的帮助。 It's for using up all of the available CPU cores on a single server/dyno, 它用于耗尽单个服务器/ dyno上所有可用的CPU内核,

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM