У меня есть первый ftp-сервер на VDS # 1 (основной), который иногда можно отключить на хостинге. Мы создали второй VDS # 2 (вторичный), который может помочь с отказоустойчивостью, когда VDS # 1 недоступен. VDS # 2 всегда имеет один и тот же список пользователей с VDS # 1, с их именами пользователей, паролями и деревом каталогов.
Когда пользователи не могут получить доступ к VDS # 1, мы хотим автоматически перенаправить их на VDS # 2.
Я написал код GOlang (код ниже), но он не работает должным образом, я не знаю почему, я новичок в вопросах FTP.
Схематическое изображение
Вы можете мне помочь? Возможно, есть способ легко перенаправить FTP-запрос через специальный ответ сервера или что-то в этом роде?
Большое спасибо всем!
func proxyConn(connection net.Conn) {
defer connection.Close()
remoteServer, remoteServerError := getActiveServer()
if remoteServerError != nil {
Error{}.PrintAndSave(remoteServerError.Error())
return
}
remoteConnection, remoteError := net.DialTCP("tcp", nil, remoteServer)
if remoteError != nil {
Error{}.PrintAndSave(remoteError.Error())
return
}
defer remoteConnection.Close()
io.Copy(remoteConnection, connection)
io.Copy(connection, remoteConnection)
}
func getActiveServer() (*net.TCPAddr, error) {
connectedServerIndex := -1
for ftpServerIndex, ftpServer := range FTP_SERVERS {
connectedServer, serverError := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", ftpServer, FTP_DEFAULT_PORT), CONNECTION_TIMEOUT)
if serverError != nil {
if ftpServerIndex == 0 {
// Send e-mail "Server unreachable"
}
} else {
connectedServerIndex = ftpServerIndex
connectedServer.Close()
break
}
}
if connectedServerIndex == -1 {
return nil, errors.New("active servers not found")
}
return net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", FTP_SERVERS[connectedServerIndex], FTP_DEFAULT_PORT))
}
func main() {
localAddress, localAddressErr := net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", LOCAL_ADDRESS, FTP_DEFAULT_PORT))
if localAddressErr != nil {
Error{}.PrintAndSave(localAddressErr.Error())
}
server, serverError := net.ListenTCP("tcp", localAddress)
if serverError != nil {
Error{}.PrintAndSave(serverError.Error())
return
}
for {
connection, connectionError := server.Accept()
if connectionError != nil {
Error{}.PrintAndSave(fmt.Sprintf("failed to accept listener: %v", connectionError))
}
go proxyConn(connection)
}
}