ISP Блокируем пользователей за перерасход CPU

Запрос улучшений, интеграции с различными системами и т.д.
Аватара пользователя
rootden
Сообщения: 260
Зарегистрирован: 2010-09-24 8:28:44
Благодарил (а): 1 раз

ISP Блокируем пользователей за перерасход CPU

Сообщение rootden » 2012-07-16 18:16:06

Сделал сегодня системную задачу в биллинге которая проверяет все заказы хостинга на предмет перерасхода cpu основываясь на данных от системного аккаунтинга в isp, sa в ос.

Раньше это были отдельные самостоятельные скрипты, а теперь все в биллинге штатно, кому надо берите.

1. sql

Код: Выделить всё


INSERT INTO `Tasks` (`UserID`,`TypeID`,`Params`,`IsActive`) VALUES (1,'CPUusage','[]','yes');

ALTER TABLE `HostingSchemes` ADD `ISPCPUusage` VARCHAR(255) NOT NULL ;

ALTER TABLE `HostingOrders` ADD `Cpucount` INT(12) NOT NULL;

DROP VIEW IF EXISTS `HostingOrdersOwners`;
DROP TABLE IF EXISTS `HostingOrdersOwners`;
CREATE
  VIEW `HostingOrdersOwners` AS
SELECT
  `HostingOrders`.*,
  (SELECT `DaysRemainded` FROM `OrdersOwners` WHERE `HostingOrders`.`OrderID` = `OrdersOwners`.`ID`) AS `DaysRemainded`,
  `OrdersOwners`.`OrderDate`,
  `OrdersOwners`.`UserID`,
  `OrdersOwners`.`ContractID`
FROM
  `HostingOrders`
LEFT JOIN `OrdersOwners`
ON (`HostingOrders`.`OrderID` = `OrdersOwners`.`ID`);


/www/domen/hosts/hosting/config/Config.xml

в секцию Tasks допишите задачу

Код: Выделить всё

  <CPUusage>
   <Name>Учет статистики по cpu ispmanager</Name>
   <Params type="array" />
   <IsActive>1</IsActive>
  </CPUusage>


в секцию Notifies

Код: Выделить всё

<HostingNoticeCPUusage>
<Name>Уведомление о превышение CPU</Name>
<GroupID>1</GroupID>
</HostingNoticeCPUusage>


/hosts/hosting/templates/Notifies/Email

кидаем HostingNoticeCPUusage.tpl

Код: Выделить всё

{*
 *  Copyright © 2012 Rootden for Dgrad-host.com
 *}
{assign var=Theme value="Превышение использования CPU" scope=global}
Здравствуйте, {$User.Name|default:'$User.Name'}!

Предупреждение №{$HostingOrder.UsageCount|default:'$HostingOrder.UsageCount'}

Уведомляем Вас о том, что ваш аккаунт {$HostingOrder.Login|default:'$HostingOrder.Login'} заказ хостинга №{$HostingOrder.OrderID|string_format:"%05u"}, израсходовал все ресурсы по CPU согласно вашему тарифу {$HostingOrder.Tarif|default:'$HostingOrder.Tarif'}.

Вы использовали: {$HostingOrder.CpuUsage|default:'$HostingOrder.CpuUsage'} часа/часов процессорного времени за текущий месяц из {$HostingOrder.CpuUsageMax|default:'$HostingOrder.CpuUsageMax'}ч положенных по тарифу.

Просим вас решить эту проблему и сообщить о принятых мерах или повысить тариф, иначе аккаунт заблокируется автоматически после 3-го предупреждения.

За более детальной информацией обращайтесь в единый центр поддержки по адресу:

http://billing.dgrad-host.com/Tickets

{$From.Sign|default:'$From.Sign'}


HostingNoticeCPUusageMax.tpl

Код: Выделить всё

{*
 *  Copyright © 2012 Rootden for Dgrad-host.com
 *}
{assign var=Theme value="Превышение использования CPU" scope=global}
Здравствуйте, {$User.Name|default:'$User.Name'}!

Ваш аккаунт заблокирован!

Уведомляем Вас о том, что вы получили 3 предупреждения и не отреагировали, ваш аккаунт {$HostingOrder.Login|default:'$HostingOrder.Login'} заказ хостинга №{$HostingOrder.OrderID|string_format:"%05u"} приостановлен.

Для разблокировки обращайтесь в единый центр поддержки по адресу:

http://billing.dgrad-host.com/Tickets

{$From.Sign|default:'$From.Sign'}


/hosts/hosting/comp/Tasks

CPUusage.comp.php

Код: Выделить всё

<?php
#-------------------------------------------------------------------------------
/** @author Rootden for Dgrad-host.com */
/******************************************************************************/
Eval(COMP_INIT);
if(Is_Error(System_Load('libs/Http.php')))
  return ERROR | @Trigger_Error(500);
/******************************************************************************/

$Hostings = DB_Select('HostingOrdersOwners',Array('ID','OrderID','SchemeID','ServerID','Login','Cpucount','UserID'),Array('Where'=>"`StatusID` = 'Active'"));

#-------------------------------------------------------------------------------
switch(ValueOf($Hostings)){
  case 'error':
    return ERROR | @Trigger_Error(500);
  case 'exception':
    # No more..
  break;
  case 'array':
    #---------------------------------------------------------------------------
     foreach($Hostings as $Hosting){
     
     #-----------------------------------------------------------------------------
     # выборка HostingSchemes нужно забрать cpu tarif
     $CH = DB_Select('HostingSchemes',Array('Name','ISPCPUusage'),Array('Where'=>"`ID` = '$Hosting[SchemeID]'"));

     Debug("USER_LOGIN = " . $Hosting['Login']);
     #Debug("HOSTING_ID  = " . $Hosting['ID']);
     #Debug("SCHEME_ID = " . $Hosting['SchemeID']);
      Debug("CH_TARIF = " . $CH[0]['ISPCPUusage']);
      #Debug("CPU_COUNT = " . $Hosting['Cpucount']);
    
     #-----------------------------------------------------------------------------
     # Если CP isp то работаем, получаем totalresourceusage
    
     $SRV = DB_Select('HostingServers',Array('SystemID','Address','Port','Protocol','Login','Password'),Array('Where'=>"`ID` = '$Hosting[ServerID]'"));
     $SRV= $SRV[0];
     if ( 'IspManager' == $SRV['SystemID'] ){
    
               Debug("ISPMANAGER > = YES");
    
            $authinfo = SPrintF('%s:%s',$SRV['Login'],$SRV['Password']);
            $Http = Array(
            'Address'  => $SRV['Address'],
            'Port'     => $SRV['Port'],
            'Host'     => $SRV['Address'],
            'Protocol' => $SRV['Protocol'],
            'Hidden'   => $authinfo,
            'IsLoggin' => FALSE
            );
            
            $Response = Http_Send('/manager/ispmgr',$Http,Array('authinfo'=>$authinfo,'out'=>'xml','func'=>'totalresourceusage','elid'=>'ok'));
            if(Is_Error($Response))
             return ERROR | @Trigger_Error(500);

               
              $Response = Trim($Response['Body']);
              $XML = String_XML_Parse($Response);
              $XML = $XML->ToArray('elem');
                  $Result = $XML['doc'];
             
              #Debug(print_r($Result, true));
            
               $found = false;
               foreach ($Result as $key => $value) {
                  if ($value['account']==$Hosting['Login']) {
                     $found = $key;
                     $CPUusage = $value['utime'] + $value['stime'];
                     break;
                  }
               }

              #Debug("Key = " . $found);
             
              #("CPUSUM_SEC = " . $CPUusage);
             
              $cpumount = ceil($CPUusage/3600);
             
                  Debug("CPUSUM_CH = " . $cpumount);
      #-----------------------------------------------------------------------------
     # сравниваем и блокируем аккаунты
    
                  #if (1 == 1) {
                 if ($cpumount >= $CH[0]['ISPCPUusage']) {
               Debug("Detect > = YES");
               
               switch ($Hosting['Cpucount']){
                  case "0":
                            $IsUpdate = DB_Update('HostingOrders',Array('Cpucount'=>'1'),Array('ID'=>$Hosting['ID']));
                            if(Is_Error($IsUpdate))
                            return ERROR | @Trigger_Error(500);
                     
                      $HostingO = Array('UsageCount' => '1', 'Login' => $Hosting['Login'], 'OrderID' => $Hosting['ID'], 'Tarif' => $CH[0]['Name'], 'CpuUsage'  => $cpumount, 'CpuUsageMax' => $CH[0]['ISPCPUusage']);
                       $IsSend = NotificationManager::sendMsg(new Message('HostingNoticeCPUusage',$Hosting['UserID'],Array('HostingOrder'=>$HostingO)));

                     $Event = Array(
                              'UserID'   => $Hosting['UserID'],
                              'PriorityID'=> 'Hosting',
                              'Text'   => SPrintF('Превышение использования CPU, заказ хостинга %s, уведомление №1',$Hosting['Login'])
                             );
                        $Event = Comp_Load('Events/EventInsert',$Event);
                        if(!$Event)
                          return ERROR | @Trigger_Error(500);
                     
                     
                     break;
                  case "1":
                     $IsUpdate = DB_Update('HostingOrders',Array('Cpucount'=>'2'),Array('ID'=>$Hosting['ID']));
                            if(Is_Error($IsUpdate))
                            return ERROR | @Trigger_Error(500);
                     
                     $HostingO = Array('UsageCount' => '2', 'Login' => $Hosting['Login'], 'OrderID' => $Hosting['ID'], 'Tarif' => $CH[0]['Name'], 'CpuUsage'  => $cpumount, 'CpuUsageMax' => $CH[0]['ISPCPUusage']);
                       $IsSend = NotificationManager::sendMsg(new Message('HostingNoticeCPUusage',$Hosting['UserID'],Array('HostingOrder'=>$HostingO)));
                     
                     $Event = Array(
                              'UserID'   => $Hosting['UserID'],
                              'PriorityID'=> 'Hosting',
                              'Text'   => SPrintF('Превышение использования CPU, заказ хостинга %s, уведомление №2',$Hosting['Login'])
                             );
                        $Event = Comp_Load('Events/EventInsert',$Event);
                        if(!$Event)
                          return ERROR | @Trigger_Error(500);
                     
                     
                     break;
                  case "2":
                     $IsUpdate = DB_Update('HostingOrders',Array('Cpucount'=>'3'),Array('ID'=>$Hosting['ID']));
                            if(Is_Error($IsUpdate))
                            return ERROR | @Trigger_Error(500);
                     
                     $HostingO = Array('UsageCount' => '3', 'Login' => $Hosting['Login'], 'OrderID' => $Hosting['ID'], 'Tarif' => $CH[0]['Name'], 'CpuUsage'  => $cpumount, 'CpuUsageMax' => $CH[0]['ISPCPUusage']);
                       $IsSend = NotificationManager::sendMsg(new Message('HostingNoticeCPUusage',$Hosting['UserID'],Array('HostingOrder'=>$HostingO)));
                     
                     $Event = Array(
                              'UserID'   => $Hosting['UserID'],
                              'PriorityID'=> 'Hosting',
                              'Text'   => SPrintF('Превышение использования CPU, заказ хостинга %s, уведомление №3',$Hosting['Login'])
                             );
                        $Event = Comp_Load('Events/EventInsert',$Event);
                        if(!$Event)
                          return ERROR | @Trigger_Error(500);
                     
                     
                     break;
                  case "3":
                     $IsUpdate = DB_Update('HostingOrders',Array('Cpucount'=>'0'),Array('ID'=>$Hosting['ID']));
                            if(Is_Error($IsUpdate))
                            return ERROR | @Trigger_Error(500);
                     
                     $HostingO = Array('UsageCount' => '1', 'Login' => $Hosting['Login'], 'OrderID' => $Hosting['ID'], 'Tarif' => $CH[0]['Name'], 'CpuUsage'  => $cpumount, 'CpuUsageMax' => $CH[0]['ISPCPUusage']);
                       $IsSend = NotificationManager::sendMsg(new Message('HostingNoticeCPUusageMax',$Hosting['UserID'],Array('HostingOrder'=>$HostingO)));
                     
                      $Comp = Comp_Load('www/API/StatusSet',Array('ModeID'=>'HostingOrders','StatusID'=>'Suspended','RowsIDs'=> $Hosting['OrderID'],'Comment'=> SPrintF('Перерасход CPU %s > тариф %s',$cpumount,$CH[0]['ISPCPUusage'])));

                     switch(ValueOf($Comp)){
                       case 'error':
                        return ERROR | @Trigger_Error(500);
                       case 'exception':
                        return ERROR | @Trigger_Error(400);
                       case 'array':
                        # No more...
                       break;
                       default:
                        return ERROR | @Trigger_Error(101);
                     } # end set staus
                           
                       $Event = Array(
                              'UserID'   => $Hosting['UserID'],
                              'PriorityID'=> 'Hosting',
                              'Text'   => SPrintF('Превышение использования CPU, заказ хостинга %s, уведомление №%s',$Hosting['Login'],$Hosting['Cpucount'])
                             );
                        $Event = Comp_Load('Events/EventInsert',$Event);
                        if(!$Event)
                          return ERROR | @Trigger_Error(500);
                     
                     break;
                  default:
                  Debug("Cpucount > 3");
                  return ERROR | @Trigger_Error(500);
               }

               } else Debug("DETECT > = NO");
            }else Debug("ISPMANAGER > = NO");
}

  break;
  default:
    return ERROR | @Trigger_Error(500);
}
#-------------------------------------------------------------------------------
return MkTime(1,30,0,Date('n'),Date('j')+1,Date('Y'));
#-------------------------------------------------------------------------------

?>

Аватара пользователя
rootden
Сообщения: 260
Зарегистрирован: 2010-09-24 8:28:44
Благодарил (а): 1 раз

Re: ISP Блокируем пользователей за перерасход CPU

Сообщение rootden » 2012-07-16 18:22:51

и еще пару файликов заменить, в архиве найдете.

работает только с isp, ост панели игнорятся, в isp должен быть активирован системный аккаунтинг.

задание будет выполнятся каждый день в 01.30 ночи, в свойствах тарифа задаются часы процессорного времени (сумма - user + sistem), если юзер все израсходует и будет игнорить предупреждения то после 3-го предупреждения акк блокируется.
Вложения
cpuisp.rar
(13.22 КБ) 493 скачивания

Аватара пользователя
Alex Keda
Сообщения: 2882
Зарегистрирован: 2009-10-07 14:30:54
Откуда: USSR
Поблагодарили: 19 раз

Re: ISP Блокируем пользователей за перерасход CPU

Сообщение Alex Keda » 2012-08-09 9:35:28

хорошая фенька, но до нормального использования надо допиливать...
сервера могут быть разные, и час на оптероне != часу на третьем пне
Убей их всех! Бог потом рассортирует...

Аватара пользователя
rootden
Сообщения: 260
Зарегистрирован: 2010-09-24 8:28:44
Благодарил (а): 1 раз

Re: ISP Блокируем пользователей за перерасход CPU

Сообщение rootden » 2012-08-15 4:05:41

Alex Keda писал(а):хорошая фенька, но до нормального использования надо допиливать...
сервера могут быть разные, и час на оптероне != часу на третьем пне


пока думаю, тут еще идеи появились учитывать и дневной расход а не только месячный, разрешить 3х кратное превышение в день. + кол запросов в день суммарно у вирт хостов юзера но это отдельным заданием.

по поводу проца тут момент такой что единица измерения часы а не проценты, корректировку не знаю как делать но с этим проблем лично у меня пока нету, вроде все справедливо просто более слабый сервер вместит меньше клиентов.

при созд тарифов за эталон брали самый старый сервер q8200, новые сейчас i7 там конечно расход по меньше будет ибо шустрее, но еще зависит от нагрузки, так что как не крути разброс будет полюбому в силу специфики шареда.

Аватара пользователя
rootden
Сообщения: 260
Зарегистрирован: 2010-09-24 8:28:44
Благодарил (а): 1 раз

Re: ISP Блокируем пользователей за перерасход CPU

Сообщение rootden » 2012-08-15 4:20:13

еще нужно будет добавить cpu mysql ибо он вообще не контролируется.

смотрел Percona MySQL можно снимать стату.

http://www.percona.com/doc/percona-serv ... userstatv2

Аватара пользователя
Alex Keda
Сообщения: 2882
Зарегистрирован: 2009-10-07 14:30:54
Откуда: USSR
Поблагодарили: 19 раз

Re: ISP Блокируем пользователей за перерасход CPU

Сообщение Alex Keda » 2013-02-21 9:21:26

включил у себя штатный сбор статистики, буду впиливать фичу в биллинг.
правда, пока ещё не знаю в каком виде =))
Убей их всех! Бог потом рассортирует...

Аватара пользователя
Alex Keda
Сообщения: 2882
Зарегистрирован: 2009-10-07 14:30:54
Откуда: USSR
Поблагодарили: 19 раз

Re: ISP Блокируем пользователей за перерасход CPU

Сообщение Alex Keda » 2013-03-08 18:45:40

реализовал
Убей их всех! Бог потом рассортирует...

Аватара пользователя
rootden
Сообщения: 260
Зарегистрирован: 2010-09-24 8:28:44
Благодарил (а): 1 раз

Re: ISP Блокируем пользователей за перерасход CPU

Сообщение rootden » 2013-03-12 6:45:11

гляну как выйдет,

я тут решил все подругому сделать более грамотно,

будем учитывать все что накапало не суммарно за месяц а ежедневно.

1 процессорное время общее cpu.
2 процессорное время mysql.
3 суммарное количество http запросов.

будет 2 лимита:

1 мягкий по тарифу - если превышение периодическое то блокировать, если не регулярное то не трогать.
2 лимит жесткий - если превышен то немедленно блокировать.

Еще нужно проверять процессы пользователя и завершать их если они жрут cpu более X процентов за Y времени, если переодически то блокировать.

Аватара пользователя
Alex Keda
Сообщения: 2882
Зарегистрирован: 2009-10-07 14:30:54
Откуда: USSR
Поблагодарили: 19 раз

Re: ISP Блокируем пользователей за перерасход CPU

Сообщение Alex Keda » 2013-03-12 11:49:09

rootden писал(а):гляну как выйдет,

я тут решил все подругому сделать более грамотно,

будем учитывать все что накапало не суммарно за месяц а ежедневно.

1 процессорное время общее cpu.
2 процессорное время mysql.
3 суммарное количество http запросов.

будет 2 лимита:

1 мягкий по тарифу - если превышение периодическое то блокировать, если не регулярное то не трогать.
2 лимит жесткий - если превышен то немедленно блокировать.

Еще нужно проверять процессы пользователя и завершать их если они жрут cpu более X процентов за Y времени, если переодически то блокировать.

у меня логика, такая
смотрим предыдущий день, если есть превышения, смотрим неделю.
если есть превышения и там и там, - лочим.
настривается практически всё, щас ещё впиливаю создание тикетов, при блокировке...
--
а как 2 и 3 штатно считаешь? или нештаттно?
Убей их всех! Бог потом рассортирует...

Аватара пользователя
rootden
Сообщения: 260
Зарегистрирован: 2010-09-24 8:28:44
Благодарил (а): 1 раз

Re: ISP Блокируем пользователей за перерасход CPU

Сообщение rootden » 2013-03-16 7:18:13

штатно не выйдет,вместо mysql будем ставить Percona и делать базу со статистикой.

http статистика в новых версиях isp появилась, но она я так понимаю тока apache логи смотрит, а нада полные логи запросов, так что тоже не штатно.


Вернуться в «Запрос улучшений»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 6 гостей