Если спросить клиентов, они назовут Виктора гением. Настоящим, недооценённым, всё как положено. Если спросить коллег, Виктора назовут везучей бестолочью, без надлежащего образования, знаний, навыков и вообще. Если спросить начальство и продавцов, то Виктор окажется затычкой последней инстанции – к нему обращаются в последнюю очередь, когда никто другой не справился. Потому что на работе Виктора не получается заработать.
Виктор – программист 1С, который, помимо прочего, увлекается решением задач производительности. Всё, что начинается с «у нас 1С тормозит» или «1С вылетает» - любимый десерт Виктора. Судя по тому, что он мужчина весьма худой, нетрудно догадаться, что десерт ему достаётся редко. Почему?
Потому что, положа руку на сердце, Виктор очень плохо разбирается в деталях производительности. Он понятия не имеет, что такое индексы и индексирование. Он никогда в жизни не видел план запроса. Не знает ни одной модели процессора, памяти, чем отличается DDR2 от DDR3, как считается APDEX, какой должна быть скорость передачи данных между СУБД и серверной частью приложения и т.д. Ну, вы поняли. Любой мало-мальски подготовленный специалист по производительности заткнёт Виктора за резинку трусов.
Но Виктор решает задачи производительности. Решает! Быстро и дёшево. Крайне редко рекомендует потратить денег на апгрейд железа или ПО (раз 5 за 20 лет практики). Максимальная сумма, которую Виктор предъявил клиенту за решённую задачу, примерно равна минимальной сумме, которую называют сертифицированные эксперты – а они называют сумму за предварительный анализ, который проблему только выявит (скорее всего).
Правда ведь, Виктор – исключительный? Нет, конечно. Это я его так назвал. Потому что Виктор знает один метод решения проблем производительности – метод исключения.
Метод исключения
Метод исключения Виктора я приведу в его собственной версии. Вообще, у него инженерное образование, ему в институте рассказывали, что такое метод исключения. Вроде, даже курсовые Виктору делать приходилось.
Но рассказывает он одну историю. Была у Виктора машина – старый Форд Мондео. Однажды он перестал заводиться. На улице был мороз, и первым предположением был АКБ. Прикурили – не помогает. На тросе покатали, с целью завести с толкача – не помогает. Поехали в автосервис.
Там молодые ребята (эксперты) проверяли всё, что прямо или косвенно могло создать проблему. Начали с бензина в баке, потом были свечи, провода, опять АКБ, выхлоп, масло (холодно же) и т.д. Но – ни в какую. Даже постояв в тепле, машина не заводилась.
Потом зашёл некий условный дядя Вася. Глянул с хитрым прищуром из-под густых бровей, вздохнул и говорит: ну-ка, воздушный фильтр вытащите. Ну чё, она и завелась. Оказывается, фильтр не меняли много лет (может, даже с завода, тут история умалчивает).
Теперь ближе к делу – краткие принципы метода исключения Виктора.
Первое – по умолчанию всё должно быть хорошо, если нет извращений. Извращениями Виктор называет любое использование системы, не предусмотренное разработчиками. Если в каком-то месте извращений нет, искать там проблемы не нужно.
Второе – ищи отклонения от среднего. Почти то же, что и первый пункт, но в более широком понимании и применении. Например, тут Виктор смотрит объём памяти на сервере (назвать какой-либо объём памяти извращением у него язык не поворачивается, т.к. он понятия не имеет, сколько этой памяти там должно быть).
Третье – не полагайся только на логи (какие бы они ни были). Логирование – это тоже нечто, сотворённое программистами. А они, как известно… Виктору можно ругать программистов, он сам такой.
Четвертое – когда анализируешь доработки системы, считай всех программистов идиотами. Тогда не пропустишь говнокод. Это, наверное, смесь статистики с психологией и самовнушением. Виктор слишком много повидал кода, который тормозил. Кода, который начинал тормозить через 5 лет после написания. Запросов, которые в тестовой среде выполнялись за миллисекунды, а в проде приводили к нехватке памяти на выполнение. Короче, вы поняли. Программисты 1С живут по принципу never look back, слишком часто меняют работу и очень хотят побольше заработать. Поэтому отрасль бизнеса «1Сник за 1Сником подчищает» всегда будет процветать.
Собственно, всё. Дальше Виктор просто садится и смотрит. Делит условно систему на кусочки, и по одному исключает. В какой-то момент область поиска сужается настолько, что Виктор может назвать причину проблемы. Ну и починить (или подсказать, как починить).
Нетрудно догадаться, что есть и пятый принцип, который Виктор не декларирует – опыт. Чем больше задач по производительности он решил, тем быстрее он разбирается в причинах тормозов, потому что использует эвристики. Хотя, Виктор предпочитает называть это системным мышлением.
Давайте посмотрим несколько примеров.
Тормозит динамический список
Это самый простой пример, которому Виктор научил уже несметное количество людей. Динамический список в 1С – это просто список строк из таблицы БД, который выводится на экран пользователю. Динамическим он называется потому, что считывает данные из БД порциями. Управлять этим процессом особо нельзя, но, к сожалению или к счастью, список можно поднастроить силами пользователя.
Так вот, если пользователь с выдумкой, он может настроить список так, что тот будет страшно тормозить. Добавит отборы, группировки, раскраску строк – и вуаля.
Как это нашёл Виктор. Клиент говорит – у одного пользователя тормозит, у второго нет. Ну, тут и любой неисключительный догадается, что надо найти 10 отличий. Благо, в динамических списках 1С есть волшебная кнопка установки стандартных настроек – её Виктор и тыкнул. Всё залетало, а дальше уже скучные детали.
Теперь все, кто знает Виктора, начинают лечение динамических списков с этой кнопки.
Доработанный динамический список
Но однажды волшебная кнопка не помогла. Правда, ситуация выглядела несколько иначе. Открывался дин. список быстро. Далее пользователь тыкал в какую-то запись, и она открывалась (в 1С это называлось «Документ»). Пользователь чего-то в документе тыкал, менял, и жал кнопку «Записать и закрыть». Форма закрывалась, и дин.список подвисал минут на 10.
Виктор говорит – ага, что-то тут не так. Раз открывается дин.список быстро, то его настройки не при делах. После записи документа он должен просто обновляться – та же операция, что при открытии. Значит, проблема где-то в форме самого документа, или в его записи.
Идёт – и тут же натыкается на чей-то never look back. Какой-то блестящий специалист засунул в обработчик формы после записи длинную и мудрёную процедуру размещения заказа в плане производства. Не в отдельном потоке, не в фоне, а прям тут, в форме.
И тормозил, соответственно, не дин.список (как казалось вначале), а форма документа. Виктор прошерстил этот код, оказалось он уже устарел – таблицы, в которые писались результаты планирования, никто давно не смотрел.
Тысяча порезов
Однажды Виктору попалась база 1С, в которой тормозило всё и везде. Причём, на уровне интерфейса, что весьма несвойственно. Вот просто всё тупо плохо работает, медленно открывается, листается, формируется, закрывается. Как будто базу в солидол засунули.
Админы говорят, что с сервером всё хорошо, ресурсы используются не полностью. Виктор обычно не верит админам, идёт сам смотреть, но кроме диспетчера задач всё равно ничего не знает ?. Однако, даже его знаний хватило, чтобы понять – памяти вроде хватает, процессор в сервере вроде есть.
Чё она тогда тормозит на любых действиях? Глянул журнал регистрации, не идёт ли какая-то бешеная постоянная запись в БД – нет, ничего такого. Никаких извращений, в терминах Виктора. Пошёл глянуть доработки – скорее, чтобы просто исключить эту гипотезу, т.к. знакомый программист, работавший с клиентом ранее, сказал, что доработок там немного и они небольшие.
Ага, небольшие… Ну, по объёму кода – да, небольшие. Строк по 20. Но каких строк… В тех же самых списках, только как… Как вам сказать-то, чтобы слезу не вышибить…
Короче, там списки, которые читаются из БД. И на каждую строку списка ребята написали запрос в БД, который что-то для этой строки динамически вычисляет из других таблиц. Например, в списке лежат товары, и для каждой строки – запрос вычисления остатка на складе. Да, и не только остатка. Да, к одной строке одной таблицы приделано по 2, а то и 3 разных запроса к разным таблицам БД.
И, да… Запросы, конечно, в цикле – по каждой строке же надо. Цикл – на клиенте. Для каждой строки переходит на сервер, делает запрос к БД, результат возвращает на клиент, делает второй запрос, опять идёт на сервер, результат возвращает на клиент, потом…
И таких списков – полтора десятка. Пользователей – человек 50. Каждый открыл 2-3 списка. В списке – строчек 20-30 (для которых идёт цикл с запросами). Записал любой документ этого типа – список обновляется полностью. Крутанул колесо мышки – лови ещё 20-30 строк для обновления.
Вот она и висела, родимая. Всё бегала запросы в цикле выполнять.
Виктор не хотел брать денег с клиента, т.к. потратил 1.5 часа, включая детальное описание результата и рекомендаций (текстом). Но клиент настоял, т.к. до того потратил 2 месяца на поиски решения.
Длинные транзакции
Однажды Виктор познакомился с транзакциями и TempDB. Произошло это случайно (как всегда у нашего героя) – пришла задача по производительности, типичная для крупных предприятий и современных конфигураций 1С.
Типичная задача: на ночь в базе 1С запускается какая-то сложная и длинная процедура, и не успевает выполниться до утра. Либо тупо не успевает, т.е. не хватает времени, либо падает с ошибкой где-то среди ночи, и утром обнаруживается, что дело не сделано. Почему такие процедуры ставят на ночь – понятно, чтобы днём не мешать пользователям (там случаются блокировки и упомянутая выше тысяча порезов).
В данном случае задачей была архивация чеков. Если кратко, то в течение дня, пока идёт розничная торговля, в 1С накапливаются тысячи маленьких документиков – чеков, каждый из которых держит в нескольких таблицах данные о движении товаров, денег и т.д. По окончании дня (закрытии кассовой смены) данные из вспомогательных таблиц удаляются, и перезаписываются заново, но уже в свёрнутом виде (количество записей сильно сокращается). Это и есть архивация чеков.
Так вот, архивация чеков за ночь не успевала выполняться. Самих чеков было 20-30 тысяч – много, но не умотаться. Да, не успевала архивация потому, что непрогнозируемо падала среди ночи. При этом был новый для Виктора симптом – в процессе архивации чеков сильно росла TempDB. Пришлось почитать, что это.
Интернет сказал Виктору, что в TempDB, помимо прочего, лежат данные транзакций – это когда 1С что-то записывает в БД, но процедура записи ещё не завершена (транзакция не зафиксирована). Виктор немного знал о транзакциях – в 1С этим часто пользоваться приходится – но не знал, что с ними бывают проблемы. Логику Виктора вы уже поняли – раз он раньше такого не встречал, то в данной задаче точно есть какое-то извращение или отклонение.
Пошёл смотреть код архивации. Ну ага, точно, извращение – все 20-30 тысяч чеков записывались в одной большой транзакции. Бежит оно циклом, обрабатывает чек за чеком, складывает в транзакцию, чтобы потом разом её и зафиксировать. И каждый обработанный чек увеличивает размер транзакции и, соответственно, TempDB.
Дальше дело техники. Виктор распараллелил 20-30 тысяч чеков на порции, чтобы каждая выполнялась в отдельной транзакции. И TempDB успокоился.
Ещё один TempDB
Когда Виктор второй раз услышал «TempDB растёт», от админов знакомого клиента, он уже знал, что делать – спросил окружающих программистов, кто запустил запись большого количества чего-то в одной транзакции. И попал пальцем в небо – один из программистов перезаписывал таблицу из 150 тыс. записей, вносил небольшую модификацию в свойства.
В такие моменты окружающие создают культ личности Виктора.
Распараллеливание кода
Виктор, как вы уже поняли, никогда не учится наперёд. Только по необходимости, когда задача заставляет. Но иногда он узнаёт о каких-то возможностях оптимизации и повышения производительности совершенно случайно – например, подслушает в курилке.
Так было с распараллеливанием. Где-то от кого-то услышал, что в 1С, оказывается, можно распараллеливать выполнение кода. Не асинхронный код писать (этого Виктор ещё не знает), а вручную запускать потоки, выполняемые на сервере (фоновые задания, в терминах 1С). Если задача состоит в обработке большого количества объектов, которые друг от друга не зависят, и не нужна хронологическая последовательность – добро пожаловать в распараллеливание.
Так Виктор победил очередную проблему – за ночь не успевало отработать отражение в регламентированном учёте. Это когда надо взять несколько тысяч объектов, и для каждого выполнить одну процедуру. В типовом варианте 1С ЕРП это делается в один поток, Виктор разделил на 15 – и на этом вся оптимизация.
Много связей
Однажды Виктор случайно узнал эвристику «много связей». Как было дело: у клиента очень долго считалась себестоимость. Это обычно длительная процедура, которая проводит много вычислений и записи в БД. Цель её – для каждой операции с товарами вычислить себестоимость и записать её куда надо.
Так вот, Виктору показалось, что тут налицо какое-то извращение, потому что «обычно в таких условиях всё нормально считается», да и сервер у клиента был топовый (да и клиент – тоже). Правда, чудо тут не один Виктор сотворил – до него в задаче поковырялся настоящий эксперт, с сертификатом. Эксперт этот нашёл запрос, который выполняется несколько часов. И сидел кумекал, что же с ним сделать.
Виктор глянул на запрос – тот оказался, в общем-то, несложным. Он соединял три таблицы – в одной лежали остатки для распределения («что»), во второй настройки распределения («как»), в третьей – база распределения («куда»). Виктор не поленился и посмотрел результат этого запроса у других клиентов – ничего особенного, выполняется быстро, записей выдаёт немного.
Дальше дело техники – найди 10 отличий. У этого клиента всё нормально было с базой распределения («куда»), но совершенно неэпическое количество записей в настройках распределения («как») и остатках («что»). Подавляющее большинство настроек («как») не были нужны – они в итоге не применялись, но запрос зачем-то исправно с ними соединялся. Остатки, которые «что» и которых тоже много – это ошибки прошлого, которые накапливаются с каждым месяцем, т.к. никогда уже не распределятся (без чьего-то волевого решения).
Ну и вуаля. Виктор удалил лишние настройки, отфильтровал остатки (которые точно не распределятся) – и всё полетело. Так Виктор узнал, что надо смотреть не только на количество записей и данных вообще, но и на количество связей, которые порождаются в запросах.
Очень много связей
Через какое-то время эвристика со связями пригодилась на другом клиенте. Симптом и проблема была той же – очень долго считается себестоимость. Программа, правда, была другая – 1С ERP (в прошлый раз была 1С УПП).
Виктор съездил на встречу, ему там целый час рассказывали о процессах, истории проблемы, основных и вспомогательных симптомах, а наш герой всё говорил «ну, надо смотреть в базе, на словах не всё понятно».
Дали Виктору базу, он сразу побежал читать протокол расчёта (текстовый файл, который выдаёт система при расчёте). В код Виктор бы всё равно не полез – его там в разы больше, чем он способен понять. А протокол оказался именно тем, что нужно – там на каждом этапе расчёта детально описывались параметры получившихся таблиц (размер, количество связей, время формирования). Полистал Виктор, полистал, полистал… И нашёл!
Полтора миллиарда связей – столько числилось в одном из пунктов. Виктор пальцем пересчитал нули, убедился – да, 1.5 млрд. Чистой воды извращение.
Дальше уже знакомый алгоритм. Виктор поглядел, что это за раздел расчёта себестоимости – внутренние перемещения комиссионных товаров (что бы это ни значило). Глянул соседний раздел с похожим названием – внутренние перемещения товаров (одного слова не хватает). Нашёл, что оформляются очень похожими, но всё-таки разными документами. И увидел разницу между ними – один сворачивается, второй нет.
Ну т.е. в документе может быть 100 тыс. строк, которые отличаются несущественными для расчёта себестоимости полями. В обычных товарах 100 тыс. строк сворачиваются, например, в 3 тыс. строк, а в комиссионных кто-то свёртку сделать забыл (разработчики), и там остаются 100 тыс. строк.
Дальше дело техники – Виктор показал программисту клиента, где чего не так, тот сам всё допилил. Собственно, такова была изначальная постановка – от Виктора требовался свежий взгляд на проблему, а не решение.
Скрытая нехватка памяти
Недавно Виктор случайно обнаружил эвристику, которой теперь активно пользуется.
Попалась, значит, ему очередная задача на тему «за ночь не успевает выполняться что-то там». Симптомы – оно то неожиданно медленно работало, то нормально успевало, то падало. Виктор исключил всё, что знал – параллельную работу других длинных процедур, неоптимальный код, проблемы с СУБД, транзакции, даже распараллеливание сделал. Некоторые его действия немного помогли, но проблема в целом не ушла.
Первым делом он глянул на память сервера 1С – ну, как умел глянул. Вроде нормально, вроде хватает. Потребление в районе 60-70 %. Поэтому фактор памяти исключил сразу. Но в итоге к нему вернулся.
Админы проводили свой анализ, и как-то скинули Виктору картинку потребления памяти. График был такой – рос в процессе выполнения длительной процедуры, потом немного падал, и где-то с этого момента начинались проблемы – или скорость процесса обработки снижалась, или вообще всё падало с ошибкой. Сначала Виктор подумал, что перезапускаются процессы сервера 1С (rphost) – такая эвристика нашему герою была известна. Он глянул в свойствах процессов – нет, не падали.
Тут Виктор вспомнил детство, когда у него был 386-й компьютер то ли с 2, то ли с 4 Мб ОЗУ. У него запускался Wolfenstein, но никак не хотел работать Doom II. Виктору тогда посоветовали разобраться с файлом подкачки – это вроде как файл на жёстком диске, в который помещается часть содержимого ОЗУ, когда памяти не хватает. При этом памяти доступной как бы становится больше, потребление именно ОЗУ как бы снижается, но скорость работы жёсткого диска сильно ниже скорости чипов ОЗУ. Прошу прощения за туповатое изложение и ошибки – я разбираюсь в этом не лучше Виктора.
Так вот, Виктор предположил, что то же самое происходит на сервере 1С. Когда потребление ОЗУ доходит до некоторой критической отметки, начинает использоваться файл подкачки, что и приводит к замедлению выполнения операций в 1С. Ну и к обрывам, по таймауту, когда что-то внутри 1С не может дождаться ответа (клиент от сервера, сервер от СУБД, кластер от агента и т.д. – это всё внутри платформы и хрен знает как оно там работает).
Пошёл Виктор к админам, спросил можно ли добавить памяти. Те сказали – да, перераспределим ресурсы между виртуальными машинами. В тот же день проблемы прекратились.
Виктор даже алгоритм какой-то эмпирический придумал, для определения необходимого количества ОЗУ на сервере. Говорит – запустите несколько сеансов 1С, поработайте полдня, в обычном для себя режиме, потом посмотрите объём памяти, занятый процессами rphost, и поделите на количество активных пользователей. Именно пользователей, а не сеансов, т.к. существенная часть сеансов – фоновые задания, которые запускаются в процессе работы пользователей. По его формуле, для 1С ERP без доработок получилось примерно 1.5-2 Гб на пользователя.
Бенефис скрытой нехватки памяти
Ну и напоследок – пример быстрого применения эвристики про память. В такие моменты одни люди начинают обожать Виктора, а другие – ненавидеть.
Пришёл к Виктору коллега спросить совета. Есть клиент, у которого регулярно, но непрогнозируемо вылетают сеансы 1С. Всё перепробовали, технологический журнал смотрели, ничего не нашли. Вылетают и всё.
Виктор послушал несколько минут и говорит – памяти не хватает. Коллега говорит – хватает, норм там памяти. Виктор отвечает – ну вы попробуйте добавить, если это не трудно.
Клиент отказался следовать совету хрен пойми кого (Виктор сам с клиентом не общался). Подключили настоящего эксперта. Тот сначала думал, что проблема в программной лицензии сервера 1С, для теста заменили на физический ключ – не помогло.
Каким-то путём эксперт дошёл до памяти и подтвердил – не хватает. Объём ОЗУ был нормальный, но админ поставил серверу 1С ограничение на её потребление.
Виктор случайно узнал, что так всё вышло. Но в голове отметил – надо не только объём ОЗУ смотреть, но и какое-то неведомое «ограничение потребления».
Заключение
Я, разумеется, привёл не все примеры задач по производительности, которые решал Виктор. Скорее хотел показать принципы решения и познания, которые он использует. Прав он или нет – решать точно не мне, я и не планирую.
Объективные трудности в его подходе есть, и Виктор сам их признаёт. Например, у него очень обрывочные знания о том, как оно там всё устроено. Садится изучать он только то, что ему попалось на «разделочный стол». И только в случае, если предыдущие эвристики не помогли.
Иногда Виктора задумывается о том, чтобы нормально поучиться, устранить жуткие пробелы в знаниях. Может, сертификат какой-нибудь получить. Но, глядя на результаты работы настоящих, сертифицированных экспертов, на их подходы и стоимость услуг, каждый раз принимает решение – ну его нахрен.
Комментарии (0)
flancer
24.09.2025 05:07По названию и половине первого предложения определил автора. Эх... опять жанр производственной фантастики появился на Хабре.
BigVal
24.09.2025 05:07Виктор это сын или внук Петровича. Петрович ваших институтов не кончал и интернетов не читал, но он и так ЧУВСТВУЕТ "что и как в движке работает" и методом тыка все починить может :-) И "мастера с сертификатами и с мануалами" часто зовут Петровича на проведение диагностики. Правда все меньше Петровичей остается, все больше "сертифицированных специалистов". А у буржуев Петровичи вообще вывелись...
gennayo
Какая у Вити профессиональная жизнь то интересная...