powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / Ограничение количества запросов к скрипту за единицу времени (APC)
5 сообщений из 5, страница 1 из 1
Ограничение количества запросов к скрипту за единицу времени (APC)
    #38148861
poiuytrewq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день,

имеется задача, ограничить количество обращений к скрипту: не чаще одного запроса в 10 секунд с одного IP.
Решил использовать для этой цели APC, пример кода ниже:

Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
<?php

if (extension_loaded('apc'))
{
	$ip = sprintf("%u", ip2long($_SERVER['REMOTE_ADDR']));

	if(apc_exists($ip))
	{
		// Если кеш ещё существует,
		// значит, последнее обращение
		// было менее 10 секунд назад

		die('Too early!');
	}
	else
	{
		// Сохраняем в кеше единичку на 10 секунд

		apc_store($ip, 1, 10);

		// Выполняем действие

		$logFileHandler	= fopen(pathinfo(__FILE__, PATHINFO_FILENAME).'.log', 'a');
		fputs($logFileHandler, date('Y-m-d H:i:s') . "\tlog entry\r\n");
		fclose($logFileHandler);
		
		die('Do action...');
	}
}
else
{
	die('APC not installed!');
}

?>



Заливаю скрипт на хостинг и начинаю лихорадочно обновлять страницу (не дожидаясь даже окончания выполнения скрипта), в результате получаю такой лог:

2013-02-13 11:06:54 log entry
2013-02-13 11:06:56 log entry
2013-02-13 11:07:01 log entry
2013-02-13 11:07:07 log entry
2013-02-13 11:07:11 log entry
2013-02-13 11:07:18 log entry
2013-02-13 11:07:20 log entry
2013-02-13 11:07:29 log entry
2013-02-13 11:07:29 log entry
2013-02-13 11:07:33 log entry

Как видно интервал в 10 секунд между запросами не соблюдается, пробую обновлять страницу примерно раз в секунду, каждый раз дожидаясь полного выполнения скрипта:

2013-02-13 11:09:15 log entry
2013-02-13 11:09:21 log entry
2013-02-13 11:09:32 log entry
2013-02-13 11:09:36 log entry
2013-02-13 11:09:42 log entry
2013-02-13 11:09:53 log entry

Собственно вопрос, почему такое происходит?
...
Рейтинг: 0 / 0
Ограничение количества запросов к скрипту за единицу времени (APC)
    #38148989
poiuytrewq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Может ли кто-нибудь протестировать скрипт на своём севрере?
...
Рейтинг: 0 / 0
Ограничение количества запросов к скрипту за единицу времени (APC)
    #38149086
Inkelyad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
poiuytrewq,

область хранения данных apc, помнится, не шарилась между различными
экземплярами php интерпретатора. (см https://bugs.php.net/bug.php?id=57825] https://bugs.php.net/bug.php?id=57825 )

Те lock переменная у этих запросов на самом деле могла быть разная.
...
Рейтинг: 0 / 0
Ограничение количества запросов к скрипту за единицу времени (APC)
    #38150615
poiuytrewq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Понятно, пробую решить задачу на файлах

Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
<?php

function remove_expired_entries($value)
{
	list($ip, $time) = explode('-', $value);
	if (time() - $time < 10) return true;
}

function clean_entries($value)
{
	list($ip, $time) = explode('-', $value);
	return $ip;
}

$file = 'access.dat';
$data = array();

if(is_readable($file))
{
	$data = array_filter(file('access.dat', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES), 'remove_expired_entries');
}

$ip = sprintf("%u", ip2long($_SERVER['REMOTE_ADDR']));

if(!in_array($ip, array_map('clean_entries', $data)))
{
	$data[] = $ip . '-' . time();
	file_put_contents($file, implode("\n", $data), LOCK_EX);

	// Do some action

	$logFileHandler	= fopen(pathinfo(__FILE__, PATHINFO_FILENAME).'.log', 'a');
	fputs($logFileHandler, date('Y-m-d H:i:s') . "\t{$ip}\r\n");
	fclose($logFileHandler);
	
	die('OK');
}

die('ERR');

?>



натравливаю на скрипт ApacheBench 1000 запросов, 100 единовременных, в лог попадает 4 записи с одинаковым временем, т.е. с момента чтения файла с данными о подключениях до момента его обновления успевают "проскочить" 4 запроса
...
Рейтинг: 0 / 0
Ограничение количества запросов к скрипту за единицу времени (APC)
    #38150688
poiuytrewq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Выставляю эксклюзивную блокировку перед началом чтения и закрываю после записи, все вроде нормально теперь работает
...
Рейтинг: 0 / 0
5 сообщений из 5, страница 1 из 1
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / Ограничение количества запросов к скрипту за единицу времени (APC)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]