Как решить проблемы с отладкой, зависанием проведения и стабильностью баз 1С на виртуальном сервере Hyper-V?

Системный администратор 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Развертывание клиент-серверной архитектуры «1С:Предприятие 8.3» в виртуализированной среде Hyper-V — стандартная практика для современных корпоративных систем. Однако при разделении сервера приложений 1С и сервера баз данных (СУБД MS SQL) на разные виртуальные машины администраторы и разработчики часто сталкиваются с загадочными симптомами: невозможностью запустить серверную отладку, внезапными отключениями баз данных и «намертво» зависающими транзакциями при проведении документов. В этой статье мы подробно разберем причины возникновения этих проблем и пошагово устраним их.

Симптомы и системный ландшафт

Рассмотрим типовую серверную конфигурацию, в которой наиболее ярко проявляются описываемые проблемы:

При такой схеме часто наблюдаются три критические проблемы:

  1. Не работает серверный отладчик. В Конфигураторе включена отладка, порты открыты, в реестре прописан ключ -debug, клиентские процедуры отлаживаются без проблем, но при попытке войти в серверный код точка останова игнорируется.
  2. Периодически «отваливаются» базы данных. С периодичностью раз в несколько недель или дней пользователи получают ошибку подключения к базе данных. Временным решением служит удаление и повторное добавление базы в список.
  3. Зависает проведение документов. В самописных или типовых конфигурациях при определенных условиях (например, при нехватке остатков на складе, когда срабатывает отказ от проведения) сеанс полностью зависает на строке Отказ = Истина, хотя в локальной (файловой) копии на домашнем компьютере разработчика все работает корректно.

---

Решение проблемы №1: Настройка серверной отладки и прав доступа

Отсутствие серверной отладки при корректно прописанном ключе -debug в параметрах запуска службы — распространенная проблема. Выясним причину этой неполадки.

Первое, на что необходимо обратить внимание — права доступа к служебному каталогу сервера 1С. По умолчанию все конфигурационные файлы кластера хранятся в папке srvinfo (путь по умолчанию: C:\Program Files\1cv8\srvinfo). Если служба сервера 1С (процесс ragent.exe) запущена от имени специально созданного локального или доменного пользователя (например, usr1cv8), этот пользователь должен обладать полными правами на чтение, запись и изменение структуры всей директории srvinfo.

Очень часто доменные политики безопасности Windows Server принудительно затирают или сбрасывают права на диске C:. В результате служба теряет доступ к конфигурационным файлам (включая файлы описания кластера 1CV8Clst.lst), что приводит к нестабильной работе: отладчик перестает инициализировать серверные сеансы, базы данных начинают отключаться, а журналы регистрации перестают записываться.

Выполним пошагово настройку прав доступа и параметров службы:

  1. Остановим службу 1C:Enterprise 8.3 Server Agent через консоль services.msc.
  2. Перейдем в каталог расположения конфигурационных файлов. Если вы хотите обезопасить систему от влияния групповых политик диска C:, рекомендуется перенести папку srvinfo на другой логический диск (например, D:\1C_Base\srvinfo).
  3. Откроем свойства папки srvinfo, перейдем на вкладку Безопасность и предоставим полные права (Full Control) пользователю, под которым запускается служба сервера 1С (usr1cv8). Обязательно нажмем кнопку Дополнительно и установим флаг «Заменить все записи разрешений дочернего объекта наследуемыми от этого объекта».
  4. Проверим строку запуска службы в реестре Windows. Откроем редактор реестра regedit, перейдем по пути:

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\1C:Enterprise 8.3 Server Agent

    Найдем параметр ImagePath и убедимся, что ключ -debug расположен корректно. Обратите внимание, что ключ -debug должен быть прописан отдельно и не должен разрывать путь к каталогу данных после ключа -d.

Правильный пример строки запуска службы в реестре:

"C:\Program Files\1cv8\8.3.10.2650\bin\ragent.exe" -srvc -agent -regport 1541 -port 1540 -range 1560:1591 -debug -d "C:\Program Files\1cv8\srvinfo"

Важное замечание: После изменения прав доступа к каталогу srvinfo и редактирования реестра недостаточно просто перезапустить службу 1С. Настоятельно рекомендуется полностью перезагрузить виртуальный сервер приложений для применения всех изменений операционной системой.

Если после этого серверные предметы отладки все еще не подключаются автоматически, проверим настройки в самом Конфигураторе:

---

Решение проблемы №2: Борьба с периодическим «отваливанием» баз в Hyper-V (настройка VMQ)

Перейдем ко второму симптому: базы данных периодически теряют соединение с сервером приложений, выдавая ошибки подключения к СУБД, которые лечатся только переподключением ИБ в кластере. Когда сервер приложений 1С и MS SQL Server разнесены по разным виртуальным машинам на одном физическом хосте, ключевую роль начинает играть стабильность виртуальной сети.

Проанализируем сетевой стек виртуализации Hyper-V. По умолчанию для повышения производительности сетевых адаптеров включена технология VMQ (Virtual Machine Queue). Она распределяет обработку сетевых пакетов виртуальных машин по разным ядрам физического процессора, перенося вычисления на сетевую карту.

Однако драйверы многих популярных физических сетевых плат (в особенности от производителей Broadcom и Intel) содержат критические ошибки при работе с механизмом VMQ в среде Hyper-V. Это приводит к возникновению кратковременных микроразрывов сетевого соединения (длительностью в доли секунды) между виртуальными машинами внутри хоста.

Для обычных веб-серверов или файловых хранилищ такие микроразрывы незаметны, поскольку протокол TCP повторно отправляет потерянные пакеты. Но связка «Сервер 1С — MS SQL Server» крайне чувствительна к любым сетевым задержкам. Как только происходит микроразрыв, менеджер кластера 1С мгновенно разрывает транзакцию и переводит соединение с СУБД в аварийный режим, из-за чего базы начинают «отваливаться».

Рассмотрим, как отключить VMQ для стабилизации сетевого соединения:

  1. На физическом хосте Hyper-V откроем Диспетчер устройств.
  2. Найдем физический сетевой адаптер (или сетевые адаптеры, объединенные в Team), обслуживающий виртуальный коммутатор.
  3. Откроем свойства адаптера, перейдем на вкладку Дополнительно (Advanced).
  4. В списке свойств найдем параметр Virtual Machine Queue (или Очередь виртуальных машин) и переведем его в состояние Disabled (Выключено).
  5. Дополнительно в свойствах сетевых адаптеров внутри самих виртуальных машин (в операционных системах серверов 1С и SQL) также рекомендуется отключить эту опцию.

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

---

Решение проблемы №3: Оптимизация транзакционного кода при отказе от проведения

Третий симптом — зависание самописной конфигурации при попытке проведения документа, если срабатывает условие отмены транзакции (Отказ = Истина). На домашнем компьютере разработчика (в файловом режиме) все проходит успешно, а на сервере сеанс «застывает».

Проанализируем исходный код проведения, который предоставил автор темы:


Процедура ОбработкаПроведения(Отказ, РежимПроведения)
    // 1. Получение запросом данных документа
    Запрос = Новый Запрос;
    Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   СписаниеНоменклатурыНоменклатура.Номенклатура КАК Номенклатура,
        |   СписаниеНоменклатурыНоменклатура.Склад КАК Склад,
        |   СУММА(СписаниеНоменклатурыНоменклатура.Количество) КАК Количество
        |ПОМЕСТИТЬ НоменклатураДокумент
        |ИЗ
        |   Документ.СписаниеНоменклатуры.Номенклатура КАК СписаниеНоменклатурыНоменклатура
        |ГДЕ
        |   СписаниеНоменклатурыНоменклатура.Ссылка = &Ссылка
        |СГРУППИРОВАТЬ ПО
        |   СписаниеНоменклатурыНоменклатура.Номенклатура,
        |   СписаниеНоменклатурыНоменклатура.Склад";
    
    Запрос.УстановитьПараметр("Ссылка", Ссылка);
    РезультатЗапроса = Запрос.Выполнить();
    
    // 2. Формирование движений-расход регистра
    Движения.РегистрХранения.Очистить();
    ВыборкаНоменклатура = РезультатЗапроса.Выбрать();
    Пока ВыборкаНоменклатура.Следующий() Цикл
        Движение = Движения.RegiistrHraneniya.ДобавитьРасход();
        // Заполнение свойств движения...
    КонецЦикла;
    
    // 3. Запись движений в БД
    Движения.РегистрХранения.Записывать = Истина;
    Движения.Записать();
    
    // 4. Запрос, получающий отрицательные остатки из регистра
    // (Выполняется обращение к таблице остатков с использованием ВЫБРАТЬ...)
    // 5. Вывод сообщений о недостатке товаров
    Если Не РезультатЗапросаПустой Тогда
        Отказ = Истина;
    КонецЕсли;
КонецПроцедуры

В чем кроется системная ошибка этого алгоритма при работе в клиент-серверном режиме?

Перед нами классическая реализация так называемой «новой методики проведения». В ней разработчик сначала записывает движения расхода в базу данных (шаг 3), а затем проверяет, не ушел ли остаток товара в минус (шаг 4). Если обнаружен дефицит, переменной Отказ присваивается значение Истина.

Когда платформа 1С завершает процедуру ОбработкаПроведения с флагом Отказ = Истина, она инициирует операцию отката транзакции (Rollback) в СУБД MS SQL. Все измененные данные должны вернуться в исходное состояние.

Зависание на сервере происходит по следующим причинам:

  1. Отсутствие управляемых блокировок. В коде не установлена блокировка на анализируемые остатки товаров. Если в этот момент параллельно выполняется другое чтение или запись в таблицу регистра (даже системными фоновыми процессами), СУБД накладывает разделяемые (Shared) блокировки. При попытке отката транзакции СУБД пытается повысить уровень блокировки до монопольной, возникает взаимная блокировка (Deadlock) или бесконечное ожидание освобождения ресурсов.
  2. Откат «грязных» данных. Запись незафиксированных движений расхода в базу данных нагружает транзакционный лог MS SQL. При отмене транзакции SQL-сервер вынужден выполнять обратное чтение лога транзакций для восстановления таблиц. На производительных серверах в условиях сетевых микроразрывов (см. Проблему №2) этот процесс может зациклиться, переводя поток rphost в состояние бесконечного ожидания.

Посмотрим на пример правильного написания кода с использованием управляемых блокировок данных. Модернизируем процедуру проведения:


Процедура ОбработкаПроведения(Отказ, РежимПроведения)
    
    // 1. Инициализируем блокировку данных
    Блокировка = Новый БлокировкаДанных;
    ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.РегистрХранения");
    ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
    // Устанавливаем источник данных для блокировки из документа
    ЭлементБлокировки.ИсточникДанных = Ссылка.Номенклатура; 
    ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура", "Номенклатура");
    Блокировка.Заблокировать();
    
    // 2. Получение данных документа запросом
    Запрос = Новый Запрос;
    // ... Настройка запроса ...
    РезультатЗапроса = Запрос.Выполнить();
    
    // 3. Формирование и запись движений (новая методика)
    Движения.РегистрХранения.Очистить();
    Движения.РегистрХранения.Записывать = Истина;
    
    // Заполняем движения...
    
    // Принудительно записываем движения, чтобы они попали в базу в рамках нашей транзакции
    Движения.Записать(); 
    
    // 4. Проверяем остатки с учетом записанных движений
    // ... Выполнение запроса контроля остатков ...
    
    Если ОбнаруженДефицит Тогда
        Отказ = Истина;
        Сообщение = Новый СообщениеПользователю;
        Сообщение.Текст = "Недостаточно товара на складе!";
        Сообщение.Сообщить();
    КонецЕсли;

КонецПроцедуры

Использование явной установки исключительной блокировки (РежимБлокировкиДанных.Исключительный) гарантирует, что другие сеансы не смогут прочитать или изменить заблокированные остатки товаров до завершения нашей транзакции. Это полностью исключает возникновение взаимных блокировок СУБД при отказе от проведения и устраняет эффект «зависания» системы.

---

Ложные тревоги в Технологическом журнале

В процессе диагностики системные администраторы часто настраивают Технологический журнал (ТЖ) 1С и пугаются обилия ошибок вида:

EXCP ... Exception=9db1fa37 ... Файл не обнаружен 'v8srvr://um-ones/UTMC/Files/SprScndInfo'

Проанализируем природу этой ошибки. Файл SprScndInfo (аббревиатура от Separator Second Info) содержит метаданные о разделителях информационной базы. Платформа 1С при каждом запуске сеанса или фонового задания пытается прочитать настройки разделения данных для облачных режимов работы.

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

---

Резюме и выводы

Мы проанализировали комплекс проблем при работе сервера 1С на виртуальной платформе Hyper-V и пришли к следующим выводам:

← На главную