Платформа «1С: Предприятие» — что под капотом?

от автора

Привет, Хабр!
В этой статье мы начнем рассказ о том, как устроена внутри платформа «1С:Предприятие 8» и какие технологии используются при ее разработке.
image
Почему мы считаем, что это интересно? Во-первых, потому что платформа «1С:Предприятие 8» — это большое (более 10 миллионов строк кода) приложение на C++ (клиент, сервер и т.д.), JavaScript (веб-клиент), и, с недавних пор еще и Java. Большие проекты бывают интересны хотя бы в силу масштаба, ведь вопросы, незаметные в маленькой кодовой базе, в таких проектах встают в полный рост. Во-вторых, «1С:Предприятие» — это тиражируемый, «коробочный» продукт, а статей про такие разработки на Хабре совсем немного. А еще всегда интересно узнать, как там живут в других командах и фирмах 🙂

Итак, приступим. В этой статье мы дадим обзор некоторых технологий, которые применяются в Платформе, обрисуем ландшафт, без глубокого погружения в реализацию. Ведь для многих механизмов подробный рассказ потянет на отдельную статью, а для некоторых — на целую книгу!
Для начала стоит определиться с базовыми вещами — что такое платформа «1С:Предприятие» и из каких компонентов она состоит. Ответ на этот вопрос не так прост, ведь под термином «Платформа» (для краткости будем называть ее именно так) понимают и средство разработки бизнес-приложений, и среду исполнения, и средства администрирования. Условно можно выделить следующие составляющие:

  • кластер серверов
  • «тонкий» клиент, способный подключаться к серверу по http и собственному бинарному протоколу
  • клиент для работы в двухзвенной архитектуре с БД, размещенной на жестком диске или сетевой папке
  • веб-клиент
  • средства администрирование сервера приложений
  • среда разработки (известная как Конфигуратор)
  • среда исполнения для iOS, Android и Windows Phone (мобильная платформа 1С)

Все эти части, за исключением веб-клиента, написаны на C++. Кроме того, существует недавно анонсированный Конфигуратор нового поколения, написанный на Java.

Нативные приложения

Для разработки нативных приложений используется C++03. Под Windows в качестве компилятора используется Microsoft Visual C++ 12 (профиль совместимый с Windows XP), а под Linux и Android — gcc 4.8, для iOS — clang 5.0. Стандартная библиотека используется единая для всех ОС и компиляторов — STLPort. Это решение позволяет снизить вероятность ошибок, специфичных для реализации STL. Сейчас мы планируем переход на реализацию STL, поставляемую с CLang, так как STLPort прекратил свое развитие и несовместим с включенным режимом поддержки C++ 11 в gcc.
Кодовая база сервера при этом общая на 99%, клиента — процентов на 95%. Более того, даже мобильная платформа использует тот же C++ код, что и «большая», хотя там процент унификации несколько ниже.
Как большинство пользователей С++ мы не претендуем на использование 100% возможностей языка и его библиотек. Так, у нас практически не используется Boost, а из возможностей языка — динамическое приведение типов. При этом мы активно применяем:

  • STL (в частности, строки, контейнеры и алгоритмы)
  • множественное наследование, в т.ч. множественное наследование реализации
  • шаблоны
  • исключения
  • умные указатели (собственная реализация)

За счет использования множественного наследования интерфейсов (полностью абстрактных классов) становится возможной компонентная модель, речь о которой пойдет ниже.

Компоненты

Для обеспечения модульности весь функционал разделен на компоненты, представляющие из себя динамические библиотеки (*.dll под Window, *.so — под Linux). Всего компонентов более полутора сотен, приведем описания некоторых их них:

backend Содержит «движок» метаданных платформы
accnt Объекты, которые прикладные разработчики используют для построения бухгалтерского учета (планы счетов и регистры бухгалтерии)
bsl Движок исполнения встроенного языка
nuke Собственная реализация аллокатора памяти
dbeng8 Движок файловой базы. Простая файл-серверная машина баз данных, основанная на ISAM, включающая также простой SQL-процессор
wbase Содержит базовые классы и функции для реализации пользовательского интерфейса Windows — оконные классы, доступ к GDI и т. п.

Разделение на множество компонент полезно с нескольких точек зрения:

  • Разделение способствует лучшему проектированию, в частности лучшей изоляции кода
  • Из набора компонентов можно гибко собирать разные варианты поставки:
    • Например, инсталляция тонкого клиента будет содержать wbase, но не будет backend
    • а на сервере wbase, наоборот, не будет
    • оба варианта будут, конечно, содержать nuke и bsl

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

SCOM

Для декомпозиции на более низком уровне используется система SCOM — схожая по идеологии с ATL библиотека. Для тех, кто с ATL не работал, кратко перечислю основные возможности и особенности.
Для специально оформленного класса SCOM:

  • Предоставляет фабричные методы, позволяющие создать класс из другой компоненты, зная только его название (без раскрытия реализации)
  • Предоставляет инфраструктуру умных указателей с подсчетом ссылок. За временем жизни SCOM-класса не нужно следить вручную
  • Позволяет узнать, реализует ли объект конкретный интерфейс, и автоматически привести указатель на объект к указателю на интерфейс
  • Создать объект-сервис, всегда доступный через метод get_service и т.д.

Например, можно описать в компоненте json.dll вот такой класс для чтения JSON:

////////////////////////////////////////////////////////////////////////////// // JSONStreamReader - Класс для чтения данных JSON class ATL_NO_VTABLE JSONStreamReader :     public SCOM_ObjectRoot,     public SCOM_Class<JSONStreamReader, &SCOM_CLSIDOF(JSONStreamReader)>,     public IJSONStreamReader { public:     BEGIN_COM_MAP( JSONStreamReader)         COM_INTERFACE_ENTRY(IJSONReader)         COM_INTERFACE_ENTRY(IJSONStreamReader)     END_COM_MAP() ... члены класса ...         } 

Классы, экземпляры которых можно создавать из других компонент, нужно зарегистрировать в SCOM-машине:

SCOM_CLASS_ENTRY(JSONStreamReader) 

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

IJSONStreamReaderPtr jsonReader = create_instance<IJSONStreamReader >(SCOM_CLSIDOF (JSONStreamReader )); 

На основе компонентной модели SCOM реализована и бизнес-логика, и интерфейсная часть «1С:Предприятия».

Пользовательский интерфейс

Кстати, об интерфейсах. Мы не используем стандартные контролы Windows, наши элементы управления реализованы напрямую на Windows API. Для Linux-версии сделана прослойка, работающая через библиотеку WxWidgets.
Библиотека элементов управления не зависит от других частей «1С:Предприятия» и используется нами еще в нескольких небольших внутренних утилитах.

За годы развития 1С:Предприятие внешний вид контролов менялся, но серьезное изменение принципов произошло только один раз, в 2009 году, с выходом версии 8.2 и появлением «управляемых форм». Помимо изменения внешнего вида, фундаментально изменился принцип компоновки формы — произошел отказ от попиксельного позиционирования элементов в пользу flow-компоновки элементов. Кроме того, в новой модели элементы управления работают не напрямую с доменными объектами, а со специальными DTO (Data Transfer Objects).
Эти изменения позволили создать веб-клиент «1С:Предприятия», повторяющий С++ логику контролов на JavaScript. Мы стараемся поддерживать функциональную эквивалентность между тонким и веб клиентами. В том случае, когда это невозможно, например, из-за ограничений доступных из JavaScript API (например, возможности работы с файлами очень ограничены), мы часто реализуем нужную функциональность при помощи расширений браузеров, написанных на C++. На данный момент мы поддерживаем Internet Explorer (только Windows), Google Chrome и Firefox (Windows и Linux) и Safari (MacOS).

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

image
Интерфейс 1С на ОС Linux

image
Интерфейс 1С на мобильном устройстве

Интерфейс 1С на других платформах

image
Интерфейс 1С на ОС Windows

image
Интерфейс 1С — веб-клиент

Open source

Хотя мы и не используем стандартные для С++ разработчика библиотеки под Windows (MFC, контролы из WinAPI), не все компоненты мы пишем сами. Уже упоминалась библиотека wxWidgets, а еще мы используем:

  • cURL для работы с HTTP и FTP.
  • OpenSSL для работы с криптографией и установки TLS соединений
  • libxml2 и libxslt для разбора XML
  • libetpan для работы с почтовыми протоколами (POP3, SMTP, IMAP)
  • mimetic для разбора сообщений электронной почты
  • sqllite для хранения журналов работы пользователей
  • ICU для интернационализации

Список еще можно продолжать.
Кроме того, мы используем сильно модифицированную версии Google Test и Google Mock при разработке юнит-тестов.
Библиотеки потребовали адаптации для совместимости со SCOM-моделью организации компонент.
Распространенность 1С делает Платформу отличной проверкой на прочность для используемых в ней библиотек. Разнообразие пользователей и сценариев быстро обнаруживает ошибки даже в самых редкоиспользуемых участах кода. Мы исправляем их у себя и стараемся отдавать обратно авторам библиотек. Опыт взаимодействия оказывается очень разный.
Разработчики cURL и libetpan быстро откликаются на pull-request, но патч, например, в OpenSSL нам так и не получилось отдать.

Заключение

Как реализована мобильная платформа 1С?
Описание внутреннего устройства веб-клиента?
Или, может быть, Вам интересен процесс выбора фич для новых релизов, разработки и тестирования?

Пишите в комментариях!

ссылка на оригинал статьи http://habrahabr.ru/post/269611/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *