|
|
ru.linux- RU.LINUX --------------------------------------------------------------------- From : Sergey Mudry 2:5020/400 03 Mar 2004 00:05:51 To : Eugene B. Berdnikov Subject : Re: раздача траффика -------------------------------------------------------------------------------- On Fri, 27 Feb 2004, Eugene B. Berdnikov wrote: EBB> Правильно. Поэтому шейпить надо на стороне провайдера. Hо если провайдер EBB> сумел правильно сконфигурить длину очереди в своем роутере (а не вогнать EBB> его в безобразный дропподром), то есть надежда, что с ним можно поговорить EBB> и о шейпинге. Который если будет - скорее всего за деньги. Ага, и маскарад туда же переносить, потому как иначе не поделишь между моими пользователями. EBB> Кроме того, не у каждого провайдера своя AS и пяток peer'ов, даже в EBB> Москве. А это значит, что прогнуться днём может не клиентский шнурок, а EBB> ствол до точки обмена трафиком, и тогда сам провайдер вряд ли что-то сможет EBB> сделать. Hет, прогибается именно мой телефонный шнурок. Если верить провайдерским графикам, их внешние каналы бывают загружены максимум на 75-80% EBB> Hасколько это реалистично - не знаю. Проблема усугубляется тем, что EBB> пустой ack маленький (типично 40-50 байт), поэтому с cbq я бы даже EBB> возиться не стал. В htb модель мира получше, можно попытаться... Пробовал повозиться с ack'ами... что-то ничего не получилось. Сделал по-другому: при помощи htb ограничиваю весь исходящий трафик на eth0 (кроме интерактивного, предназначенного для самого роутера), внутрь htb засунул wrr - он равномерно делит между клиентами (esfq там тоже должен работать). И адаптивный алгоритм подбора общего ограничения, исходя из желаемого времени ping'а до удаленного конца ppp0 (это должно довольно точно соответствовать длине провайдерской очереди). Экспериментирую с вот таким скриптом: === Cut === #!/bin/bash PATH=/bin:/sbin:/usr/bin:/usr/sbin PAUSE_TIME=20 MEASURE_TIME=60 NUM_OF_PINGS=5 LOCAL_IP=`ifconfig eth0 | grep "inet addr:[0-9\.]*" -o | cut -b 11-` PING_IP_TARGET=`ifconfig ppp0 | grep "P-t-P:[0-9\.]*" -o | cut -b 7-` MIN_PING_TIME=600 MAX_PING_TIME=1200 RATE=3000 # initial rate, bps STEP=500 # increasing step, bps MIN_RATE=2000 setup_rate() { tc class change dev eth0 parent 8000:0 classid 8000:1 \ htb rate ${1}bps prio 5 } count_rx_bytes() { tc -s qdisc | awk \ 'BEGIN { F=0 } /qdisc htb 8000:/ { F=1 } /Sent/ { if(F!=0) print $2; F=0 }' } ping_time() { ping -w $MEASURE_TIME \ -i $(( $MEASURE_TIME / $NUM_OF_PINGS )) \ -c $NUM_OF_PINGS \ -s 8 -n $1 | grep "time=[0-9]*" -o | cut -b 6- } cleanup() { echo "Resetting..." tc qdisc del dev eth0 root 2>/dev/null exit 0 } avg_ping() { POS=$(( ( $1 + 3 ) / 2 )) eval echo \${$POS} } trap 'cleanup' 2 tc qdisc del dev eth0 root 2>/dev/null R2Q=$(( $MIN_RATE / 1500 )) tc qdisc add dev eth0 root handle 8000: htb default 1 r2q $R2Q tc class add dev eth0 parent 8000:0 classid 8000:1 htb \ rate ${MIN_RATE}bps prio 5 tc class add dev eth0 parent 8000:0 classid 8000:2 htb \ rate 50Kbps prio 5 tc qdisc add dev eth0 parent 8000:1 handle 8002: wrr dest ip 32 0 tc filter add dev eth0 parent 8000:0 protocol ip prio 5 u32 \ match ip src $LOCAL_IP \ match ip sport 3128 0xFFFF \ flowid 8000:1 tc filter add dev eth0 parent 8000:0 protocol ip prio 5 u32 \ match ip src $LOCAL_IP \ flowid 8000:2 for((NUM=32;NUM>=1;--NUM)); do HNUM=$(printf %X $NUM) tc class change classid 8002:$HNUM dev eth0 \ wrr min1=0.3 max1=1.0 decr1=0.000000003 incr1=0.0001 done echo "Setting initial rate to $RATE" ACTION="NONE" while true; do sleep $PAUSE_TIME RC1=`count_rx_bytes` echo -n "Timing..." ping_time $PING_IP_TARGET >/tmp/ping-temp & PING_PID=$! sleep $MEASURE_TIME RC2=`count_rx_bytes` RX=$(( ( $RC2 - $RC1 ) / $MEASURE_TIME )) RX_LOAD=$(( $RX * 100 / $RATE )) echo -n " RX: $RX($RX_LOAD%) ..." wait $PING_PID PING=`sort -n /tmp/ping-temp` AVG_PING=`avg_ping $NUM_OF_PINGS $PING` echo -ne "\tPING:" $PING " ($AVG_PING)" if [ $AVG_PING -gt $MAX_PING_TIME -a $RX_LOAD -gt 50 ]; then RATE=$(( $RATE * 80 / 100 )) [ $ACTION == "UP" ] && STEP=$(( $STEP / 2 )) [ $RATE -lt $MIN_RATE ] && RATE=$MIN_RATE ACTION="DOWN" elif [ $AVG_PING -lt $MIN_PING_TIME -a $RX_LOAD -gt 50 ]; then [ $ACTION == "UP" ] && STEP=$(( $STEP * 125 / 100 )) RATE=$(( $RATE + $STEP )) ACTION="UP" else ACTION="NONE" echo fi if [ $ACTION != "NONE" ]; then echo -e "\t-- rate $ACTION to $RATE" setup_rate $RATE fi done === Cut === В двух словах: ppp0 - наружу (маскарад), eth0 - в локалку. Выдерживается пауза 20 сек, в течение следующих 60 сек равномерно посылается 5 ping'ов, время измеряется и усредняется. Также одновременно с ping'ами подсчитывается входящий трафик за эти 60 сек, вычисляется скорость. Если средний ping вылазит из заданных пределов - соответственно корректируем ограничение скорости на eth0. Кроме того, если загрузка линии (входящий трафик, деленный на выставленное ограничение) окажется меньше 50%, то результат ping'а считается недостоверным, и ничего не меняется. О результатах измерений и переключениях скорости пишет на stdout. Довольно терпимо получается, завтра попробую оставить на день, посмотрю статистику. EBB> В крайнем случае можно сделать бутерброд с tfb внутри - говорят, оно EBB> точное как аптекарские весы (и мои измерения это подтверждают:). Ага, а токены - это гирьки :) htb вроде тоже неплох, правда на очень мелких ограничениях - не уверен. -- С уважением, Serg. --- ifmail v.2.15dev5.3 * Origin: Donbass Internet Center DIPT (2:5020/400) Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор
Архивное /ru.linux/13331f9aeaf9e.html, оценка из 5, голосов 10
|