Примерно год назад коллеги задали мне вопрос: «Как я мог бы выразить свою работу одним словом?». Тогда я на этот вопрос ответить с ходу не смог, довольно долго думал, но решение не приходило.
На слайде я перечислил те определения, которыми я сам себя мог бы охарактеризовать: я экономлю людям время, экономлю ресурсы заказчикам, делаю одно, второе, третье…, но в качестве ответа на этот вопрос все это не подходит.
Но однажды мы с дочкой шли мимо Сеченовского института, и я ей стал рассказывать про ту работу, которую мы проделали для них – про то, что нам надо было заставить их систему работать в тех условиях, в которых она никогда ранее не работала. И дочка мне сказала: «Папа, ты же работаешь новатором. Я смотрела про них мультфильм».
Этот ответ, действительно, правильный. Ведутся дискуссии о том, насколько корректно «изобретать велосипед», если можно «погуглить» в «Яндексе». С моей точки зрения изобретательность предпочтительнее информированности. Как только человечество разучится изобретать, оно вымрет, ведь чтобы изобретать, надо все-таки тренироваться.
Если говорить еще о моих работах, то я являюсь автором книги «Настольная книга 1С:Эксперта по технологическим вопросам», а также действительно занимаюсь всем тем, что написано на слайде.
Узкие места традиционной технологии нагрузочного тестирования
На конференции уже поднимался вопрос о том, что технологии нагрузочного тестирования достаточно дороги. Мы с этим вопросом столкнулись еще в 2009 году. Восемь лет назад в 20-х числах сентября мы проводили первое в истории нагрузочное тестирование «1С:УПП» на 1000 пользователей в одной информационной базе.
На слайде представлена модель, которую нам тогда пришлось изобрести. Эта модель отличалась от существующих на тот момент стандартов – она определила дальнейшее развитие нагрузочных тестов.
Как оказалось, самое мощное оборудование потребовалось не для сервера 1С и не для сервера СУБД, а для того, чтобы запустить 1000 клиентов. Конечно, это было обычное приложение и толстые клиенты, которые запрашивали под себя существенно более высокие требования к ресурсам, чем те, которые необходимы для тонких клиентов. Но, тем не менее, мы тогда на себе прочувствовали, насколько много ресурсов отнимает запуск клиентов.
Еще потребовался полный комплект лицензий. Основная проблема, с которой мы тогда столкнулись, – это производительность аппаратного ключа, т. е. именно он стал тормозом, который довольно долго не давал нам продвинуться дальше. Но мы его, в конце концов, победили и заставили работать.
Надо отметить, что аппаратный ключ, кроме своего физического носителя имеет еще одну характеристику – это стоимость. Достаточно сложно обосновать покупку 1000 дополнительных лицензий (помимо продуктива), которые потребовались нам для нагрузочного тестирования на 1000 клиентов.
В конечном итоге, мы «уперлись» в возможности типового решения «Тест-центр», которое использовалось тогда для запуска нагрузочного тестирования. Дело в том, что основное время тестирования уходило не на прогон нагрузочного теста, а на запуск клиентов. Тест, который мы тогда проводили, должен был продержаться примерно около часа, но чтобы его запустить, мне примерно четыре с половиной часа нужно было запускать клиентов. Я научился запускать их разными способами, но быстро это делать не получалось. Потом мы это улучшили, но все равно оказывалось, что технологическая оснастка, с которой приходилось работать, выставляет нам нашу же проблему. Мы пытаемся оптимизировать наше решение, чтобы бизнес-процессы клиента выполнялись за отведенное время, а у нас самих не получается оптимизировать наш инструмент для нагрузочных тестов так, чтобы они выполнялись за отведенное время.
С этой ситуацией я вновь столкнулся два года назад в командировке в Мирном, когда нам за две недели нужно было выполнить нагрузочное тестирование системы. Мне стало очевидно, что мы за это время не успеем выполнить наш рабочий план, потому что возникало «бутылочное горлышко» – основные ресурсы и время тратились на запуск клиентов, а тестировать нам надо было серверную часть кода прикладного решения.
Кроме этого, мы не раз замечали, что при превышении некоторых параметров платформа входит в нестабильный режим. У меня даже иногда возникали мысли, что мы неправильно измеряем требования к центрам обработки данных. Мы стараемся их измерять в установившемся режиме, когда все работает, но вдруг случается нехватка какого-то ресурса, и система входит в состояние «турбулентности». В этом случае запас прочности, который имеется в системе, должен существенно отличаться от того, что требуется для работы в установившемся режиме.
В одном из докладов конференции уже говорилось о том, что иногда «тормозом», который не дает системе развиваться дальше, становится сама система управления. В частности, в условиях вхождения системы в нестабильное состояние централизованное управление с помощью COM-соединителя, используемое в традиционной технологии нагрузочного тестирования, становится одним из первоочередных узких мест.
Все это, рано или поздно, можно было бы победить, но у нас было мало времени. И, поскольку эти ситуации не характерны для продуктива (все эти проблемы нам создавала технологическая оснастка, с которой мы работали), нам нужно было в первую очередь нормализовать наши бизнес-процессы. Ну а потом, когда мы их вывели в нормальный режим, то уже смогли решать задачи заказчика.
Для чего нужен нагрузочный тест?
Что такое нагрузочный тест? Это, в первую очередь, модель, которая используется для двух задач.
- Первая – многопользовательское функциональное тестирование. Оно не так широко распространено, как однопользовательское. Были попытки сделать многопользовательское тестирование стандартом разработки, но в силу того, что это – дорого, реализовать это удалось далеко не везде.
- Вторая – ресурсное тестирование, когда нас просят посчитать, сколько оборудования, человеко-часов и времени потребуется на проведение каких-то операций.
Что надо сделать партнеру для проведения нагрузочного теста? Взять и запустить какой-то код в большом количестве сеансов. Он, в основном, проводит многопользовательское функциональное тестирование, особенно если речь идет о работах на регулярной основе. Практически, он тестирует серверную часть кода – записать документ или набор записей, выполнить запрос.
Спрашивается, для чего в таком случае нужно поднимать клиентов? Ответ – ни для чего, в таком нагрузочном тестировании клиентские соединения не нужны.
Обход основных узких мест путем переноса работы с клиентских соединений на фоновые задания
Для поиска «узких мест» прикладного решения я сначала хотел заняться построением какой-то имитационной модели, но потом в голову пришла мысль, что можно использовать сервер для запуска фоновых заданий по созданию и проведению документов. При этом сразу появляется множество бонусов.
- Во-первых, фоновое задание не требует клиентских лицензий. Таким образом, стоимость теста падает на полную стоимость лицензий.
- Во-вторых, фоновые задания существенно быстрее запускаются. В нашем случае первая тысяча фоновых заданий запускалась практически мгновенно. Дальше их запуск происходил медленнее, но это все равно было на порядки быстрее, чем запускались клиентские соединения.
- В-третьих, как оказалось, для фоновых заданий не нужно большое количество ресурсов. Если для запуска тысячи клиентских приложений 1С нам нужно примерно 128 Гб оперативной памяти и хотя бы 32 ядра, то для запуска тысячи фоновых заданий нам ничего из этого не нужно. Обычный сервер на 8 ядер с 16 Гб оперативной памяти вполне справляется с этой задачей.
Стандартный нагрузочный тест, который входит в состав «КИП», измеряет способность сервера запускать клиентские приложения, а при данной технологии работает именно серверная часть кода.
Изменение способа управления сеансами
Чтобы распараллелить выполнение, многие функции можно выполнять децентрализованно, т.е. обработку, под руководством которой работает клиент, можно сделать достаточно умной.
Централизованно клиенту даются только 2 задания.
- Первое – это начинать выполнять тестовые действия – допустим, начинать проводить документы или ждать чего-то. Эти действия обычно прописаны в какой-то обработке.
- Второе – что этого клиента можно выгружать (завершать его сеанс).
Все остальное можно сделать децентрализованным и отдать на откуп клиенту. В этом случае мы получаем существенно более надежную схему. Если отвалился клиент – ничего, запустим нового. Если стартовало не 1600 клиентов, 1580 – ничего, мы даем команду начать тесты, и 1580 клиентов, которые к этому моменту запустились, нормально продолжают работу. В данном случае перфекционизм не нужен. За счет этого мы сильно экономим время.
Техническая реализация альтернативной технологии
В таблице на слайде представлены функции, которые в нашей и в традиционной технологии выглядят по-разному. Я попытался максимально подробно все расписать, чтобы вы могли воспроизвести эту технологию самостоятельно.
- В третьем столбце описано, как работает обычный алгоритм в «Тест-центре».
- Во втором столбце описано, как это сделали мы. Например, команду на запуск теста мы сделали просто переключением константы. При тестировании на большое количество пользователей этот механизм оказался значительно более простым и надежным.
Что надо сделать клиентам после запуска? Им надо в конкурентном режиме разобрать номера. На слайде представлен код. Берем, запускаемся, у каждого свой номер.
А далее, когда вам известен порядковый номер каждого рабочего места, клиенту надо просто дождаться команды на начало работы теста.
Аналогично подается команда на завершение работы теста, но с некоторой паузой, чтобы клиенты успевали отработать, чтобы не было конфликтов и блокировок, и чтобы нигде не возникало ненужных очередей.
Дальше по каждому номеру пользователя однозначно определяется имя обработки с определенными параметрами, которую надо запустить.
Для этого используется регистр сведений «БИТ_НастройкаТеста», куда записывается номер пользователя (например, 189) и выполняемая обработка («Тест_5»).
Далее вызывается метод «Выполнить», куда передается имя обработки и параметр «Номер пользователя».
Больше на клиент ничего не передается, и, таким образом, клиент находится в полностью независимом полете. Он получил имя процедуры и выполняет ее.
Эту процедуру можно сделать сколько угодно умной. Это позволяет дозапускать клиентов и делать так, чтобы клиенты были полностью независимыми, и чтобы тест начинался при любом количестве запущенных клиентов.
Еще одна технология, которую удалось обкатать – это независимость настроек теста от метаданных.
В традиционном тесте обычно используется какой-то эталонный документ, который надо скопировать, а потом эту копию провести, распровести или еще что-то с ней сделать.
На заполнение такой тестовой базы может уйти два с половиной человеко-месяца. При этом миграция документов из одной тестовой системы в другую невозможна. Если вы делаете обновление релиза или каким-то образом серьезно поменяете код прикладного решения, то документы из одного места в другое уже не перенесутся.
Но если хранить описания документов в регистре сведений – так, как это представлено на слайде, документы можно будет без проблем переносить в другую тестовую систему.
Обратите внимание, что табличные части сохраняются в хранилище значений, а основные реквизиты документов хранятся в реквизите с типом «Любая ссылка». Как это организовано, можно увидеть на следующем слайде.
Например, первая роль, первый пользователь с первым номером.
Документ «Регистрация цен номенклатуры поставщика», название реквизита «ДокументОснование» и дальше – значение реквизита.
С помощью этого регистра мы можем набирать любое количество различных документов. Набирали до 200 000, и все было нормально.
И главное, этот механизм обеспечивает безболезненную миграцию с одной базы в другую. Если мы ERP 2.2 обновим на релиз ERP 2.3, то, скорее всего, перетащив этот регистр, мы увидим полностью заполненные готовые базы для теста.
Нюансы отдельных настроек
Еще очень важная настройка – «ПодключитьОбработчикОжидания».
Традиционные технологии предполагают работу в модальном синхронном режиме. У такого режима есть значительное неудобство: если вы запустили клиентское приложение, и оно пошло выполнять предназначенные ему действия, вы с этим «мертвым» окном уже ничего не сделаете, пока все действия не будут выполнены.
А в нашем случае, даже если у нас все-таки запускаются клиентские соединения, а не фоновые задания, и нам надо открывать формы документов, то при переходе с формы одного документа на другую (т.е. мы сначала проводим «Реализацию», потом проводим «Поступление»), мы используем подключение обработчика ожидания. Это делает окно «живым». «Реализация» проведена, окно живое, мы можем в приложении параллельно что-то делать, а потом через определенное время запускается проведение «Поступления». Это технология тоже очень сильно помогает.
В фоновом задании у нас используется «КИП.Пауза» – там без этого не обойтись (или надо свой аналогичный скрипт писать).
Результаты тестирования:
- В нашем случае у нас был проведен большой тест на 15 010 фоновых заданий.
- Тест продолжался восемь часов.
- За это время провелось больше 180 000 документов.
- Запуск фоновых заданий занял примерно час. Для примера скажу, что я не представляю, сколько времени потребовалось для того, чтобы запустить 15 000 клиентских приложений 1С. Это было бы очень долго, и потребовалось бы немереное количество оборудования.
Особенности настроек кластера – тема достаточно серьезного тюнинга. Те настройки кластера, которые представлены на слайде выше, мы подбирали вручную.
- Почему-то более 90 рабочих процессов у нас запустить не получилось.
- Учитывая ограничения на память, на каждый из запущенных рабочих процессов подобрали количество соединений в 170.
- При этом порадовало, что для обеспечения технологических функций такого большого теста нам хватило 5 лицензий.
Подтверждение жизнеспособности предложенных технологий
Теперь расскажу про то, какую нагрузку это выдержало.
Первой ласточкой, когда мы начали это собирать, было тестирование для компании «АЛРОСА» в Мирном. Тогда нам удалось очень быстро собрать прототип системы, реализующей задачу по выполнению нагрузочного тестирования для заказчика, и упростить дальнейшую оптимизацию кода прикладного решения. Мы поняли, что наша идея начинает работать.
Дальше для нас было очень знаковое тестирование в «Норильском никеле». Знаковое – потому что технология, которую мы разработали, оказалась тиражируемой. Каждый гениальный программист способен написать свой гениальный код. Но гениальность этого кода иногда может оценить только он сам, потому что другие могут просто не понять, что он хотел. Люди, которым мы передали эту технологию, сказали, что она действительно серьезно облегчила их работу. Это при том, что тестирование проводил не я, и обучались они «с нуля». Тиражируемость технологии для нас очень важна, потому что не всегда можно научить людей работать с тем, что сделали сами. А тут это получилось и получилось хорошо.
Следующий шаг. У нас было желание проверить, сколько наша технология нагрузочного тестирования вообще выдержит, т.е. какие ее реальные пределы. Мы попробовали запустить тестирование на каркасной конфигурации – сначала тысячу потоков, потом десять тысяч, потом 25 тысяч потоков. 25 тысяч получилось запустить на реальном оборудовании. Попробовали запустить 40 тысяч, но система вошла в режим «турбулентности», из которого ее, к сожалению, вывести не удалось. Таким образом, мы считаем, что 25 тысяч соединений в одной базе – это то, что нам удалось сделать с помощью данной технологии. Весь код, представленный на слайдах, работает при таких серьезных стрессовых режимах.
Дальше мы попробовали узнать, как наше тестирование будет работать в ERP, и получили результат в 15 тысяч соединений. Конфигурацию ERP мы выбрали, как образец сложного современного типового решения, на котором можно проверить технологию и заодно определить, нет ли в самом решении каких-либо «узких» мест. Оказалось, что есть. Мы их нашли и передали в «1С». При этом сами убедились, что наша технологическая оснастка работает. И главное – мы провели это тестирование в совершенно вменяемые сроки и в свободное от основной работы время.
Гибридные технологии
Хочу привести пример гибридного использования нашей технологии, который позволил протестировать систему на высокую нагрузку, и при этом сэкономить.
Нам говорят, что мы с помощью своей технологии не можем воспроизвести все ситуации, которые могут быть в реальной базе по заданию нагрузочного теста.
Но в проекте для Центрального Банка России у нас использовался прототип гибридного подхода к нагрузочному тестированию:
- В качестве 820 пользователей работали роботы – сеансы запускались автоматизировано, под ними создавались и проводились документы.
- И параллельно в системе работали 30 бухгалтеров. Они делали все то, что им требовалось для повседневной работы, и оценивали общую производительность системы. Мы не могли запрограммировать то, что они делали.
Результат, который мы получили, был довольно близок к работе реальной системы, по сравнению с тем, что мы могли бы смоделировать за разумные деньги.
Приведенный пример технологии можно использовать на реальном проекте:
- с помощью фоновых заданий создаем нагрузку на сервер;
- нагрузку на клиентские приложения 1С делаем поменьше, т. к. эта проверка дорого стоит;
- какое-то количество соединений создаем вручную.
Получаем полнофункциональное тестирование системы любого размера.
В заключение хотелось бы сказать, что из всех технологий все слышат почему-то только про нагрузочный тест с помощью фоновых заданий. Это важная технология, но она не единственная, и в конце доклада я еще раз перечислю их все, и их преимущества по сравнению с традиционной технологией. Итак, это:
- нагрузочный тест с помощью фоновых заданий – нужно меньше лицензий, быстрее запуск, ниже требования к оборудованию;
- нагрузочный тест с помощью клиентских приложений 1С, работающих в асинхронном немодальном режиме – сохраняется возможность работы в клиентских приложениях, что повышает удобство;
- децентрализованный способ управления клиентскими приложениями, участвующими в нагрузочном тесте – выше надежность тестовой оснастки, сама она перестает быть точкой отказа;
- децентрализованный способ управления фоновыми заданиями, участвующими в нагрузочном тесте – то же самое, выше надежность тестовой оснастки, сама она перестает быть точкой отказа;
- механизм хранения реквизитов и табличных частей всех метаданных, которые надо создавать и использовать в ходе теста, в регистре сведений, что обеспечивает простоту миграции тестовых данных при существенных изменениях конфигурации;
- гибридные технологии тестирования – отказ от описания и программирования неформализуемых действий.
И все эти технологии проверены нами на сверхвысокой нагрузке, в условиях ограниченных сроков, бюджета и вычислительных ресурсов. Они, собственно, все и были созданы, чтобы в эти ограничения вписываться.
Данная статья написана по итогам доклада, прочитанного на конференции INFOSTART EVENT 2017 COMMUNITY.