Workaround me в 1С/MS SQL и не только, системный подход к созданию костылей

15.08.22

База данных - HighLoad оптимизация

Workaround свидетельствует о невозможности решить проблему "правильным путем" и вызывает чувство стыда. Но практика показывает, что способность решать проблемы через workaround является порой единственным способом решить проблему в разумное время. А победителей, как говорят, не судят, так почему бы не создавать workaround по системе?

Нормальные герои всегда идут в обход

Айболит 66

Думаю, что многие встречались с необъяснимым поведением компонентов 1С, подсистем ОС, драйверов, СУБД  которое видно в трассировке, но трассировка не отвечала на главный вопрос - почему? Т.е. по документации должно работать, но не работает.

Несмотря на все более возрастающее движение за системы с открытым кодом, всегда есть что-то, к чему нет исходников,  либо нет компетенций, ресурсов в них разбираться. Ну даже если Вы найдете причину в открытом коде – скажем, PostgreSQL, чтобы это исправить, нужны хорошие навыки и  компетенции. И все дороги, получается, ведут по пути Workaround (обходной путь), поскольку решение службы поддержки ждать дольше.

Более тяжелым случаем являются ограничения платформы (например, ограничения 1С при горизонтальном масштабировании, см.:   Язык мой враг мой), которые тоже приходится обходить.

В английском закрепился термин, и ему посвящена статься в Wiki , где его связывают с анти-паттерном

Workaround wiki

Надо сказать. Workaround не обязательно костыль, или заплата, но он всегда несет в себе какие-то минусы – ведь мы действуем обходным путем

Термины не возникают на пустом месте – значит, сложилась предыстория, приемы, методы, которые нужно было как то назвать. Например, названия трюков на вейкборде Ollie, Wake to wake и т.д… это ниточка, за которой тянется техника, подводящие упражнения и многое другое.

Умение создавать workaround жизненно важно для систем,

  1. У которых маленькие технологические окна. Например наша, где роботы работают почти круглосуточно 1C Методика похудения 100%   и с высокой нагрузкой.
  2. Устаревшие системы, которые сняты с поддержки
  3. Системы с высокой нагрузкой, использующие горизонтальное масштабирование, где проявляются эффекты бутылочных горлышек.
  4. Системы крупных вендоров, где не будет мгновенной реакции службы поддержки (Конечно, Вы можете попробовать расширенную поддержку 1С Корп, но руководство будет смотреть на Васа не на поддержку 1С  😉  )
  5. Я надеюсь, в комментариях добавят еще интересные кейсы

 

Разберем методы создания Workaround на реальных историях. Предлагаемая классификация методов наверняка неполная, и в комментариях к статье добавят много нового.

 

История №1. Как MS SQL случайным образом отключал соединения 1С (актуально и сейчас)

Все началось с жалоб пользователей на ошибки сверки с Backoffice при закрытии дня. Анализ показал, что некоторые фоновые задания, применяющиеся при расчетах с горизонтальным масштабированием, завершались некорректно. Надо заметить, что 1С сейчас хранит историю только по 1000  последних фоновых заданий, и мы создали расширенное логгирование в конфигурации для отслеживания таких ситуаций.  Подробнее о проблеме можно посмотреть тут  Язык мой Враг мой.

В 1С проблему можно локализовать анализом тех. журнала, а там заметили следующее

16:42.3540-0,SCOM,2,process=rphost,t:clientID=2352,Func='setSrcProcessName(MyDB, MyDB)'

16:42.4481-0,EXCP,2,process=rphost,p:processName= MyDB,t:clientID=2352,t:applicationName=BackgroundJob,t:connectID=14847,Exception=DataBaseException,Descr='Ошибка СУБД:

Microsoft SQL Server Native Client 11.0: TCP Provider: An existing connection was forcibly closed by the remote host.



HRESULT=80004005, HRESULT=80004005, SQLSrvr: SQLSTATE=08001, state=1, Severity=10, native=10054, line=0

Удивительно – но MS SQL сам отключает коннекты  «случайным образом»? Анализ логов MS SQL \Операционной системы ничего не дал, в какие то критические режимы MS SQL не входил.

Выхода было два, либо копать глубже с трассировкой на уровне стека TCP и MS SQL Profiler, либо задать вопрос Google – возможно, он не даст прямое решение, но какую то идею.

К счастью. Google сразу вывел на статью Microsoft TLS connection forcibly closed,  где была описана ошибка в TLS протоколах и Workaround для  нашей версии Windows – отключить TLS_DHE_* в групповых политиках.

В данном случае  workaround сделан по принципу

 

Не работает – измени окружение

Поскольку проблемные методы шифрования были убраны из политик и оставлены работающие – окружение 1С – MS SQL сервер изменилось.

У кого-то возникнет вопрос – а как действовать, если Google не вывел на прямой ответ?

Многие бросаются ставить все возможные патчи - ковровой бомбардировкой на ОС, SQL Server, 1С. Мне не нравится этот метод, поскольку они могут привести к другим проблемам, если длительно не выдержаны и протестированы на резервном контуре\контуре тестирования. Кроме того,  в рассматриваемом случае патчи есть только для новых ОС

В рассматриваемом случае можно еще больше локализовать проблему – ведь ошибка TCP провайдера не означает, что проблема на транспортном уровне модели OSI. Нужно проверять еще прикладной, представления, сеансовый. В документации по ошибке есть пример network traсe, который позволяет ее выявить  и, судя по всему, это сделано  O Wire Shark  и придется привлечь системных администраторов.

Если повезет, можно быстро понять, что дело на уровне шифрования TLS, но если нет возможности заниматься анализом, можно поступить по другому.

В нашем случае ошибка регистрируется периодически для фоновых заданий при взаимодействии сервера приложений 1С и SQL сервера и вредит она фоновым заданиям

Вариант 1. А что, если сделать повторный запуск фоновых заданий в 1С, если оно не доработало? В целом это нормальный вариант, который повысит выживаемость 1С в нестабильной среде при любых таких плавающих проблемах.  Такой подход называется

 

Не работает - Измени подсистему и ее поведение

Вариант 2. Перенастроить кластер 1С на сервер с MS SQL и включить Shared memory protocol. Радикальная смена стека протоколов поможет обойти проблему по пути  «Не работает – измени окружение». Да на нагрузка на оборудование возрастет, но зато прикладные проблемы уйдут

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

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

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

 

История №2. Как ускорить запись в регистр сведений 1С? Почти Антипаттерн, пока 1С не исправит

При использовании горизонтального масштабирования на уровне кластера 1С можно создать множество параллельных задач, которые постят движения в регистры, импортируют операции, и можно даже параллельно считать статьи баланса. Однако узким местом в 1С является запись в регистры (подробнее изложено в статье Язык мой Враг мой).

Допустим, нам нужно импортировать операции, по которым 6 миллионов изменений за день, а уникальных операций около миллиона в день. Изменения поступают по шине RabbitMQ

Построим регистры СУУ_АгрегированнаяСделкаКП (Индексы по измерениям , поле Удалено, Дата)

 

 

СУУ_НеобязательныеРеквизитыДляАгрегированныхОпераций (Индексы по измерениям)

 

 

С импортом новых операций проблем не возникнет, их можно записывать в регистры сведений сразу набором по 1000 шт за один раз с распараллеливанием.

Но если мы захотим обновить 1000 операций , то это можно сделать только по отдельным ИдИсхСистемы - поскольку фильтр отбора по измерений 1С работает только на равенство везде, т.е. получим 1000 отдельных вызовов .Записать()

Метаданные типа Документ еще хуже – документы можно записывать по одному, а не несколько в крупном DML.

Даже если эти записи распараллелены на 40 потоков – SQL сервер будет под атакой тысяч небольших DML операций со всеми вытекающими для производительности.

Добавлю, что при обновлении нужно решать проблему правильной записи версий, чтобы версия 1 не записалась поверх версии 2

Как укрупнить DML в таких условиях, если хочется остаться в рамках 1С?

 

Изменить свое отношение к проблеме, решай другую проблему

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

Но ведь можно ничего не обновлять, а писать сразу версии! Сделаем регистры сведений периодическими и будем писать версии (версия в стандартном поле Период)! Главное, чтобы версия была одинакова и у реквизитов, и у операций. Поле Период по факту будет временем начала записи пакета из 1000 операций\необязательных реквизитов

Да, усложнится отбор операций для последующей обработки  - ведь нам нужно отбирать последние версии операций и соединять их при необходимости с последними версиями необязательных реквизитов. Но зато мы можем организовать импорт максимально быстро в данном окружении.

Анонс: Эффективное написание запросов в этом случае тема отдельной статьи.

1С и в этом случае добавляет барьеров в виде неэффективных соединений с временными таблицами (подробно тут: 1С Миссия невыполнима. Общие реквизиты разделители против временных таблиц), но в целом задача решается просто изменением подхода к проблеме.

Хочется еще быстрее – тогда пишите в регистр сведений напрямую, минуя 1С , но это уже другая история.

 

История №3. Как рабочий процесс 1С терял контекст драйвера Oracle

Дело было в 2014 году , мы активно распараллеливали фоновыми заданиями задачи импорта. Появилась задача импортировать операции с базы на Oracle  в 1С, обращение к серверу Oracle шло с использованием драйвера Oracle12c, на сервере приложений. В процессе эксплуатации начали регистрироваться сбои. Текст ошибки не помню, но суть была в потере контекста для определения параметров Oracle_home, причем периодически, а не постоянно.  

Замечу, для драйверов Microsoft для Oracle ничего подобного не наблюдалось, но по разным причинам нужно было использовать родной драйвер Oracle

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

 

Не работает - Измени подсистему и ее поведение

               

Подсистема работы с внешними источниками в 1С тогда еще была с ограниченным функционалом, поэтому использовали ADODB

Сначала была попытка соединиться правильно, но если не удавалось, создавали Ole вызов клиента 1С на сервере из фонового задания, и уже через Ole брали данные. Обходной вариант выглядел так (код сократил для удобочитаемости)

ADOConnection = СУУ_СоздатьОбъектАДО(ИДВызова, "ADODB.Connection");

                Если ADOConnection = Неопределено Тогда

                               Возврат Неопределено;

                КонецЕсли;

               

                ОбъектОЛЕ = Неопределено;

               

                СоединениеУстановлено = Ложь;

                // установка соединения

                Попытка

               

                               ADOConnection.Open(СтрокаСоединения);

                               СоединениеУстановлено = Истина;

                              

                Исключение

                // Ошибка

                              

                КонецПопытки;

               

                Если НЕ СоединениеУстановлено Тогда

               

                               // сюда дойдем, если при подключении через родной объект ADODB.Connection произошла ошибка

                              

                               // на ORACLE x64 + 1С x64 + Windows x64 есть ошибка - после какого-то количества успешных подключений возникает ошибка.

                               //решение проблемы не найден. есть только обход:

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

                               //из клиента 1С, который всегда x32

                               //для этого написана микро-конфа с тремя экспортными методами:

                               //ADOConnectionObj();

                               //ADOCommandObj();

                               //ADORecordsetObj();

                               //фишка - если получили Connection таким образом, то и Command нужно тоже получить из 32-х разрядного клиента,

                               //иначе будет ошибка на этом моменте: Command.ActiveConnection = ADOConnection;

                              

                               ОбъектОЛЕ = Неопределено;

                               Попытка

                                              

                                               ОбъектОЛЕ =  Новый COMобъект("V82.Application");

                                               ОбъектОЛЕ.Visible=Ложь;

                                               ОбъектОЛЕ.Connect("File=""C:\1C\ComSrv""; Usr="""";Pwd="""";");

                                               ОбъектОЛЕ.Visible=Ложь;

                                               СоединениеОЛЕ = Истина;

                                              

                               Исключение

                                               //Сообщаем об ошибке

                                                УничтожитьОбъектАДО(ADOConnection);

                                               УничтожитьОбъектОЛЕ(ОбъектОЛЕ);

                                              

                                               Возврат Неопределено;

                               КонецПопытки;

 

Некрасиво получается, а что делать?

Не работает – убери подсистему из окружения

 

Более красивый вариант – создать DBLink с Oracle на MSSQL сервере, где находилась база 1С , и обращаться уже к DBlink, используя только драйвера Microsoft, так в принципе можно сделать более универсальным код работы с внешними СУБД. Минус – слишком много слоев и сложный маршрут по сети (1С сервер – MS Sql сервер – Oracle сервер).

 

История №4  из Java

Я не эксперт в Java, но писал небольшие приложения для склеивания 1С с различными шинами, приложениями, для администрирования СУБД и т.д. Ведь когда что-то в 1С невозможно, проще найти это в мире Java и интегрировать.

При попытке написать приложение с использованием JSF + Glassfish обнаружил, что связка категорически не хочет работать даже с Hello word, см. тут: Мой наивный вопрос на StackOverflow

Я не смог найти рецептов, понять причину проблемы, и пришлось решить сменой сервера приложений Glassfish на Payara. Да, вот так радикально. Вообще качество  решений на Java это тема отдельной статьи. Количество конкурирующих решений размывает качество тестирования на конечных потребителях. И после этого начинаешь очень ценить порядок и предсказуемость в платформе 1С.

Присоединяйтесь к нашему телеграм каналу. Очень интересно будет увидеть в комментариях случаи и решения не укладывающиеся в данную классификацию и другие методы создания Workaround.

Workaround Обходной путь Программирование MS SQL

См. также

Администрирование СУБД Платформа 1С v8.3 Конфигурации 1cv8 Россия Бесплатно (free)

При хранении файлов в томах на диске они иногда исчезают. Разбираемся, почему.

23.05.2024    9966    human_new    18    

56

HighLoad оптимизация Инструменты администратора БД Системный администратор Программист Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Обработка для простого и удобного анализа настроек, нагрузки и проблем с SQL сервером с упором на использование оного для 1С. Анализ текущих запросов на sql, ожиданий, конвертация запроса в 1С и рекомендации, где может тормозить.

2 стартмани

15.02.2024    12417    241    ZAOSTG    80    

115

HighLoad оптимизация Программист Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Встал вопрос: как быстро удалить строки из ТЗ? Рассмотрел пять вариантов реализации этой задачи. Сравнил их друг с другом на разных объёмах данных с разным процентом удаляемых строк. Также сравнил с выгрузкой с отбором по структуре.

09.01.2024    14010    doom2good    49    

71

HighLoad оптимизация Системный администратор Программист Бесплатно (free)

При переводе типовой конфигурации 1C ERP/УТ/КА на PostgreSQL придется вложить ресурсы в доработку и оптимизацию запросов. Расскажем, на что обратить внимание при потерях производительности и какие инструменты/подходы помогут расследовать проблемы после перехода.

20.11.2023    13529    ivanov660    6    

81

HighLoad оптимизация Бесплатно (free)

Казалось бы, КОРП-системы должны быть устойчивы, быстры и надёжны. Но, работая в рамках РКЛ, мы видим немного другую картину. Об основных болевых точках КОРП-систем и подходах к их решению пойдет речь в статье.

15.11.2023    7157    a.doroshkevich    22    

74

Администрирование СУБД Системный администратор Бесплатно (free)

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

13.11.2023    17753    ivanov660    32    

77
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Pavel_Vladivostok 58 31.07.23 08:55 Сейчас в теме
интересная структура регистра СУУ_АгрегированнаяСделкаКП, похоже на РНК для учета стоимости облигаций, но состав какой-то странный, для чего этот регистр если не секрет?
2. 1CUnlimited 320 04.08.23 15:38 Сейчас в теме
(1) Просто регистр для хранения сделок и операций , которые грузятся из внешней системы бэкофис (поэтому там есть ИсхСистема и ИдИсхСистемы) - учет ценных бумаг . Поскольку количество операций велико грузим версии , это позволяет одним действием записать много и не делать update. На сегодняшний момент единственный вариант реализации на уровне метаданных 1С , с высокой производительностью загрузки. Традиционный объект документ гораздо медленней и не позволяет записать сразу несколько документов одним .Записать()
Оставьте свое сообщение