Почему стандартное подключение «не подходит»
Стандартная схема работы с 1С выглядит примерно так:
-
Сайт делает запрос (например, через SOAP или COM).
-
1С открывает сессию под конкретной лицензией.
-
1С обрабатывает запрос и закрывает сессию.
На низкой нагрузке это работает без проблем. Но при большом потоке заказов и запросов каждая сессия требует отдельной лицензии, а также расходуется время на подключение.
Пример типичной ошибки при перегрузке:
Ошибка: Нет доступных лицензий для подключения
То есть, чем выше нагрузка, тем больше шансов, что запросы не будут обработаны. Классическое решение — покупать больше лицензий — быстро становится дорогим и не всегда оправданным.
Идея решения: собственный SOAP-сервер
Решение, которое мы применяем: собственный SOAP-сервер на PHP, который будет иметь одно постоянное подключение к 1С и принимать множество запросов с сайта.
Идея проста:
-
Сайт делает запрос к нашему серверу (REST или SOAP).
-
SOAP-сервер обрабатывает запрос и использует одно подключение к 1С.
-
Ответ возвращается на сайт.
Выгоды очевидны:
-
Экономия лицензий (вместо N подключений — одно постоянное).
-
Очередь запросов и контроль нагрузки.
-
Возможность кэширования и логирования запросов.
Архитектура решения
Наша архитектура выглядит так:
[Сайт: REST/SOAP] --> [Наш PHP SOAP-сервер] --> [1С]
Схема работы:
-
Пользователь или система делает запрос на сайт.
-
Сервер сайта пересылает запрос к нашему SOAP-серверу.
-
SOAP-сервер добавляет запрос в очередь (опционально) и выполняет его через одно постоянное подключение к 1С.
-
Результат возвращается сайту.
Так мы гарантируем, что даже при сотнях параллельных запросов к 1С лицензий хватает на всех.
Пример реализации на PHP
Создание SOAP-сервера
Минимальный пример сервера на PHP:
<?php
class OneCService {
private $oneC;
public function __construct() {
// Подключение к 1С через COM
$this->oneC = new COM("V83.Application");
$this->oneC->Connect("Srvr=\"srv\";Ref=\"Base\";Usr=\"user\";Pwd=\"pwd\"");
}
public function getOrder($orderId) {
// Пример запроса к 1С
return $this->oneC->GetOrder($orderId);
}
public function createOrder($data) {
// Создание заказа в 1С
return $this->oneC->CreateOrder($data);
}
}
// Инициализация SOAP-сервера
$server = new SoapServer(null, ['uri' => 'http://example.com/soap']);
$server->setClass('OneCService');
$server->handle();
Теперь сервер слушает SOAP-запросы и использует одно подключение к 1С.
Приём REST-запросов через SOAP-сервер
Чтобы сайт мог работать через REST, мы трансформируем JSON-запросы в вызов методов сервера:
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$input = json_decode(file_get_contents('php://input'), true);
$soap = new OneCService();
switch($input['action']) {
case 'getOrder':
echo json_encode($soap->getOrder($input['orderId']));
break;
case 'createOrder':
echo json_encode($soap->createOrder($input['data']));
break;
default:
http_response_code(400);
echo json_encode(['error' => 'Unknown action']);
}
}
Таким образом один сервер принимает как SOAP, так и REST-запросы, экономя лицензии и контролируя нагрузку.
Управление очередью запросов
На высоконагруженных проектах желательно организовать очередь запросов, чтобы избежать коллизий. Например, можно использовать SplQueue или Redis:
$queue = new SplQueue();
$queue->enqueue($request);
// обработка очереди
while (!$queue->isEmpty()) {
$req = $queue->dequeue();
// выполнение через одно подключение к 1С
}
Это позволяет обрабатывать большое количество запросов без переполнения сессий.
Что стоит учесть при разработке
При построении собственного SOAP-сервера для интеграции с 1С на высоконагруженных проектах важно учесть несколько моментов. Ошибки в этих местах приводят к потере соединений, таймаутам и, конечно, к неэкономному расходу лицензий.
Управление сессией 1С
-
Проблема: 1С может разорвать долгие сессии (тайм-аут), или при повторном подключении потребуется новая лицензия.
-
Решение: держим одно постоянное подключение, но периодически проверяем его живость.
-
Пример проверки:
function checkConnection($oneC) {
try {
$oneC->Ping(); // вызов тестового метода 1С
return true;
} catch (Exception $e) {
// сессия упала — переподключаемся
$oneC->Connect("Srvr=\"srv\";Ref=\"Base\";Usr=\"user\";Pwd=\"pwd\"");
return false;
}
}
-
Совет: если сервер долго стоит, добавьте cron или таймер для «профилактического переподключения».
Обработка ошибок 1С
-
Проблема: 1С может возвращать ошибки при высоких нагрузках или некорректных данных.
-
Решение: оборачивать вызовы 1С в try-catch, логировать ошибки и при необходимости повторять запрос.
function safeCall($oneC, $method, $params = []) {
try {
return call_user_func_array([$oneC, $method], $params);
} catch (Exception $e) {
error_log("Ошибка 1С: " . $e->getMessage());
// возможно повторное выполнение запроса
return null;
}
}
-
Совет: логируйте не только текст ошибки, но и входные параметры, чтобы потом можно было воспроизвести проблему.
Кэширование частых запросов
-
Частые запросы, например, остатки товаров или справочники, можно кэшировать, чтобы не нагружать 1С.
-
Простейший пример с Redis:
$cacheKey = "product_stock_{$productId}";
$stock = $redis->get($cacheKey);
if ($stock === false) {
$stock = $oneC->GetProductStock($productId);
$redis->set($cacheKey, $stock, 300); // кэш на 5 минут
}
return $stock;
-
Совет: кэшировать только данные, которые не требуют мгновенного обновления. Для заказов кэш не подходит.
Очередь запросов
-
При высоких нагрузках сразу несколько параллельных запросов к одному подключению могут вызвать ошибки.
-
Решение: организовать очередь с приоритетами.
Пример простого очередевого механизма на PHP:
$queue = new SplQueue();
// добавление запросов
$queue->enqueue($request);
// обработка очереди
while (!$queue->isEmpty()) {
$req = $queue->dequeue();
safeCall($oneC, $req['method'], $req['params']);
}
-
Для продакшена лучше использовать Redis или RabbitMQ, чтобы очередь была распределённой и устойчивой к сбоям.
Мониторинг и метрики
-
Почему важно: сервер может работать, но нагрузка и ошибки будут расти незаметно.
-
Что мониторить:
-
количество активных подключений к 1С;
-
очередь запросов;
-
количество ошибок 1С;
-
время ответа на запрос.
-
-
Совет: используйте Prometheus + Grafana или хотя бы простой лог-файл с регулярной проверкой.
Бонус: защита от “штормов” на сайте
-
Если сайт генерирует десятки параллельных запросов к 1С, это может мгновенно «съесть» сессию.
-
Решение: лимитирование запросов и throttling.
$maxRequestsPerSecond = 10;
if ($requestCount > $maxRequestsPerSecond) {
http_response_code(429); // Too Many Requests
exit("Слишком много запросов. Попробуйте позже.");
}
Это предотвратит перегрузку вашего единственного подключения и поможет экономить лицензию 1С.
Итог
Теперь мы имеем свой SOAP-сервер, который может:
-
Принимать как REST, так и SOAP-запросы с сайта.
-
Использовать одно постоянное подключение к 1С, экономя лицензии.
-
Обрабатывать множество параллельных запросов, сохраняя стабильность.
Это решение идеально подходит для высоконагруженных сайтов, где стандартная схема подключения к 1С перестаёт работать. С его помощью можно масштабировать интеграцию, добавить очередь и кэширование, вести логирование и при этом не тратиться на лишние лицензии.
Итог: экономия ресурсов + стабильная работа + гибкость интеграции — всё это делает SOAP-сервер эффективным инструментом для работы с 1С в современных веб-проектах.