Как подружить веб-клиент и HTTP-соединение при работе с несколькими базами 1С?

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

При разработке современных систем на платформе 1С:Предприятие 8.3 часто возникает архитектурная задача: одна база должна запрашивать данные из другой через HTTP-сервисы. Ситуация осложняется, когда основной пользователь работает через веб-клиент, а обе базы (источник и приемник) являются файловыми и опубликованы на одном веб-сервере Apache. В этой статье мы подробно разберем, почему возникает ошибка «Не могу установить соединение» и как правильно настроить взаимодействие между базами.

Анализ проблемы: почему тонкий клиент работает, а веб-клиент — нет?

Рассмотрим стандартную ситуацию. У нас есть две базы. В первой базе (клиентской) написан код, который на сервере инициирует HTTPСоединение ко второй базе (сервисной). При запуске через тонкий клиент все отрабатывает успешно, но при входе через браузер (веб-клиент) тот же самый код выдает ошибку: «Ошибка работы с Интернет: Не могу установить соединение».

Проанализируем причину. Несмотря на то, что код выполняется в процедуре &НаСервереБезКонтекста, окружение веб-клиента накладывает свои ограничения. Когда сервер 1С первой базы пытается обратиться к localhost, на котором работает Apache, возникает конфликт ресурсов или сетевых разрешений внутри самого процесса веб-сервера. Для файловых баз на одном Apache это часто приводит к «зацикливанию» (deadlock) потоков исполнения.

Решение №1: Разнесение баз по разным серверам или портам

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

  1. Разные физические или виртуальные машины. Как показывает практика, перенос сервисной базы на другой IP-адрес мгновенно решает проблему с установкой соединения.
  2. Использование разных портов Apache. Если возможности использовать другой компьютер нет, можно настроить Apache так, чтобы он слушал несколько портов (например, 80 и 8080). Опубликуйте первую базу на порту 80, а вторую — на 8080. Это позволит операционной системе четко разграничивать входящие и исходящие потоки веб-сервера.

Решение №2: Оптимизация кода запроса и замена localhost на IP

Выясним причину, почему localhost может подводить. Зачастую система пытается разрешить имя localhost через протокол IPv6 (адрес ::1), в то время как публикация 1С ожидает IPv4 (127.0.0.1). Посмотрим на пример правильной инициализации соединения:


&НаСервереБезКонтекста
Процедура ВыполнитьЗапросНаСервере()
    // Вместо "localhost" используем явный IP-адрес
    СерверИсточник = "127.0.0.1"; 
    Порт = 80;
    АдресРесурса = "/Base2/hs/v1/getData/";
    
    // Принудительно устанавливаем заголовки для закрытия соединения
    Заголовки = Новый Соответствие;
    Заголовки.Вставить("Connection", "close");
    
    НТТР = Новый HTTPСоединение(СерверИсточник, Порт, , , , 30);
    Запрос = Новый HTTPЗапрос(АдресРесурса, Заголовки);
    
    Попытка
        Ответ = НТТР.Получить(Запрос);
        Сообщить("Код состояния: " + Ответ.КодСостояния);
    Исключение
        Сообщить("Ошибка: " + ОписаниеОшибки());
    КонецПопытки;
КонецПроцедуры

Использование заголовка Connection: close крайне важно в сценарии с одним сервером. Это заставляет веб-сервер закрывать соединение сразу после ответа, не дожидаясь тайм-аута Keep-Alive, что освобождает потоки Apache для новых запросов.

Решение №3: Использование COM-объекта WinHttp (только для Windows-серверов)

Проанализируем альтернативный подход. Платформенный объект HTTPСоединение обладает множеством внутренних проверок безопасности и настроек прокси. Иногда более эффективным (и быстрым) оказывается использование системной библиотеки Windows WinHttp.WinHttpRequest.5.1.

Важно: Этот метод будет работать только если серверная часть 1С (или Apache в случае файловой базы) работает под управлением ОС Windows.


&НаСервереБезКонтекста
Функция ВыполнитьЗапросЧерезWinHttp(URL)
    Попытка
        ВебКлиент = Новый COMОбъект("WinHttp.WinHttpRequest.5.1");
        
        // Установка тайм-аутов: Resolve, Connect, Send, Receive (в мс)
        ВебКлиент.SetTimeouts(5000, 5000, 10000, 10000);
        
        ВебКлиент.Open("POST", URL, Ложь); // Ложь - синхронный вызов
        ВебКлиент.SetRequestHeader("Content-Type", "application/json");
        ВебКлиент.SetRequestHeader("Accept", "application/json");
        
        // Тело запроса
        Данные = "{""test"": ""value""}";
        ВебКлиент.Send(Данные);
        
        Если ВебКлиент.Status = 200 Тогда
            Возврат ВебКлиент.ResponseText;
        Иначе
            Возврат "Ошибка сервера: " + ВебКлиент.Status;
        КонецЕсли;
    Исключение
        Возврат "Критическая ошибка: " + ОписаниеОшибки();
    КонецПопытки;
КонецФункции

Как отмечают разработчики, использование WinHttp часто показывает лучшую производительность по сравнению со штатным HTTPСоединение, так как объект работает напрямую с системными сокетами, минуя некоторые уровни абстракции платформы 1С.

Решение №4: Настройка параметров потоков в Apache

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

Необходимо отредактировать файл конфигурации httpd.conf. Найдите секцию mpm_winnt_module (для Windows) и увеличьте количество потоков:


<IfModule mpm_winnt_module>
    ThreadsPerChild      150
    MaxConnectionsPerChild    0
</IfModule>

Параметр ThreadsPerChild определяет, сколько одновременных соединений может обрабатывать Apache. Увеличение этого значения позволяет серверу выделить свободный поток для второй базы, пока первая ожидает ответа.

Рекомендации по отладке HTTP-сервисов в веб-клиенте

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

  1. Проверка прав доступа. Убедитесь, что пользователь, под которым запущен Apache (обычно USR1CV8 или SYSTEM), имеет права на запуск сетевых соединений и доступ к каталогам обеих файловых баз.
  2. Логирование. Если 1С выдает общую ошибку соединения, всегда проверяйте файл error.log в папке logs вашего Apache. Там часто фиксируется реальная причина (например, AH00161: server reached MaxRequestWorkers setting).
  3. Валидация JSON. При передаче данных через HTTPЗапрос.УстановитьТелоИзСтроки() всегда проверяйте кодировку. Для веб-сервисов стандартом является UTF-8 без маркера BOM.
  4. Тестирование вне 1С. Прежде чем грешить на код 1С, попробуйте вызвать ваш HTTP-сервис через сторонние утилиты (например, Postman или cURL) с того же сервера, где установлена база.

Подводя итог, можно сказать, что «дружба» веб-клиента и HTTP-соединения требует внимательного отношения к сетевой инфраструктуре. Наилучшим архитектурным решением остается разнесение сервисов на разные порты или IP-адреса, а для повышения стабильности и скорости на Windows-серверах — использование объекта WinHttp.

← На главную