Plataforma "1C: Enterprise": que hai baixo o capó?

Ola Habr!
Neste artigo comezaremos a historia sobre como funciona dentro plataforma "1C: Enterprise 8" e que tecnoloxías se utilizan no seu desenvolvemento.

Plataforma "1C: Enterprise": que hai baixo o capó?

Por que pensamos que isto é interesante? En primeiro lugar, porque a plataforma 1C:Enterprise 8 é unha aplicación grande (máis de 10 millóns de liñas de código) en C++ (cliente, servidor, etc.), JavaScript (cliente web) e, máis recentemente, E Java. Os grandes proxectos poden ser interesantes polo menos pola súa escala, porque os problemas que son invisibles nunha pequena base de código xorden con toda forza nestes proxectos. En segundo lugar, "1C:Enterprise" é un produto replicable, "en caixa", e hai moi poucos artigos sobre tales desenvolvementos en Habré. Tamén sempre é interesante saber como é a vida noutros equipos e empresas.

Entón, imos comezar. Neste artigo daremos unha visión xeral dalgunhas das tecnoloxías que se usan na plataforma e esbozaremos a paisaxe, sen mergullarnos a fondo na implementación. De feito, para moitos mecanismos, unha historia detallada requiriría un artigo separado, e para algúns, un libro enteiro!
Para comezar, paga a pena decidir sobre as cousas básicas: que é a plataforma 1C:Enterprise e de que compoñentes consta. A resposta a esta pregunta non é tan sinxela, porque o termo "Plataforma" (para brevidade, chamarémolo así) refírese a un medio para desenvolver aplicacións empresariais, un ambiente de execución e ferramentas de administración. Pódense distinguir grosso modo os seguintes compoñentes:

  • clúster de servidores
  • cliente “delgado” capaz de conectarse ao servidor mediante http e o seu propio protocolo binario
  • cliente para traballar nunha arquitectura de dous niveis cunha base de datos situada nun disco duro ou cartafol de rede
  • cliente web
  • ferramentas de administración do servidor de aplicacións
  • entorno de desenvolvemento (coñecido como Configurator)
  • entorno de execución para iOS, Android e Windows Phone (plataforma móbil 1C)

Todas estas partes, a excepción do cliente web, están escritas en C++. Ademais, está o recentemente anunciado Configurador de nova xeración, escrito en Java.

Aplicacións nativas

C++03 úsase para desenvolver aplicacións nativas. Para Windows, úsase Microsoft Visual C++ 12 (un perfil compatible con Windows XP) como compilador, e para Linux e Android - gcc 4.8, para iOS - clang 5.0. A biblioteca estándar utilizada é a mesma para todos os sistemas operativos e compiladores - STLPort. Esta solución reduce a probabilidade de erros específicos da implementación STL. Actualmente estamos planeando migrar á implementación STL que se envía con CLang, xa que STLPort foi descontinuado e é incompatible co modo habilitado para C++11 de gcc.
O código base do servidor é 99% común, o do cliente - 95%. Ademais, incluso a plataforma móbil usa o mesmo código C++ que o "grande", aínda que a porcentaxe de unificación alí é algo menor.
Como a maioría dos usuarios de C++, non pretendemos utilizar o 100% das capacidades da linguaxe e das súas bibliotecas. Polo tanto, practicamente non usamos Boost, e unha das características da linguaxe é a transmisión de tipos dinámicos. Ao mesmo tempo, utilizamos activamente:

  • STL (específicamente cadeas, contedores e algoritmos)
  • herdanza múltiple, incl. herdanza de implementación múltiple
  • modelos
  • excepcións
  • punteiros intelixentes (implementación personalizada)

Ao usar a herdanza múltiple de interfaces (clases completamente abstractas), faise posible un modelo de compoñentes, que se comentará a continuación.

Compoñentes

Para garantir a modularidade, toda a funcionalidade divídese en compoñentes, que son bibliotecas dinámicas (*.dll para Windows, *.so para Linux). Hai máis de cento cincuenta compoñentes en total; aquí tes descricións dalgúns deles:

motor
Contén o motor de metadatos da plataforma

accnt
Obxectos que usan os desenvolvedores de aplicacións para crear rexistros contables (cadros contables e rexistros contables)

bsl
Motor de execución de linguaxe incorporado

nuclear
Implementación personalizada do asignador de memoria

dbeng8
Motor de base de datos de ficheiros. Un motor de base de datos de servidor de ficheiros sinxelo baseado en ISAM, que tamén inclúe un procesador SQL sinxelo

wbase
Contén as clases básicas e funcións para implementar a interface de usuario de Windows: clases de xanela, acceso GDI, etc.

Dividir en varios compoñentes é útil desde varios puntos de vista:

  • A separación promove un mellor deseño, en particular un mellor illamento do código
  • A partir dun conxunto de compoñentes pode montar de forma flexible diferentes opcións de entrega:
    • Por exemplo, unha instalación de cliente lixeiro conterá wbase, pero non terá backend
    • pero no servidor wbase, pola contra, non o será
    • ambas opcións conterán, por suposto, nuke e bsl

Todos os compoñentes necesarios para esta opción de lanzamento cárganse cando se inicia o programa. Isto, en particular, é necesario para rexistrar as clases SCOM, que se comentarán a continuación.

SCOM

Para a descomposición a un nivel inferior utilízase o sistema SCOM, unha biblioteca similar en ideoloxía á ATL. Para aqueles que non traballaron con ATL, enumeramos brevemente as principais capacidades e características.
Para unha clase SCOM especialmente deseñada:

  • Ofrece métodos de fábrica que permiten crear unha clase a partir doutro compoñente coñecendo só o seu nome (sen revelar a implementación)
  • Ofrece unha infraestrutura de punteiro intelixente para contar referencias. A duración da clase SCOM non é necesario supervisar manualmente
  • Permítelle descubrir se un obxecto implementa unha interface específica e converter automaticamente un punteiro ao obxecto nun punteiro á interface
  • Cree un obxecto de servizo que sexa sempre accesible a través do método get_service, etc.

Por exemplo, pode describir unha clase para ler JSON (por exemplo, JSONStreamReader) no compoñente json.dll.
As clases e instancias pódense crear a partir doutros compoñentes; deben rexistrarse na máquina SCOM:

SCOM_CLASS_ENTRY(JSONStreamReader)

Esta macro describirá unha clase especial de gravadora estática, cuxo construtor chamarase cando se cargue o compoñente na memoria.
Despois diso, podes crear unha instancia del noutro compoñente:

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

Para apoiar os servizos, SCOM ofrece unha infraestrutura adicional bastante complexa. O elemento central é o concepto dun proceso SCOM, que serve como contedor para executar servizos (é dicir, desempeña o papel de Localizador de servizos) e tamén contén un enlace a recursos localizados. O proceso SCOM está ligado ao fío do sistema operativo. Grazas a isto, dentro da aplicación podes recibir servizos como este:

SCOM_Process* process = core::current_process();
if (process)
         return get_service<IMyService>(process);

Ademais, cambiando procesos lóxicos (SCOM) ligados a un fío, pódense obter aplicacións que son practicamente independentes desde o punto de vista do espazo de información, que se executan dentro do mesmo fío. Así funciona o noso cliente fino cunha base de datos de ficheiros: dentro dun proceso do sistema operativo hai dous procesos SCOM, un asociado co cliente e o segundo co servidor. Este enfoque permítenos unificar a escritura de código que funcionará tanto na base de datos de ficheiros local como na versión cliente-servidor "real". O prezo desta uniformidade é superior, pero a práctica demostra que paga a pena.

Baseándose no modelo de compoñentes SCOM, impléntanse tanto a lóxica empresarial como a parte da interface de 1C: Enterprise.

Interfaz de usuario

Por certo, sobre interfaces. Non utilizamos controis estándar de Windows; os nosos controis impléntanse directamente na API de Windows. Para a versión de Linux, creouse unha capa que funciona a través da biblioteca wxWidgets.
A biblioteca de controis non depende doutras partes de 1C:Enterprise e é utilizada por nós noutras outras pequenas utilidades internas.

Ao longo dos anos de desenvolvemento de 1C:Enterprise, a aparencia dos controis cambiou, pero un cambio serio nos principios ocorreu só unha vez, en 2009, co lanzamento da versión 8.2 e a aparición de "formularios xestionados". Ademais de cambiar a aparencia, o principio do deseño do formulario cambiou fundamentalmente: houbo un rexeitamento do posicionamento píxel por píxel dos elementos a favor do fluxo de elementos. Ademais, no novo modelo, os controis non funcionan directamente con obxectos de dominio, senón con DTO especiais (Obxectos de transferencia de datos).
Estes cambios fixeron posible crear un cliente web 1C:Enterprise que replica a lóxica C++ dos controis JavaScript. Tentamos manter a equivalencia funcional entre clientes lixeiros e web. Nos casos nos que isto non é posible, por exemplo debido ás limitacións da API de JavaScript dispoñible (por exemplo, a capacidade de traballar con ficheiros é moi limitada), moitas veces implementamos a funcionalidade necesaria mediante extensións de navegador escritas en C++. Actualmente admitimos Internet Explorer e Microsoft Edge (Windows), Google Chrome (Windows), Firefox (Windows e Linux) e Safari (MacOS).

Ademais, a tecnoloxía de formularios xestionados úsase para crear unha interface para aplicacións móbiles na plataforma 1C. Nos dispositivos móbiles, a representación dos controis implícase mediante tecnoloxías propias do sistema operativo, pero para a lóxica de deseño de formularios e a resposta da interface utilízase o mesmo código que na plataforma "grande" 1C:Enterprise.

Plataforma "1C: Enterprise": que hai baixo o capó?
Interface 1C no sistema operativo Linux

Plataforma "1C: Enterprise": que hai baixo o capó?
Interface 1C nun dispositivo móbil

Interface 1C noutras plataformas Plataforma "1C: Enterprise": que hai baixo o capó?
Interface 1C no sistema operativo Windows

Plataforma "1C: Enterprise": que hai baixo o capó?
Interface 1C - cliente web

código aberto

Aínda que non usamos bibliotecas estándar para desenvolvedores de C++ en Windows (MFC, controis de WinAPI), non escribimos todos os compoñentes nós mesmos. A biblioteca xa foi mencionada wxWidgets, e tamén usamos:

  • cURL para traballar con HTTP e FTP.
  • OpenSSL para traballar con criptografía e establecer conexións TLS
  • libxml2 e libxslt para a análise de XML
  • libetpan para traballar con protocolos de correo (POP3, SMTP, IMAP)
  • mimética para analizar mensaxes de correo electrónico
  • sqllite para almacenar rexistros de usuarios
  • UTI para a internacionalización

A lista segue.
Ademais, usamos unha versión moi modificada Proba de Google и Google Mock ao desenvolver probas unitarias.
As bibliotecas requiriron unha adaptación para ser compatibles co modelo de organización de compoñentes SCOM.
A prevalencia de 1C fai da plataforma unha excelente proba de forza para as bibliotecas utilizadas nela. Unha variedade de usuarios e escenarios revela rapidamente erros incluso nas áreas de código máis raramente usadas. Corrixímolos nós mesmos e tentamos devolvelos aos autores da biblioteca. A experiencia da interacción resulta ser moi diferente.
Desenvolvedores cURL и libetpan responder rapidamente ás solicitudes de extracción, pero o parche, por exemplo, está en OpenSSL Nunca conseguimos devolvelo.

Conclusión

No artigo tocamos varios aspectos principais do desenvolvemento da plataforma 1C: Enterprise. No ámbito limitado do artigo, tocamos só algúns aspectos interesantes, na nosa opinión.
Pódese atopar unha descrición xeral dos distintos mecanismos da plataforma aquí.
Que temas lle interesarían en próximos artigos?

Como se implementa a plataforma móbil 1C?
Descrición da estrutura interna do cliente web?
Ou quizais estás interesado no proceso de selección de funcións para novos lanzamentos, desenvolvemento e probas?

Escribe nos comentarios!

Fonte: www.habr.com

Engadir un comentario