1С-Битрикс: Управление сайтомНа главную страницу
Клиентам
Маркетплейс
Партнерам
Разработчикам
Интеграция с 1С
Идея?


Личный кабинет
Авторизоваться
Регистрация
(войти) Корзина
Логин:

Пароль:



Забыли свой пароль?
Регистрация
Войти как пользователь:
Войти как пользователь
Вы можете войти на сайт, если вы зарегистрированы на одном из этих сервисов:
ВКонтакте
Мой Мир
Twitter
Facebook
Google
Livejournal
Яндекс
Rambler
Mail.Ru
Liveinternet
Blogger
OpenID
Используйте вашу учетную запись VKontakte.ru для входа на сайт.
Используйте вашу учетную запись Мой Мир@Mail.ru для входа на сайт.
Используйте вашу учетную запись на Twitter.com для входа на сайт.
Используйте вашу учетную запись на Facebook.com для входа на сайт.
Используйте вашу учетную запись Google для входа на сайт.
.livejournal.com
@yandex.ru
@rambler.ru
@mail.ru
http://www.liveinternet.ru/users/ /
.blogspot.com
OpenID:
  • Документация
    • Управление сайтом
    • Корпоративный портал
    • .NET Forge CMS
    • Отраслевые решения
    • Marketplace
    • Аренда приложений (SaaS)
  • Обучение и сертификация
    • Онлайн-курсы и сертификация
    • Учебные центры
    • Мое обучение
    • Учебные видеоролики
  • Центр поддержки
    • Поддержка
    • FAQ
    • Мои обращения
  • Сообщество
    • Блоги Битрикс
    • Блоги веб-разработчиков
    • Общие форумы
    • Веб-разработчики
      • Моя страница
      • Мои сообщения
      • Группы
      • Найти коллег
  • Cтатьи
    • Архив
Главная / Общение / Сообщество разработчиков / Оптимизация веб-проектов / Блог
Федеральный семинар «1С-Битрикс»: Веб для бизнеса

Оптимизация веб-проектов: Блог

Основное
Блог
Микроблог
Участники

Оптимизация веб-проектов

Тема: Производительность
Описание: Группа по вопросам производительности веб-проектов.

Особенности работы веб систем при экстремальных нагрузках

8
Шаромов Денис
07.07.201113:3407.07.2011 13:34:45
Еще в процессе первого нагрузочного тестирования Битрикса версии 6.0 коллеги из QSoft столкнулись с ситуацией, о которой сегодня хочу написать. На тот момент она не была детально изучена, но на последнем тестировании версии 9.5, которое проводилось совместно с компанией Онтико, стали понятны симптомы проблемы и последствия. В финальном отчете проблема описана на 19 странице под заголовком "Особенности генерации тестовой нагрузки", хочу сейчас подробно остановиться на том, как это было.

Читать подробнее...

Шаромов Денис
07.07.201113:3407.07.2011 13:34:45
Просмотров:1790 Комментариев:5 8

Оптимизация времени генерации страницы

11
Ryzhonin Nikolay
30.06.201117:2130.06.2011 17:21:07
Часто возникают вопросы производительности проектов на базе "1С-Битрикс", для решения которых нет необходимости прибегать к "экстремальным методам". Чтобы, помочь в решение таких проблем, особенно разработчикам только начинающим работать с "1С-Битрикс", рассмотрим пример оптимизации "некой" страницы информационного сайта. Для этого будем использовать только встроенный в продукт инструментарий.

И так, что мы имеем:
  • VMBitrix (512M памяти)
  • инфоблок новостей ~12600, в каждой новости заполнен анонс, детальная информация, название, теги и ряд свойств
  • страница с 2-мя компонентами news.list, которые выводят два блока новостей (топ 0 - 10 шт и обычные - 10 шт).
  • топ новости, не должны попадать в обычные
  • разделение на топ и обычные новости происходит при помощи числового свойства MAIN_NEWS
  • при выводе новостей проверяется период активности, ежедневно добавляется 5 - 10 новостей
Характерны следующие проблемы:
  • тяжолая фильтрация по дате активности
  • кэширование в период максимальной нагрузки не может полностью закрыть проблему производительности. Так как, обычно в этот же момент происходит довольно частый сброс кэша, после добавления новостей, их изменения или при других событиях (добавление комментариев, оценок и.т.д.). Поэтому необходимо добиться быстрой генерации страницы без использования кэширования.

Читать подробнее...

Ryzhonin Nikolay
30.06.201117:2130.06.2011 17:21:07
Просмотров:1745 Комментариев:12 11

Оптимизация файлов стилей сайта

16
Ryzhonin Nikolay
24.06.201115:3524.06.2011 15:35:54
Коллеги, в связи с подготовкой к выпуску в одном из ближайших обновлений Главного модуля, встроенного механизма оптимизации CSS файлов, решил опубликовать краткий анонс данного функционала.

Скорость отображения страницы браузером пользователя зависит, как непосредственно от времени генерации на сервере, так и от скорости загрузки браузером пользователя. Тут возникает ряд проблем, которые и призван решить новый функционал главного модуля.
  • браузеры создают ограниченное количество параллельных запросов к одному хосту
  • при разработке продукта в идеологии Битрикса, создается большое количество мелких css файлов
  • IE имеет ограничение на количество подключаемых внешних CSS файлов

Для решения данных проблем многие разработчики в ручную переносили стили компонентов в стили шаблонов сайтов. Данный подход обладает рядом минусов:

  • теряется целостность компонентов/шаблонов компонентов, что усложняет перенос компонент/шаблонов между сайтами или разными проектами
  • усложняется работа с компонентами и их шаблонами

Новый функционал позволяет автоматизировать данный процесс, и лишен приведенных выше недостатков. Для его включения необходимо в настройках главного модуля установить галочку «Объединять CSS файлы шаблонов в один файл».



С этого момента ядро начнет собирать объединенный файл стилей сайта, по мере открытия пользователями разных страниц сайта. При этом для каждого шаблона сайта создается следующие файлы стилей:

  • объединенный файл стилей шаблонов компонент
  • объединенные файлы стилей шаблонов компонент для IE (с учетом ограничения на количество селекторов в одном файле)
  • объединенный файл стилей для шаблонов сайта (styles.css, template_styles.css)

Объединенный файл стилей, после того как соберет все стили используемые в данном шаблоне сайта, заново не формируется. За исключением случая изменения одного из файла стилей который входит в его состав, в этом случае «накопление» объединенного файла стилей начинается заново.

результат объединения сss стилей (print.css и colors.css не объединялись, так как явно прописаны в шаблоне)



Дополнительным бонусом является возможность формировать уже сжатую копию объединенного файла стилей. Данная возможность позволяет отдавать файлы стилей в сжатом виде (например при помощи nginx и mod_gzip_static) не сжимая их на лету. Для этого необходимо в настройках главного модуля включить «Создавать сжатую копию объединенного файла CSS » а также настроить nginx:

Код
gzip_static on;
gzip_http_version 1.0;
в результате скорость отдачи файлов стилей увеличивается на порядок:
без сжатия
Цитата
Server Software:        nginx/0.7.67 
Document Path:          /bitrix/cache/css/s1/light_red_styles.css?1307718092 
Document Length:        199325 bytes 
Time taken for tests:   27.775 seconds
Requests per second:    36.00 [#/sec] (mean)
Transfer rate:          7017.45 [Kbytes/sec] received 

с сжатием
Цитата
Server Software:        nginx/0.7.67 
Document Path:          /bitrix/cache/css/s1/light_red_styles.css?1307718092 
Document Length:        153107 bytes 
Time taken for tests:   2.236 seconds 
Requests per second:    447.29 [#/sec] (mean) 
Transfer rate:          67002.39 [Kbytes/sec] received 

Важно!
Включая данный функционал на своем проекте вы должны понимать, что в виду того что все стили используемых шаблонов компонент объединяются, возможно возникновение ситуации пересечения стилей из разных шаблонов. Учитывая это вы должны для всех шаблонов создавать уникальное название стилей, при соблюдение этого правила верстка вашего сайта не пострадает.
Ryzhonin Nikolay
24.06.201115:3524.06.2011 15:35:54
Просмотров:2014 Комментариев:36 16

Выполнение всех агентов на cron

15
Ryzhonin Nikolay
20.06.201114:1520.06.2011 14:15:41
Добрый день, уважаемые коллеги!
Вначале немного представлюсь. Меня зовут Рыжонин Николай, в "1С-Битрикс" я курирую направление производительности продуктов компании. Если у вас есть вопросы, предложения или пожелания, касающиеся производительности, обращайтесь e-mail: rns@bitrix.ru

Данная тема уже не раз подымалась (например тут), но тем не менее все таки решил опубликовать обобщенное решения для выполнения всех агентов из под cron.

Для начала полностью отключим выполнение агентов на хите. Для этого выполним следующую команду в php консоли.
Код
COption::SetOptionString("main", "agents_use_crontab", "N"); 
echo COption::GetOptionString("main", "agents_use_crontab", "N"); 

COption::SetOptionString("main", "check_agents", "N"); 
echo COption::GetOptionString("main", "check_agents", "Y");

В результате выполнения должно быть "NN".
После этого убираем из файла /bitrix/php_interface/dbconn.php определение следующих констант:
Код
define("BX_CRONTAB_SUPPORT", true);
define("BX_CRONTAB", true);
И добавляем 
Код
if(!(defined("CHK_EVENT") && CHK_EVENT===true))
   define("BX_CRONTAB_SUPPORT", true);
 


Создаем файл проверки агентов и рассылки системных сообщений /bitrix/php_intarface/cron_events.php
Код
<?
$_SERVER["DOCUMENT_ROOT"] = realpath(dirname(__FILE__)."/../..");
$DOCUMENT_ROOT = $_SERVER["DOCUMENT_ROOT"];

define("NO_KEEP_STATISTIC", true);
define("NOT_CHECK_PERMISSIONS",true); 
define('CHK_EVENT', true);

require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");

@set_time_limit(0);
@ignore_user_abort(true);

CAgent::CheckAgents();
define("BX_CRONTAB_SUPPORT", true);
define("BX_CRONTAB", true);
CEvent::CheckEvents();
?>

И добавляем данный скрипт в cron
Код
 */5 * * * * /usr/bin/php -f /home/bitrix/www/bitrix/php_interface/cron_events.php

После этого все агенты и отправка системных событий будут обрабатывается из под cron, раз в 5 минут. Чтобы не увеличивалась очередь отправки почтовых сообщений, советую изменить параметр отвечающий за количество почтовых событий обрабатываемых за раз. Для этого выполняем в php консоли следующую команду
Код
COption::SetOptionString("main", "mail_event_bulk", "20"); 
echo COption::GetOptionString("main", "mail_event_bulk", "5");
Ryzhonin Nikolay
20.06.201114:1520.06.2011 14:15:41
Просмотров:2250 Комментариев:22 15

Настройка и оптимизация сервера на Debian

0
Артём Шевцов
04.12.201011:3504.12.2010 11:35:15
Уважаемое сообщество, общими силами хотелось бы создать пост о настройке и оптимизации сервера. В своем первом посте я писал о аренде сервера.

На сервере от начальной конфигурации заменили диски на SAS но по монитору производительности это не дало ни каких преимуществ.

Читать подробнее...

Артём Шевцов
04.12.201011:3504.12.2010 11:35:15
Просмотров:2978 Комментариев:11 0
Теги: Debian, настройка сервера, сервер

Инфоблоки+ и "Got error 139 from storage engine" (дополнение по возможным проблемам)

0
Ryzhonin Nikolay
17.09.201015:3217.09.2010 15:32:53
Если для решения проблемы "Got error 139 from storage engine" вы воспользоваться советов приведенным в посте Инфоблоки+ и "Got error 139 from storage engine" у вас может возникнуть следующая проблема:

При работе в базе разваливается одна из таблиц при этом в логи сервера БД валяться ошибки с сообщением 'нет доступа к странице xxx возможно она повреждена или удалена' (нет оригинала сообщения поэтому вольная интерпритация).

При этом база в общем то работает и даже из поврежденной таблици можно вытащить всю информацию кроме конкретной записи и того что после нее.

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

Чтобы избежать ее небходимо:

1. для инфоблоков с большим количеством свойств проверить не превышает ли теоретически они этот предел (в таблицах b_iblock_element_prop_xxs).

2. ну и делать чаще дамп

Если же произошла ошибка то помогает только удаление целиком таблици и восстановление ее из дампа либо того что удалось вытащить, но лучше при возникновении этой ошибки удалить и восстановить целиком базу так как иногда наблюдался "пост эффект" (аналогичная ошибка на других таблицах на которых она теоретически не должна была появляться).


В целом же если учесть это и в проверить то других ошибок не возникает, база работает стабильно.
Ryzhonin Nikolay
17.09.201015:3217.09.2010 15:32:53
Просмотров:953 Комментариев:10 0
Теги: MySQL, Инфоблоки

Нестабильность Zend Server при большом количестве процессов Apache

0
Usoltsev Igor
07.09.201010:4007.09.2010 10:40:40
Во время тестов (CentOS 5.5 32-bit, kernel 2.6.18-194, Zend Server CE 5.0.2, nginx, Apache/2.2.3, MySQL) второй раз наблюдаем, что при небольших и средних нагрузках оптимизатор Zend ведёт себя предсказуемо
Код
"Opcode Caching is Up and Running"

а при увеличении нагрузки (кол-ве запросов/сек ~ 15-20, одновременных пользователей/сессий > 300) может отключаться:
Код
"Opcode Caching Disabled"

При этом, естественно производительность веб сервера катастрофически падает (кроме нагрузки добавляется отсутствие кэширования). Такое поведение характерно при большом количестве допустимых дочерних процессов (child processes) Apache, параметр MaxClients >= 50
При уменьшении MaxClients до 20, этот негативный эффект (баг) пропадает и оптимизатор Zend Server (Optimizer +) продолжает успешно работать несмотря на нагрузку
Эффект описан на форуме Zend, пока безответно, но надеюсь, что разработчики заметят и исправят smile:)

P.S. Обращаю внимание, что описанный эффект характерен для действительно БОЛЬШИХ нагрузок (> 1 млн.хитов в сутки), и на то, что необходимость запускать более 20 процессов Apache возникает крайне редко
Usoltsev Igor
07.09.201010:4007.09.2010 10:40:40
Просмотров:1029 Комментариев:5 0
Теги: zend server ce, apache, linux

CIblockElement::GetList и Инфоблоки+

2
Ryzhonin Nikolay
22.06.201021:1422.06.2010 21:14:12
При использовании инфоблоков+ и выборке нужных свойств напрямую
Код

$rs = CIBlockElement::GetList(
    array(),
    array('IBLOCK_ID' => 1, 'PROPERTY_SHOW_MAIN' => 1),
    false,
    false,
    array(
       'ID', 'NAME', 'PROPERTY_P1', 'PROPERTY_P2'
    )
);

на каждое свойство делается запрос

Код
SELECT BP.*
FROM
b_iblock_property BP, b_iblock B
WHERE
BP.IBLOCK_ID=B.ID AND B.ID IN (7) AND UPPER(BP.CODE)=UPPER('PHONE') 


таким образом если мы достаем 20 свойств то получаем 20 запросов к таблице b_iblock_property для одного компонента, а если на странице 5 компонентов то это уже 100 запросов.

Вопрос к разработчикам: Почему бы получение описания свойств внутри одного запроса GetList не объединить в один запрос который получает описание сразу всех нужных свойств?

В тикете 66176 подымался данный вопрос, но предлагалось только кешировать эти запросы что не оптимально.
Ryzhonin Nikolay
22.06.201021:1422.06.2010 21:14:12
Просмотров:2283 Комментариев:6 2

Битрикс + nginx = любовь. Apache — третий лишний

3
Алексей Шоков
18.06.201000:3618.06.2010 00:36:14
Apache — это, по большому счёту, такой рудемент уже. И держится он только потому, что много в мире виртуальных хостингов, на которых .htaccess решает. Ну и всяких специфических расширений к нему куча (если уж случилась ситуация, что такое расширение нужно — тут да, тут без вариантов Apache).

Представим, что мы на собственном сервере, на котором имеются все возможности доступа к конфигурации. Тогда что нам мешает полностью избавиться от Apache в пользу nginx? Мне не помешало ничего smile:)

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

Собственно, основная проблема только с ЧПУ, с тем, как его настроить. Решается просто:

Код
server {

   ...

   if (!-e $request_filename) {
      rewrite  ^(.*)$  /bitrix/urlrewrite.php last;
   }

   location ~ \.php$ {
      if (!-f $request_filename) {
         rewrite  ^(.*)/index.php$  $1/ redirect;
      }

      ...

   }

   ...

}

Далее, наткнулся на ограничение максимального размера заголовка. Возможно, это я такой везучий, но так уж случилось у меня с настройками по умолчанию, поэтому, думаю, может и у других быть. Я решил проблему на уровне всего сервера:

Код
http {

   ...

   fastcgi_buffer_size  128k;
   fastcgi_buffers  4 256k;
   fastcgi_busy_buffers_size  256k;

   ...

}

Тесты производительности, надеюсь, будут в ближайшее время...
Алексей Шоков
18.06.201000:3618.06.2010 00:36:14
Просмотров:3648 Комментариев:10 3
Теги: nginx, apache

Инфоблоки+ и "Got error 139 from storage engine"

0
Ryzhonin Nikolay
01.04.201007:4201.04.2010 07:42:38
На одном из проектов при переходе на инфоблоки+ (MySQL 5.0.x, InnoDB) столкнулись с ошибкой MySQL "Got error 139 from storage engine".

Данная ошибка проявлялась при вставке, или изменении данных, но не всех элементах. На ее появление влияло заполненность информации в элементе.

Ошибка возникала из за того, что в инфоблоке+ было много свойств (больше 150). В результате суммарная длина полей типа TEXT и VARCHAR в строке таблицы `b_iblock_element_prop_sXX` превышала ограничение MySQL на длину строки таблицы (примерно половина от размера страницы памяти 16 кБ).

Уменьшить количество свойств в инфоблоке в виду сложности проекта и нехватки времени не представлялось возможным, поэтому было принято решение собрать MySQL с увеличенным размером страници памяти до 64 кБ.

и так по порядку:

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

2. в исходниках MySQL находим файл innobase/include/univ.i

и устанавливаем следующие значения

#define UNIV_PAGE_SIZE (8 * 8192)
#define UNIV_PAGE_SIZE_SHIFT 16

3. собираем, устанавливаем и восстанавливаем базы данных

После данной модификации проблема была закрыта. На стабильности работы не отразилось.

Если превышение лимита небольшое можно для начала попробовать изменить длину полей DESCRIPTION_X с 255 на 1.




Ryzhonin Nikolay
01.04.201007:4201.04.2010 07:42:38
Просмотров:2156 Комментариев:21 0
Теги: MySQL, Инфоблоки

Oracle готовит Unbreakable MySQL | LAMP сервер?

0
Usoltsev Igor
18.11.200910:4818.11.2009 10:48:14
По сообщениям информированных источников, в течение Oracle OpenWorld (Oct. 11-15, San Francisco), активно обсуждались предположения о том, что Oracle готовится оснастить свой дистрибутив Linux (Oracle Enterprise Linux, коммерческое название инициативы Unbreakable Linux) приобретённой вместе с Sun СУБД MySQL — и получить таким образом достойное орудие против платформы Windows Server-SQL Server. Что-то типа Unbreakable Linux+MySQL сервер.

По заявлениям Ларри Эллисона [по крайней мере, до принятия Евросоюзом окончательного решения 25.11.2009] Oracle, имея за плечами согласие и поддержку Департамента юстиции США, не намерена оказываться от MySQL для получения согласования сделки по приобретению Sun от органов Европейского союза.

Во время своих выступлений на Oracle OpenWorld совсем неслучайно и Ларри Эллисон (Larry Ellison), и сооснователь Sun Скотт Макнили (Scott McNealy) настойчиво говорили о том, что MySQL в гораздо большей степени соревнуется с MS SQL Server, чем с Oracle.

Согласно недавнему исследованию агенства Evans Data, более 50% разработчиков в странах с активно развивающимися рынками (emerging markets: Китай, Индия, Восточная Европа и Латинская Америка) используют Microsoft’s SQL Server, 46% – MySQL. Технологии Oracle в этом сегменте (Small Medium Business) используются куда менее активо.

Это рынок, на который Oracle нацеливает Unbreakable MySQL и на котором ожидается серьёзная борьба с Microsoft, с использованием маркетингового потенциала и опыта управления проектами Oracle. Кроме прочего, борьба может иметь идеологический оттенок: open source (LAMP) подход к разработке программного обеспечения против проприетарного подхода Microsoft.

Опыт работы с open source проектами у Oracle есть, и значительный: Linux, OCFS2, работы с PHP и др. проекты. С 2005 года Oracle владеет финской open source software компанией Innobase OY, разработчиком транзакционной технологии InnoDB, поставляемой и активно использующейся с MySQL. Активно развивается сотрудничество Oracle с компанией Zend: Zend Server теперь доступен через сеть Oracle’s Unbreakable Linux Network (напомню, что в продуктовой линейке Zend кроме платных есть прекрасный бесплатный продукт для оптимизации выполнения PHP – Zend Server CE). По этим шагам можно предположить, что Oracle давно и последовательно ведёт подготовку к запуску Unbreakable LAMP платформы.

В случае успеха эта стратегия позволит Oracle получить доступ (и, возможно, лидерство) к развивающемуся сегменту мелких и средних компаний - будущей клиентской базе - и в дальнейшем возможность продавать платные полнофункциональные продукты Oracle, по мере роста компаний и их потребностей.
Usoltsev Igor
18.11.200910:4818.11.2009 10:48:14
Просмотров:669 Комментариев:1 0
Теги: linux, MySQL, Oracle

Как я заставил Автокеширование работать на себя

0
Дегтярёв Михаил
28.09.200901:0728.09.2009 01:07:14
Уже который год на битриксе, а от автокеширования толку не было. Ну не снимало оно общей нагрузки с сервера. И тогда я решил заняться им вплотную.

Диспозиция - проект, на котором 20-30 тысяч страниц. Ежедневно Яндекс и Гугль индексируют по 10-20 тысяч страниц, не считая Yahoo и менее заметных роботов. Sitemap не ставим принципиально - вера не позволяет.
Основная нагрузка как раз идёт на громадный спред страниц, где-то по 5-6 тысяч в сутки. С использованием автокеширования с настройками по умолчанию получалось, что за 7200 секунд (2 часа) страницы успевали устаревать, и почти каждый раз при заходе пользователя, они создавались заново. Как результат - загрузка до 5.06 днём.

Контент на сайте, в основном, статика - статьи и новости. Динамика - только заголовки обновлений. Подсчитал среднюю частоту захода человека на одну страницу для страниц, созданных более месяца назад. И решил поставить автокеширование на 2 суток, то есть 86400 секунд. Закешировали буквально всё, что не должно быть динамическим - весь текст статей, новостей, поиск по тегам, архивы. Через 2 дня кеш "прогрелся", а загрузка сервера упала где-то до 2.17 в часы пик, то есть в два раза.

Теперь во-первых, пользователь всё ещё видит актуальную информацию, несмотря на то, что она берётся из кеша. Из-за закешированных "украшательств" типа облака тегов или списка похожих материалов, бот Google ежедневно индексирует в 1.5 раза меньше страниц. На Яндексе не отразилось.

Чего по-прежнему не хватает - это автоматического обновления кеша при обновлении элемента инфоблока. Когда меняем текст старой статьи, он не меняется до устаревания кеша. То ли глюк битрикса, то ли где-то собака порылась.

Так что примите к сведению - стоящие по умолчанию значения на время автокеширования не всегда хороши. Особенно для больших проектов.
Дегтярёв Михаил
28.09.200901:0728.09.2009 01:07:14
Просмотров:1192 Комментариев:4 0
Теги: автокеширование, производительность

Критическая уязвимость в http-сервере Nginx

0
Usoltsev Igor
16.09.200916:0816.09.2009 16:08:10
14.09.2009 23:23 Критическая уязвимость в http-сервере Nginx:
В web-сервере Nginx обнаружена удаленная критическая уязвимость (CERT VU#180065, CVE-2009-2629): переполнение буфера, которое может привести к выполнению произвольного кода с правами рабочих процессов или к осуществлению атаки "отказ в обслуживании" через передачу специальным образом сформированного URL.

Уязвимые версии: 0.1.0-0.8.14. С исправлением выпущены версии nginx-0.8.15, nginx-0.7.62, nginx-0.6.39 и nginx-0.5.38. Доступен патч и обновления для Debian, Fedora, FreeBSD. Ожидается в скором времени выход обновлений для RHEL, CentOS, OpenSUSE, SLES, Ubuntu, Gentoo, Mandriva и т.д. Информации о наличии эксплоита в публичном доступе пока нет.


В новой версии "Виртуальной машины Битрикс" 1.3 nginx обновлён до версии 0.7.62.
Usoltsev Igor
16.09.200916:0816.09.2009 16:08:10
Просмотров:1319 Комментариев:4 0
Теги: nginx security

Запросы MySQL в статусе state statistics

1
Usoltsev Igor
07.07.200914:2407.07.2009 14:24:43
Проблема клиента Битрикс - долго выполняется запрос.
innotop показывает печальную картину:
Код
CXN    When   Load  QPS     Slow  QCacheHit  KCacheHit  BpsIn    BpsOut
local  Now    0.00  286.87     0     68.14%     99.20%  279.27k   1.14M
local  Total  0.00  259.85     3     71.51%     99.08%  219.76k   1.44M

CXN     Cmd    ID      User      Host           DB            Time      Query
local   Query  132330  bitrix  192.168.0.1    bitrix  01:01:07  SELECT DISTINCT
local   Query  158219  bitrix  192.168.0.1    bitrix     12:37  SELECT DISTINCT

Попытаемся разобраться.
Версия MySQL не самая старая
Код
mysql> select version();
+--------------------------+
| version()                |
+--------------------------+
| 5.0.32-Debian_7etch6-log |
+--------------------------+
1 row in set (0.00 sec)

Выясним, что это за долгоиграющий запрос и в каком статусе находится?
Код
mysql> show full processlist;
...
| 132330 | bitrix | 192.168.0.1:45057 | bitrix | Query   | 3612 | statistics | 
SELECT DISTINCT BE.ID as ID,BE.NAME as NAME,BE.XML_ID as EXTERNAL_ID,BE.IBLOCK_ID as IBLOCK_ID,BE.IBLOCK_SECTION_ID as IBLOCK_SECTION_ID,B.DETAIL_PAGE_URL as DETAIL_PAGE_URL,BE.PREVIEW_PICTURE as PREVIEW_PICTURE, FPV1.VALUE as PROPERTY_MANUFACTURER_SRC_VALUE, FPV1.ID as PROPERTY_MANUFACTURER_SRC_VALUE_ID, FPEN2.VALUE as PROPERTY_STICKERS_VALUE, FPEN2.ID as PROPERTY_STICKERS_ENUM_ID, FPV2.ID as PROPERTY_STICKERS_VALUE_ID, FPV4.VALUE as PROPERTY_ARTICULS_VALUE, FPV4.ID as PROPERTY_ARTICULS_VALUE_ID, FPV5.VALUE as PROPERTY_RATE_VALUE, FPV5.ID as PROPERTY_RATE_VALUE_ID,L.DIR as LANG_DIR,BE.CODE as CODE,B.IBLOCK_TYPE_ID as IBLOCK_TYPE_ID,B.CODE as IBLOCK_CODE,B.XML_ID as IBLOCK_EXTERNAL_ID FROM b_iblock B      INNER JOIN b_lang L ON B.LID=L.LID      INNER JOIN b_iblock_element BE ON BE.IBLOCK_ID = B.ID INNER JOIN b_iblock_section_element BSE ON BSE.IBLOCK_ELEMENT_ID = BE.ID  INNER JOIN b_iblock_section BS ON BSE.IBLOCK_SECTION_ID = BS.ID  LEFT JOIN b_iblock_property FP1 ON FP1.IBLOCK_ID=B.ID AND  FP1.CODE='MANUFACTURER_SRC'  LEFT JOIN b_iblock_element_property FPV1 ON FP1.ID=FPV1.IBLOCK_PROPERTY_ID     AND FPV1.IBLOCK_ELEMENT_ID=BE.ID  LEFT JOIN b_iblock_property FP2 ON FP2.IBLOCK_ID=B.ID AND  FP2.CODE='STICKERS'  LEFT JOIN b_iblock_element_property FPV2 ON FP2.ID=FPV2.IBLOCK_PROPERTY_ID   AND FPV2.IBLOCK_ELEMENT_ID=BE.ID         LEFT JOIN b_iblock_property_enum FPEN2 ON FP2.ID = FPEN2.PROPERTY_ID AND FPV2.VALUE_ENUM=FPEN2.ID  LEFT JOIN b_iblock_property FP4 ON FP4.IBLOCK_ID=B.ID AND  FP4.CODE='ARTICULS'  LEFT JOIN b_iblock_element_property FPV4 ON FP4.ID=FPV4.IBLOCK_PROPERTY_ID   AND FPV4.IBLOCK_ELEMENT_ID=BE.ID  LEFT JOIN b_iblock_property FP5 ON FP5.IBLOCK_ID=B.ID AND  FP5.CODE='RATE'  LEFT JOIN b_iblock_element_property FPV5 ON FP5.ID=FPV5.IBLOCK_PROPERTY_ID        AND FPV5.IBLOCK_ELEMENT_ID=BE.ID  INNER JOIN b_iblock_property FP6 ON FP6.IBLOCK_ID=B.ID AND  FP6.CODE='MANUFACTURER'  INNER JOIN b_iblock_element_property FPV6 ON FP6.ID=FPV6.IBLOCK_PROPERTY_ID      AND FPV6.IBLOCK_ELEMENT_ID=BE.ID  INNER JOIN b_iblock_property FP7 ON FP7.IBLOCK_ID=B.ID AND  FP7.CODE='BIG_PHOTO'  INNER JOIN b_iblock_element_property FPV7 ON FP7.ID=FPV7.IBLOCK_PROPERTY_ID AND FPV7.IBLOCK_ELEMENT_ID=BE.ID        INNER JOIN b_iblock_property_enum FPEN7 ON FP7.ID = FPEN7.PROPERTY_ID AND FPV7.VALUE_ENUM=FPEN7.ID  INNER JOIN b_iblock_property FP9 ON FP9.IBLOCK_ID=B.ID AND  FP9.CODE='BIG_PLANS'  INNER JOIN b_iblock_element_property FPV9 ON FP9.ID=FPV9.IBLOCK_PROPERTY_ID       AND FPV9.IBLOCK_ELEMENT_ID=BE.ID        INNER JOIN b_iblock_property_enum FPEN9 ON FP9.ID = FPEN9.PROPERTY_ID AND FPV9.VALUE_ENUM=FPEN9.ID  INNER JOIN b_iblock_property FP11 ON FP11.IBLOCK_ID=B.ID AND  FP11.CODE='STABILIZATION'  INNER JOIN b_iblock_element_property FPV11 ON FP11.ID=FPV11.IBLOCK_PROPERTY_ID    AND FPV11.IBLOCK_ELEMENT_ID=BE.ID  INNER JOIN b_iblock_property FP12 ON FP12.IBLOCK_ID=B.ID AND  FP12.CODE='PHOTO_RESOLUTION'  INNER JOIN b_iblock_element_property FPV12 ON FP12.ID=FPV12.IBLOCK_PROPERTY_ID    AND FPV12.IBLOCK_ELEMENT_ID=BE.ID  INNER JOIN b_iblock_property FP13 ON FP13.IBLOCK_ID=B.ID AND  FP13.CODE='OPTICAL_ZOOM'  INNER JOIN b_iblock_element_property FPV13 ON FP13.ID=FPV13.IBLOCK_PROPERTY_ID       AND FPV13.IBLOCK_ELEMENT_ID=BE.ID WHERE 1=1  AND B.ID IN (0,21)         AND     (               (BE.WF_STATUS_ID=1 AND BE.WF_PARENT_ELEMENT_ID IS NULL)         ) AND (((BE.ACTIVE_TO >= now() OR BE.ACTIVE_TO IS NULL) AND (BE.ACTIVE_FROM <= now() OR BE.ACTIVE_FROM IS NULL)))  AND ((((BE.ACTIVE='Y'))))  AND ((((FPV6.VALUE_NUM = '218232')) OR ((FPV6.VALUE_NUM = '218235')) OR ((FPV6.VALUE_NUM = '218237')) OR ((FPV6.VALUE_NUM = '218238'))))  AND ((((FPEN7.VALUE LIKE 'ДА'))))  AND ((((FPEN9.VALUE LIKE 'ДА'))))  AND ((((FPV11.VALUE_ENUM = '1388'))))  AND ((((FPV12.VALUE >= '8'))))  AND ((((FPV13.VALUE >= '5'))))  AND ((BS.ID = 1481))


Интересно, что команда EXPLAIN для этого запроса выполняется так же долго и "висит" в том же состоянии.
Запрос сам по себе, конечно, жутковатый - объединение более 30 таблиц, но это не повод выполняться долго.

Важнее статус STATISTICS - наводит на грустные размышления... На сайте bugs.mysql.com находим упоминания об ужасных запросах Битрикс:
Bitrix's terible queries with multiple inner join parts
а также "оптимистичные" рассуждения о том, что Это не баг: для некоторых запросов ЛЮБАЯ DBMS может намного большее время в фазе оптимизации, чем выполнения.

К счастью там же упоминаются параметры, которые напрямую влияют на длительность фазы оптимизации запроса сервера MySQL. Один из них представляется важным в нашей ситуации optimizer_search_depth:

Код
mysql> show global variables like 'optimizer_search_depth';
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| optimizer_search_depth | 62    |
+------------------------+-------+


Установлено значение по умолчанию, попробуем уменьшить, как рекомендуется в документации MySQL и проверить на примере команды EXPLAIN:

Код
mysql> explain select...
Query aborted by Ctrl+C
Empty set (4.90 sec)

прервал, всё по-прежнему долго

Код
mysql> set session optimizer_search_depth=30;
Query aborted by Ctrl+C
Empty set (7.92 sec)

прервал, долго

Код
mysql> set session optimizer_search_depth=10;
28 rows in set (0.22 sec)

намного лучше! Попробуем предоставить оптимизатору MySQL самому подобрать значение параметра:

Код
mysql> set session optimizer_search_depth=0;
28 rows in set (0.03 sec)

Значит может, если захочет!
Странно то, что этот параметр по умолчанию установлен в значение 62 - можно даже предположить, что разработчики MySQL надеются успешно бороться с запросами о 60-ти таблицах %)

Оставляем optimizer_search_depth = 0, закрываем проблему.

P.S. Важные моменты:
1) Менять параметр при необходимости нужно на уровне сессии (не для всей системы) и проверять проблемный запрос:
Код
mysql> [B]set session[/B] optimizer_search_depth=...;

В случае положительного результата можно попробовать выполнить с новым значением параметра типичные небыстрые запросы Битрикса, которые можно
получить из "Монитора производительности", чтобы убедиться, что изменение этого параметра не скажется отрицательно на производительности всей системы. И только после этого в период минимальной нагрузки (например, в 04:00 smile;) можно попробовать изменить параметр для всей системы:
Код
mysql> [B]set global[/B] optimizer_search_depth=...;

2) Описанная проблема не является багом Битрикса и сложные запросы тут ни при чём. Клиент сам выбирает базу данных, а MySQL - активно развивающийся продукт.
Usoltsev Igor
07.07.200914:2407.07.2009 14:24:43
Просмотров:2379 Комментариев:1 1
Теги: MySQL оптимизатор параметры

Проблемы с блокировками MySQL типа AUTO_INC: Битрикс невиновен

0
Usoltsev Igor
26.06.200914:1726.06.2009 14:17:52
Активный бизнес проект на базе LAMP + Битрикс версии 8, десятки тысяч хитов в сутки. MySQL версии 5.032 Innodb, обычная нагрузка на сервер ~ 300 запросов в секунду.
Периодически требуется пакетная загрузка данных о товарах PHP-скриптом из CSV файла: 100-200 тысяч записей. Во время выполнения возникает ошибка:

Deadlock found when trying to get lock; try restarting transaction

Клиент взволнованно спрашивает: "... скажите, импортировать в ИБ 170 тыс элементов это вообще проблема для Битрикса? Может ли это быть связано с переходом на 8ку?"

Два традиционных вопроса: кто виноват и что делать?

Читать подробнее...

Usoltsev Igor
26.06.200914:1726.06.2009 14:17:52
Просмотров:1896 Комментариев:6 0
Теги: MySQL блокировки масштабируемость

Вопросы производительности Битрикс

1
Usoltsev Igor
20.03.200918:3320.03.2009 18:33:44
Последствия медленной отправки почты на производительность Битрикс, влияние использования постоянных соединений с БД (MySQL Innodb) на блокировки

Партнёры "Битрикс" готовят к запуску сайт с высокой ожидаемой посещаемостью и большой активностью по добавлению и модификации контента (инфоблоки).
Конфигурация: два выделенных сервера (для Веб и БД), в качестве БД использовалась MySQL с обязательным хранением таблиц в Innodb, учитывая планируемую нагрузку.

Предварительная конфигурация сайта, Apache и MySQL проводилась в соответствии с рекомендациями курса «Конфигурирование веб-систем для оптимальной работы» и активно используя "Монитор производительности" для диагностики "тяжёлых" страниц и запросов, мониторинга и настройки параметров БД (query_cache_size, tmp_table_size, max_heap_table_size, max_tmp_tables, table_cache и т.д.).
Однако, когда уже казалось, что сайт показывает хорошие результаты по производительности, проявились 2 неприятные проблемы:
  • периодически без системы возникающие ошибки вида MySQL Query Error: UPDATE b_stat_day SET ... [Lock wait timeout exceeded; try restarting transaction], и в этом случае все серверные процессы Apache оказывались блокированными, сайт блокирован до перезапуска MySQL.
  • непредсказуемое бессистемное замедление формирования отдельных страниц, которое проявлялось либо в большом времени формирования страниц - 30-60 секунд, либо даже ошибке 504 nginx timeout!

Начали разбираться с MySQL, мониторинг состояния производился командами:

mysql> show full processlist;
mysql> drop table if exists innodb_lock_monitor;
mysql> CREATE TABLE innodb_lock_monitor (a INT) ENGINE=INNODB;
mysql> SHOW ENGINE INNODB STATUS\G;
mysql> DROP TABLE innodb_lock_monitor;


Выяснилось, что перед ошибкой, которую выводил PHP, в БД происходил deadlock на одних и тех же SQL-запросах типа

INSERT INTO b_iblock_section_element...

Попытались решить проблему на уровне приложения - уменьшая количество одновременных вставок элементов инфоблоков - безрезультатно.
DEADLOCK этот довольно интересного типа insert intention waiting, описание которого можно посмотреть в багах MySQL. Возникает при множественных одновременных вставках в таблицу (как раз наш случай - активная работа с инфоблоками) и, по мнению специалистов MySQL, [как бы] багом вовсе не является, а есть правильное поведение MySQL+Innodb в определённых условиях. Ну да шут с ним smile;)
Интереснее показалось нам другое: судя по диагностике блокировок Innodb (которая выводится в секции TRANSACTION команды SHOW ENGINE INNODB STATUS), всякий раз при возникновении проблем, блокирующей оказывалась транзакция с тем же OS thread id, что и транзакция, которую ранее MySQL выбирал в качестве "жертвы" при разборе DEADLOCK'а и должен был откатить. В подтверждение этого предположения, проблема с возникшими блокировками решалась силовым удалением "виновного" thread'а:

MYSQL> kill thread_id

Бесплатная служба поддержки MySQL пока не сильно помогла нам в анализе причин происходящего smile:(

По совету Максима Смирнова, обратили внимание на используемое постоянное соединение с БД, которое могло быть причиной подобного поведения - см., например, обсуждение в блоге Peter Zaitsev Are PHP persistent connections evil ?. Для исключения каких бы то ни было проблем и учитывая, что в случае с MySQL новые соединения создаются быстро и незначительно влияют на общую производительность сайта, мы отключили постоянное соединение с БД:

define("DBPersistent", false); в файле dbconn.php

Блокировки больше не проявлялись.

В это же время Денис Шаромов с Максимом Смирновым обнаружили похожую периодически возникающую проблему (nginx timeout) на другом сайте, связанную с медленной работой процедуры отправки почты.

Проверили на нашем проекте - 60 секунд на отправку сообщения!
Это и была причина появления обеих проблем: и Nginx timeout, и MySQL Lock! В первом случае связь очевидна, во втором - задержка отправки почтового уведомления на хите задерживала завершение транзакции по добавлению/модификации элемента инфоблока, дальше - заложенный в MySQL-Innodb DEADLOCK и, видимо, проблема с открытыми транзакциями и постоянными соединениями. Возникала проблема неожиданно, при обработке события отправки почты на хите.
Администраторы разобрались с почтой, обработка почтовых событий была перенесена на cron:

1) define("BX_CRONTAB_SUPPORT", true); в dbconn.php
2) добавить в crontab вызов php -f /..../bitrix/modules/main/tools/cron_events.php


Последнюю рекомендацию, с моей точки зрения, нужно применять на всех сайтах во избежание зависимости доступности сайта от работы службы почты. Либо постоянно мониторить скорость работы почты.
Usoltsev Igor
20.03.200918:3320.03.2009 18:33:44
Просмотров:3725 Комментариев:7 1
Теги: mail mysql innobd

Пример оптимизации "живого" проекта на платформе Битрикс

0
Usoltsev Igor
20.11.200816:4820.11.2008 16:48:46
Активно развивающийся проект на платформе Битрикс 7.0 (Oracle версии 10.2.0.1, размер более 50 ГБ, Linux i386, выделенный сервер).
Предварительное замечание: этот сервер изначально был не совсем подготовлен для быстрой работы: 32-разрядная ОС на оборудовании x86_64, 32-битный Oracle, RAID-6 для файлов БД, 2 не самых быстрых (1.5 ГГц), зато 4-х ядерных процессора и 16 ГБ ОЗУ.
В связи с ростом нагрузки более чем в 2 раза с начала года - более 400,000 хитов в сутки, до 60,000 посетителей в сутки и после недавнего обновления на версию Битрикс 7.0 сайт стал испытывать определённые проблемы:

При load average 60 сайт удовлетворительно работал(что само по себе удивительно, Максим Смирнов искренне порадовался стабильности работы Linux+Oracle), при нагрузке 75 чувствовались проблемы.
Поскольку основную нагрузку создавали процессы Oracle, первым делом анализируем его.
Из отчётов AWR/statspack виясняем, что основное время пользовательские процессы вели активную "умственную" деятельность (CPU time):
Код
[FONT=Courier]Top 5 Timed Events                                         Avg %Total
~~~~~~~~~~~~~~~~~~                                        wait   Call
Event                                 Waits    Time (s)   (ms)   Time
------------------------------ ------------ ----------- ------ ------
CPU time                                          8,511         73.6
db file scattered read            2,836,881       1,012      0   8.7
db file sequential read           2,452,163         606      0   5.2
log file sync                        24,138         463     19   4.0
log file parallel write              26,075         283     11   2.4
---------------------------------------------------------------------
Instance Efficiency Percentages (Target 100%)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            Buffer Nowait %:   99.98       Redo NoWait %:  100.00
            Buffer  Hit   %:   94.95    In-memory Sort %:  100.00
            Library Hit   %:   98.75        Soft Parse %:   98.75
         Execute to Parse %:    7.35         Latch Hit %:   99.90
Parse CPU to Parse Elapsd %:   86.79     % Non-Parse CPU:   96.29[/FONT]

Ну и поскольку мы видим, что на разбор SQL тратится совсем немного времени, менее 4% (%Non-Parse CPU: 96.29), а думать пользовательским процессам вообще говоря не о чем, кроме разбора и выполнения - ищем неэффективные запросы - с помощью тех же родных оракловских инструментов AWR/statspack выявляем самые ресурсоёмкие (по критериям SQL ordered by Elapsed Time, SQL ordered by CPU Time, SQL ordered by Gets) запросы и проверяем инилизационные параметры.
Проверяем ключевые параметры Oracle:
    optimizer_features_enable = 10.2.0.1 [Ок]
    optimizer_mode = ALL_ROWS [Ок, для версии 10.2.0.1]
    optimizer_index_cost_adj = 100 [Ок]
    optimizer_index_caching = 0 [Значение по умолчанию, предполагает, что для получения ЛЮБОГО индексного блока придётся выполнить операцию физического чтения с диска, не способствует индексному доступу к данным, увеличим до 90(%), для активизации использования индексов]
    cursor_space_for_time = FALSE [Ок, в условиях ограниченной памяти для SGA]
    session_cached_cursors = 50 [Мало, но некритически, рекомендуем увеличить до 150]
    cursor_sharing = FORCE [Ок]
    open_cursors = 300 [Ок]

Анализирум-оптимизируем явно "медленные" запросы, достраиваем недостающие индексы на таблицах B_FORUM_PRIVATE_MESSAGE, B_IBLOCK_ELEMENTB_IBLOCK_SECTION_ELEMENT, B_STAT_* - скрипты для создания индексов отправляем разработчикам для включения в будущие релизы Битрикса.
Проверяем системную статистику Oracle - никогда не собиралась, в этом случае это оправдано, т.к. используется 32-битный Oracle с ограничением SGA ~ 2,7 GB, т.е. наша БД активно использует кеш файловой системы и для неё операции физического чтения это чтение из кэша - в общем, "правды нет" и системная статистика тут вряд ли поможет.
Load_average ~ от 10 до 15
Проверяем httpd сервер:
    apache.MaxRequestsPerChild = 500 - мало, процессы apache живут не более 3-5 минут, рекомендуем увеличить до 2500
    apache.MaxClients = 100 - много для 8-ядерной машины, постоянно запущены от 50 до 60 процессов, рекомендует уменьшить до 30

Load_average ~ от 8 до 12
Уже удовлетворительно, пробуем копнуть глубже, используем модуль Битрикс "Монитор производительности":

    1. Настройки -> Производительность -> Очистка - удаляем старые данные
    2. Настройки -> Производительность -> Включить - запускаем процедуру сбора данных на 1 минуту - процедура достаточно "тяжелая" для системы, желательно проверять загрузку системы во время выполнения.
    3. Настройки -> Производительность -> Хиты с группировкой - с помощью фильтров можно выявить самые ресурсоёмкие страницы нашего Битрикс приложения, самые медленные запросы и планы выполнения запросов(!) - сам был приятно удивлён

Таким образом с помощью "Монитора производительности" удалось выяснить основную причину проблем - неэффективные постраничные запросы, с выборкой и обработкой всего массива строк на стороне PHP, характерные для "старых" компонентов 1.0. Компоненты 2.0 формируют более оптимальный SQL код - в PHP возвращается из БД точно необходимое для отображения запрошенной станицы количество строк. Обновлённые запросы компонентов 2.0 также более эффективны с точки зрения производительности БД.
Что в результате?

Load_average ~ от 3 до 7
Средний % Idle CPU ~ 40-60%
- это тот резерв, которого мы добивались!
С учётом появившегося резерва можно быть уверенным, что сайт выдержит планируемое 2-х кратное увеличение нагрузки.
P.S. Отражение результатов в статистике Oracle
Код
[FONT=Courier]Top 5 Timed Events                                         Avg %Total
~~~~~~~~~~~~~~~~~~                                        wait   Call
Event                                 Waits    Time (s)   (ms)   Time
------------------------------ ------------ ----------- ------ ------
CPU time                                          5,041         80.9
log file sync                        33,127         657     20  10.6
db file sequential read             482,404         379      1   6.1
log file parallel write              33,075         372     11   6.0
SQL*Net message to client        19,624,717          29      0   0.5
---------------------------------------------------------------------[/FONT]

Потребляемое нашей системой CPU time уменьшилось в 1,7 раза: с 8500 до 5000 секунд - система тратит меньше процессорных циклов вследствие оптимизации запросов
Количество операций чтения блоков (db file sequential read) уменьшилось более, чем в 5 раз
Многоблочное чтение (FULL SCAN'ы, db file scattered read) исчезли из TOP-5 - большая часть доступа к данным происходит по индексам
Операции, связанные с записью лог-файлов (log file sync, log file parallel write) незначительно увеличились количественно, что говорит о возросшем количестве транзакций (нагрузке), но продолжают быть достаточно медленными - 20 миллисекунд, это много, и является последствием использования RAID-6 для БД
Usoltsev Igor
20.11.200816:4820.11.2008 16:48:46
Просмотров:2610 Комментариев:12 0

Группы на сайте создаются не только сотрудниками «1С-Битрикс», но и партнерами компании. Поэтому мнения участников групп могут не совпадать с позицией компании «1С-Битрикс».
 
Технологии Эрмитаж
BitrixMobile
Автокеширование
SiteUpdate
Производительность Виртуальная машина
Веб-окружение
Результаты тестов
Выбрать хостинг
Веб-кластер
Безопасность Проактивная защита
Веб-антивирус
Аутентификация

Контакты Поиск Карта сайта
Телефон: +7 (495) 229-14-41
Оставайтесь с нами: Facebook Twitter Habrahabr VKontakte Developers Google 1+
Как распознать QR код?Контакты QR


© 2001-2012 «Битрикс», «1С-Битрикс». Работает на 1С-Битрикс: Управление сайтом.
Английская версия Немецкая версия