Дисклеймер
В этой статье выражено личное мнение автора, его видение мира, его путь, и это все не претендует на абсолютную верность и объективность. Автор не несет никакой ответственности за последствия использования данной информации, он только надеется что эта информация поможет сделать кому-то жизнь проще.
Предисловие
Сначала я просто хотел написать небольшую статью о том, как мы разносили базы по службам, но в ходе углубления в этот процесс мы добавляли всякие разные штуки (мониторинг служб, потом мониторинг пользователей внутри 1С, потом прикрутили заббикс, и, наконец, пришли к CI/CD на базе 1С). В итоге я понимаю что пихать это в одну статью будет слишком — решил разделить на несколько. Ну а название навеяно циклом статей "сети для самых маленьких", которые принесли мне много приятных минут и к которым я отсылаю всех, кто "хочет изучить сети". Итак, мы приступаем!
Когда ты признаешь проблему, значит ты на половину уже вылечился (с) один знакомый психиатр
В этой статье я хочу поделится своим опытом администрирования большого числа 1С в корпоративном секторе. Базы все разные, есть разработка, есть тестовые, все как у всех. Но их просто достаточно много. И все было хорошо, но в определенный момент проводить какие-то админские работы стало крайне тяжело и рискованно.
Какие у нас были сложности:
- Подвисшая база тянула за собой перезапуск службы, а значит страдали невинные (пользователи других баз)
- Было тяжело понять кто сегодня "герой дня" — какая база заняла все ресурсы
- Обновление релизов — обновление одной тянуло за собой автоматическое обновление всех баз на этой службе
- Ручное подключение баз пользователям, ручное изменение в случае переездов
- Мониторинг
И только сейчас я понимаю что это была только вершина айсберга...
Акт первый, действие нулевое
Небольшое отвлечение на основные постулаты, осознание которых далось большой кровью и болью.
- 1С не умеет адекватно работать в виртуализированной среде. Это печальный факт (особенно если учесть что на дворе уже практически 2019 год), судя по всему, исправлять никто не собирается. Виртуализация, даже правильно настроенная, будет вам стоить примерно 15-25% производительности. Смиритесь. (Источник — Гилев и собственные тесты)
- Забудьте про нормальный кластер — его тут нет. Сразу закладывайте время простоя равное времени подъема машины из бекапа и/или восстановлении на другом сервере. Альтернатива — DNS и одинаково настроенные сервера приложений на одну и туже базу — так можно уложится в 3-5 минут и даже реализовать полуручное переключение. (источник — собственный опыт)
- При выборе процессора смотрите только на частоту. Процессор в 6 ядер по 3,4Ггц порвет в куски процессор на 20 ядер по 2Ггц. Проблема в том, что 1С вообще ничего не знает про параллельные вычисления. По сути это работает так — у нас есть определенное число воркеров для каждой службы, их раскидывают по процессорам, и если в каком то воркере пользователь запустил какой-то тяжелый отчет то в системе будет загружено только одно ядро процессора. Именно то, на котором работает воркер с запущенным заданием… Для БД ситуация кстати ровно обратная. (источник — Гилев, собственный опыт, опыт коллег)
- Не используйте логи в "новом" формате (запись в SQLLite) — вы очень быстро столкнетесь с тем, что производительность этого решения еще хуже чем файлового варианта. (Источник — собственный опыт, опыт коллег)
- 1С оооочень не любит IPv6. На всех серверах с 1С лучше сразу понижать приоритет IPv6 до минимума. И нет, отключить вы IPv6 не сможете (Источник — Гилев, собственный опыт)
- Используйте для виртуальных серверов виртуальные сетевые карточки E1000. С остальными проблема по производительности (Источник — Гилев, но на собственном опыте не подтвердилось, хотя особо и не тестили)
- Обслуживание баз дает хороший прирост производительности, особенно периодический пересчет итогов, а так же обслуживание индексов SQL (Источник — собственный опыт, Гилев)
- Поиск причин падения 1С сродни поеданию неочищенного кактуса. Выяснить что-то толком можно только через боль, унижения и страдания. (Источник — собственный опыт)
- Нет ни одного официального образа ни под один гипервизор. Про докер я вообще молчу. (Источник — сайт 1С)
- Программная лицензия для сервера привязывается к — сюрприз, сюрприз — серийному номеру процессора. В эпоху повсеместной виртуализации ход потрясающий. Поясняю — активировали сервер, переехали на другую ноду, перезагрузили машину — 1С не запуститься. Расчехляйте новый активационный код. (Источник — собственный опыт, болтливая техническая поддержка 1С =))
- 1С — это учетная система, а не отчетная. Хотите много нормальных жирных отчетов и быстро — выводите это за рамки 1С. (Источник — собственный опыт)
- У 1С есть два неоспоримых достоинства, за счет которых она будет процветать еще долго:
- стоимость самого продукта/разработчиков
- скорость разработки
и к сожалению для российского бизнеса они являются первоочередными. А зачастую и единственными, на что вообще смотрят. (Источник — печальная реальность)
- Никогда не используйте файловую шару как место под хранилище конфигураций 1С. Только службу. Иначе маты со стороны разработки о упавшем черт знает когда хранилище станут вашим неизменным спутником по жизни. (Источник — собственный опыт, опыт коллег)
Акт первый, действие первое
Первая короткая сценка из корпоративной жизни
На сцене — Админ (А), программист 1С (П1С) и представитель бизнеса (ПБ)
ПБ — У нас медленно работает программа!
А — у меня в системе все хорошо!
П1С — я все написал правильно, у меня на компьютере все работает быстро!
ПБ (робко и растерянно) — но она же долго…
А и П1С хором — у нас все хорошо, проблема на вашей стороне!
Проблемы всегда случаются не вовремя (с) (5-летний философ)
И вот в одно прекрасное солнечное утро (на самом деле это была глубокая зимняя ночь) мы поняли что завтра надо запустить новую базу. Завтра наступал тот прекрасный день, который уже много раз описывался тысячами авторов и имя ему — легион! Тьфу, простите, занесло. Имя этому дню был дедлайн. Час ночи, завтра на 200 компах должна запуститься новая база." Да не проблема, у нас же все компы в домене! Сейчас быстренько сделаем логин-скрипт и дело в шляпе!" подумаете вы. И будуте правы — так же подумали и мы. И сделали. Только, как обычно это бывает, погорели на мелочи — я в логон-скрипте я прописал %filename%.bat а коллега выложил %filename%.cmd.
Ну и понятное дело с утра хелпдеск побежал делать все руками, а мне было очень стыдно за такой тупой фейл. Извинялся перед парнями тортиком.
Но мысль автоматизации этого процесса у меня в голове засела очень крепко и стал даже вырисовываться план внедрения.
В итоге мы пришли к следующей идеологии:
- Все раздается через AD — создаются группы вида 1cbases-%версия платформы%-%имя базы% и туда силами хелпдеста добавляются пользователи, которым нужна база.
- 1cbases — это префикс по которому удобно искать группы
- версия платформы 81, 82 и 83 (релиз не принципиален)
- название базы соответствует имени файла с настройками
- выделяется общая файловая шара где выкладываются все файлы с настройкой подключения к базам (одна база — один файл)
- при блокировании компьютера вызывается скрипт, который считывает группы пользователя и на их основании добавляет пользователям нужные базы 1С
Как мы это делали:
- Через групповые политики добавляется новое задание в планировщик:
- запускать от имени пользователя
- событие — разблокировка компьютера
- действие — запуск нашего скрипта
- Создаем нужные группы в АД и заполняем их пользователями
- Создаем нужные файлы для запуска самих 1С. Тут остановлюсь чуть поподробнее. Изначально мы долго мучили интернет своими запросами и нашли полное описание структуры файлов *.v8i. Но потом нашелся способ проще и гениальнее.
- запускаем 1С
- настраиваем подключение к базе
- проверяем что все работает
- кликаем правой клавишей по названию базы и выбираем пункт — "Сохранить ссылку в файл"
#Первым шагом создаем место для логов
if (Test-Path "$env:HOMEDRIVE!script_reportadd_1c_bases_report.txt")
{
Remove-Item "$env:HOMEDRIVE!script_reportadd_1c_bases_report.txt" -Force -ErrorAction SilentlyContinue;
}
New-Item "$env:HOMEDRIVE!script_reportadd_1c_bases_report.txt" -ItemType file -Force -ErrorAction SilentlyContinue;
Add-Content -Value ("Дата последнего запуска: " + (Get-Date -Format F)) -Path "$env:HOMEDRIVE!script_reportadd_1c_bases_report.txt";
if ( (gwmi Win32_OperatingSystem | select Caption, CSDVersion) -notlike "*server*") # запрет запуска на серверных ОС
{
Add-Content -Value "Операционная система распознана как клиентская" -Path "C:!script_reportadd_1c_bases_report.txt";
if (!(Test-Path "$env:APPDATA1C1CEstartibases.v8i")) #если нет этого файла 1С подтягивает данные из списка баз 8.1 и игнорирует список баз 8.2
{
New-Item "$env:APPDATA1C1CEstartibases.v8i" -ItemType file -Force; # Создаем этот файл если его нет
Add-Content -Value "Файл $env:APPDATA1C1CEstartibases.v8i не найден, создали его" -Path "C:!script_reportadd_1c_bases_report.txt";
}
if (Test-Path "$env:APPDATA1C1CEstart1CEStart.cfg")
{
Remove-Item "$env:APPDATA1C1CEstart1CEStart.cfg" -Force #-ErrorAction SilentlyContinue #удаление старого конфигурационного файла для 8.1
}
New-Item "$env:APPDATA1C1CEstart1CEStart.cfg" -ItemType file -Force #создание нового конфигурационного файла для 8.2
$GroupList = ([ADSISEARCHER]"samaccountname=$($env:USERNAME)").Findone().Properties.memberof -replace '^CN=([^,]+).+$','$1' # Создание списка групп пользователя
foreach ($Group in $GroupList) # генерация списка общих баз на основе имени группы
{
if ($Group.Length -gt 6) # Проверка длины имени группы
{
If ($Group.Substring(0,7) -eq "1cbases") # вычисление группы указывающей на базу 1С
{
Switch ($Group.Substring(8,2)) # выбор платформы 8.1 или 8.2
{
"81" {Add-Content "$env:APPDATA1C1Cv81ibases.v8l" -Value ("\gold585.intTechFilesCommonBases" + $Group.Substring(11) +".v8i")} # Создание строчки из файла со списком общих баз для 8.1
"82" {Add-Content "$env:APPDATA1C1CEstart1CEStart.cfg" -Value ("CommonInfoBases=\gold585.intTechFilesCommonBases" + $Group.Substring(11) +".v8i")} # Создание строчки из файла со списком общих баз для 8.2
"83" {Add-Content "$env:APPDATA1C1CEstart1CEStart.cfg" -Value ("CommonInfoBases=\gold585.intTechFilesCommonBases" + $Group.Substring(11) +".v8i")} # Создание строчки из файла со списком общих баз для 8.3
}
Add-Content -Value ("Пользователь принадлежит групп $Group") -Path "C:!script_reportadd_1c_bases_report.txt";
Add-Content -Value ("Добавлено значение: CommonInfoBases=\gold585.intTechFilesCommonBases" + $Group.Substring(11) +".v8i") -Path "C:!script_reportadd_1c_bases_report.txt";
}
}
}
}
else
{
Add-Content -Value "Операционная система распознана как серверная" -Path "C:!script_reportadd_1c_bases_report.txt";
}
Что получили:
- Добавление баз теперь не было морокой — просто делали группу, добавляли файл с настройками — дальше все происходило автоматом
- Могли спокойно переносить базы куда угодно, просто меняя конфигурацию в файле с настройками подключения к базе (как показала практика — очень удобно)
- Сберегли обувь хелпдеску
Акт первый, действие второе
Вторая короткая сценка из корпоративной жизни
На сцене — Админ (А), программист 1С (П1С), разговор после ухода представителя бизнеса
А — Ваш этот 1С — $#%но!!! Сколько можно решать железом проблемы архитектуры и уровня разработчиков!
П1С — да это ваши сервера #$@но! У меня на локальной файловой базе все летает! Настройте уже ваше хозяйство по нормальному!
Спорщики удаляются со сцены сыпля взаимными обвинениями, опускается занавес, свет гаснет.
И с этой стороны ни чуть не лучше… (с) печальный ослик Иа-Иа в свой собственный день рождения
Вот представьте себе — сидите вы в удобном кресле, в одной руке чашка вкусного чая, в другой пышущая жаром и свежестью булочка из кулинарии ближайшего магазина, за окном приятно пахнет весной… И это, конечно же, самое подходящие время для звонка с проблемой! Коллега — Байконур, у нас %@па!
Я — я так понимаю что стадию Хьюстона с проблемами мы уже успешно пролетели?
Коллега — да. База %имя базы% подвисла, вообще не отвечает, ТОПы уже рвут и мечут. 3 раза мне уже звонили. Надо перезагружать службу.
Я — так там же еще пачка баз на этой службе!!!
Коллега — да, поэтому вторая половина ТОПов тоже рвет и мечет что их отключат...
В итоге конечно все согласовали, перезапустили, но осадочек остался.
Идеология:
- В продуктовой среде мы должны следовать правилу — одна база — одна служба
- Запускаться службы должны исключительно из-под доменных учеток
- Логи нужно вынести на отдельный диск и включить на эти папки сжатие (при разбитии по дням это очень сильно экономит место и ускоряет (незначительно) поиск по логам)
- Каждой службе выдается alias в DNS для того, чтобы отвязать разработку от ip и/или dns сервера (в этом случае разработка вообще не волнуется на предмет того, где фактически находится сервер — физика, виртуальная машина в приватном облаке или вообще в публичном облаке)
- На каждую службу мы выделяем 500 портов для пользовательских соединений (наше внутреннее решение)
Как мы это делали (для нового сервера. для уже существующего часть шагов не актуальны):
- Создаются учетки под каждую службу
- На машине, где они будут работать им выдаются права на "запуск как службе"
- Ставиться MS офис, обязательно с активацией по MAK-ключу
- Ставится sqlncli — утилита из набора MS SQL Native Client. На данный момент выше 2012 не появлялось
- Создается папка C:WindowsSysWOW64configsystemprofileDesktop — в противном случае есть проблемы с выгрузками в Word/Excel
- Для Windows 2016 и 1С 8.1 нужно скопировать старую версию dll (В папке C:Program FilesCommon FilesSystemOle DB надо заменить два файла sqloledb.dll и sqloledb.rll взятых со старых серверов)
- Ставятся дополнительное ODBC драйверы, если нужно подключатся к MySQL/PostgreSQL
Настройка папки для службы и логов:
- Создается папка на отдельном диске называется в формате 1CServer%basename% (в стандартном случае это делает сама служба, ибо у нее есть в настройках запуска путь к логам)
- Если внутрь каталога только что созданной службы переносятся данные из другого каталога (другой службы, другого сервера), то необходимо заменить владельцев (иначе служба не получит к ним доступа) с заменой владельца подконтейнеров
- Владельцем папки делается учетная запись службы
@echo off
chcp 1251
установка кодировки
set base=%base_name%
название базы без пробелов на английском – для каталога с логами
set dsce=%base name%
название базы с пробелами на английском – для имени службы
set dscr=%Имя базы%
название базы на русском – для представления службы
set sver=8.3
краткая версия – для имени и представления службы
set fver=1cv88.3.9.2170
часть пути к нужной нам версии платформы 1С
set port=8040
управляющий порт
set regp=8041
основной порт
set rnge=8060:8491
диапазон портов для службы
set name="1C:Enterprise %sver% Server Agent (x86-64) %dsce%"
имя службы (для реестра) по аналогии с типовыми, только добавляется название базы для уникальности названий
set bpth="C:Program Files%fver%binragent.exe" -srvc -agent
путь к исполняемому файлу для запуска службы
set logs=D:1C_Server_%base%
каталог для логов
set user="%login%@%domain_name%"
такой формат позволяет использовать логины длиннее 20 символов
пароль нигде не указывал при создании, потому что потом всё равно надо его заново указать, только тогда у пользователя будут права на запуск служб;
set view="Агент сервера 1С:Предприятия %sver% (x86-64) %dscr%"
представление службы в оснастке
sc create %name% binPath= "%bpth% -regport %regp% -port %port% -range %rnge% -d "%logs%"" type= "own" start= "auto" error= "severe" depend= "Tcpip/Dnscache/lanmanworkstation/lanmanserver" obj= %user%DisplayName= %view%
тут:
type= "own" – тип службы, какие бывают еще сам посмотри
start= "auto" – автоматический запуск
error= "severe" – не помню что значит, но устанавливает правильное значение ключа в реестре ErrorControl = 2
depend= "Tcpip/Dnscache/lanmanworkstation/lanmanserver" – зависимости (на четвертой вкладке указаны, вручную не настраиваются)
sc description %name% %view%
задает представление в оснастке, сразу при создании не указывается
sc failure %name% reset= 0 actions= "restart/0"
настройка на вкладке восстановление – перезапуск во всех случаях, через 0 минут; сброс счетчика через 0 дней
То же самое без комментариев:
@echo off
chcp 1251
set base=%base_name%
set dsce=%base name%
set dscr=%Имя базы%
set sver=8.3
set fver=1cv88.3.9.2170
set port=8040
set regp=8041
set rnge=8060:8491
set name="1C:Enterprise %sver% Server Agent (x86-64) %dsce%"
set bpth="C:Program Files%fver%binragent.exe" -srvc -agent
set logs=D:1C_Server_%base%
set user="%login%@domain.company"
set view="Агент сервера 1С:Предприятия %sver% (x86-64) %dscr%"
sc create %name% binPath= "%bpth% -regport %regp% -port %port% -range %rnge% -d "%logs%"" type= "own" start= "auto" error= "severe" depend= "Tcpip/Dnscache/lanmanworkstation/lanmanserver" obj= %user% DisplayName= %view%
sc description %name% %view%
sc failure %name% reset= 0 actions= "restart/0"
Нюансы:
- Для того, чтобы в службах не было кроказябр
- в cmd ввести команду chcp 1251
- файл надо сохранить в ANSI кодировке
- Обязательно надо проверить на отсутствие дублирующих ключей в строке запуска — служба с ними не стартует!!!
- Для того, чтобы удалить службу, можно воспользоваться командой — sc delete «Имя заданное в переменной name»
- Добавить порты используемые 1С в разрешения в firewall
- Нужен всего один физический ключ на сервер — все службы будут активироваться им
После проведения всех мероприятий в итоге мы пришли к:
- Базы можно спокойно перезагружать, не трогая другие базы
- Всегда можно найти "героя" — базу, которая съедает все ресурсы
- Любые работы с базой касаются только одной конкретной базы
В следующих статьях я планирую рассказать (если эта статья народу зайдет):
- как мы перевели авторизацию в MSSQL на kerberos и вообще оптимизировали доступы
- как мы сделали мониторинг служб — кто сколько занял ресурсов
- как мы сделали мониторинг внутри службы 1С выявления блокировок пользователями быстрее, чем они позвонят
- как мы пытались внедрить CI для 1С и что из этого вышло
Автор: Dr_Wut