Python S SH Прорыв туннеля на AWS Elasti c Beanstalk - PullRequest
0 голосов
/ 14 января 2020

Текущее состояние

  • A Flask Сервер, развернутый на AWS Elasti c Beanstalk в качестве рабочего.
  • Cronjob вызывает запрос 4 раза в день ночью с 20-минутными перерывами между
  • Этот триггер запускает соединение S SH (для последующего подключения к MySQL) [См. Код 1]

Проблема

Этот код работает отлично в течение нескольких дней и, возможно, даже 1 или 2 недель. Но после этого приложение разрывается со следующей ошибкой:

Problem setting SSH Forwarder up: Couldn't open tunnel 127.0.0.1:3309 <> 10.10.0.30:3306 might be in use or destination not reachable

Обходное решение

Я просто перезапускаю Elasti c Beanstalk Instance, и все работает нормально для следующие несколько дней. Но это не долгосрочное решение.

Вопрос

Как мне убедиться, что S SH не выходит из строя? Что может быть причиной этой неудачи? Я создаю слишком много туннелей S SH? Они делают ie всю ночь? У кого-нибудь есть предложения, как решить или как сузить проблему?

Коды

helper.py

def _get_tunnel():
# print('Creating SSH-Tunnel')
private_key_path = os.getcwd() + "/src/ms_student_onboarding"
connection = None
try:
    connection = sshtunnel.SSHTunnelForwarder(
        (config.data["ssh"][config.data["env"]]["host"], 22),
        ssh_username=config.data["ssh"][config.data["env"]]["username"],
        ssh_password=config.data["ssh"][config.data["env"]]["password_sql"],
        ssh_pkey=private_key_path,
        ssh_private_key_password=config.data["ssh"][config.data["env"]][
            "password_sql"
        ],
        remote_bind_address=(
            config.data["ssh"][config.data["env"]]["remote_bind_address"],
            3306,
        ),
        local_bind_address=(
            config.data["ssh"][config.data["env"]]["local_bind_address"],
            config.data["ssh"][config.data["env"]]["local_port"],
        )
        # set_keepalive=60
    )
    return connection
except:
    print("_get_tunnel exeption. Closing Connection.")
    if connection is not None:
        connection.stop()
    traceback.print_exc(file=sys.stdout)
    return None

flask .py

    if config.data["env"] == "live":
    tunnel = connector._get_tunnel()
    try:
        tunnel.start()
        print("Tunnel Created and Started")
        time.sleep(2)
    except (
        sshtunnel.BaseSSHTunnelForwarderError,
        sshtunnel.HandlerSSHTunnelForwarderError,
    ) as e:
        tunnel.stop()
        return f"Failed to start SSH Tunnel. Stopping. {e}"

try:
    connection = connector._get_mysql_conection()
except pymysql.OperationalError as e:
    log = f"Failed to create MySQL Connection in server.py: {e}"
    print(log)
    traceback.print_exc()
    return log

try:

    # DO SERVICE STUFF HERE - ACTUAL CODE CUTTED OUT #

    # Close open mysql-connection and then ssh-tunnel
    if connection is not None:
        connection.close()

    if config.data["env"] == "live" and tunnel is not None:
        tunnel.stop()

    print(f"{service} Job Finished!")
    response = application.response_class(
        response=json.dumps({"success": True}),
        mimetype="application/json",
        status=200,
    )
    return response
except Exception as e:
    print(f"{service} Service failed in server.py: {e}")
    """
    Since we defined the tunnel and connection handler centrally in our server,
    we can close them after successful or failed execution and thus limiting
    potential connection errors either to via ssh tunnels or mysql servers.
    """
    if connection is not None:
        connection.close()
    if config.data["env"] == "live" and tunnel is not None:
        tunnel.stop()
    traceback.print_exc()
    return f"Exception occurred in {service} while executing {service}_service: {e}"
...