счетчик на сайт (программная часть)
Файл inc_count.php:
<?
$bNew = 1;
$a = getdate;
if($was)
{
$period = ($a['hours']-$hours + 24*($a['yday']-$yday)
+ 365*($a['year']-$year*60 + $a['minutes']-$minutes;
if ($period < 30) $bNew = 0; // полчаса
}
setcookie("was","1");
setcookie("minutes",$a['minutes']);
setcookie("hours",$a['hours']);
setcookie("yday",$a['yday']);
setcookie("year",$a['year']);
if ($bNew)
{
$f = fopen("counter.dat","r");
$i = fgets($f,20);
fclose($f);
$i++;
$f = fopen("counter.dat","w");
fputs($f,"$i");
fclose($f);
}
?>
Вызов этого скрипта в коде файла index.html (сайт был на фреймах, index.html - основной документ, в нем фреймсет):
...
<frame src="inc_count.php">
...
Вывод результатов в документе left.shtml:
You are the
<>
visitor of our site.
это конечно хорошо, но интересовало далеко не это, а что - то наподобе spylog или mail.ru'counter...
В чем проблема?
Можно рассматривать системы от простейшей - приведенной выше.
До сложнейших распределенных способов. Имел минимальное общение
с такими системами, и то понимаю что вопрос
слишком широк, а методы оптимизации - как всегда ноу хау
каждого из счетчиков.
Книжки о таком не пишут - маловата аудитория, так что каждый
извращается как может. Либо покупает готовый продукт.
Придется ее делать отдельной частью, что сильно замедлит работу.
В свое время делал примерно так.
/* откроем файл и добавим в него запись */
fd=0; fdlock=0;
/* откроем файл защелку*/
fdlock=open(confData.lockFileName,O_RDWR);
if(fdlock < 0)
{
errprintf(errfile,"Can't open lockfile: ");
errprintf(errfile,strerror(errno; exit(1);
}
flock(fdlock,LOCK_SH);
/* если все чисто - откроем файл данных и запишем все в него*/
fd=open(confData.dataFileName,O_WRONLY|O_CREAT|O_APPEND,
S_IRUSR|S_IWUSR|S_IRGRP);
if(fd < 0)
{
errprintf(errfile,"Can't open output\n");
errprintf(errfile,strerror(errno; exit(1);
}
c_to_out_file[11+11+11+5*OTHERSTRINGLEN+5+10+DELTA-1]='\0';
if(write(fdconst void*)c_to_out_file,strlen(c_to_out_file==-1)
{
errprintf(errfile,"Can't write output file ");
errprintf(errfile,strerror(errno;
}
close(fd);
flock(fdlock,LOCK_UN);
close(fdlock);
lock файл нужен был для того, чтобы из файла с данными безболезненно все отгребать
причем c_to_out_file - хитрая строка, которую можно было проверить на целостность
ЗЫ Идея не в счетчике для своего сайта.. - это давно пройденый этап... Идея в создании своего spyloga с нагрузкой примерно в 100000 - 1000000 обращений в сутки...(показов счетчиков) со 100 - 10000 пеользователей....
собиратель -> отрезатель -> заливатель
соответствено - собиратель был самым маленьким и быстрым cgi скриптом, который формировал
строчку соответствующую запросу к счетчику + быстро выдавал картинку (тоже неочевидно как
сделать быстро, я генерил статику, так что с ней не было проблем)
отрезатель с некоторым интервалом забирал данные из файла не мешая собирателю и
сохранял их в другой файл с именем timestamp
заливатель - заливал эти данные из файлов timestamp в базюку
целостность строки с данными проверялась на случаи дисковых и т.п. сбоев, чтобы плохие строчки в базюку не попадали,
и в худшем случае пропадала только 1 строка а не все идущие за ней
лочил файл собиратель, чтобы отрезатель подождал
- это то чего я делал.
Далее в зависимости от фантазии по базюке строятся графики и т.п. (я этим не занимался но
подозреваю, что с большой нагрузкой справятся только способы, связанные с оффлайновой
генерацией отчетов - тогда хоть оценить сложность можно, на лету это нереально
более менее понятно, только вот "строчку соответствующую запросу к счетчику" и проверка целостности данных не до конца ясна (
/* строка для вывода в результирующий файл формат: 10 байт начала - длина строки
* в байтах (записано цифрами и дополнено нулями слева, считается без
* символа новой
* строkи \t, следующие 10 байт - Id пришедшее в QUERY_STRING, \t,
* следущие 10 байт - момент запроса в секундах, \t
* последние 10 байтов - CRC32 строки без 20 байтов служебной информации;
* ,посередине - все поля, интересующие нас, разделены символами
* табуляции \t, идущиев следующем порядке: c_referer c_user_agent
* c_remote_addr c_remote_host c_x_forwarded_for
* \t = знак разделителя может различаться
* */
для которой легко опознать правильность (при правильных выборе <заголовок>,<разделитель> )
<CRC32> - генерировался для всей строки, в принципе данная строка могла расширяться для совместимости с разными версиями
данные брались самые простые, чтобы javascript код не сувать в страницы
Надо хорошо продумать как это всё хранить. Если просто кидать строчку за строчкой в базу, она очень скоро ляжет. Определись, за какой период хочется хранить информацию о посетителях. И насколько подробной должна быть статистика. Скажем, должно ли в ней фиксироваться, откуда пришёл посетитель.
<?
/*
Хлам №5 от Manlix (manlix.ru)
Скрипт написан на php.
Текстовый скрипт посещений, выводит:
общее количество посещений
количество посещений за сегодня
количество уникальный посещений за сегодня
p.s. Используется код из скрипта Manlix SW Graphic Counter v0.3 (http://manliks.ru/manlix)
*/
$date = date("d.m.Y",time;
$date_array = file("date.inc.dat");
$ip = $_SERVER[REMOTE_ADDR];
if ($date_array[0] == $date)
{
$open_today = fopen("today.inc.dat","a");
fwrite($open_today,"$ip\r\n");
fclose($open_today);
}
if ($date_array[0] != $date)
{
$today_array = file("today.inc.dat");
$count_today = count($today_array);
$base_array = file("base.inc.dat");
$all_temp = $count_today + $base_array[0];
$open_w_base = fopen("base.inc.dat","w");
fwrite($open_w_base,$all_temp);
fclose($open_w_base);
$open_w_today = fopen("today.inc.dat","w");
fwrite($open_w_today,"$ip\r\n");
fclose($open_w_today);
$open_w_date = fopen("date.inc.dat","w");
fwrite($open_w_date,$date);
fclose($open_w_date);
}
$today_array = file("today.inc.dat");
$base_array = file("base.inc.dat");
$all = count($today_array) + $base_array[0];
$all_today = count($today_array);
$unique = count(array_unique($today_array;
echo "Всего посещений: $all<br>Сегодня: $all_today<br>Уникальных за сегодня: $unique";
?>
типа сначала строку в файл надо зашифровать определенным способом, а потом ее расшифровать... причем, если что-то в троке не так - не учитывать ее..
По поводу того, как хранить-
статистика максимально-полная за допустим месяц... (расширение до года) - я думаю, стоит ли заниматься всякого рода созданием новых таблиц для каждого пользователя со всей инфой, или стоит индекс по уникальным ид пользователей и выборка из общей таблицы с инфой, или просто одну таблицу для всего ?
ИМХО - конечно вариант с отдельными таблицами для каждого юзера (со всей инфой) более приемлем, однако тут вопрос, а скоко таблиц база удержит..
И возникает вопрос, а какую базу лучше юзать...
По умолчанию - хотелось бы MySQL & PHP использовать....
Еще очень хорошая мысль - хранить не одну таблицу каждого типа для всех юзеров, а несколько, по некоему хешу от ID сайта, таблицы разбросать по разным винтам или даже сервакам. Так все будет клево масштабироваться. А то mysql быстро ляжет.
ну я примерно так и представлял...
Оставить комментарий
stm7884696
интересует меня, как устроена программная часть (серверная) субжа...Неплохо было бы какие-нить исходники посмотреть, и/или описание алгоритмов и работы...
+ что нить по оптимизации...
Ну и обработка статистики для подачи пользователям...
Короче - весь механизм...
Кто знает, поделитесь, плзз...