Отладка обмена с 1С: логи, зависшие сессии, повторный импорт

Четыре источника правды в строгом порядке, механика зависшего цикла импорта и безопасный повторный запуск обмена руками на боевом сайте.

Дмитрий Мещеряков
Дмитрий Мещеряков
📅 7 октября 2026 г.📖 8 мин чтения

«Обмен не работает» — самая бесполезная формулировка из всех, что приходят в поддержку. Под ней скрывается минимум пять разных ситуаций: 1С не приходила, приходила и получила отказ, прислала пустой файл, прислала полный файл без нужного поля, или всё прошло идеально, а витрина отдаёт кэш.

Каждая из них лечится по-своему, и перебор настроек в админке не приближает ни к одной. Работает другое — чтение источников в жёстко заданном порядке.

Порядок здесь не педантизм. Он экономит часы: восемь из десяти «неразрешимых» проблем закрываются на втором шаге, где выясняется, что спорного поля не было в самой выгрузке, и весь дальнейший разговор про настройки сайта не имеет смысла.

Что такое отладка обмена

Отладка обмена — это восстановление цепочки «1С отправила → сайт принял → сайт разобрал → данные изменились» с определением звена, где цепочка порвалась. Не поиск правильной галочки, а сужение области поиска: каждый источник отвечает ровно на один вопрос и либо снимает подозрение с целого куска системы, либо указывает на него.

Источников четыре, и они читаются в этом порядке.

№ИсточникОтвечает на вопрос
1Лог веб-сервера1С вообще приходила?
2XML в /upload/1c_catalog/Что она прислала?
3Журнал обмена БитриксаЧто он с этим сделал?
4Лог ошибок PHPПочему упал?

Источник 1: приходила ли 1С

bash
# Все запросы обмена за сегодня
grep "1c_exchange" /var/log/nginx/access.log | tail -50

# Только коды ответа и режимы — компактная картина цикла
grep "1c_exchange" /var/log/nginx/access.log \
  | awk '{print $4, $7, $9}' \
  | sed 's/.*mode=\([a-z]*\).*" \([0-9]*\)/\1 \2/' \
  | tail -30

Что здесь видно сразу:

Запросов нет вообще. Сайт ни при чём. Вопрос к регламентному заданию в 1С или к сети между ними. Разговор с администратором 1С начинается с этой строки, а не с обсуждения настроек Битрикса.

Есть checkauth с кодом 401. Права. Пользователь обмена заблокирован, сменился пароль или его выкинули из группы.

Цепочка обрывается на file. Файл не долез. Смотрите права на запись в /upload/1c_catalog/ и client_max_body_size в nginx — второе особенно вероятно, если каталог недавно вырос.

Десятки одинаковых mode=import подряд. Тот самый бесконечный progress, к которому мы вернёмся отдельно.

Приёмы разбора логов по датам и кодам ответа подробнее разобраны в статье про анализ логов nginx и Apache.

Источник 2: что именно приехало

Здесь закрывается большинство споров. XML-файлы лежат в /upload/1c_catalog/ до следующего обмена, и это единственный достоверный источник того, что было отправлено. Админка показывает результат разбора — то есть уже интерпретацию.

bash
cd /home/site/www/upload/1c_catalog/
ls -la --time-style=full-iso

# Дата формирования и версия схемы — первое, на что смотрим
head -c 400 import.xml

# Есть ли в выгрузке конкретный товар
grep -c "SM-1024" import.xml

# Сколько всего товаров в файле
grep -c "<Товар>" import.xml

Дальше — точечная проверка спорного товара. Кириллические теги здесь работают на нас:

bash
# Вырезать блок одного товара по артикулу с контекстом
grep -A 40 "<Артикул>SM-1024</Артикул>" import.xml
💡 Совет

Дата изменения файла — половина диагноза. Файл вчерашний, а обмен «шёл сегодня ночью» — значит, сегодняшний обмен не дошёл до шага file, и вы смотрите на позавчерашние данные. Эта проверка занимает секунду и регулярно закрывает вопрос целиком.

⚠️ Важно

Не открывайте многогигабайтный import.xml в редакторе. Ни в консольном, ни тем более по SFTP. Каталоги на 100–200 тысяч товаров дают файлы, которые кладут и редактор, и терминал, а на сервере с ними ещё и память съедается. Работайте grep, head, sed -n '1000,1100p' — этого достаточно для любой диагностики.

Источник 3: журнал обмена Битрикса

Журнал включается в настройках модуля торгового каталога, там же указывается путь к файлу. Важная деталь: по умолчанию он выключен. На большинстве проектов его нет, и когда он нужен, включать уже поздно — авария прошла.

Поэтому журнал включают заранее, на этапе настройки обмена, вместе с ротацией:

bash
# /etc/logrotate.d/bitrix-1c-exchange
/home/site/www/upload/1c_exchange.log {
    weekly
    rotate 8
    compress
    missingok
    notifempty
    copytruncate
}

Без ротации журнал обмена — это будущий инцидент «на сервере кончилось место», и произойдёт он через несколько месяцев, когда про включённое логирование все забудут.

Источник 4: почему упал

bash
# Ошибки PHP за время обмена
tail -200 /var/log/php-fpm/error.log | grep -iE "fatal|memory|timeout"

# Классика жанра для больших каталогов
grep -i "allowed memory size" /var/log/php-fpm/error.log | tail

Два характерных диагноза:

Allowed memory size exhausted. Шаг импорта пытается держать в памяти слишком много. Правильный ответ — уменьшить размер порции в настройках обмена. Поднимать memory_limit можно, но это отодвигает проблему, а не решает: каталог продолжит расти.

Обрыв без записи в лог PHP. Скорее всего, соединение закрыл веб-сервер по своему таймауту, а PHP при этом продолжал работать. Проверяются fastcgi_read_timeout в nginx и max_execution_time в PHP. Как разделять эти два случая, подробно разобрано в статье про диагностику PHP-FPM.

Зависшая сессия: механика бесконечного progress

Это самая непрозрачная неисправность обмена, и она заслуживает отдельного разбора, потому что снаружи выглядит как поломка Битрикса, а формально всё работает правильно.

Напомню устройство шага из разбора протокола обмена: импорт пошаговый, и позиция, на которой он остановился, хранится в сессии. Ответ progress означает «я обработал порцию, приходи ещё за продолжением».

Теперь представим, что 1С не подставляет сессионную куку из ответа checkauth. Что происходит:

text
Запрос 1 → новая сессия A → прогресс 0    → обработано 500 → progress
Запрос 2 → новая сессия B → прогресс 0    → обработано 500 → progress
Запрос 3 → новая сессия C → прогресс 0    → обработано 500 → progress
...

Каждый раз импортируются одни и те же первые 500 товаров. Обмен идёт вечно, база нагружена, данные формально обновляются — и никогда не доходит до конца.

Как убедиться, что дело именно в этом:

bash
# Смотрим, приходит ли кука в запросах импорта.
# В логе её видно, только если формат лога включает $http_cookie;
# если нет — временно добавьте отдельный формат для этого location
grep "mode=import" /var/log/nginx/access.log | tail -5

Три причины потери сессии, в порядке частоты:

1С не сохраняет куку. Ошибка настройки на стороне 1С или обмен настроен по устаревшей схеме.

Смена домена или протокола на редиректе. 1С ходит на http://site.ru, сайт редиректит на https://www.site.ru, кука остаётся на другом домене. Проверяется одной командой:

bash
curl -sI "http://site.ru/bitrix/admin/1c_exchange.php?type=catalog&mode=checkauth" | head -3
# Ищем 301/302 — их быть не должно, 1С обязана ходить на конечный адрес

Балансировщик без липких сессий. Несколько бэкендов, файловое хранилище сессий, каждый запрос попадает на другой сервер. Лечится общим хранилищем сессий или закреплением обмена за одним бэкендом.

Повторный импорт руками

Иногда нужно перезапустить разбор уже лежащего на сайте файла — например, после того как вы поправили сопоставление свойств. Полный цикл обмена ради этого гонять не обязательно.

bash
# 1. Авторизация, сохраняем куки в файл
curl -s -c /tmp/1c.jar -u "exchange1c:password" \
  "https://site.ru/bitrix/admin/1c_exchange.php?type=catalog&mode=checkauth"

# 2. Импорт с той же кукой, повторяем до success
for i in $(seq 1 200); do
  RESP=$(curl -s -b /tmp/1c.jar -c /tmp/1c.jar \
    "https://site.ru/bitrix/admin/1c_exchange.php?type=catalog&mode=import&filename=import.xml")
  echo "[$i] $(echo "$RESP" | head -1)"
  echo "$RESP" | head -1 | grep -q "^success" && break
  echo "$RESP" | head -1 | grep -q "^failure" && break
done

Ключевая деталь — -c вместе с -b: куки не только отправляются, но и обновляются. Без этого вы своими руками воспроизведёте зависшую сессию из предыдущего раздела.

⚠️ Важно

Это настоящий импорт со всеми последствиями. Он изменит цены, остатки и активность элементов ровно так же, как обмен из 1С — включая деактивацию товаров, которых нет в файле, если такая настройка включена. На боевом сайте запускается только после бэкапа базы и с пониманием, что лежит в файле. Отлаживают на копии — той же, на которой проверяют обновления Битрикса.

Симптом → причина → проверка

СимптомВероятная причинаЧем проверить
Нет запросов в логе1С не запускалась или не дошлаgrep 1c_exchange access.log
checkauth возвращает 401Права пользователя обменаcurl -u вручную
Обрыв на mode=fileПрава на папку, client_max_body_sizels -la upload/1c_catalog/
Бесконечный progressПотеряна сессияРедиректы, куки в запросах
failure без деталейПамять или праваerror.log, вторая строка ответа
Обмен успешен, данных нетПоля нет в XMLgrep по артикулу в import.xml
Данные в базе, но не на сайтеКэш каталогаСброс кэша, политика кэширования
Цены не обновилисьТип цены не сопоставленСопоставление в настройках обмена
Обмен идёт часамиОбработчик на каждом элементеПрофилирование, события
Товары продублировалисьЗатёрт XML_IDСравнение XML_ID с <Ид> в XML

Итоги

Порядок источников важнее знания настроек. Лог сервера → XML → журнал обмена → лог PHP. Нарушение порядка означает, что вы правите настройки сайта в ситуации, где 1С не приходила вовсе.

XML — единственный достоверный источник того, что прислали. Спор «мы выгрузили, у вас не приехало» разрешается одним grep по артикулу, а не созвоном на сорок минут.

Журнал обмена включайте заранее и с ротацией. Включённый после аварии, он бесполезен; включённый без ротации — сам станет следующей аварией.

Бесконечный progress — это сессия, а не Битрикс. Три причины: 1С не хранит куку, редирект между доменами, балансировщик без липких сессий.

Повторный импорт руками — рабочий инструмент, но с полными последствиями. С -b и -c одновременно, после бэкапа, желательно не на бою.

Наблюдение напоследок. Тяжелее всего диагностируются не падения, а обмены, которые проходят успешно и ничего не меняют. Падение оставляет след в логе, а молчаливое игнорирование несопоставленного свойства — нет. Поэтому первый вопрос при «обмен прошёл, но ничего не изменилось» — не «что сломалось», а «а это поле вообще приезжало». В большинстве случаев ответ отрицательный, и искать на сайте нечего.

Частые вопросы

Где посмотреть лог обмена с 1С в Битриксе?

Журнал обмена включается в настройках модуля торгового каталога, там же задаётся путь к файлу. По умолчанию журнал выключен, поэтому на большинстве проектов его просто нет — включать нужно до того, как понадобится, а не после аварии. Отдельно от него есть лог веб-сервера, который пишется всегда и показывает сами запросы 1С к 1c_exchange.php.

Почему обмен с 1С бесконечно отвечает progress?

Потому что прогресс импорта хранится в сессии, а 1С по какой-то причине её теряет: не сохраняет куку из ответа checkauth, ходит по адресу с другим доменом или через балансировщик, отдающий запросы на разные серверы. Каждый шаг создаёт новую сессию с нулевым прогрессом, поэтому Битрикс честно обрабатывает первую порцию и снова отвечает progress. Внешне это выглядит как зависание, хотя формально всё работает.

Как перезапустить импорт из 1С вручную?

Пройти цепочку curl-запросов к 1c_exchange.php с сохранением куки: checkauth, затем import с именем уже лежащего на сайте файла, затем повторять import до ответа success. Это настоящий импорт, изменяющий данные, поэтому на боевом сайте так делают только осознанно и после бэкапа, а отлаживают на копии.

Обмен прошёл успешно, но данные не изменились. Почему?

Три типичные причины. Первая — нужного поля не было в присланном XML, и это видно за минуту при открытии файла. Вторая — данные обновились в базе, но витрина отдаёт кэш, который никто не сбросил. Третья — сопоставление не настроено: несопоставленный тип цены или свойство игнорируются молча, без единой строчки в логе.

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

Ориентир для каталога в 10 000 товаров — единицы минут на offers.xml и до получаса на полный import.xml. Обмен, который идёт несколько часов, почти всегда упирается не в объём данных, а в обработчик события, выполняющийся на каждом элементе, или в отсутствующий индекс в базе. Это диагностируется профилированием, а не увеличением таймаутов.