2

我正在尝试编写一个简单的负载均衡器。它工作正常,直到其中一台服务器(BalanceServer)没有关闭连接然后......客户端(ReverseProxy)断开连接,但与 BalanceServer 的连接保持打开状态。我尝试将回调(#3)添加到ReverseProxy.connectionLost以关闭与其中一台服务器的连接,就像我在服务器断开连接时关闭连接(clientLoseConnection)一样,但当时 ServerWriter 为 Null,我无法在 # 处终止它1 和 #2


当一侧断开连接时,如何确保所有连接都关闭?我想当客户端和其中一个服务器都挂起时,这里的某种超时也会很好,但是如何添加它以便它在两个连接上都有效?


from twisted.internet.protocol import Protocol, Factory, ClientCreator
from twisted.internet import reactor, defer
from collections import namedtuple

BalanceServer = namedtuple('BalanceServer', 'host port')

SERVER_LIST = [BalanceServer('127.0.0.1', 8000), BalanceServer('127.0.0.1', 8001)]

def getServer(servers):
    while True:
        for server in servers:
            yield server

# this writes to one of balance servers and responds to client with callback 'clientWrite'
class ServerWriter(Protocol):
    def sendData(self, data):
        self.transport.write(data)

    def dataReceived(self, data):
        self.clientWrite(data)

    def connectionLost( self, reason ):
        self.clientLoseConnection()

# callback for reading data from client to send it to server and get response to client again    
def transferData(serverWriter, clientWrite, clientLoseConnection, data):
    if serverWriter:
        serverWriter.clientWrite = clientWrite
        serverWriter.clientLoseConnection = clientLoseConnection
        serverWriter.sendData(data)

def closeConnection(serverWriter):
    if serverWriter: #1 this is null
        #2 So connection is not closed and hangs there, till BalanceServer close it 
        serverWriter.transport.loseConnection()

# accepts clients
class ReverseProxy(Protocol):
    def connectionMade(self):
        server = self.factory.getServer()
        self.serverWriter = ClientCreator(reactor, ServerWriter)
        self.client = self.serverWriter.connectTCP( server.host, server.port )

    def dataReceived(self, data):
        self.client.addCallback(transferData, self.transport.write, 
                    self.transport.loseConnection, data )

    def connectionLost(self, reason):
        self.client.addCallback(closeConnection) #3 adding close doesn't work


class ReverseProxyFactory(Factory):
    protocol = ReverseProxy
    def __init__(self, serverGenerator):
        self.getServer = serverGenerator

plainFactory = ReverseProxyFactory( getServer(SERVER_LIST).next )
reactor.listenTCP( 7777, plainFactory )
reactor.run()
4

1 回答 1

1

您可能想查看twisted.internet.protocols.portforward连接两个连接然后断开它们的示例。或者只使用txloadbalancer,甚至不编写自己的代码。

但是,loseConnection如果从来没有任何流量通过它,则永远不会强行终止连接。因此,如果您没有应用程序级别的 ping 或任何数据通过您的连接,它们可能仍然永远不会关闭。 这是 Twisted 中长期存在的错误。 实际上,存在时间最长的错误。也许您想帮助解决问题:)。

于 2010-12-05T22:26:13.013 回答