<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css" href="http://www.1gb.ua/wiki/skins/common/feed.css?63"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://www.1gb.ua/wiki/index.php?action=history&amp;feed=atom&amp;title=%D0%9E%D0%B3%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81%D0%BE%D1%80%D0%BD%D0%BE%D0%B9_%D0%BD%D0%B0%D0%B3%D1%80%D1%83%D0%B7%D0%BA%D0%B8_%28%D1%80%D0%B5%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F%29</id>
		<title>Ограничение процессорной нагрузки (реализация) - История изменений</title>
		<link rel="self" type="application/atom+xml" href="http://www.1gb.ua/wiki/index.php?action=history&amp;feed=atom&amp;title=%D0%9E%D0%B3%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81%D0%BE%D1%80%D0%BD%D0%BE%D0%B9_%D0%BD%D0%B0%D0%B3%D1%80%D1%83%D0%B7%D0%BA%D0%B8_%28%D1%80%D0%B5%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F%29"/>
		<link rel="alternate" type="text/html" href="http://www.1gb.ua/wiki/index.php?title=%D0%9E%D0%B3%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81%D0%BE%D1%80%D0%BD%D0%BE%D0%B9_%D0%BD%D0%B0%D0%B3%D1%80%D1%83%D0%B7%D0%BA%D0%B8_%28%D1%80%D0%B5%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F%29&amp;action=history"/>
		<updated>2026-04-17T05:08:01Z</updated>
		<subtitle>История изменений этой страницы в вики</subtitle>
		<generator>MediaWiki 1.10.1</generator>

	<entry>
		<id>http://www.1gb.ua/wiki/index.php?title=%D0%9E%D0%B3%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81%D0%BE%D1%80%D0%BD%D0%BE%D0%B9_%D0%BD%D0%B0%D0%B3%D1%80%D1%83%D0%B7%D0%BA%D0%B8_%28%D1%80%D0%B5%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F%29&amp;diff=4950&amp;oldid=prev</id>
		<title>Teak: Защищена страница «Ограничение процессорной нагрузки (реализация)» [edit=autoconfirmed:move=autoconfirmed]</title>
		<link rel="alternate" type="text/html" href="http://www.1gb.ua/wiki/index.php?title=%D0%9E%D0%B3%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81%D0%BE%D1%80%D0%BD%D0%BE%D0%B9_%D0%BD%D0%B0%D0%B3%D1%80%D1%83%D0%B7%D0%BA%D0%B8_%28%D1%80%D0%B5%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F%29&amp;diff=4950&amp;oldid=prev"/>
				<updated>2008-10-13T08:40:28Z</updated>
		
		<summary type="html">&lt;p&gt;Защищена страница «&lt;a href=&quot;/wiki/index.php?title=%D0%9E%D0%B3%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BF%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81%D0%BE%D1%80%D0%BD%D0%BE%D0%B9_%D0%BD%D0%B0%D0%B3%D1%80%D1%83%D0%B7%D0%BA%D0%B8_%28%D1%80%D0%B5%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F%29&quot; title=&quot;Ограничение процессорной нагрузки (реализация)&quot;&gt;Ограничение процессорной нагрузки (реализация)»&lt;/a&gt; [edit=autoconfirmed:move=autoconfirmed]&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая статья&lt;/b&gt;&lt;/p&gt;&lt;div&gt;== Принцип работы ==&lt;br /&gt;
Каждую минуту запускается парсер запросов к серверу, который записывет время обработки запросов в базу данных MySQL, а в начало каждого php-скрипта добавляется префикс, получающий статистику нагрузки для своего сайта и принимающий решение о блокировании дальнейшей обработки скрипта.&lt;br /&gt;
&lt;br /&gt;
Сама база данных работает в отдельном экземпляре MySQL с максимально упрощенной авторизацией, все таблицы держатся в памяти, поэтому дополнительные запросы статистики не создают заметной нагрузки на сервер.&lt;br /&gt;
&lt;br /&gt;
== Реализация ==&lt;br /&gt;
&lt;br /&gt;
Статистика нагрузки рассчитывается сервером и записывается в базу, к которой можно подключиться из своих скриптов и понять помент, в который нужно заблокировать работу сайта для предотвращения выхода им за допустимую процессорную нагрузку.&lt;br /&gt;
&lt;br /&gt;
Собственный алгоритм блокировки можно реализовать на любом из доступных языков программирования (ASP, PERL и т.д.), ниже приведено подробное описание формата данных и наша реализация блокировки на php.&lt;br /&gt;
&lt;br /&gt;
'''Разработчикам''', если Вы решили воспользоваться этим интерфейсом для получения информации о нагрузке настоятельно рекомендуем подписаться на изменения этой страницы (зарегистрироватся в Wiki и отметить эту страницу для наблюдения), т.к. при изменение структуры таблиц будет отражаться тут.&lt;br /&gt;
&lt;br /&gt;
=== Формат конфигурационного файла ===&lt;br /&gt;
В конфигурационном для нашей реализаци используются пары ключ-значение по одному на строку в формате:&lt;br /&gt;
 key=value&lt;br /&gt;
&lt;br /&gt;
Сейчас подерживаются два параметра: FULL_BLOCK, IP_BLOCK в обоих указывается процент нагрузки от одного ядра процессора.&lt;br /&gt;
&lt;br /&gt;
Пример содержания файла:&lt;br /&gt;
 FULL_BLOCK=3.5&lt;br /&gt;
 IP_BLOCK=1.5&lt;br /&gt;
&lt;br /&gt;
=== Параметры для доступа к базе ===&lt;br /&gt;
 Сервер: 127.0.0.1&lt;br /&gt;
 Порт: 3399&lt;br /&gt;
 База: ProcLimit;&lt;br /&gt;
 Пользователь: user&lt;br /&gt;
 Без пароля.&lt;br /&gt;
&lt;br /&gt;
=== Структура таблиц ===&lt;br /&gt;
Список сайтов (таблица недоступна для свободного чтения)&lt;br /&gt;
{|class=&amp;quot;simple&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
!align=center colspan=4|Sites&lt;br /&gt;
|-&lt;br /&gt;
!Поле||Тип||Пример||Описание&lt;br /&gt;
|-&lt;br /&gt;
|ID||CHAR(32)||6652D7688AF645EFF4FBD40B05A62C28||MD5 имени сайта, буквы заглавные&lt;br /&gt;
|-&lt;br /&gt;
|Name||VARCHAR(255)||MYSITE.RU||Доменное имя сайта заглавными буквами, без WWW.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Лог запросов&lt;br /&gt;
{|class=&amp;quot;simple&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
!align=center colspan=4|Logs&lt;br /&gt;
|-&lt;br /&gt;
!Поле||Тип||Пример||Описание&lt;br /&gt;
|-&lt;br /&gt;
|HASH||INT||-1839737443||Хеш строки из лог-файла, нужен для внутренних целей.&lt;br /&gt;
|-&lt;br /&gt;
|Site_ID||CHAR(32)||6652D7688AF645EFF4FBD40B05A62C28||MD5 имени сайта, буквы заглавные&lt;br /&gt;
|-&lt;br /&gt;
|Time||DATETIME||2008-04-03 21:10:15||Время вызова файла скрипта&lt;br /&gt;
|-&lt;br /&gt;
|ProcessorTime||INT||76||Число миллисекунд процессорного времени, потраченых сервером на обработку запроса.&lt;br /&gt;
|-&lt;br /&gt;
|IP||INT(4)||-712745798||IP-адрес, IP-адрес с которого был сделан запрос (алгоритм перевода IP-адреса в число можно посмотреть в примере реализации)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Статистика по сайту&lt;br /&gt;
{|class=&amp;quot;simple&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
!align=center colspan=4|Summary&lt;br /&gt;
|-&lt;br /&gt;
!Поле||Тип||Пример||Описание&lt;br /&gt;
|-&lt;br /&gt;
|Site_ID||CHAR(32)||6652D7688AF645EFF4FBD40B05A62C28||MD5 имени сайта, буквы заглавные&lt;br /&gt;
|-&lt;br /&gt;
|ProcessorTime||INT||2037||Число миллисекунд процессорного времени, потраченное сервером на обработку запросов к сайту за последний час.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Статистика по сайту и IP-адресу&lt;br /&gt;
{|class=&amp;quot;simple&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
!align=center colspan=4|IPSummary&lt;br /&gt;
|-&lt;br /&gt;
!Поле||Тип||Пример||Описание&lt;br /&gt;
|-&lt;br /&gt;
|Site_ID||CHAR(32)||6652D7688AF645EFF4FBD40B05A62C28||MD5 имени сайта, буквы заглавные&lt;br /&gt;
|-&lt;br /&gt;
|IP||INT||367||IP-адрес, с которого поступали запросы (алгоритм перевода IP-адреса в число можно посмотреть в примере реализации)&lt;br /&gt;
|-&lt;br /&gt;
|ProcessorTime||INT||2037||Число миллисекунд процессорного времени, потраченное сервером на обработку запросов к сайту, поступивших с этого IP-адреса.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Пример реализации на PHP ===&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
 	$path_1gb = $_SERVER[&amp;quot;SCRIPT_FILENAME&amp;quot;];&lt;br /&gt;
 	if ($path_1gb == '')&lt;br /&gt;
 		$path_1gb = $_SERVER[&amp;quot;PATH_TRANSLATED&amp;quot;];&lt;br /&gt;
 	$path_1gb = substr( $path_1gb, 0, - strlen($_SERVER['SCRIPT_NAME'])) . '/';&lt;br /&gt;
 	&lt;br /&gt;
 	$config_1gb = &amp;quot;$path_1gb/.cpu_limit.conf&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
 	if( !($cfg_1gb = @file($config_1gb ) ) )&lt;br /&gt;
 		return;&lt;br /&gt;
        &lt;br /&gt;
 	$logfile_1gb_path = $path_1gb . '/.proclimit_' . strtolower( @md5($path_1gb) );&lt;br /&gt;
 	&lt;br /&gt;
 	@mkdir($logfile_1gb_path);&lt;br /&gt;
 	&lt;br /&gt;
 	$logfile_1gb = &amp;quot;$logfile_1gb_path/.cpu_limit_&amp;quot;.date('Y-m-d').&amp;quot;.log&amp;quot;;&lt;br /&gt;
 	$logfile_1gb_debug = &amp;quot;$logfile_1gb_path/.cpu_limit_&amp;quot;.date('Y-m-d').&amp;quot;_ok.log&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
 	$full_time_1gb = 60 * 60 * 1000;&lt;br /&gt;
 &lt;br /&gt;
 	$ip_1gb = $_SERVER[&amp;quot;REMOTE_ADDR&amp;quot;];&lt;br /&gt;
 	@list($ip_1gb) = @split( ',', $ip_1gb );&lt;br /&gt;
 	$ip_parts_1gb = @split( '\.', $ip_1gb );&lt;br /&gt;
 	if (count ($ip_parts_1gb) != 4)&lt;br /&gt;
 		return;&lt;br /&gt;
 	$ip_1gb = @intval( $ip_parts_1gb[0] ) &amp;lt;&amp;lt; 24;&lt;br /&gt;
 	$ip_1gb |= @intval( $ip_parts_1gb[1] ) &amp;lt;&amp;lt; 16;&lt;br /&gt;
  	$ip_1gb |= @intval( $ip_parts_1gb[2] ) &amp;lt;&amp;lt; 8;&lt;br /&gt;
 	$ip_1gb |= @intval( $ip_parts_1gb[3] );&lt;br /&gt;
 &lt;br /&gt;
 	if( $ip_1gb &amp;gt; 2147483647 )&lt;br /&gt;
 	{&lt;br /&gt;
 		// Значит у нас 64-битная система. Нужно получить отрицательное число, как в 32-битной&lt;br /&gt;
 		$ip_1gb |= 0xFFFFFFFF00000000;&lt;br /&gt;
 	}&lt;br /&gt;
 &lt;br /&gt;
 	$host_1gb = @addslashes(@strtoupper($_SERVER[&amp;quot;HTTP_HOST&amp;quot;]));&lt;br /&gt;
 	if( @substr($host_1gb, 0, 4) == &amp;quot;WWW.&amp;quot; )&lt;br /&gt;
 		$host_1gb = substr( $host_1gb, 4 );&lt;br /&gt;
 	$site_id_1gb = @strtoupper( @md5( $host_1gb ) );&lt;br /&gt;
 	&lt;br /&gt;
 	$full_block_1gb = 0.50 * $full_time_1gb;&lt;br /&gt;
 	$client_block_1gb = 0.50 * $full_time_1gb;&lt;br /&gt;
 	foreach( $cfg_1gb as $lin1_1gb )&lt;br /&gt;
 	{&lt;br /&gt;
 		$lparts_1gb = @split(&amp;quot;=&amp;quot;, $lin1_1gb);&lt;br /&gt;
 		if( count( $lparts_1gb) != 2 )&lt;br /&gt;
 			continue;&lt;br /&gt;
 		$name_1gb = strtoupper( trim( $lparts_1gb[0] ) );&lt;br /&gt;
 		$val_1gb = trim( $lparts_1gb[1] );&lt;br /&gt;
 		&lt;br /&gt;
 		if( $name_1gb == &amp;quot;FULL_BLOCK&amp;quot; )&lt;br /&gt;
 			$full_block_1gb = @floatval( $val_1gb ) / 100 * $full_time_1gb;&lt;br /&gt;
 		if( $name_1gb == &amp;quot;IP_BLOCK&amp;quot; )&lt;br /&gt;
 			$client_block_1gb = @floatval( $val_1gb ) / 100 * $full_time_1gb;&lt;br /&gt;
 	}&lt;br /&gt;
 	&lt;br /&gt;
 	$con_1gb = @mysql_connect( &amp;quot;127.0.0.1:3399&amp;quot;, &amp;quot;user&amp;quot; );&lt;br /&gt;
 	if( !$con_1gb )&lt;br /&gt;
 	{&lt;br /&gt;
 		if( $logfile = @fopen( $logfile_1gb_debug, &amp;quot;at+&amp;quot; ) )&lt;br /&gt;
 		{&lt;br /&gt;
 			@fwrite( $logfile, date( &amp;quot;Y-m-d H:i:s&amp;quot; ) . &amp;quot;, accounting database is offline\n&amp;quot; );&lt;br /&gt;
 			@fclose( $logfile );&lt;br /&gt;
 		}&lt;br /&gt;
 		return;	&lt;br /&gt;
 	}&lt;br /&gt;
 	@mysql_query( &amp;quot;use ProcLimit;&amp;quot;, $con_1gb);&lt;br /&gt;
 &lt;br /&gt;
 	&lt;br /&gt;
 	$q_1gb = &amp;quot;SELECT ProcessorTime FROM Summary WHERE Summary.Site_ID = '$site_id_1gb'&amp;quot;;&lt;br /&gt;
 	$res_1gb = @mysql_query( $q_1gb, $con_1gb );&lt;br /&gt;
 	if( $res_1gb )&lt;br /&gt;
 		$res_1gb = @mysql_fetch_row( $res_1gb );&lt;br /&gt;
 &lt;br /&gt;
 	if( $res_1gb )&lt;br /&gt;
 	{&lt;br /&gt;
 		$load_from_ip_1gb = @round ($res_1gb[0] * 100 / $full_time_1gb, 2);&lt;br /&gt;
 		if( $res_1gb[0] &amp;gt;= $full_block_1gb )&lt;br /&gt;
 		{&lt;br /&gt;
 			if( $logfile = @fopen( $logfile_1gb, &amp;quot;at+&amp;quot; ) )&lt;br /&gt;
 			{&lt;br /&gt;
 				@fwrite( $logfile, date( &amp;quot;Y-m-d H:i:s&amp;quot; ) . &amp;quot;, blocked: $_SERVER[REMOTE_ADDR] ($load_from_ip_1gb %)\n&amp;quot; );&lt;br /&gt;
 				@fclose( $logfile );&lt;br /&gt;
 			}&lt;br /&gt;
 			die( &amp;quot;Сервер перегружен, попробуйте зайти позже&amp;quot; );&lt;br /&gt;
 		}&lt;br /&gt;
 	}&lt;br /&gt;
 &lt;br /&gt;
 				&lt;br /&gt;
 	$q_1gb = &amp;quot;SELECT ProcessorTime FROM IPSummary WHERE IPSummary.Site_ID = '$site_id_1gb' AND IPSummary.IP = '$ip_1gb'&amp;quot;;&lt;br /&gt;
 	$res_1gb = @mysql_query( $q_1gb, $con_1gb );&lt;br /&gt;
 	if( $res_1gb )&lt;br /&gt;
  		$res_1gb = @mysql_fetch_row( $res_1gb );&lt;br /&gt;
 	&lt;br /&gt;
 	if( $res_1gb )&lt;br /&gt;
 	{&lt;br /&gt;
 		$load_total_1gb = @round ($res_1gb[0] * 100 / $full_time_1gb, 2);&lt;br /&gt;
 		if( $res_1gb[0] &amp;gt; $client_block_1gb )&lt;br /&gt;
 		{&lt;br /&gt;
 			if( $logfile = @fopen( $logfile_1gb, &amp;quot;at+&amp;quot; ) )&lt;br /&gt;
 			{&lt;br /&gt;
 				@fwrite( $logfile, date( &amp;quot;Y-m-d H:i:s&amp;quot; ) . &amp;quot;, blocked: $_SERVER[REMOTE_ADDR] (IP load = $load_total_1gb %)\n&amp;quot; );&lt;br /&gt;
 				@fclose( $logfile );&lt;br /&gt;
 			}&lt;br /&gt;
 			die( &amp;quot;Сервер перегружен, попробуйте зайти позже&amp;quot; );&lt;br /&gt;
 		}&lt;br /&gt;
 	}&lt;br /&gt;
  &lt;br /&gt;
 	&lt;br /&gt;
 	if( $logfile = @fopen( $logfile_1gb_debug, &amp;quot;at+&amp;quot; ) )&lt;br /&gt;
 	{&lt;br /&gt;
 		@fwrite( $logfile, date( &amp;quot;Y-m-d H:i:s&amp;quot; ) . &amp;quot;, ok $_SERVER[REMOTE_ADDR] (IP load = $load_total_1gb %, total = $load_from_ip_1gb %)\n&amp;quot; );&lt;br /&gt;
 		@fclose( $logfile );&lt;br /&gt;
 	}&lt;br /&gt;
 	&lt;br /&gt;
 	&lt;br /&gt;
 	unset( &lt;br /&gt;
 		$path_1gb, $config_gile, $ip_1gb, $host_1gb, $logfile_1gb, $logfile_1gb_debug, $logfile, $cfg_1gb, $full_1gb, $full_block_1gb, $client_block_1gb, &lt;br /&gt;
 		$lin1_1gb, $lparts_1gb, $name_1gb, $val_1gb, $q_1gb, $res_1gb, $ip_parts_1gb, $full_time_1gb, $load_from_ip_1gb, $load_total_1gb, $site_id_1gb, $logfile_1gb_path&lt;br /&gt;
 		);&lt;br /&gt;
 	&lt;br /&gt;
 ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Перевод IP-адреса в число на C# ===&lt;br /&gt;
 private static int IPToInt(IPAddress ip)&lt;br /&gt;
 {&lt;br /&gt;
   byte[] ip_bytes = ip;&lt;br /&gt;
   int iip = ip_bytes[0] &amp;lt;&amp;lt; 24;&lt;br /&gt;
   iip |= ip_bytes[1] &amp;lt;&amp;lt; 16;&lt;br /&gt;
   iip |= ip_bytes[2] &amp;lt;&amp;lt; 8;&lt;br /&gt;
   iip |= ip_bytes[3];&lt;br /&gt;
   return iip;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
== Смотрите также ==&lt;br /&gt;
* [[Ограничение процессорной нагрузки]]&lt;br /&gt;
&lt;br /&gt;
[[Категория:Серверная нагрузка]]&lt;br /&gt;
[[Категория:Программирование]]&lt;/div&gt;</summary>
		<author><name>Teak</name></author>	</entry>

	</feed>