Cisco 7500 series в качестве NAS

chtito2
Сообщения: 479
Зарегистрирован: Чт апр 17, 2008 5:26 pm

Сообщение chtito2 »

Не можно, а нужно! :) Полный патч не даю т.к. там достаточно изменений, не имеющих отношения к traffic2sql, но на словах примерно так:

0. Собственно, сама таблица:
CREATE TABLE `ipn_traffic_summary` (
`uid` int(10) unsigned NOT NULL,
`traffic_class` smallint(5) unsigned NOT NULL,
`traffic_in` bigint(20) unsigned NOT NULL,
`traffic_out` bigint(20) unsigned NOT NULL,
UNIQUE KEY `ipn_traffic_summary_uniq` (`uid`,`traffic_class`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
1. В Abills/mysql/Ipn_Collector.pm в функции traffic_add_user() в условии добавляется:
if ($DATA->{INBYTE} + $DATA->{OUTBYTE} > 0) {
....

$self->query($db,
"UPDATE ipn_traffic_summary
SET traffic_in=traffic_in+'$DATA->{INBYTE}', traffic_out=traffic_out+'$DATA->{OUTBYTE}'
WHERE uid='$DATA->{UID}' AND traffic_class='$DATA->{TARFFIC_CLASS}';", 'do');

}
2. В traffic_user_get() череда if/elsif/else (до foreach) окружается в if/else:
if ($attr->{MONTHLY_TRAFFIC_HACK}) {
$self->query($db, "SELECT traffic_class, traffic_in / $CONF->{MB_SIZE}, traffic_out / $CONF->{MB_SIZE}
FROM ipn_traffic_summary
WHERE uid='$uid';");

} else {
череда if/elseif/else что была раньше
}

foreach my $line (@{ $self->{list} }) {
Обратите внимание что изменение полностью обратно-совместимо и не затронуло текущей функциональности: чтобы получить новую ф-ть нужно послать traffic_user_get() аттрибут MONTHLY_TRAFFIC_HACK => 1.

3. В traffic2sql в единственный вызов traffic_user_get() добавляется этот самый аттрибут:
my($used_traffic) = $Ipn->traffic_user_get({ UID => $uid, MONTHLY_TRAFFIC_HACK => 1 });
В общем-то все остальное делалось ради этого 3-го шага. Теперь traffic2sql у меня выполняется в 10-15 раз быстрее.

4. В Abills/mysql/Users.pm в функцию добавления нового пользователя add() добавляется в самый конец (разумеется перед return :))
$self->query($db, "INSERT INTO ipn_traffic_summary (uid, traffic_class)
VALUES ('$self->{UID}',0), ('$self->{UID}',1);", 'do');
Это подразумевает, что у вас как и у меня два класса траффика для каждого тарифного плана (0 - инет, 1 - страна). Можете добавить или удалить классы при необходимости - UPDATE, приведенный в 1-м шаге прозрачно подхватит ваши изменения.

5. Накопленный в таблице ipn_traffic_summary трафик нужно в начале очередного учетного периода обнулять. Для этого:
а) в traffic2sql поближе к началу добавляем:
my ($hour, $min) = (localtime)[2,1];
Тем самым узнав текущий час и минуту.
б) Теперь объяснить где изменить немножко сложно: в traffic2sql, функции processing(), внутри условия
if ($Ipn->{INTERIM}{$ip}) {
сразу ПОСЛЕ большого условия while:
while(my($k, $v)=each %$ip_stats) {
...
}
Добавляем:
# XXX this must occur _after_ a "periodic monthly", so that we deal with updated activate date here:
if ($hour == 0 && $min == 1) {
$db->do("UPDATE ipn_traffic_summary t JOIN users u USING (uid)
SET traffic_in=0, traffic_out=0
WHERE activate=DATE_FORMAT(NOW(), '%Y-%m-%d')");
}
Важно это добавить внутри if ДО этого else:
}
#If user Don't have interium traffic
elsif($total_user_sum > 0 && $uid > 0) {
С индентацией в файле не очень гладко, но учтя указанные моменты найти несложно.

Как сказано в комментарии обнулять нужно строго после periodic monthly. У меня periodic monthly запускается ровно в полночь, а подчистка UPDATE через минуту после него в 00:01 ежедневно. У меня учетный период длится с числа по число (это требует не указанных здесь изменений в Абиллсе), но вполне можно приспособить для тех, у кого с 1-го по 1-е.

Перед началом эксплуатации необходимо мигрировать существующую юзерскую базу. Это тривиально и происходит двумя запросами MySQL 5.1 (для двух классов трафика):
begin;
insert into ipn_traffic_summary (uid,traffic_class) (select distinct(uid),0 from users);
insert into ipn_traffic_summary (uid,traffic_class) (select distinct(uid),1 from users);
commit;
Вот и все! В результате traffic2sql длится 1-2 секунды.

Ответить