Plattform "1C: Enterprise" - hva er under panseret?

Hei Habr!
I denne artikkelen vil vi begynne historien om hvordan det fungerer innvendig plattform "1C:Enterprise 8" og hvilke teknologier som brukes i utviklingen.

Plattform "1C: Enterprise" - hva er under panseret?

Hvorfor synes vi dette er interessant? For det første fordi 1C:Enterprise 8-plattformen er en stor (mer enn 10 millioner kodelinjer) applikasjon i C++ (klient, server, etc.), JavaScript (webklient) og, nylig, og Java. Store prosjekter kan være interessante i det minste på grunn av omfanget, fordi problemstillinger som er usynlige i en liten kodebase oppstår med full kraft i slike prosjekter. For det andre er "1C:Enterprise" et replikerbart, "innpakket" produkt, og det er svært få artikler om slik utvikling på Habré. Det er også alltid interessant å vite hvordan livet er i andre lag og selskaper.

Så la oss komme i gang. I denne artikkelen vil vi gi en oversikt over noen av teknologiene som brukes i plattformen og skissere landskapet, uten å dykke dypt ned i implementeringen. For mange mekanismer vil en detaljert historie faktisk kreve en egen artikkel, og for noen en hel bok!
Til å begynne med er det verdt å bestemme seg for de grunnleggende tingene - hva 1C:Enterprise-plattformen er og hvilke komponenter den består av. Svaret på dette spørsmålet er ikke så enkelt, fordi begrepet "Plattform" (for korthets skyld vil vi kalle det på den måten) refererer til et middel for å utvikle forretningsapplikasjoner, et kjøretidsmiljø og administrasjonsverktøy. Følgende komponenter kan grovt skilles:

  • serverklynge
  • "tynn" klient som er i stand til å koble til serveren via http og sin egen binære protokoll
  • klient for å jobbe i en to-lags arkitektur med en database plassert på en harddisk eller nettverksmappe
  • nettklient
  • administrasjonsverktøy for applikasjonstjenere
  • utviklingsmiljø (kjent som Configurator)
  • kjøretidsmiljø for iOS, Android og Windows Phone (mobilplattform 1C)

Alle disse delene, med unntak av webklienten, er skrevet i C++. I tillegg er det den nylig annonserte Ny generasjons konfigurator, skrevet i Java.

Innebygde apper

C++03 brukes til å utvikle native applikasjoner. For Windows brukes Microsoft Visual C++ 12 (en profil som er kompatibel med Windows XP) som kompilator, og for Linux og Android - gcc 4.8, for iOS - clang 5.0. Standardbiblioteket som brukes er det samme for alle operativsystemer og kompilatorer - STLPort. Denne løsningen reduserer sannsynligheten for STL-implementeringsspesifikke feil. Vi planlegger for øyeblikket å migrere til STL-implementeringen som ble levert med CLang, ettersom STLPort har blitt avviklet og er inkompatibel med gccs C++11-aktiverte modus.
Serverens kodebase er 99% vanlig, klientens - 95%. Dessuten bruker selv mobilplattformen den samme C++-koden som den "store", selv om prosentandelen av forening der er noe lavere.
Som de fleste C++-brukere, hevder vi ikke å bruke 100 % av funksjonene til språket og dets biblioteker. Så vi bruker praktisk talt ikke Boost, og en av språkfunksjonene er dynamisk type casting. Samtidig bruker vi aktivt:

  • STL (spesifikt strenger, beholdere og algoritmer)
  • flergangsarv, inkl. multippel implementeringsarv
  • maler
  • unntakene
  • smarte pekere (egendefinert implementering)

Ved å bruke multippel arv av grensesnitt (helt abstrakte klasser), blir en komponentmodell mulig, som vil bli diskutert nedenfor.

Komponenter

For å sikre modularitet er all funksjonalitet delt inn i komponenter, som er dynamiske biblioteker (*.dll for Windows, *.so for Linux). Det er mer enn hundre og femti komponenter totalt; her er beskrivelser av noen av dem:

backend
Inneholder plattformens metadatamotor

aknt
Objekter som applikasjonsutviklere bruker til å bygge regnskapsposter (kontoplaner og regnskapsregistre)

bsl
Innebygd språkutførelsesmotor

nuke
Tilpasset implementering av minneallokator

dbeng8
Fildatabasemotor. En enkel filserverdatabasemotor basert på ISAM, som også inkluderer en enkel SQL-prosessor

wbase
Inneholder basisklassene og funksjonene for implementering av Windows-brukergrensesnittet - vindusklasser, GDI-tilgang, etc.

Å dele inn i flere komponenter er nyttig fra flere synspunkter:

  • Separasjon fremmer bedre design, spesielt bedre kodeisolasjon
  • Fra et sett med komponenter kan du fleksibelt sette sammen forskjellige leveringsalternativer:
    • For eksempel vil en tynnklientinstallasjon inneholde wbase, men vil ikke ha backend
    • men på wbase-serveren vil det tvert imot ikke være det
    • begge alternativene vil selvfølgelig inneholde nuke og bsl

Alle komponenter som kreves for dette oppstartsalternativet, lastes inn når programmet starter. Dette er spesielt nødvendig for å registrere SCOM-klasser, som vil bli diskutert nedenfor.

SCOM

For dekomponering på et lavere nivå brukes SCOM-systemet, et bibliotek som i ideologisk likhet med ATL. For de som ikke har jobbet med ATL, lister vi kort opp hovedfunksjonene og funksjonene.
For en spesialdesignet SCOM-klasse:

  • Gir fabrikkmetoder som lar deg lage en klasse fra en annen komponent som bare kjenner navnet (uten å avsløre implementeringen)
  • Gir en smart pekerinfrastruktur som teller referanser. SCOM-klassens levetid trenger ikke å overvåkes manuelt
  • Lar deg finne ut om et objekt implementerer et spesifikt grensesnitt og automatisk konvertere en peker til objektet til en peker til grensesnittet
  • Opprett et tjenesteobjekt som alltid er tilgjengelig gjennom get_service-metoden osv.

Du kan for eksempel beskrive en klasse for lesing av JSON (for eksempel JSONStreamReader) i json.dll-komponenten.
Klasser og forekomster kan opprettes fra andre komponenter; de må registreres i SCOM-maskinen:

SCOM_CLASS_ENTRY(JSONStreamReader)

Denne makroen vil beskrive en spesiell statisk opptakerklasse, hvis konstruktør vil bli kalt når komponenten lastes inn i minnet.
Etter dette kan du opprette en forekomst av den i en annen komponent:

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

For å støtte tjenester tilbyr SCOM en ekstra, ganske kompleks infrastruktur. Sentralt i det er konseptet med en SCOM-prosess, som fungerer som en beholder for å kjøre tjenester (dvs. spiller rollen som Service Locator), og som også inneholder en binding til lokaliserte ressurser. SCOM-prosessen er knyttet til OS-tråden. Takket være dette kan du i applikasjonen motta tjenester som dette:

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

Dessuten, ved å bytte logiske (SCOM) prosesser knyttet til en tråd, kan du få applikasjoner som er praktisk talt uavhengige fra synspunktet til informasjonsrommet, som kjører innenfor samme tråd. Slik fungerer vår tynnklient med en fildatabase - inne i en OS-prosess er det to SCOM-prosesser, en assosiert med klienten og den andre med serveren. Denne tilnærmingen lar oss forene skrivingen av kode som vil fungere både på den lokale fildatabasen og i den "ekte" klient-serverversjonen. Prisen for slik ensartethet er overhead, men praksis viser at det er verdt det.

Basert på SCOM-komponentmodellen implementeres både forretningslogikken og grensesnittdelen av 1C: Enterprise.

Brukergrensesnitt

Forresten, om grensesnitt. Vi bruker ikke standard Windows-kontroller; kontrollene våre implementeres direkte på Windows API. For Linux-versjonen er det laget et lag som fungerer gjennom wxWidgets-biblioteket.
Biblioteket med kontroller er ikke avhengig av andre deler av 1C:Enterprise og brukes av oss i flere andre små interne verktøy.

I løpet av årene med utvikling av 1C:Enterprise har utseendet til kontroller endret seg, men en alvorlig endring i prinsipper skjedde bare én gang, i 2009, med utgivelsen av versjon 8.2 og bruken av "administrerte skjemaer". I tillegg til å endre utseendet, har prinsippet om formoppsett endret seg fundamentalt - det var en avvisning av piksel-for-piksel-plassering av elementer til fordel for flyt-layout av elementer. I tillegg, i den nye modellen, fungerer ikke kontroller direkte med domeneobjekter, men med spesielle DTOer (Dataoverføringsobjekter).
Disse endringene gjorde det mulig å lage en 1C:Enterprise-webklient som replikerer C++-logikken til JavaScript-kontroller. Vi prøver å opprettholde funksjonell ekvivalens mellom tynne og nettklienter. I tilfeller der dette ikke er mulig, for eksempel på grunn av begrensninger av JavaScript API tilgjengelig (for eksempel muligheten til å jobbe med filer er svært begrenset), implementerer vi ofte den nødvendige funksjonaliteten ved å bruke nettleserutvidelser skrevet i C++. Vi støtter for øyeblikket Internet Explorer og Microsoft Edge (Windows), Google Chrome (Windows), Firefox (Windows og Linux) og Safari (MacOS).

I tillegg brukes teknologi for administrerte skjemaer for å lage et grensesnitt for mobilapplikasjoner på 1C-plattformen. På mobile enheter implementeres gjengivelsen av kontroller ved hjelp av teknologier som er hjemmehørende i operativsystemet, men for skjemalayoutlogikken og grensesnittresponsen brukes den samme koden som i den "store" 1C:Enterprise-plattformen.

Plattform "1C: Enterprise" - hva er under panseret?
1C-grensesnitt på Linux OS

Plattform "1C: Enterprise" - hva er under panseret?
1C-grensesnitt på en mobil enhet

1C-grensesnitt på andre plattformer Plattform "1C: Enterprise" - hva er under panseret?
1C-grensesnitt på Windows OS

Plattform "1C: Enterprise" - hva er under panseret?
Grensesnitt 1C - webklient

Åpen kilde

Selv om vi ikke bruker standardbiblioteker for C++-utviklere under Windows (MFC, kontroller fra WinAPI), skriver vi ikke alle komponentene selv. Biblioteket er allerede nevnt wxWidgets, og vi bruker også:

  • cURL for arbeid med HTTP og FTP.
  • OpenSSL for arbeid med kryptografi og etablering av TLS-forbindelser
  • libxml2 og libxslt for XML-parsing
  • libetpan for arbeid med e-postprotokoller (POP3, SMTP, IMAP)
  • etterligne for å analysere e-postmeldinger
  • sqllite for lagring av brukerlogger
  • ICU for internasjonalisering

Listen fortsetter.
I tillegg bruker vi en svært modifisert versjon Google -test и Google Mock ved utvikling av enhetstester.
Bibliotekene krevde tilpasning for å være kompatible med SCOM-komponentorganisasjonsmodellen.
Utbredelsen av 1C gjør plattformen til en utmerket styrketest for bibliotekene som brukes i den. En rekke brukere og scenarier avslører raskt feil i selv de mest sjeldent brukte kodeområdene. Vi retter dem selv og prøver å gi dem tilbake til bibliotekforfatterne. Opplevelsen av samhandling viser seg å være svært forskjellig.
Utviklere cURL и libetpan svare raskt på pull-forespørsler, men oppdateringen, for eksempel, inn OpenSSL Vi klarte aldri å gi den tilbake.

Konklusjon

I artikkelen kom vi inn på flere hovedaspekter ved utviklingen av 1C: Enterprise-plattformen. I det begrensede omfanget av artikkelen berørte vi bare noen interessante, etter vår mening, aspekter.
En generell beskrivelse av de ulike plattformmekanismene finnes her.
Hvilke emner vil være av interesse for deg i fremtidige artikler?

Hvordan implementeres 1C-mobilplattformen?
Beskrivelse av den interne strukturen til webklienten?
Eller kanskje du er interessert i prosessen med å velge funksjoner for nye utgivelser, utvikle og teste?

Skriv i kommentarfeltet!

Kilde: www.habr.com

Legg til en kommentar