Pull to refresh

Мониторинг обмена распределенной базы данных 1С средствами Zabbix

Reading time9 min
Views22K
Приветствую хабросообщество! В России очень популярно использование желтой программы. К сожалению, стабильность работы оставляет желать лучшего. Многие системные администраторы (которые являются по совместительству администраторами/программистами 1С) решают проблемы мониторинга ежедневных обработок и постоянно работающих выгрузок 1С очень просто — устанавливают оповещение по электронной почте. Если что-то плохое произошло — отправляется письмо, администратор заходит на сервер, смотрит ошибку, исправляет, профит. Но это не выход для ленивых правильных администраторов!
В интернете по мониторингу 1С есть только шаблоны для мониторинга службы 1С. Попробуем расширить зону мониторинга.
В этой статье мы попытаемся рассказать как решить следующие проблемы:
  • Есть постоянно работающая 1С, которая вылетает с неисправляемыми ошибками (блокировки, платформенные ошибки, другое) и они решаются простым перезапуском. Например, онлайн-выгрузки (в нашем случае это выгрузка на весы/кассовое оборудование)
  • Есть 1С, которые запускаются периодически, раз в N минут/часов (могут не отработать по разным причинам). Например, обмены и другие регламентные операции



В крупных организациях вопросы мониторинга 1С занимаются программисты/администраторы 1С. Системный администратор (если есть такая отдельная должность, а у нас есть) мониторит только свое железо/программы и 1С не очень то жалует. Мы преодолели этот барьер, предлагаем преодолеть его и вам :)

Про организацию


Крупная розничная сеть, используем в качеству СТУ 1С. Много объектов, везде должен быть обмен с центральной базой. На серверах объектов крутятся постоянно-запущенные 1С (обмен с кассами и весами).
Дополнительные условия:
  • Сервер мониторинга Zabbix.
  • Планировщик заданий на сервере, который запускает задание. Пусть будет "Обмен".
  • zabbix_sender over HTTP. Можно вызывать и обычный zabbix_sender.exe
  • 1С, из которой можно отправить http-запрос (в нашем случае https) или запустить zabbix_sender с нужными параметрами


Архитектура решения


Приведем общую схему работы, потом разберем каждую часть.

Zabbix

Шаблон
<?xml version="1.0" encoding="UTF-8"?>
<zabbix_export>
    <version>2.0</version>
    <date>2015-06-05T11:21:26Z</date>
    <groups>
        <group>
            <name>My Templates</name>
        </group>
    </groups>
    <templates>
        <template>
            <template>1C Habr template</template>
            <name>1C Habr template</name>
            <groups>
                <group>
                    <name>My Templates</name>
                </group>
            </groups>
            <applications>
                <application>
                    <name>1С разное</name>
                </application>
            </applications>
            <items>
                <item>
                    <name>1С Статус обмена</name>
                    <type>2</type>
                    <snmp_community/>
                    <multiplier>0</multiplier>
                    <snmp_oid/>
                    <key>exchange.status</key>
                    <delay>0</delay>
                    <history>90</history>
                    <trends>365</trends>
                    <status>0</status>
                    <value_type>3</value_type>
                    <allowed_hosts/>
                    <units/>
                    <delta>0</delta>
                    <snmpv3_contextname/>
                    <snmpv3_securityname/>
                    <snmpv3_securitylevel>0</snmpv3_securitylevel>
                    <snmpv3_authprotocol>0</snmpv3_authprotocol>
                    <snmpv3_authpassphrase/>
                    <snmpv3_privprotocol>0</snmpv3_privprotocol>
                    <snmpv3_privpassphrase/>
                    <formula>1</formula>
                    <delay_flex/>
                    <params/>
                    <ipmi_sensor/>
                    <data_type>0</data_type>
                    <authtype>0</authtype>
                    <username/>
                    <password/>
                    <publickey/>
                    <privatekey/>
                    <port/>
                    <description/>
                    <inventory_link>0</inventory_link>
                    <applications>
                        <application>
                            <name>1С разное</name>
                        </application>
                    </applications>
                    <valuemap>
                        <name>1Ok / 0Fail</name>
                    </valuemap>
                </item>
                <item>
                    <name>Перезапуск 1С Обмен с Центром</name>
                    <type>2</type>
                    <snmp_community/>
                    <multiplier>0</multiplier>
                    <snmp_oid/>
                    <key>exchange.restart</key>
                    <delay>0</delay>
                    <history>90</history>
                    <trends>365</trends>
                    <status>0</status>
                    <value_type>3</value_type>
                    <allowed_hosts/>
                    <units/>
                    <delta>0</delta>
                    <snmpv3_contextname/>
                    <snmpv3_securityname/>
                    <snmpv3_securitylevel>0</snmpv3_securitylevel>
                    <snmpv3_authprotocol>0</snmpv3_authprotocol>
                    <snmpv3_authpassphrase/>
                    <snmpv3_privprotocol>0</snmpv3_privprotocol>
                    <snmpv3_privpassphrase/>
                    <formula>1</formula>
                    <delay_flex/>
                    <params/>
                    <ipmi_sensor/>
                    <data_type>0</data_type>
                    <authtype>0</authtype>
                    <username/>
                    <password/>
                    <publickey/>
                    <privatekey/>
                    <port/>
                    <description/>
                    <inventory_link>0</inventory_link>
                    <applications>
                        <application>
                            <name>1С разное</name>
                        </application>
                    </applications>
                    <valuemap>
                        <name>1C Restart</name>
                    </valuemap>
                </item>
            </items>
            <discovery_rules/>
            <macros/>
            <templates/>
            <screens/>
        </template>
    </templates>
    <triggers>
        <trigger>
            <expression>{1C Habr template:exchange.status.nodata(30m)}=1&{1C Habr template:exchange.status.time()}>084500&{1C Habr template:exchange.status.time()}<200000</expression>
            <name>{HOST.NAME} 1C Обмена не было более 30 минут</name>
            <url/>
            <status>0</status>
            <priority>1</priority>
            <description/>
            <type>0</type>
            <dependencies/>
        </trigger>
        <trigger>
            <expression>{1C Habr template:exchange.restart.count(1h,100)}>2</expression>
            <name>{HOST.NAME} 1C перезапуск Обмен с Центром более 3 раз за 1 часа</name>
            <url/>
            <status>0</status>
            <priority>1</priority>
            <description/>
            <type>0</type>
            <dependencies/>
        </trigger>
        <trigger>
            <expression>{1C Habr template:exchange.restart.last(0)}=2</expression>
            <name>{HOST.NAME} 1C перезапуск Обмен с Центром ошибка!</name>
            <url/>
            <status>0</status>
            <priority>2</priority>
            <description/>
            <type>0</type>
            <dependencies/>
        </trigger>
    </triggers>
</zabbix_export>


В шаблоне два items:
  1. 1С Статус обмена (exchange.status) — сюда 1С отправляет данные о том что работает. Триггеры:
    • {HOST.NAME} 1C Обмена не было более 30 минут — триггер, по которому запускается действие перезапуска 1С. Ограничено по времени, настройте в выражении триггера под себя вот эту часть
      &{1C Habr template:exchange.status.time()}>084500&{1C Habr template:exchange.status.time()}<200000

  2. Перезапуск 1С Обмен с Центром (exchange.restart) — сюда отправляет значение только скрипт
    • {HOST.NAME} 1C перезапуск Обмен с Центром ошибка! — триггер срабатывает, скрипт не смог корректно отработать (нет нужных заданий или другие ошибки при завершении 1С)
    • {HOST.NAME} 1C перезапуск Обмен с Центром более 3 раз за 1 часа — нужно чтобы определить количество перезапусков, слишком частые перезапуски говорят о некорректной работе системы


Action

Создаем action (и когда в zabbix сделают экспорт всех настроек...):



Как видно, запуск происходит 3 раза (сразу после триггера, через 30 и 40 минут), если триггер не исчезнет. Для уверенности.
Включить выполнение команд

На каждом сервере нужно в zabbix_agentd.conf добавить строчку
EnableRemoteCommands=1


1С отправляет данные в Zabbix средствами zabbix_sender over HTTP. Можно сделать через zabbix_sender.exe. В 8.1 проблемы с http-запросами с несколькими GET-параметрами, поэтому приводим наш рабочий код. В 8.2 говорят все хорошо, можно использовать стандартные методы.
В постоянно работающих 1С запрос должен отправляться раз в N-минут, в периодических запусках — по завершению (если они идут недолго). 1С сообщает Zabbix'у что она работает и не надо ее трогать. Как только перестает сообщать — убиваем все процессы и запускаем новый.
КОД 1С 8.1
Функция ОтправитьСтатусДляЗаббикса(КлючДляОтправки, ЗначениеДляОтправки) Экспорт
                ИмяСервера  = ВРег(ИмяКомпьютера());
                
                ТекстЗапроса = "http://zabbix.example.com/zabbix_sender/index.php?server=" + ИмяСервера + "&key=" + КлючДляОтправки + "&value=" + ЗначениеДляОтправки;
                
                Попытка
                               WinHttp = Новый COMОбъект("WinHttp.WinHttpRequest.5.1"); 
                               WinHttp.Option(2,"Windows-1251"); 
                               WinHttp.Open("GET", ТекстЗапроса, 0); 
                               WinHttp.SetRequestHeader("Accept-Language", "ru"); 
                               WinHttp.SetRequestHeader("Accept-Charset","Windows-1251"); 
                               WinHttp.setRequestHeader("Content-Language", "ru"); 
                               WinHttp.setRequestHeader("Content-Charset", "Windows-1251"); 
                               WinHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=Windows-1251");     
                               WinHttp.Send();
                               ОтветСервера = WinHttp.ResponseText();
                Исключение
                               Возврат Ложь;
                КонецПопытки;
                
                Если ОтветСервера = "OK" Тогда
                               Возврат Истина;
                Иначе 
                               Возврат Ложь;
                КонецЕсли;
КонецФункции


Windows

Создаем файл C:\ZBX\restart-1c.ps1 со следующим содержимым:
restart-1c.ps1
param([string]$programm_name="nul")
Try{
    $servername=$env:computername
    $zabbixhost="zabbix.example.com"
    $zabbix_key=$programm_name+".restart"
    switch ($programm_name)
    {
        "exchange" 
        {
            $window_name="1С:Предприятие - Астор: Обмен данными"
            $schedule_name="Обмен"
        }
        default {
            throw "No param"
        }
    }

    ################### Прибиваем процессы, запускаем другие ###################
    Get-Process | Where-Object {$_.MainWindowTitle -eq $window_name} | Stop-Process -Force
    Sleep 10;
    schtasks /end /TN $schedule_name
    Sleep 10;
    schtasks /run /TN $schedule_name
    if ($LastExitCode -ne 0){
        throw "LastExitCode -ne 0"
    }

    #Send to Zabbix
    $get_str1="https://$zabbixhost/zabbix_sender/index.php?server=$servername&key=$zabbix_key$vm_name&value=100"
    $wc = New-Object system.Net.WebClient;
    $Result = $wc.downloadString("$get_str1")
} Catch 
{
        #Send to Zabbix Error
    $get_str2="https://$zabbixhost/zabbix_sender/index.php?server=$servername&key=$zabbix_key$vm_name&value=2"
    $wc = New-Object system.Net.WebClient;
    $Result = $wc.downloadString("$get_str2")
}


И импортируем задание на сервер. Оно запускает powershell-скрипт (к сожалению, в zabbix_action ограничены команды длиной в 255 символов, поэтому не получиться сразу передать скрипт):
Планировщик
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
  <RegistrationInfo>
    <Author>example/username</Author>
  </RegistrationInfo>
  <Triggers />
  <Principals>
    <Principal id="Author">
      <UserId>Server\username</UserId>
      <LogonType>InteractiveToken</LogonType>
      <RunLevel>HighestAvailable</RunLevel>
    </Principal>
  </Principals>
  <Settings>
    <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
    <DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
    <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
    <AllowHardTerminate>true</AllowHardTerminate>
    <StartWhenAvailable>false</StartWhenAvailable>
    <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
    <IdleSettings>
      <Duration>PT10M</Duration>
      <WaitTimeout>PT1H</WaitTimeout>
      <StopOnIdleEnd>true</StopOnIdleEnd>
      <RestartOnIdle>false</RestartOnIdle>
    </IdleSettings>
    <AllowStartOnDemand>true</AllowStartOnDemand>
    <Enabled>true</Enabled>
    <Hidden>false</Hidden>
    <RunOnlyIfIdle>false</RunOnlyIfIdle>
    <WakeToRun>false</WakeToRun>
    <ExecutionTimeLimit>P3D</ExecutionTimeLimit>
    <Priority>7</Priority>
  </Settings>
  <Actions Context="Author">
    <Exec>
      <Command>powershell.exe</Command>
      <Arguments>-windowstyle hidden -nologo -NonInteractive -File "C:\ZBX\restart-1c.ps1" exchange</Arguments>
    </Exec>
  </Actions>
</Task>


Обязательное условие — задание в планировщике обязательно должно быть создано под пользователем, под которым выполняется 1С. У нас это выделенный пользователь, который залогинен в систему.
Оправдания

Нам пришлось прибегнуть к такому механизму (нельзя было делать просто Stop-Process 1cv8.exe), т.к. на сервере работает много запущенных 1С, которые работают и не должны просто так перезапускаться, без необходимости.
Если Вы все правильно сделали (а я правильно описал), то теперь у вас будет работать перезапуск программы, если она вдруг перестает работать (с завершением всех заданий и .exe).

Возможно у Вас есть какие-то вопросы (описывать техническое решение — не мой конек) — буду рад ответить, пишите в личку. У нас реализован еще механизм контроля обмена с каждой кассой и с каждыми весами (с использованием Низкоуровнего обнаружения и нединамическое обновление конфигурации 1С одной кнопкой, возможно кому-то будет полезно, напишем про это статью)
Приветствуется конструктивная критика, советы :)
Моей самооценке Мне интересно знать, когда решения кому-то помогает, поэтому если не сложно и если вы используете часть или полное решение — нажмите кнопочку в опросе, спасибо!
Only registered users can participate in poll. Log in, please.
Решение помогло?
66.67% ДА4
33.33% ДА2
6 users voted. 20 users abstained.
Tags:
Hubs:
Rating0
Comments4

Articles