Как и зачем мы написали высоконагруженный масштабируемый сервис для 1С:Предприятия: Java, PostgreSQL, Hazelcast

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

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

    СВ использует распределенное хранилище Hazelcast и поисковую систему Elasticsearch. Еще речь пойдет о Java и о том, как мы горизонтально масштабируем PostgreSQL.
    image


    Постановка задачи


    Чтобы было понятно, зачем мы делали Систему Взаимодействия, расскажу немного о том, как устроена разработка бизнес-приложений в 1С.

    Для начала – немного о нас для тех, кто еще не знает, чем мы занимаемся:) Мы делаем технологическую платформу «1С:Предприятие». Платформа включает в себя средство разработки бизнес-приложений, а также runtime, позволяющий бизнес-приложениям работать в кросс-платформенном окружении.

    Клиент-серверная парадигма разработки


    Бизнес-приложения, созданные на «1С:Предприятии», работают в трёхуровневой клиент-серверной архитектуре «СУБД – сервер приложений – клиент». Прикладной код, написанный на встроенном языке 1С, может выполняться на сервере приложений или на клиенте. Вся работа с прикладными объектами (справочниками, документами и т.д.), а также чтение и запись базы данных выполняется только на сервере. Функциональность форм и командного интерфейса также реализована на сервере. На клиенте выполняется получение, открытие и отображение форм, «общение» с пользователем (предупреждения, вопросы…), небольшие расчеты в формах, требующие быстрой реакции (например, умножение цены на количество), работа с локальными файлами, работа с оборудованием.

    В прикладном коде заголовках процедур и функций надо явно указывать, где будет выполняться код — с помощью директив &НаКлиенте / &НаСервере (&AtClient / &AtServer в англоязычном варианте языка). Разработчики на 1С сейчас поправят меня, сказав, что директив на самом деле больше, но для нас это сейчас не существенно.

    Из клиентского кода можно вызвать серверный код, а вот из серверного кода вызвать клиентский нельзя. Это фундаментальное ограничение, сделанное нами по ряду причин. В частности потому, что серверный код должен быть написан так, чтобы одинаково выполняться, откуда бы его ни вызвали – с клиента или с сервера. А в случае вызова серверного кода из другого серверного кода клиент отсутствует как таковой. И потому, что в ходе выполнения серверного кода клиент, вызвавший его, мог закрыться, выйти из приложения, и серверу будет уже некого вызывать.

    image
    Код, обрабатывающий нажатие кнопки: вызов серверной процедуры с клиента сработает, вызов клиентской процедуры с сервера — нет

    Это значит, что если мы с сервера захотим передать какое-то сообщение в клиентское приложение, например, что закончилось формирование «долгоиграющего» отчета и отчет можно посмотреть – такого способа у нас нет. Приходится идти на ухищрения, например, из клиентского кода периодически опрашивать сервер. Но такой подход загружает систему лишними вызовами, да и вообще выглядит не очень изящно.

    А еще есть необходимость, например, при поступившем телефонном SIP-звонке оповестить об этом клиентское приложение, чтобы оно по номеру звонящего нашло его в базе контрагентов и показало пользователю информацию о звонящем контрагенте. Или, например, при поступлении на склад заказа уведомить об этом клиентское приложение заказчика. В общем, кейсов, где такой механизм бы пригодился, немало.

    Собственно постановка


    Создать механизм обмена сообщениями. Быстрый, надежный, с гарантированной доставкой, с возможностью гибкого поиска сообщений. На базе механизма реализовать мессенджер (сообщения, видеозвонки), работающий внутри приложений 1С.

    Спроектировать систему горизонтально масштабируемой. Возрастающая нагрузка должна закрываться увеличением количества нод.

    Реализация


    Серверную часть СВ мы решили не встраивать непосредственно в платформу 1С:Предприятие, а реализовывать как отдельный продукт, API которого можно вызывать из кода прикладных решений 1С. Сделано это было по ряду причин, главная из которых – хотелось сделать возможным обмен сообщениями между разными приложениями 1С (например, между Управлением Торговлей и Бухгалтерией). Разные приложения 1С могут работать на разных версиях платформы 1С:Предприятие, находиться на разных серверах и т.п. В таких условиях реализация СВ как отдельного продукта, находящегося «сбоку» от инсталляций 1С – оптимальное решение.

    Итак, мы решили делать СВ как отдельный продукт. Небольшим компаниям мы рекомендуем пользоваться сервером СВ, который мы установили в своем облаке (wss://1cdialog.com), чтобы избежать накладных расходов, связанных с локальной установкой и настройкой сервера. Крупные же клиенты, возможно, сочтут целесообразной установку собственного сервера СВ на своих мощностях. Аналогичный подход мы использовали в нашем облачном SaaS продукте 1cFresh – он выпускается как тиражный продукт для инсталляции у клиентов, и также развернут в нашем облаке https://1cfresh.com/.

    Приложение


    Для распределения нагрузки и отказоустойчивости развернем не одно Java-приложение, а несколько, перед ними поставим балансировщик нагрузки. Если нужно передать сообщение с ноды на ноду – используем publish/subscribe в Hazelcast.

    Общение клиента с сервером – по websocket. Он хорошо подходит для систем реального времени.

    Распределенный кэш


    Выбирали между Redis, Hazelcast и Ehcache. На дворе 2015 год. Redis только-только зарелизили новый кластер (слишком новый, страшно), есть Sentinel с кучей ограничений. Ehcache не умеет собираться в кластер (этот функционал появился позже). Решили попробовать с Hazelcast 3.4.
    Hazelcast собирается в кластер «из коробки». В режиме одной ноды он не очень полезен и может сгодиться только как кэш – не умеет скидывать данные на диск, потеряли единственную ноду – потеряли данные. Мы разворачиваем несколько Hazelcast-ов, между которыми бэкапим критические данные. Кэш не бэкапим – его не жалко.

    Для нас Hazelcast – это:

    • Хранилище пользовательских сессий. Каждый раз ходить за сессией в базу – долго, поэтому все сессии кладем в Hazelcast.
    • Кэш. Ищешь профиль пользователя – проверь в кэше. Написал новое сообщение – положи в кэш.
    • Топики для общения инстансов приложения. Нода генерирует событие и помещает его в топик Hazelcast. Другие ноды приложения, подписанные на этот топик, получают и обрабатывают событие.
    • Кластерные блокировки. Например, создаем обсуждение по уникальному ключу (обсуждение-синглтон в рамках базы 1С):

    conversationKeyChecker.check("БЕНЗОКОЛОНКА");
    
          doInClusterLock("БЕНЗОКОЛОНКА", () -> {
    
              conversationKeyChecker.check("БЕНЗОКОЛОНКА");
    
              createChannel("БЕНЗОКОЛОНКА");
          });

    Проверили, что канала нет. Взяли блокировку, снова проверили, создали. Если после взятия блокировки не проверять, то есть шанс, что другой поток в этот момент тоже проверил и сейчас попробует создать такое же обсуждение – а оно уже существует. Делать блокировку через synchronized или обычный java Lock нельзя. Через базу – медленно, да и базу жалко, через Hazelcast – то, что надо.

    Выбираем СУБД


    У нас большой и успешный опыт работы с PostgreSQL и сотрудничества с разработчиками этой СУБД.

    С кластером у PostgreSQL непросто – есть XL, XC, Citus, но, в общем-то, это не noSQL, которые масштабируются из коробки. NoSQL как основное хранилище рассматривать не стали, хватило и того, что берем Hazelcast, с которым прежде не работали.

    Раз нужно масштабировать реляционную БД – значит, шардинг. Как вы знаете, при шардинге мы разделяем базу данных на отдельные части так, чтобы каждую из них можно было вынести на отдельный сервер.

    Первый вариант нашего шардинга предполагал возможность разнести каждую из таблиц нашего приложения по разным серверам в разных пропорциях. Много сообщений на сервере А – пожалуйста, давайте перенесем часть этой таблицы на сервер Б. Такое решение просто-таки вопило о преждевременной оптимизации, так что мы решили ограничиться multi-tenant подходом.

    Почитать про multi-tenant можно, например, на сайте Citus Data.

    В СВ есть понятия приложения и абонента. Приложение – это конкретная инсталляция бизнес-приложения, например, ERP или Бухгалтерии, со своими пользователями и бизнес-данными. Абонент – это организация или физическое лицо, от имени которого выполняется регистрация приложения в сервере СВ. У абонента может быть зарегистрировано несколько приложений, и эти приложения могут обмениваться сообщениями между собой. Абонент и стал жильцом (tenant) в нашей системе. Сообщения нескольких абонентов могут находиться в одной физической базе; если мы видим, что какой-то абонент стал генерировать много трафика – мы выносим его в отдельную физическую базу (или даже отдельный сервер БД).

    У нас есть главная БД, где хранится таблица роутинга с информацией о локации всех абонентских базах данных.

    image

    Чтобы главная БД не была узким местом, таблицу роутинга (и другие часто востребованные данные) мы держим в кэше.

    Если начнет тормозить БД абонента, будем внутри резать на партиции. На других проектах для партиционирования больших таблиц используем pg_pathman.

    Поскольку терять сообщения пользователей плохо, мы поддерживаем наши БД репликами. Комбинация синхронной и асинхронной реплик позволяет подстраховаться на случай потери основной БД. Потеря сообщения произойдет только в случае одновременного отказа основной БД и ее синхронной реплики.

    Если теряется синхронная реплика – асинхронная реплика становится синхронной.
    Если теряется основная БД – синхронная реплика становится основной БД, асинхронная реплика – синхронной репликой.

    Elasticsearch для поиска


    Поскольку, помимо прочего, СВ – это еще и мессенджер, здесь нужен быстрый, удобный и гибкий поиск, с учетом морфологии, по неточным соответствиям. Мы решили не изобретать велосипед и использовать свободную поисковую систему Elasticsearch, созданную на основе библиотеки Lucene. Elasticsearch мы также разворачиваем в кластере (master – data – data), чтобы исключить проблемы в случае выхода из строя узлов приложения.

    На github мы нашли плагин русской морфологии для Elasticsearch и используем его. В индексе Elasticsearch мы храним корни слов (которые определяет плагин) и N-граммы. По мере того, как пользователь вводит текст для поиска, мы ищем набираемый текст среди N-грамм. При сохранении в индекс слово «тексты» разобьется на следующие N-граммы:

    [те, тек, текс, текст, тексты, ек, екс, екст, ексты, кс, кст, ксты, ст, сты, ты],

    А также будет сохранен корень слова «текст». Такой подход позволяет искать и по началу, и по середине, и по окончанию слова.

    Общая картина


    image
    Повтор картинки из начала статьи, но уже с разъяснениями:

    • Балансировщик, выставленный в интернет; у нас – nginx, может быть любой.
    • Инстансы Java-приложения общаются между собой через Hazelcast.
    • Для работы с веб-сокетом используем Netty.
    • Java-приложение написано на Java 8, состоит из бандлов OSGi. В планах – миграция на Java 10 и переход на модули.

    Разработка и тестирование


    В процессе разработки и тестирования СВ мы столкнулись с рядом интересных особенностей продуктов, используемых нами.

    Нагрузочное тестирование и утечки памяти


    Выпуск каждого релиза СВ – это нагрузочное тестирование. Оно пройдено успешно, когда:

    • Тест работал несколько суток и не было отказов в обслуживании
    • Время отклика по ключевым операциям не превысило комфортного порога
    • Ухудшение производительности по сравнению с предыдущей версией не больше 10%

    Тестовую базу заполняем данными – для этого получаем с продакшн-сервера информацию о самом активном абоненте, умножаем его цифры на 5 (количество сообщений, обсуждений, пользователей) и так тестируем.

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

    1. Стресс-тест
    2. Только подключения
    3. Регистрация абонентов

    При стресс-тесте мы запускаем несколько сотен потоков, и те без остановки нагружают систему: пишут сообщения, создают обсуждения, получают список сообщений. Имитируем действия обычных пользователей (получить список моих непрочитанных сообщений, написать кому-нибудь) и программных решений (передать пакет другой конфигурации, обработать оповещение).

    Например, вот так выглядит часть стресс-теста:

    • В систему заходит пользователь
      • Запрашивает свои непрочитанные обсуждения
      • С 50% вероятностью читает сообщения
      • С 50% вероятностью пишет сообщения
      • Далее пользователь:
        • С 20% вероятностью создает новое обсуждение
        • Случайно выбирает любое из своих обсуждений
        • Заходит внутрь
        • Запрашивает сообщения, профили пользователей
        • Создает пять сообщений, адресованных случайным пользователям из этого обсуждения
        • Выходит из обсуждения
        • Повторяет 20 раз
        • Выходит из системы, возвращается обратно к началу сценария

      • В систему заходит чат-бот (эмулирует обмен сообщениями из кода прикладных решений)

        • С 50% вероятностью создает новый канал для обмена данными (специальное обсуждение)
        • С 50% вероятностью пишет сообщение в любой из существующих каналов



    Сценарий «Только подключения» появился не просто так. Бывает ситуация: пользователи подключили систему, но пока не втянулись. Каждый пользователь утром в 09:00 включает компьютер, устанавливает соединение с сервером и молчит. Эти ребята опасны, их много – из пакетов у них только PING/PONG, но соединение до сервера они держат (не держать не могут – а вдруг новое сообщение). Тест воспроизводит ситуацию, когда за полчаса в системе пытаются авторизоваться большое число таких пользователей. Он похож на стресс-тест, но фокус у него именно на этом первом входе – чтобы не было отказов (человек не пользуется системой, а она уже отваливается – сложно придумать что-то хуже).

    Сценарий регистрации абонентов берет свое начало с первого запуска. Мы провели стресс-тест и были уверены, что в переписке система не тормозит. Но пошли пользователи и начала по таймауту отваливаться регистрация. При регистрации мы использовали /dev/random, который завязан на энтропию системы. Сервер не успевал скопить достаточно энтропии и при запросе нового SecureRandom застывал на десятки секунд. Выходов из такой ситуации много, например: перейти на менее безопасный /dev/urandom, поставить специальную плату, которая формирует энтропию, генерировать случайные числа заранее и хранить в пуле. Мы временно закрыли проблему пулом, но с тех пор прогоняем отдельный тест на регистрацию новых абонентов.

    В качестве генератора нагрузки мы используем JMeter. Работать с вебсокетом он не умеет, нужен плагин. Первыми в поисковой выдаче по запросу «jmeter websocket» идут статьи с BlazeMeter, в которых рекомендуют плагин от Maciej Zaleski.

    С него мы и решили начать.

    Почти сразу после начала серьезного тестирования мы обнаружили, что в JMeter начались утечки памяти.

    Плагин – это отдельная большая история, при 176 звездах у него 132 форка на github-е. Сам автор в него не коммитит с 2015 года (мы брали его в 2015 году, тогда это не вызвало подозрений), несколько github issues по поводу утечек памяти, 7 незакрытых pull request-ов.
    Если решите проводить нагрузочное тестирование с помощью этого плагина, обратите внимание на следующие обсуждения:

    1. В многопоточной среде использовался обычный LinkedList, в итоге получали NPE в рантайме. Решается либо переходом на ConcurrentLinkedDeque, либо synchronized-блоками. Для себя выбрали первый вариант (https://github.com/maciejzaleski/JMeter-WebSocketSampler/issues/43).
    2. Утечка памяти, при дисконнекте не удаляется информация о соединении (https://github.com/maciejzaleski/JMeter-WebSocketSampler/issues/44).
    3. В режиме streaming (когда вебсокет не закрывается в конце сэмпла, а используется дальше в плане) не работают Response pattern-ы (https://github.com/maciejzaleski/JMeter-WebSocketSampler/issues/19).

    Это из тех, что на github-е. Что мы сделали:

    1. Взяли форк Elyran Kogan (@elyrank) – в нем исправлены проблемы 1 и 3
    2. Решили проблему 2
    3. Обновили jetty с 9.2.14 на 9.3.12
    4. Обернули SimpleDateFormat в ThreadLocal; SimpleDateFormat не потокообезопасный, что приводило к NPE в рантайме
    5. Устранили еще одну утечку памяти (неправильно закрывалось соединение при дисконнекте)

    И все-таки он течет!

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

    Прошло два дня…

    Теперь память стала заканчиваться у Hazelcast-а. В логах было видно, что спустя пару дней тестирования Hazelcast начинает жаловаться на нехватку памяти, а еще через некоторое время кластер разваливается, и ноды продолжают погибать поодиночке. Мы подключили JVisualVM к hazelcast-у и увидели «восходящую пилу» – он регулярно вызывал GC, но никак не мог очистить память.

    image

    Оказалась, что в hazelcast 3.4 при удалении map / multiMap (map.destroy()) память освобождается не полностью:

    github.com/hazelcast/hazelcast/issues/6317
    github.com/hazelcast/hazelcast/issues/4888

    Сейчас ошибка исправлена в 3.5, но тогда это была проблема. Мы создавали новые multiMap с динамическими именами и удаляли по нашей логике. Код выглядел примерно так:

    public void join(Authentication auth, String sub) {
        MultiMap<UUID, Authentication> sessions = instance.getMultiMap(sub);
        sessions.put(auth.getUserId(), auth);
    }
    
    public void leave(Authentication auth, String sub) {
        MultiMap<UUID, Authentication> sessions = instance.getMultiMap(sub);
        sessions.remove(auth.getUserId(), auth);
    
        if (sessions.size() == 0) {
            sessions.destroy();
        }
    }

    Вызов:

    service.join(auth1, "НОВЫЕ_СООБЩЕНИЯ_В_ОБСУЖДЕНИИ_UUID1");
    service.join(auth2, "НОВЫЕ_СООБЩЕНИЯ_В_ОБСУЖДЕНИИ_UUID1");

    multiMap создавался для каждой подписки и удалялся, когда он был не нужен. Решили, что заведем Map<String,Set>, в качестве ключа будет название подписки, а в качестве значений идентификаторы сессий (по которым потом можно получить идентификаторы пользователей, если нужно).

    public void join(Authentication auth, String sub) {
        addValueToMap(sub, auth.getSessionId());
    }
    
    public void leave(Authentication auth, String sub) { 
        removeValueFromMap(sub, auth.getSessionId());
    }

    Графики выправились.

    image

    Что еще мы узнали о нагрузочном тестировании


    1. JSR223 нужно писать на groovy и включать compilation cache – это сильно быстрее. Ссылка.
    2. Графики Jmeter-Plugins проще понимать, чем стандартные. Ссылка.


    Про наш опыт с Hazelcast


    Hazelcast для нас был новым продуктом, мы начали работать с ним с версии 3.4.1, сейчас на нашем production сервере стоит версия 3.9.2 (на момент написания статьи последняя версия Hazelcast – 3.10).

    Генерация ID


    Мы начинали с целочисленных идентификаторов. Давайте представим, что нам нужен очередной Long для новой сущности. Sequence в БД не подходит, таблицы участвуют в шардинге – получится, что есть сообщение ID=1 в БД1 и сообщение ID=1 в БД2, в Elasticsearch по такому ID не положишь, в Hazelcast тоже, но самое страшное, если вы захотите свести данные с двух БД в одну (например, решив, что одной базы достаточно для этих абонентов). Можно завести в Hazelcast несколько AtomicLong и держать счетчик там, тогда производительность получения нового ID – incrementAndGet плюс время на запрос в Hazelcast. Но в Hazelcast есть кое-что более оптимальное – FlakeIdGenerator. Каждому клиенту при обращении выдается диапазон ID, например, первому – от 1 до 10 000, второму – от 10 001 до 20 000 и так далее. Теперь клиент может выдавать новые идентификаторы самостоятельно, пока не закончится выданный ему диапазон. Работает быстро, но при перезапуске приложения (и клиента Hazelcast) начинается новая последовательность – отсюда пропуски и т.д. К тому же разработчикам не очень понятно, почему ID целочисленные, но идут так сильно вразнобой. Мы все взвесили и перешли на UUID-ы.

    Кстати, для тех, кто хочет быть как Твиттер, есть такая библиотека Snowcast – это реализация Snowflake поверх Hazelcast. Посмотреть можно здесь:

    github.com/noctarius/snowcast
    github.com/twitter/snowflake

    Но у нас до нее уже руки не дошли.

    TransactionalMap.replace


    Еще один сюрприз: TransactionalMap.replace не работает. Вот такой тест:

    @Test
    public void replaceInMap_putsAndGetsInsideTransaction() {
    
        hazelcastInstance.executeTransaction(context -> {
            HazelcastTransactionContextHolder.setContext(context);
            try {
                context.getMap("map").put("key", "oldValue");
                context.getMap("map").replace("key", "oldValue", "newValue");
                
                String value = (String) context.getMap("map").get("key");
                assertEquals("newValue", value);
    
                return null;
            } finally {
                HazelcastTransactionContextHolder.clearContext();
            }        
        });
    }
    
    Expected : newValue
    Actual : oldValue

    Пришлось написать свой replace, использовав getForUpdate:

    protected <K,V> boolean replaceInMap(String mapName, K key, V oldValue, V newValue) {
        TransactionalTaskContext context = HazelcastTransactionContextHolder.getContext();
        if (context != null) {
            log.trace("[CACHE] Replacing value in a transactional map");
            TransactionalMap<K, V> map = context.getMap(mapName);
            V value = map.getForUpdate(key);
            if (oldValue.equals(value)) {
                map.put(key, newValue);
                return true;
            }
    
            return false;
        }
        log.trace("[CACHE] Replacing value in a not transactional map");
        IMap<K, V> map = hazelcastInstance.getMap(mapName);
        return map.replace(key, oldValue, newValue);
    }

    Тестируйте не только обычные структуры данных, но и их транзакционные версии. Бывает, что IMap работает, а TransactionalMap уже нет.

    Подложить новый JAR без даунтайма


    Сначала мы решили записывать в Hazelcast объекты своих классов. Например, у нас есть класс Application, мы хотим его сохранить и прочитать. Сохраняем:

    IMap<UUID, Application> map = hazelcastInstance.getMap("application");
    map.set(id, application);

    Читаем:

    IMap<UUID, Application> map = hazelcastInstance.getMap("application");
    return map.get(id);

    Все работает. Потом мы решили построить индекс в Hazelcast, чтобы искать по нему:

    map.addIndex("subscriberId", false);

    И при записи новой сущности начали получать ClassNotFoundException. Hazelcast пытался дополнить индекс, но ничего не знал про наш класс и хотел, чтобы ему подложили JAR с этим классом. Мы так и сделали, все заработало, но появилась новая проблема: как обновить JAR без полной остановки кластера? Hazelcast не подхватывает новый JAR при понодовом обновлении. В этот момент мы решили, что вполне можем жить без поиска по индексу. Ведь если использовать Hazelcast как хранилище типа ключ-значение, то все будет работать? Не совсем. Здесь снова разное поведение IMap и TransactionalMap. Там где IMap-у все равно, TransactionalMap кидает ошибку.

    IMap. Записываем 5000 объектов, считываем. Все ожидаемо.

    @Test
    void get5000() {
        IMap<UUID, Application> map = hazelcastInstance.getMap("application");
        UUID subscriberId = UUID.randomUUID();
    
        for (int i = 0; i < 5000; i++) {
            UUID id = UUID.randomUUID();
            String title = RandomStringUtils.random(5);
            Application application = new Application(id, title, subscriberId);
            
            map.set(id, application);
            Application retrieved = map.get(id);
            assertEquals(id, retrieved.getId());
        }
    }

    А в транзакции не работает, получаем ClassNotFoundException:

    @Test
    void get_transaction() {
        IMap<UUID, Application> map = hazelcastInstance.getMap("application_t");
        UUID subscriberId = UUID.randomUUID();
        UUID id = UUID.randomUUID();
    
        Application application = new Application(id, "qwer", subscriberId);
        map.set(id, application);
        
        Application retrievedOutside = map.get(id);
        assertEquals(id, retrievedOutside.getId());
    
        hazelcastInstance.executeTransaction(context -> {
            HazelcastTransactionContextHolder.setContext(context);
            try {
                TransactionalMap<UUID, Application> transactionalMap = context.getMap("application_t");
                Application retrievedInside = transactionalMap.get(id);
    
                assertEquals(id, retrievedInside.getId());
                return null;
            } finally {
                HazelcastTransactionContextHolder.clearContext();
            }
        });
    }

    В 3.8 появился механизм User Class Deployment. Вы можете назначить одну главную ноду и обновлять JAR-файл на ней.

    Сейчас мы полностью сменили подход: сами сериализуем в JSON и сохраняем в Hazelcast. Hazelcast-у не нужно знать структуру наших классов, а мы можем обновляться без даунтайма. Версионированием доменных объектов управляет приложение. Одновременно могут быть запущены разные версии приложения, и возможна ситуация, когда новое приложение пишет объекты с новыми полями, а старое еще про эти поля не знает. И в то же время новое приложение вычитывает объекты, записанные старым приложением, в которых нет новых полей. Такие ситуации обрабатываем внутри приложения, но для простоты не меняем и не удаляем поля, только расширяем классы путем добавления новых полей.

    Как мы обеспечиваем высокую производительность


    Четыре похода в Hazelcast – хорошо, два в БД – плохо


    Ходить за данными в кэш всегда лучше, чем в БД, но и хранить невостребованные записи не хочется. Решение о том, что кэшировать, мы откладываем на последний этап разработки. Когда новая функциональность закодирована, мы включаем в PostgreSQL логгирование всех запросов (log_min_duration_statement в 0) и запускаем нагрузочное тестирование минут на 20. По собранным логам утилиты типа pgFouine и pgBadger умеют строить аналитические отчеты. В отчетах мы в первую очередь ищем медленные и частые запросы. Для медленных запросов строим план выполнения (EXPLAIN) и оцениваем, можно ли такой запрос ускорить. Частые запросы по одним и тем же входным данным хорошо ложатся в кэш. Запросы стараемся держать «плоскими», по одной таблице в запросе.

    Эксплуатация


    СВ как онлайн-сервис была запущена в эксплуатацию весной 2017 года, как отдельный продукт СВ вышел в ноябре 2017 (на тот момент в статусе бета-версии).

    Более чем за год эксплуатации серьезных проблем в работе онлайн-сервиса СВ не случалось. Онлайн-сервис мониторим через Zabbix, собираем и деплоим из Bamboo.

    Дистрибутив сервера СВ поставляется в виде нативных пакетов: RPM, DEB, MSI. Плюс для Windows мы предоставляем единый инсталлятор в виде одного EXE, который устанавливает сервер, Hazelcast и Elasticsearch на одну машину. Сначала мы называли эту версию установки «демонстрационной», но сейчас стало понятно, что это самый популярный вариант развертывания.

    138,00

    Мы делаем средства разработки бизнес-приложений

    Поделиться публикацией

    Похожие публикации

    Комментарии 72
      0
      Посмотрите решение от Инстаграмм: rob.conery.io/2014/05/28/a-better-id-generator-for-postgresql

      Instagram ultimately decides that they don’t want to rely on app code to create the id, nor do they want to introduce complexity with a Snowflake-style system. Instead, they cracked open Postgres and created their own Function.
      A really neat idea! Sharding Postgres logically using schemas is a very interesting way to speed up reads and writes – but it obviously messes up id generation. This solution, however, seems pretty elegant!

      Что касается UUID, в самой 1С, насколько падает производительность для достижения уникальных UUID? Вы пробовали делать сравнения c другими решениями?
        0
        Спасибо! Интересное решение — а вы такой подход где-то пробовали уже?
        Сравнение не делали, к сожалению. Решили, что когда на нагрузочном тестировании увидим, что упираемся именно в генерацию ID, тогда и вернемся к вопросу.
        0
        Простите, но я так и не понял зачем вы все это делали. Зачем нужна система обмена сообщениями в 1С?
          0
          Про это есть в начале статьи. Видимо, не вполне ясно сформулировали. Попробуем еще раз:
          • Дать разработчикам прикладных решений надежный механизм обмена сообщениями между различными инсталляциями продуктов 1С
          • Дать конечным пользователям 1С мессенджер внутри рабочего места
            0
            Взаимодействие сервера 1с с клиентом 1с (речь про управляемые формы) похоже на взаимодействие браузера с веб-сервером эпохи веб 1.0. Система взаимодействия — это что-то типа WebSocket, только прикрученное сбоку и неудобное в использовании.
              +2
              Как и «ОписаниеОповещения» вместо замыканий))
                +1

                Ага. Оповещения это ад. Может bsl-движок в опенсорс отдать? Я прям подпишусь переделать Оповещения. Так жить нельзя (

            0
            А можно насчет вот этого поподробнее?
            Дать разработчикам прикладных решений надежный механизм обмена сообщениями между различными инсталляциями продуктов 1С

            На ИТС есть инструкция только лишь насчет обмена сообщениями между пользователями.
            Почему вы не хотите просто реализовать веб-сокеты в платформе? И разработчикам было бы легче, и вам не нужно было бы изобретать очередной велосипед.
              0
              Почему вы не хотите просто реализовать веб-сокеты в платформе?

              Да, можно было сделать и так.
              Но мессенджер внутри приложений 1С все же нужен (в частности, из-за возможности контекстного обсуждения конкретных объектов в 1С — документов и т.п.). А делать отдельно реализацию веб-сокетов и мессенджера — накладно. Плюс единая реализация позволяет, например, интерактивно взаимодействовать коду с пользователем внутри мессенджера — в частности, писать чат-ботов, интерактивно взаимодействующих с пользователем:
              image
                +3

                Ну я бы очень поспорил насчёт необходимости мессенджера внутри платформы(за годы как-то даже ни разу не приходила в голову такая идея), но не буду. А вот вебсокеты могли бы закрыть огромный пласт задач по интеграции, которые постоянно приходится решать. Дайте нам то, что есть у всех — а потом уже играйтесь со своими джавами и питонами:)

                  0
                  Так как 1С всегда целится на низкий порог вхождения, вполне понятны причины создания этого продукта.
                  Что касается интеграции есть же NativeAPI.
                    +1

                    Низкий уровень вхождения и знания C++, необходимые для написание внешних компонент на NativeAPI, как-то не очень сочетаются)))

                      0
                      NativeAPI для нестандартных выходящих за рамки задач, вполне себе решение, мы сами нанимали фрилансера C++ для таких задач, не имеет отношения к порогу вхождения.
                        0

                        C++/CLI очень легко позволяет сделать компоненту-розетку, в которую дальше втыкается весь мир .net
                        А уж vb.net — это тот же 1С, только на английском. Обучить 1Сника запросто. Единственное, C++/CLI не кроссплатформенный

                    0
                    Доступность websocket на клиенте позволила бы закрыть целый ряд интеграционных задач с внешними сервисами, которые уже реализуют websocket. Например: Slack, IP телефония, собственный сайт не на 1с.
                      0
                      Доступность websocket на клиенте и так есть. Поле HTML Вам в помощь:)
                      Для особо продвинутых, правда, только на платформе MS Windows на сервере есть ОболочкаHTMLДокумента.ПолучитьCOMОбъект(). А далее уже, вопрос фантазии.

                        0
                        Это понятно. Сами так используем, но хотелось бы нативный объект. Тем более что он уже реализован, но работает только с собственным сервером(СВ)
                  0
                  А можно ли отправить сообщение в систему взаимодействия из стороннего приложения, не 1с?
                    0
                    Делаете в прикладном решении http/web сервис, который посылает ваше сообщение в систему взаимодействия.
                      0
                      Сейчас единственный способ аутентификации в системе — это через 1С. Сервер 1С: Предприятия проверяет права пользователя клиента 1С и выдает ему подписанный токен для входа, который клиент передает в систему взаимодействия.

                      Задача уже в работе, так что скоро будет можно. Это будет новый способ аутентификации и/или вебхуки. Мы собираем сценарии, так что если поделитесь своим (здесь в комментариях или мне в личные сообщения), то мы убедимся, что новый функционал подойдет для решения вашей задачи.
                        0
                        А во тут поподробнее… т.е. on-primise СВ подключается к конкретной инфобазе 1С и обслуживается пользователей этой инфобазы? Можно зацепить несколько инфобаз? С разных серверов приложений?
                        PS
                        Почитал мануал на ИТС — за что вы так админов ненавидите все-таки?
                          0
                          Что читали и, если можно, в чем суть недовольства?
                          Только, если можно, конструктивно — чего не хватает и т.д.
                            0
                            Вот это все. its.1c.ru/db/cs20#bookmark:cs:TI000000001
                            Претензии не к документации как таковой, а к тому что можно было сделать нормальный инсталлятор под Linux. Если уж душит жаба готовую виртуалку отдавать…
                              0
                              Понятно
                                0
                                Впрочем насчет документации как раз вчера RegionSoft «На CRM наговаривают лишнего: разбираемся со сплетнями» опубликовал. Там 1совская документация отлично описана… Начиная со слов «Поехать в село Сухобезводное, зайти в сосновый бор,..."
                                  0
                                  1С-ская документация — это ОЧЕНЬ обширная тема. По платформенной могу как-то комментировать и что-то говорить, по другим продуктам — увы.
                                  Но, в общем и целом, мест и путей совершенствования документации — вагон и маленькая тележка. Тут никто [особо] не спорит.
                              0
                              А меня больше волнует вопрос: почему пользователей ИТС так ненавидите? В интернете полно ссылок на ИТС-статьи (и сами представители 1С любят такие давать на партнерсе), но при попытке перейти на нее получаешь — «Доступ к данному материалу ограничен». Далее нужно менять домен с RU на UA и лишь после этого шаманства можно читать статью. Зачем? Ведь содержимое ИТС в технических разделах идентичное до последнего знака препинания. И сервер один и тот же, что позволяет авторизироваться на обоих порталах под одной учеткой.
                                0
                                Кстати, если бы я админил сервера 1С, то сделал бы автоматический форвардинг с RU на UA и EU — раз «на верху» приняли решение не пересекать национальные поддержки, но оставить единый сервер.
                              0
                              Несколько баз можно зацепить через механизм совместного использования приложений
                              downloads.v8.1c.ru/content//Platform/8_3_13_1472/1cv8upd_8_3_13_1472.htm#7ab36123-0fe7-11e8-a3f7-0050569f678a
                              its.1c.ru/db/v8313doc#bookmark:dev:TI000002046
                              its.1c.ru/db/v8313doc#bookmark:adm:TI000000755
                              (инфа по ссылкам доступна только для подписчиков ИТС, сорри)
                              Совместное использование, например, дает возможность написать пользователю другой базы. Это все в 8.3.13.
                              СВ подключается к конкретной инфобазе 1С и обслуживается пользователей этой инфобазы?

                              Скорее, инфобаза 1С подключается к СВ, разные базы с разных серверов приложений могут подключаться к одной СВ
                              для использования механизма совместного использования базы нужно подключать, используя один email (чтобы они были в одном абоненте).
                                0
                                «используя один email (чтобы они были в одном абоненте).» Вы сейчас про Fresh? Я про on-primise… У меня 3 базы, NTLM авторизация, каждый юзер «де-факто» имеет по пользователю в каждой базе… Я с этим в СВ взлечу?
                                  0
                                  Каждый юзер имеет по пользователю в каждой базе

                                  Возможно, тут понадобится включить «сопоставление пользователей» — это такой способ сказать Системе Взаимодействия, что это один и тот же пользователь в каждой ИБ; сопоставлять можно по имени, по полному имени и по ключу соответствия, который администратор ИБ может задавать сам для пользователей.
                                  В деталях все описано в документации, ссылки я приводил выше.
                                  Но даже если сопоставление не включить, то все будет работать, просто будет по три копии каждого пользователя.
                          +2
                          Обожаю статьи от PeterG :-) Каждый раз что-то новое и каждый раз впечатление что где-то в мире есть 2 разных фирмы 1С — в одной крутые продвинутые ребята, которые в курсе всех современных технологий разработки, а в другой какие-то… вредители.
                          Павел! Вы с 2015 года знаете про Elastic! Так какого… лешего мы до сих пор смотрим журнал регистраций и технологический журнал руками или через убогую встроенную в 1С клиента гляделку? Так тяжело сделать нативную нормальную выгрузку в «ёлку»? Чтобы админы не мучились с многочисленными костылями, Лустин не троллил «одинэсников» профнепригодностью из-за неумения срастить 1С и Elastic, а курс молодого бойца для программера не начинался с фразы «и не вздумай искать по журналу регистрации не поставив фильтр по датам — завалишь сервак»?
                          PS
                          Впрочем приличные люди вместо предложения «потренировать скиллы в установки 1С rpm'ов» давно бы готовые образы виртуалок под вмваре и гипер-в раздавали бы уже…
                            +1

                            Это можно продолжать до бесконечности. С одной стороны они поняли что конфигуратор никуда не годится, а с другой — начали перепиливать Эклипс!!! в надежде сделать из него новый конфигуратор. Эти же люди реализуют в 1С на уровне платформы систему расчета СЛАУ, но не могут сделать вебсокеты. Эти же люди придумывают "1С: Центр администрирования " на платформе 1С, но заставляют для него писать скрипты на Python. Все ну никак не складывается какого-то общего направления развития:)

                              0
                              Эти же люди придумывают «1С: Центр администрирования » на платформе 1С, но заставляют для него писать скрипты на Python. Все ну никак не складывается какого-то общего направления развития:)

                              Мне кажется разработчикам самим не нравится их платформа, поэтому они всё чаще обращаются к сторонним разработкам. Казалось бы, развивайте встроенный язык, создавайте экосистему. 1С как платформа — отличное решение для несложных систем учёта. Но язык 1С не только жутко ограничен в возможностях, но ещё и очень медленный.

                              Факт, что «вебсокеты» для 1с написаны на java исчерпывающе описывает отношение разработчиков к языку 1с, imho.
                                +1
                                Мне кажется разработчикам самим не нравится их платформа, поэтому они всё чаще обращаются к сторонним разработкам.

                                Давайте все же разделять понятия.
                                Платформа — это набор софта для разработки и функционирования бизнес-приложений. Грубо говоря — это:
                                • Инструменты разработки
                                  • Конфигуратор, написан на С++ или
                                  • EDT, написан на Java

                                • Среда выполнения (runtime)
                                  • Сервер приложений (С++)
                                  • Тонкий (исполняемый) клиент, С++
                                  • Веб-клиент (JavaScript)

                                • Прочее (например, инструменты администрирования, и, в том числе, Система Взаимодействия)

                                Бизнес-приложения пишутся на языке 1С, компоненты платформы – на тех средствах разработки, которые подходят для решения задач наилучшим образом.
                                1С как платформа — отличное решение для несложных систем учёта.

                                А еще, например, для написания ERP, успешно конкурирующей с другими лидерами рынка:
                                image
                                Ну и вообще.
                                Факт, что «вебсокеты» для 1с написаны на java исчерпывающе описывает отношение разработчиков к языку 1с, imho.

                                Ваше утверждение звучит примерно как «Факт, что НТТР-сервисы реализованы в платформе на C++, исчерпывающе описывает отношение разработчиков к языку 1С».
                                Повторюсь, бизнес-приложения пишутся на языке 1С, сама платформа (которая предоставляет те или иные возможности для разработки бизнес-приложений на языке 1С) – на тех средствах разработки, которые подходят для решения задач наилучшим образом.
                                Язык разработки 1С не предназначен для решения низкоуровневых задач типа реализации сокетов. Он предназначен для решения бизнес-задач. Платформа реализовала Систему Взаимодействия на тех средствах, которые подошли, с нашей точки зрения, лучше всего (Java, Hazelcast, Elasticsearch, Postgres) и сделала ее доступной в среде разработки 1С (объект СистемаВзаимодействия и т.д.)
                                  –1
                                  Но веб-сервисы и http-сервисы — часть платформы, несмотря на то, что их удобнее было реализовать на PHP и JS. С тем же успехом можно утверждать, что для решения таких низкоуровневых задач язык 1С не предназначен.

                                  Я могу написать сайт на 1С. Не знаю, насколько это полезно, но несколько лет назад у меня не было такой возможности.

                                  Я расстроен от того, что вместо развития языка и платформы представлена «надстройка», которую, в принципе, можно было сделать и внешней компонентой. СВ — это же первый «компонент системы», требующий отдельную СУБД?
                                    0
                                    Но веб-сервисы и http-сервисы — часть платформы

                                    СВ — тоже часть платформы (только опциональная), объектная модель СВ доступна в языке 1С.

                                    Я расстроен от того, что вместо развития языка и платформы представлена «надстройка», которую, в принципе, можно было сделать и внешней компонентой.

                                    Не расстраивайтесь :)
                                    Веб-сервисы и http-сервисы тоже при желании можно, наверное, сделать внешней компонентой. И что?

                                    СВ — это же первый «компонент системы», требующий отдельную СУБД?

                                    Насколько помню — да.
                                    Отдельная БД для СВ нужна, в частности, потому что:
                                    • При интенсивном обмене сообщениями размер СУБД и нагрузка на нее скажется на быстродействии инфобазы
                                    • Есть возможность обмена сообщениями между разными инфобазами, поэтому целесообразнее хранить сообщения в отдельной СУБД, а не делить их между инфобазами (а также не хранить полные копии всех сообщений в каждой инфобазе)
                                      0
                                      Трудно не расстраиваться когда успел попробовать вкусностей из других фреймворков и языков.)
                                        0
                                        вкусностей из других фреймворков и языков

                                        «Если бы губы Никанора Ивановича да приставить к носу Ивана Кузьмича, да взять сколько-нибудь развязности, какая у Балтазара Балтазарыча» (ц) Гоголь

                                        Ну а если серьезно — да, в других языках и фреймворках есть немало хорошего, что, возможно, пригодилось бы в разработке приложений на 1С. У нас длинный список кандидатов на реализацию. Реализуем потихоньку, вот до СВ добрались.
                                          0
                                          Интересно, в этом списке есть вещи вроде тайп хинтинга или чего то подобного, замыканий, работы с коллекциями в стиле Коллекция.ДляКаждого(Функция).Где(Функция2) и т.п. улучшений языка?
                                          Действительно интересно, без сарказма. Заодно замыкания бы позволили структурам поведение добавлять, чего бывает не хватает.
                                            0
                                            Если очень уж интересно, откликайтесь на заявки хендхантеров из 1С, изучите бэклог, увольтесь по результатам испытательного срока — минимум действий, а получите инсайды настолько секретные, что их запрещено разглашать на ежегодных встречах в Космосе (содержимое которых тоже запрещено разглашать)
                                              0
                                              Хех, даже если бы я захотел так сделать — из Брянска это было бы сложновато провернуть))
                                                0
                                                Было бы желание. Мой друг вообще из Киева (Украина) приехал к друзьям в Москву на месяц; чисто в качестве проверки своих сил попробовал пройти собеседование в 1С и остался у них работать на несколько лет на разработке типовых. А вам из Подмосковья сложно выехать :)
                                            0
                                            А вы не хотели бы поделиться этим списком с остальными разработчиками, чтобы они помогли вам расставить приоритеты? ))
                                            Мне кажется, мнение разработчиков, которым остро необходимы те или иные инструменты в системе 1С помогло бы вам улучшить систему, и удовлетворенность системой.
                                          0
                                          Насколько помню — да.

                                          А как же журнал регистрации на SQLite?
                                            0

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

                                              0
                                              Только он не работает, и в последних платформах снова по умолчанию старый формат.
                                          0
                                          Павел, ну мы же тут не дети и понимает что главное конкурентное преимущество 1С при внедрение ERP это цена. По нынешнем временам на SAP деньги остались только у Роснефти :-). А второе — это конечно огромное коммьюнити (то бишь программеров). С котором кроме лично вас (за что вам отдельное спасибо) в компании 1С никто не работает.
                                          PS
                                          Так когда нам ждать сервер консолидации журналов регистрации на Эластике?
                                            +1
                                            видимо пока никто в открытый доступ не выложит свои наработки ( да хотя бы конфиг для filebeat) не будет движения.
                                              0
                                              а когда выложат, то от платформы этого требоваться не будет :-)
                                                0
                                                Ну не факт… Все-таки встроенные решения обычно проще поднять. Сейчас связку 1С — «Ёлка» у меня пытаются поднять админ + sql dev + два «одинэсника». А так может силами одного «одинэсника» можно будет обойтись. Если 1С сподобится нормальные инсталляторы делать или виртуалки станет раздавать.
                                              0
                                              Павел

                                              Меня зовут Петр :)
                                              главное конкурентное преимущество 1С при внедрение ERP это цена.

                                              Низкая по сравнению с конкурентами цена — лишь один из факторов (цена, кстати, низкая во многом из-за удачного выбора модели разработки, позволяющего создавать решения на платформе 1С на порядок быстрее, чем на конкурирующих платформах). Ну и не будем забывать, что если бы функциональность продукта была ощутимо беднее, чем у конкурентов — выбрали бы конкурентов.
                                              А второе — это конечно огромное коммьюнити (то бишь программеров).

                                              Ну вот оно огромное в частности из-за удачной модели разработки.
                                              С котором кроме лично вас (за что вам отдельное спасибо) в компании 1С никто не работает.

                                              Всегда пожалуйста :)
                                              Жаль, конечно, что складывается впечатление, будто я один работаю с коммьюнити. Будем исправляться.
                                              Так когда нам ждать сервер консолидации журналов регистрации на Эластике?

                                              Пока не готов ответить, к сожалению.
                                                0
                                                Прошу прощения, Петр. Насчет «исправления» это все-таки не к вам, а к БГН. Мы же знаем кто реальные решения по этому вопросу в 1С принимает.
                                        0
                                        >Вы с 2015 года знаете про Elastic! Так какого… лешего мы до сих пор смотрим журнал регистраций и технологический журнал руками или через убогую встроенную в 1С клиента гляделку

                                        Нуралиев год назад на открытом воскресенье говорил, что пока рассматривать какое-то более серьезное хранилище под чем текстовые файлы под ЖР не хотят. Не забывайте, что у 1С существенная доля пользователей до сих пор работают с базами в файловом режиме и им этот хайтек ни разу не нужен.
                                        0

                                        Подскажите, реализована ли уже система взаимодействия на мобильной платформе? Если нет, то когда планируется?

                                        0
                                        Каждый раз читаю такие статьи и каждый раз думаю (по другим комментариям видно что не только я) — тут такие клевые технологии используют, но при этом не могут сделать такой элементарщины как логи в скуль, нормальные web-socket, работу с гит нативную… У меня реально ощущение что люди живут в другой вселенной :((((( а самое обидное что об этом просят уже годы, и такое ощущение что к сообществу относяться как к отбросам — хотите? Хрен когда получите…

                                        И я уже молчу про отладку, мониторинг и прочее… Зато мы сделали чатик внутри 1С!!! Это киллекфича!!!

                                        P.S.
                                        Не рассказывайте мне пожалуйста что логи в скуль это нереально. В sqllite сделали же, почему нельзя просто дать возможность выбора куда писать.
                                          0
                                          > У меня реально ощущение что люди живут в другой вселенной

                                          1С действительно живут в другой, существенно более приближенной «к земле» вселенной. В которой большом количестве офисов попросту нет sql серверов. Да и серверов как таковых тоже, а в качестве сервера используется одна из рабочих станций (бухгалтера, например).

                                          >sqllite сделали же

                                          Сделали, да не взошло, так что теперь назад делают (см. downloads.v8.1c.ru/content//Platform/8_3_13_1198/1cv8upd_8_3_13_1198.htm#b398b60e-9891-11e7-a3f7-0050569f678a)
                                            0
                                            >1С действительно живут в другой, существенно более приближенной «к земле» вселенной. В которой большом количестве офисов попросту нет sql серверов. Да и серверов как таковых тоже, а в качестве сервера используется одна из рабочих станций (бухгалтера, например).

                                            нет, все-таки другая вселенная. Для описанных вами компаний сейчас очень активно развиваются облачные сервисы, которые гораздо более выгодные. А там, где покрупнее уже и скуль есть, и отдельная машина под 1С
                                              0
                                              Кажется вы переоцениваете степень доверчивости наших коммерсов. Свои сокровенные (и не всегда отражающие юридическую реальность, скажем так) данные в облако? И ни в какое-нить импортное, а в наше, родное, с доступом т-ща майора/налоговика/пожарника. Серьезно?

                                              Оф. бухгалтерию в облако еще куда ни шло, но опер/упр. учёт? Серьезно? :)

                                              Страшно далеки вы от народа
                                          0
                                          Касаемо логов в скуль, наверное слишком все сложно, но вот писать их в обычный текстовый файл (без развеселых скобочек) и выдать описание полей (хотя уже умельцы разобрались) можно было бы.

                                          Но тогда любой несертифицированный специалист сможет эти логи хоть куда отправлять. А это может повлиять на всю экосистему 1С.
                                            0
                                            да, согласен, исчезнут сотни «интеграторов» которые на этой закрытости делают кучу бабла. Я вот тут с коллегами инженерами 3 недели сидел, пока мы прикрутили мониторинг сессий и блокировок из 1С в заббикс. Работает по итогу очень даже неплохо, но для того, чтобы понять как это сделать я год по крупицам собирал инфу. То там обрывок, то тут кусочек… Почему блин нельзя это отдавать по какому-нибудь урлу в виде json? или xml?
                                            Но я все-таки надеюсь что коллеги прислушаются к обществу и заведут у себя голосовалку за фичи как МС. И начнут их делать.
                                            А то эта статья, как я уже и говорил, кажется каким-то плевком в лицо сообщества… =(
                                              0
                                              а планируете выложить эту систему в общий доступ?
                                                0
                                                Да, надо все-таки сесть и дописать статью как мы все это делали
                                                0
                                                так там же есть интерфейс на java и из утилиты командной строки. причем документация из командной строки по ключу /help вполне адекватная
                                                  0
                                                  Там же — это где? Можно линки?
                                                    0
                                                    https://its.1c.ru/db/v8312doc#bookmark:cs:TI000000189 — спец приблуда для администрирования кластера из командной строки, ставится как сервис параллельно с сервером 1с + её консольный клиент
                                                    its.1c.ru/db/metod8dev/content/4985/hdoc — интерфейс на java для этой приблуды
                                                      0
                                                      Ну так то 8.3.12. Далеко не у всех он есть. У многих еще 8.1
                                                        0
                                                        Ну вообще это работает и в 8.3.8 (а может и раньше). В любом случае режим совместимости у 1с достаточно хорошо работает и можно запускать старые конфигурации на новых платформах.
                                                  0
                                                  > исчезнут сотни «интеграторов»

                                                  У вас причинное-следственная связь нарушена :)
                                                  Эта куча интеграторов — одна из основ бизнеса 1С. Без них бизнес-модель 1Са не будет работать.

                                                  > которые на этой закрытости делают кучу бабла

                                                  Деньги партнеры делают на лицензиях/программировании/консалтинге. О какой закрытости речь? Любой желающий может купить, например, технологическую поставку (https://rarus.ru/1c8/1c-predpriyatie-8-3-tehnologicheskaya-postavka/) для освоения и даже коммерческого использования платформы.

                                                  Примерно такой же подход у эппл (https://en.wikipedia.org/wiki/Mac_Developer_Program).
                                                0
                                                В личке aavolkov задал ряд инетресных вопросов, переношу сюда вместе с ответами.

                                                ВОПРОС: Первый вопрос (архитектурный): почему не очередь сообщений типа RabbitMQ? Там же адресная доставка, масштабируемость, нагрузки и прочее реализованы из коробки. Нужно всего-лишь прикрутить «воркер» к платформе и всё будет работать, да и на «плюсах» эти воркеры, конечно, есть. К тому-же RabbitMQ запилен на Erlang-е, который очень бережно относится к потокам (тредам) и прочему (типа распределения нагрузки, мониторинга состояния процессов), чего нельзя сказать о том-же самом в Java (без методичной настройки снаружи и педантичного многопоточного ковыряния внутри).

                                                RabbitMQ прекрасен, и мы много его используем в других проектах. Если бы мы делали отдельно чат и отдельно механизм publish-subscribe, второй совершенно точно делали бы через rabbitMQ (и AMQP в платформе). Но нужен был чат и транспорт два в одном. Для чата в качестве клиента помимо 1С: Предприятия ожидался сайт и standalone-приложение, так что вебсокет показался удобнее. А вебсокет в rabbitmq на тот момент (2014-2015 год) то ли не вызвал большого доверия, то ли не существовал. Возможен еще один вариант — не влез в osgi. Иногда даже у библиотек с заявленной поддержкой osgi по факту она реализована плохо и требует допиливания. Может быть, мы вообще забыли включить его в сравнение, потому что он был не очень на слуху. Не хочу вас обманывать, про тогда не скажу, сейчас обязательно рассмотрели бы такой вариант. Может, еще и рассмотрим в будущем.

                                                ВОПРОС: Если есть ElasticSearch, то почему нет возможности выбрать сообщения поиском из встроенного языка платформы (8.3.12 и 3.0.6)?

                                                Мы индексируем сообщения в ES, но пока не успели поддержать поиск сообщений/наименований_форм на уровне встроенного языка.

                                                ВОПРОС: Почему при создании обсуждения с единственным участником «все пользователи» и отсылки в это обсуждение сообщения — в БД СВ (postresql) сообщения регистрируются к доставке «всем» и «каждому пользователю» в отдельности (я сужу по таблице «unread_conversation»)? Я конечно, понимаю, что нужно удалять прочитанные «уведомления» для каждого конкретного пользователя, но может инфу о том, что конкретный пользователь прочёл сообщение хранить в самой БД 1С с возможностью управления этим параметром (типа, пометить сообщения с такой-то даты непрочтёнными или прочтёнными, как в почте)?

                                                Думаю, тут опять же вопрос других клиентов — в 1С вы, конечно, можете хранить, но что делать остальным клиентам? Про unread_conversation вы совершенно верно заметили, это для того, чтобы снимать непрочитанность для каждого пользователя в отдельности. Также у нас есть место, где хранится ID и дата последнего прочитанного сообщения — таблица conversation_user (last_read_message_at, last_read_message_id). Но да, это снова на сервере.

                                                ВОПРОС: (он вытек из третьего, когда я копал): Как удалить пользователя из СВ, который был физически удалён из базы данных 1С (напомню, 8.3.12 и 3.0.6), т.е. пользователь, при удалении из БД 1С, автоматом не удаляется из БД СВ и нет какой-то функции, которую бы можно было вызвать из языка платформы.

                                                Сейчас никак, но мы сами редко на уровне ИБ и удаляем пользователей по-настоящему. Обычно прибавляем к нему «ув.» и оставляем в таком виде. Так повелось задолго до системы взаимодействия, так что у нас проблема так остро не стоит. Но, наверное, дать такую возможность было бы неплохо, согласен с вами.

                                                ВОПРОС: я не могу понять — если сообщение обсуждения создавать во вкладке «Обсуждения», то адресат, пока не прочитает эти сообщения, будет каждый раз получать их при входе в «1С» (в виде уведомлений внизу экрана).
                                                Если же неконтекстное сообщение создать (послать) и прочитать программно (обсуждение с признаком «Отображение = ложь», чтобы их визуально не отображать, конечно), то факт получения сообщения обработчиком новых сообщений уже считает сообщение прочтённым, хотя по бизнесу — оно может требовать реакции пользователя и, пока пользователь не отреагировал (даже между сеансами) — сообщение должно быть непрочтённым. То есть, правильно ли я понял, что управления прочтённостьюсообщений в языке платформы нет?

                                                Я не совсем понял этот сценарий, вы написали

                                                сообщение создать (послать) и прочитать программно

                                                Так вы его прочитали или нет?
                                                Смотрите, модель такая: оповещения приходят тем, кто онлайн.
                                                Если пользователь оффлайн, то при старте он запросит обновления по таблице unread_conversation (это не оповещения — попадают ли они тут в обработчик я не подскажу). Для чтения есть параметр visible, если клиент передает его равным true, то из unread_conversation приедут только видимые обсуждения. Что из этого выведено в язык тоже, к сожалению, подсказать не могу (но могут на v8).

                                                aavolkov — спасибо за хорошие сложные вдумчивые вопросы!
                                                  0
                                                  Продолжаем отвечать на вопросы aavolkov.

                                                  Основная идея теперь понятна — сервер взаимодействия разрабатывается, как некая готовая архитектура коммуникации для различных платформ, что, конечно, предполагает открытый API. В виду его закрытости и достаточно плотной интеграции с некоторыми объектами платформы 1С, я грешным делом, подумал, что эта история будет работать только из 1С-ных решений (конкретная ЦА, если угодно). Значит, ждём открытого API?)

                                                  По срокам сказать не смогу, но такая цель перед нами ставилась с самого начала, так что это должно случиться.

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

                                                  Если я правильно понял сценарий, то мы на сервере это не делаем (обсуждение не пропадет из таблицы unread, пока пользователь/код не вызовут setLastReadMessageId). Возможно, это уже при вызове из языка делается. Надо у команды тонкого клиента спросить.

                                                  Если же я программно (кодом в 1С) создам техническое/неконтекстное сообщение на источнике (например, уведомление о критическом изменении курса валютной пары, которое пользователь-приемник должен увидеть в отдельной форме с графиками и прочей аналитикой, эту форму пользователь должен открыть нажатием кнопки на начальной странице (логично, что это кнопка должна «покраснеть»)), то на приемнике:
                                                  Я программно (кодом) подписываюсь на событие нового сообщения нужного обсуждения/канала(«conversation»), получаю новое сообщение, когда нахожусь в онлайн, и делаю такие вещи, как: программное открытие уведомления внизу экрана, окрашивание кнопки открытия формы, проигрывание сигнала тревоги и т.п. прекрасные штуки. Но, если пользователь-приемник не проявил никакой реакциии и закрыл сеанс 1С, то, при следующем открытии сеанса 1С — приемник НЕ получуит это сообщение снова (в отличие от сценария доставки видимого сообщения на вкладке «Обсуждения»). Это произойдет потому, что строка доставки сообщения для пользователя удаляется из таблицы «unreaded» сразу в тот момент, когда отрабатывает подписка на получение новых сообщений.
                                                  Таким образом, возникает 2 различных поведения сервера взаимодействия по удалению признака необходимости оповещения приемника в зависимости от контекста процессинга сообщения. Иными словами появляется такой «условный» признак, как «прочтённость». И мне, например, бы очень хотелось этим признаком управлять в зависимости от того — завершён ли бизнес-процесс коммуникации (в моём примере — нажатие на красную кнопку) или нет.

                                                  И ещё один вопрос возник: проводились ли какие-либо синтетические тесты нагрузки СВ, т.е. где отправителем и приемником является некий «шустрый» многопоточный сервис (не 1С, видимо), чтобы протестировать скорость процессинга сообщений (например, количество полученных/доставленных сообщений в секунду в зависимости от количества источников/получателей). Ну, например, для http обычно проводят такие базовые тесты утилитой ab.

                                                  В таком виде не проводились, но идея хорошая, спасибо! Мы делаем нагрузочное тестирование, но с упором на интерактивные сценарии. Также стараемся мониторить отзывчивость системы в production и оперативно что-то доделывать, когда видим появление узких мест. Но самому интересно провести такой тест.

                                                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                Самое читаемое