LINUX.ORG.RU
решено ФорумAdmin

Проверять не отвалился ли клиент

 , , , , tcpflow


0

2

Есть такая задача — проверять не отвалился ли клиент.

Подробнее:

На локалке крутится «монолитный» http-клиент. В его код лазить не получится. Т.е. тупо приложение, и все.

Вообще, основной причиной является то, что на стороне клиента сеть плохая и сервер отпинывает клиента из-за долгих таймаутов.

Нужно каким либо способом проверять что он все еще получает данные с сервера. И если он «подвис» то убить клиента по пиду и запустить его заново.

Мои предположения:

Пишем баш-скрипт который в цикле проверяет что-то, например из tcpdump или tcpflow или netstat или ???, с-grep-ать/с-sed-ить и если что-то не понравилось то перезапускает клиента.

Нужна ваша помощь в подсказках:

1) откуда именно можно взять инфу о статусе соединения и факте отсутствия/наличия процесса передачи данных извне локально работающему клиенту?
2) основных критических причинах по которым можно считать что что-то пошло не так, т.е., что именно в статусах считать за ошибку?
3) возможен совершенно иной (не тот до которого додумался я) принцип проверки?

UPD: кстати, могу рассмотреть какой-либо апликейшн в качестве прокси-прослойки которое сможет задетектить сетевой касяк само, или его будет удобнее использовать нежели имеющегося чугунного клиента, но всеравно оно должно передавать клиенту данные которые успешно получило.

★★★★★

Последнее исправление: deep-purple (всего исправлений: 8)

" http-клиент" вообще это что ? Как он данные получает ? Запрос-ответ? Или данные «рекой льются»? Вобщем «мало золота».

anc ★★★★★
()

Если клиент умеет использовать прокси, можно запилить тупую проксю, которая будет мониторить или даже перезапускать клиента. Это программер-вей.

Еще я как-то давно ковырялся в пакетах через ip_conntrack. У него есть урезанная фигня в /proc/net, а есть вот это.

staseg ★★★★★
()
Ответ на: комментарий от staseg

Умеет. А какая прокся умеет? Ведь тогда это прокся будет отваливаться с точки зрения сервера. Не так ли? Ну т.е. сервер будет отпинывать проксю. Будет ли в проксе толк или там есть какие-то волшебные рычажки? Аааа, все, перечитал, понял, свою проксю писать...

deep-purple ★★★★★
() автор топика
Последнее исправление: deep-purple (всего исправлений: 1)
Ответ на: комментарий от staseg

Ссылка норм. Но чот жырно будет ради моей мелкой затеи. Я думал что будет вариант попроще. Но этот тоже не откидываю.

deep-purple ★★★★★
() автор топика
Последнее исправление: deep-purple (всего исправлений: 1)
Ответ на: комментарий от anc

Вообще клиент серит в stdout вполне конкретным сообщением «Connection reset by peer», но, кажись, не в тот момент. Щас проверяю.

Блин, его хрен поймаешь. Оно может и несколько часов без разрыва пахать, а может каждую минуту обрываться. Так что с этим пока не поймаю точно известно не будет.

deep-purple ★★★★★
() автор топика
Последнее исправление: deep-purple (всего исправлений: 1)
Ответ на: комментарий от deep-purple

Нет. Нельзя ориентироваться на это сообщение.

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от deep-purple

Тут вопрос не в грепе, ведь при отсутствии трафика грепать нечего будет :) А в выявлении самого отсутствия трафика.
А так man pcap-filter. прописывается в конце tcpdump любыми условиями, например tcpdump -i eth0 src ip-сервера and src port 80

anc ★★★★★
()
Ответ на: комментарий от staseg

ip_conntrack

Эта мысль меня навела на достаточно простое решение. Создаем правило в iptables, грепаем счетчик пакетов, если не изменяется за какое-то время то рестартуем клиента.

anc ★★★★★
()
Ответ на: комментарий от anc

пусти поток от клиента через socat.

socat tcp-l:localport,reuseaddr tcp:remoteserver:remoteport
http-client localhost:localport

socat мрёт, если одна из сторон закрыла соединение(скорее всего это будет закрытие со стороны сервера), убиваем нашего «чудо» http клиента и запускаем снова socat и http клиента. Получаем проксю «из говна и палок».

dhampire ★★★
()
Ответ на: комментарий от dhampire

Да я так понял что ТС сам факт закрытия соединения не интересует, его интересует прекращение потока данных. Хотя да, тоже одно из «изящных» решений :)

anc ★★★★★
()
Ответ на: комментарий от dhampire

anc

Хы )) Сработало!

Правда еще глянул в маны и нашел там опцию -T она гасит соката если ничего не происходит N секунд. Опытным путем подобрад 7 секунд (клиент кеширует). Вобщем оказалось что соединение не обрывается, а просто ничего не происходит. Не знаю почему. Наверное что-то на низком уровне, потеря пакетов, чексуммы. В любом случае проблемой является плохая сеть и костылик из соката помогает задетектить. Пойду скрипт калякать.

deep-purple ★★★★★
() автор топика
Последнее исправление: deep-purple (всего исправлений: 1)
Ответ на: комментарий от deep-purple

Накалякал. Копипаста ))

Как его облагородить можно?

#!/bin/bash


SOCAT="socat -T7 tcp-l:6060,reuseaddr tcp:foo.bar:9999"
CLIENT="client http://localhost:6060/"
APP="encoder"


SOCAT_PID=0
CLIENT_PID=0
APP_PID=0

# main loop
while :
do
    # kill all depends processes
    if [ $APP_PID -gt 0 ]; then
        echo "Kill encoder process $APP_PID"
        kill -9 "$APP_PID" >/dev/null 2>&1
        APP_PID=0
    fi
    if [ $CLIENT_PID -gt 0 ]; then
        echo "Kill client process $CLIENT_PID"
        kill -9 "$CLIENT_PID" >/dev/null 2>&1
        CLIENT_PID=0
    fi
    if [ $SOCAT_PID -gt 0 ]; then
        echo "Kill socat process $SOCAT_PID"
        kill -9 "$SOCAT_PID" >/dev/null 2>&1
        SOCAT_PID=0
    fi
    # start all depends processes
    echo "Starting socat.."
    eval "$SOCAT >/dev/null 2>&1 &"
    SOCAT_PID=$!
    sleep 2
    echo "Starting client.."
    eval "$CLIENT >/dev/null 2>&1 &"
    CLIENT_PID=$!
    sleep 2
    echo "Starting encoder.."
    eval "$APP >/dev/null 2>&1 &"
    APP_PID=$!
    sleep 2
    # checking loop
    while :
    do
        sleep 2
        if ! kill -s 0 "$SOCAT_PID" >/dev/null 2>&1; then
            echo "FUCK! Restart all!"
            break
        fi
    done
done

deep-purple ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.