Ежемесячный чек-ап Zimbra: девять команд и таблица трактовки

К клиенту-производству в Химках я за девять месяцев приезжал трижды. Утром не открывалась почта, потом не синхронизировались телефоны, потом перестал работать поиск. Три разных симптома, три разных счёта. Причина была одна, и я нашёл её только на третий раз. После этого и появился регламент из девяти команд, который занимает полчаса раз в месяц.

Три выезда, три счёта, одна причина

Есть клиенты, у которых почта ломается всегда по-разному. Каждый раз новый симптом, каждый раз «ну надо же, а раньше такого не было», каждый раз выезд. Со стороны это выглядит как невезение или как старое железо. Обычно это ни то ни другое.

Если вы вызываете подрядчика к почтовому серверу два-три раза в год и каждый раз с новой формулировкой — почти наверняка у вас одна причина, которая проявляется по-разному в зависимости от того, что в этот момент нагрузило сервер. Найти её по одному симптому нельзя: каждый симптом честно объясняется сам собой, лечится за несколько часов и уходит. По трём — можно, если сесть и разложить их рядом на одном листе.

Мешает этому простая вещь. Заявки разделены во времени, между ними месяцы, и к третьей никто уже не помнит подробностей первой. Помнит только сумму счетов.

Я разложил три заявки рядом в апреле 2026 года и потратил на разбор целый день без счёта клиенту. Потому что мне самому было неловко.

Химки, производство на 46 мест: как выглядели три заявки

Клиент — производственная компания, цех и офис на территории бывшего завода в Химках, 46 рабочих мест. Почта на Zimbra 9 с 2021 года, виртуалка на своём гипервизоре. Всё вело моё подразделение, так что чужого админа тут винить не в кого.

Июль 2025. Утро понедельника, веб-почта не открывается ни у кого. В логе:

2025-07-14 08:41:22,619 ERROR [qtp1740189450-231:https://mail.example.ru/service/soap/]
 [] system - Fatal error occurred while handling exception
java.lang.OutOfMemoryError: Java heap space

Сам перезапуск mailboxd занял четыре минуты, всё поднялось. Три часа — это от звонка в 08:41 до момента, когда я до сервера добрался и понял, что перезапускать: два часа из них люди просто сидели без почты. Списали на «письмо с кривым вложением» — такое бывает, битое вложение с ложным заявленным размером действительно способно уронить mailboxd. Счёт: 3 часа.

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

2025-11-06 15:12:07,884 WARN  [ImapServer-77] [] mailbox -
 Failed to lock mailbox 341
com.zimbra.cs.mailbox.MailboxLock$LockFailedException: timeout

Тюнинговали таймауты блокировок и пул потоков IMAP, стало лучше. Счёт: 5 часов.

Март 2026. Поиск по почте не находит письма за последнюю неделю. В mailbox.log:

2026-03-19 11:48:33,102 WARN  [Index-3] [] index -
 Caught exception while indexing message id [489217] - indexing blocked. Possibly corrupt index?

Переиндексировали три ящика, поиск заработал. Счёт: 4 часа.

Двенадцать часов работ и три разных объяснения. Каждое по отдельности было технически верным. Все три вместе — неверными.

Ложная версия, которая стоила клиенту 60 тысяч

После второго выезда я построил версию, которая звучала убедительно: диск не тянет. Логика была такая — mailboxd и MariaDB конкурируют за один шпиндель, при пиковой нагрузке растёт IOwait, отсюда и блокировки, и подвисания. На форуме Zimbra такой сценарий описан не раз: показатель ожидания диска около десяти процентов, и тормозит буквально всё.

Померил. IOwait действительно держался на 8–11% в утренние часы. Версия подтвердилась, и мы перенесли виртуалку на NVMe-датастор. Аренда места на быстром хранилище обошлась клиенту примерно в 60 тысяч рублей за год плюс наши 4 часа на миграцию.

IOwait упал до 1,5%. Симптомы остались.

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

Настоящая причина: память, которая не выросла вместе с сервером

В апреле я сел и выписал три инцидента в столбик. Нехватка кучи Java. Таймаут блокировки ящика при активных IMAP-клиентах. Прерванная индексация. И вдруг стало видно: это три разных проявления одного дефицита — mailboxd банально не хватает памяти под свои задачи.

Дальше я посмотрел, сколько ему выдано:

$ zmlocalconfig mailboxd_java_heap_size
mailboxd_java_heap_size = 4915

$ free -g
              total        used        free      shared  buff/cache   available
Mem:             47          19           2           0          25          27

4915 мегабайт кучи при 47 гигабайтах оперативной памяти на машине. Меньше десяти процентов.

Механика простая, и о неё спотыкаются многие. Инсталлятор при установке выделяет под кучу Java примерно 30% физической памяти на тот момент. Сервер ставили в 2021 году на виртуалку с 16 ГБ — отсюда и 4915 МБ. Потом компания росла, и памяти виртуалке добавили до 48 ГБ. Куча не изменилась ни на байт: она не пересчитывается сама, её поднимают руками. Три года сервер жил с настройкой трёхлетней давности и ломался в новом месте каждый раз, когда нагрузка подрастала.

Проверка гипотезы заняла двадцать минут — я посмотрел, как ведёт себя сборщик мусора:

$ tail -f ~zimbra/log/zmmailboxd.out

Ориентир, которым я пользуюсь: если сборка срабатывает раз в несколько секунд — это нормальная жизнь. Если каждую секунду, да ещё с паузами больше ста миллисекунд — куче тесно. У нас было именно второе, в утренний час особенно наглядно.

Лечение:

zmlocalconfig -e mailboxd_java_heap_size=8192
zmmailboxdctl restart

Восемь гигабайт. Для среды с большим числом IMAP-клиентов и крупными ящиками обычно советуют 6–8 ГБ, иногда до 10. С апреля выездов по этим симптомам не было.

Честно про ограничение: подъём кучи — не универсальное лекарство. Если память действительно течёт — из-за расширения, из-за индексации, из-за чего-то ещё — увеличенная куча просто отодвинет следующий сбой на месяц-другой. Отличить одно от другого можно только по поведению после изменения: если через три недели картина в логе сборщика вернулась к прежней, значит, дело не в размере, и надо снимать дамп кучи и разбираться, что её держит.

Проверьте у себя за две минуты

Начните с той самой пары цифр, которая три года пряталась у меня на виду:

su - zimbra
zmlocalconfig mailboxd_java_heap_size
free -m | awk '/Mem:/ {print "RAM всего, МБ:", $2}'
grep -c OutOfMemoryError ~zimbra/log/zmmailboxd.out

Трактовка:

Что увиделиЧто это значитКогда действовать
Куча близка к 30% от RAMЗначение соответствует объёму памяти — вероятно, RAM после установки не менялиНичего не трогать
Куча заметно меньше 20% от RAMПамять серверу добавляли, а куча осталась от прежней конфигурацииВ ближайшее окно
Куча больше трети RAM машиныСлишком большая куча даёт длинные паузы сборщика — веб-почта «залипает» на секунды, а остальным службам Zimbra памяти уже не остаётсяПересмотреть значение
OutOfMemoryError встречается хоть разMailboxd уже падал по памяти, просто в тот раз поднялся самНа этой неделе
Сборка мусора каждую секунду, паузы >100 мсКуче тесно прямо сейчасСегодня

Две минуты, две команды, и вы либо спокойны, либо знаете, куда смотреть дальше.

Регламент: девять команд раз в месяц

После апреля я собрал всё в один список. Проходится за 25–35 минут на сервере среднего размера, ничего не останавливает, ничего не меняет. Только смотрит.

# всё выполняется из-под пользователя zimbra: su - zimbra
# 1. версия и патч-уровень
zmcontrol -v
# 2. состояние служб
zmcontrol status
# 3. место
df -h /opt; du -sh /opt/zimbra/store /opt/zimbra/index /opt/zimbra/db /opt/zimbra/log
# 4. очередь
zmqstat; qshape deferred | head -20
# 5. память mailboxd
zmlocalconfig mailboxd_java_heap_size; grep -c OutOfMemoryError ~zimbra/log/zmmailboxd.out
# 6. целостность базы
/opt/zimbra/libexec/zmdbintegrityreport -v
# 7. хранилище и индекс
zgrep -B2 NO_SUCH_BLOB /opt/zimbra/log/mailbox.log*
grep -c 'Possibly corrupt index' /opt/zimbra/log/mailbox.log
# 8. сертификат
/opt/zimbra/bin/zmcertmgr viewdeployedcrt | grep -A2 Validity
# 9. антиспам и антивирус
zmlocalconfig | grep -E 'antispam_enable_(rule_updates|restarts|rule_compilation)'
ls -la /opt/zimbra/data/clamav/db/ | head

Что смотреть в выводе каждой команды

Что смотреть в каждом пункте:

Тревожный признакЧто за ним стоит
1Патч-уровень отстаёт больше чем на два выпускаОткрытые уязвимости, которые давно закрыты у всех остальных
2Команда думает дольше минуты или врёт про службыВнутри статусной обвязки зашит таймаут в 60 секунд; если сервер отвечает медленнее, вы получите неверную картину
3Занятость /opt больше 85%Дальше сервер начнёт отбивать входящие и остановится сам
4В отложенных больше сотни писем к одному доменуЛибо получатель нас не принимает, либо завис антивирусный слой
5Куча меньше пятой части памяти машиныРовно тот случай, из-за которого я трижды ездил в Химки
6Отчёт нашёл повреждённые таблицыДвижок InnoDB штатной починке не поддаётся: только дамп, пересоздание и заливка обратно
7Есть NO_SUCH_BLOB или упоминания повреждённого индексаМетаданные и файлы писем разъехались, поиск начнёт врать
8До конца срока меньше 30 днейПросроченный сертификат роняет не только веб — по нему же ходит внутренняя связка со службой каталога
9Все три флага в false, базы антивируса старше неделиСпам-правила не обновляются, устаревший антивирус способен положить весь поток почты в отложенные

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

Сколько стоит пропущенный чек-ап

Сравню два столбца по одному и тому же серверу.

Как былоКак стало
ПроверкиНет30 минут раз в месяц, 6 часов в год
Аварийные выезды3 за 9 месяцев0 с апреля — но честно: с фикса прошёл месяц, а не год
Часы по авариям12 ч, из них 7 в нерабочее время
Лишние решенияПеренос на быстрое хранилище, ~60 000 ₽/годПригодился, но проблему решал не он
Простой почтыУтро понедельника целиком плюс два частичных

Утро понедельника на производстве — это отгрузки. Сорок шесть человек, из них двенадцать в отделе снабжения, которые с восьми утра согласовывают заявки поставщикам письмами. Три часа без почты в понедельник директор оценил в сдвиг двух отгрузок на день. Рубли посчитал я, и он не спорил: 46 человек по 3 часа при себестоимости часа 1 100 ₽ — это 151 800 ₽ впустую, и это только фонд оплаты, без штрафов за сдвиг отгрузки по договорам.

Мой счёт за три выезда — 12 часов, по ставке 3 500 ₽ в час это 42 000 ₽, из них 7 часов в нерабочее время. Регламент стоит 6 часов в год — 21 000 ₽. Даже если он поймает всего одну аварию из трёх, он окупается вдвое, а с учётом того, что за одну аварию простой стоил дороже годового регламента в семь раз, — считать тут вообще нечего.

И отдельно про то, чего регламент не делает. Он не чинит. Он показывает, что сломается, за недели до того, как это станет заявкой. Дальше всё равно нужен человек, который прочитает вывод и поймёт, что NO_SUCH_BLOB в трёх строках — это ерунда, а в трёхстах — повод останавливать сервер сегодня ночью. Разница между этими двумя случаями в цифрах не написана.

Как внедрить это у себя

Не надо строить систему мониторинга ради девяти команд. Начните проще.

  • Заведите файл-журнал. Раз в месяц прогоняете список, вывод складываете в один текстовый файл с датой в имени. Ценность появляется на третьем месяце: вы начинаете видеть динамику, а не срез. Store прибавляет 8 ГБ в месяц — это норма. Прибавил 60 — идите смотреть, что случилось.
  • Первые три пункта поставьте в крон с отправкой на почту администратора. Место, службы и версия — это то, что должно приходить само.
  • Проверку целостности базы поставьте раз в неделю ночью. Она штатная и умеет отчитываться сама.
  • Пункт про сертификат заведите с запасом в 30 дней. Этого хватает, чтобы спокойно перевыпустить, а не бегать в пятницу вечером.

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

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

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

Почему куча Java не увеличивается сама, когда добавляют память серверу?

Потому что размер кучи фиксируется один раз — во время установки Zimbra, как процент от того объёма памяти, который был на машине в тот момент. Дальше это просто число в локальной конфигурации, и оно живёт своей жизнью. Виртуалке добавили памяти, ядро видит больше, а mailboxd продолжает работать со старым значением. У клиента в Химках было 4915 МБ кучи при 47 ГБ памяти — настройка трёхлетней давности на сервере, который за три года вырос вдвое. Проверяется одной командой, меняется двумя, а вылезает тремя разными авариями.

Можно ли просто поставить кучу побольше, с запасом?

Запас нужен, но не любой ценой. Слишком большая куча даёт длинные паузы сборщика мусора: раз в несколько минут веб-клиент замирает на секунду-две, и пользователи говорят «почта подвисает», что диагностировать сложнее, чем честное падение. Практический коридор для среды с активными IMAP-клиентами и крупными ящиками — 6–8 ГБ, иногда до 10. И ещё: если после подъёма кучи через три недели картина в логе сборщика вернулась к прежней — значит, память где-то течёт, и лечится это не размером, а поиском утечки по дампу кучи.

Три флага автообновления антиспама выключены. Это точно надо включать?

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

Что делать, если zmcontrol status показывает службу остановленной, а она работает?

Сначала перепроверить другим способом: посмотреть процессы и порты, а не только сводку. У статусной команды внутри зашит таймаут в шестьдесят секунд, и если сервер отвечает медленнее — а он отвечает медленнее, когда нагружен, — вы увидите картину, которой нет. Это известное поведение, обсуждается на официальном форуме. Второй частый источник вранья — осиротевшие PID-файлы после жёсткой перезагрузки: служба стартует, но обвязка ищет её по устаревшему идентификатору процесса. Так что расхождение статуса и реальности — само по себе диагностический признак.

У нас есть Zabbix. Зачем ещё какой-то ручной регламент?

Мониторинг ловит состояния, а регламент ловит тенденции. Zabbix прекрасно скажет вам, что диск заполнен на 90 процентов — то есть тогда, когда уже поздно. Он не скажет, что store прибавляет по 60 ГБ в месяц вместо обычных восьми, что индекс за квартал вырос вдвое, а куча Java три года не менялась при выросшем вдвое сервере. Для этого нужен человек, который раз в месяц кладёт срез рядом с предыдущим и смотрит на разницу. Идеально — когда есть оба: система шлёт алерты, человек раз в месяц смотрит динамику.

Нужна помощь с проектом?

Специалисты АйТи Фреш помогут с архитектурой, DevOps, безопасностью и разработкой — 15+ лет опыта

📞 Связаться с нами
#Zimbra#эксплуатация#регламент#mailboxd#профилактика
Комментарии 0

Оставить комментарий

загрузка...

Подпишитесь на рассылку ITfresh

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

Реквизиты оператора персональных данных

ООО «АЙТИ-ФРЕШ», ИНН 7719418495, КПП 771901001. Юридический адрес: 105523, г. Москва, Щёлковское шоссе, д. 92, корп. 7. Контакт: info@itfresh.ru, +7 903 729-62-41. Оператор обрабатывает e-mail подписчика в целях рассылки информационных и рекламных материалов до момента отзыва согласия.