Plattform "1C: Enterprise" - vad finns under huven?

Hej Habr!
I den här artikeln börjar vi historien om hur det fungerar inuti plattform "1C:Enterprise 8" och vilka tekniker som används i dess utveckling.

Plattform "1C: Enterprise" - vad finns under huven?

Varför tycker vi att detta är intressant? För det första eftersom 1C:Enterprise 8-plattformen är en stor (mer än 10 miljoner rader kod) applikation i C++ (klient, server, etc.), JavaScript (webbklient) och, på senare tid, och java. Stora projekt kan vara intressanta åtminstone på grund av sin omfattning, eftersom problem som är osynliga i en liten kodbas uppstår med full kraft i sådana projekt. För det andra är "1C:Enterprise" en replikerbar, "boxad" produkt, och det finns väldigt få artiklar om sådan utveckling på Habré. Det är också alltid intressant att veta hur livet är i andra team och företag.

Så låt oss börja. I den här artikeln kommer vi att ge en översikt över några av de teknologier som används i plattformen och skissera landskapet, utan att dyka djupt ner i implementeringen. För många mekanismer skulle en detaljerad berättelse faktiskt kräva en separat artikel, och för vissa, en hel bok!
Till att börja med är det värt att bestämma sig för de grundläggande sakerna - vad 1C:Enterprise-plattformen är och vilka komponenter den består av. Svaret på den här frågan är inte så enkelt, eftersom termen "Plattform" (för korthetens skull kallar vi det så) hänvisar till ett sätt att utveckla affärsapplikationer, en runtime-miljö och administrationsverktyg. Följande komponenter kan grovt särskiljas:

  • serverkluster
  • "tunn" klient som kan ansluta till servern via http och sitt eget binära protokoll
  • klient för att arbeta i en tvåskiktsarkitektur med en databas på en hårddisk eller nätverksmapp
  • webbklient
  • applikationsserveradministrationsverktyg
  • utvecklingsmiljö (känd som Configurator)
  • runtime-miljö för iOS, Android och Windows Phone (mobilplattform 1C)

Alla dessa delar, med undantag för webbklienten, är skrivna i C++. Dessutom finns det nyligen tillkännagivna Ny generation konfigurator, skrivet på Java.

Inbyggda appar

C++03 används för att utveckla inbyggda applikationer. För Windows används Microsoft Visual C++ 12 (en profil som är kompatibel med Windows XP) som kompilator, och för Linux och Android - gcc 4.8, för iOS - clang 5.0. Standardbiblioteket som används är detsamma för alla operativsystem och kompilatorer - STLPort. Denna lösning minskar sannolikheten för STL-implementeringsspecifika fel. Vi planerar för närvarande att migrera till STL-implementeringen som levereras med CLang, eftersom STLPort har upphört och är inkompatibelt med gccs C++11-aktiverade läge.
Serverns kodbas är 99% vanlig, klientens - 95%. Dessutom använder även den mobila plattformen samma C++-kod som den "stora", även om andelen förening där är något lägre.
Som de flesta C++-användare gör vi inte anspråk på att använda 100 % av språkets och dess biblioteks kapacitet. Så vi använder praktiskt taget inte Boost, och en av språkfunktionerna är dynamisk typcasting. Samtidigt använder vi aktivt:

  • STL (särskilt strängar, behållare och algoritmer)
  • multipelarv, inkl. arv av flera implementeringar
  • mallar
  • undantag
  • smarta pekare (anpassad implementering)

Genom att använda flera arv av gränssnitt (helt abstrakta klasser) blir en komponentmodell möjlig, vilket kommer att diskuteras nedan.

Komponenter

För att säkerställa modularitet är all funktionalitet uppdelad i komponenter, som är dynamiska bibliotek (*.dll för Windows, *.so för Linux). Det finns mer än etthundrafemtio komponenter totalt; här är beskrivningar av några av dem:

backend
Innehåller plattformens metadatamotor

acnt
Objekt som applikationsutvecklare använder för att bygga bokföringsdokument (kontoplan och bokföringsregister)

bsl
Inbäddad språkexekveringsmotor

nuke
Anpassad implementering av minnesallokator

dbeng8
Fildatabasmotor. En enkel filserverdatabasmotor baserad på ISAM, som även innehåller en enkel SQL-processor

wbase
Innehåller basklasserna och funktionerna för implementering av Windows-användargränssnittet - fönsterklasser, GDI-åtkomst, etc.

Att dela upp i flera komponenter är användbart ur flera synvinklar:

  • Separation främjar bättre design, särskilt bättre kodisolering
  • Från en uppsättning komponenter kan du flexibelt montera olika leveransalternativ:
    • Till exempel kommer en tunn klientinstallation att innehålla wbase, men kommer inte att ha backend
    • men på wbase-servern blir det tvärtom inte det
    • båda alternativen kommer givetvis att innehålla nuke och bsl

Alla komponenter som krävs för detta startalternativ laddas när programmet startar. Detta är i synnerhet nödvändigt för att registrera SCOM-klasser, vilket kommer att diskuteras nedan.

SCOM

För nedbrytning på lägre nivå används SCOM-systemet, ett bibliotek som i ideologi liknar ATL. För de som inte har arbetat med ATL listar vi kort de viktigaste funktionerna och funktionerna.
För en specialdesignad SCOM-klass:

  • Tillhandahåller fabriksmetoder som låter dig skapa en klass från en annan komponent och bara känna till dess namn (utan att avslöja implementeringen)
  • Tillhandahåller en referensräknande smart pekarinfrastruktur. SCOM-klassens livslängd behöver inte övervakas manuellt
  • Låter dig ta reda på om ett objekt implementerar ett specifikt gränssnitt och automatiskt konvertera en pekare till objektet till en pekare till gränssnittet
  • Skapa ett serviceobjekt som alltid är tillgängligt via metoden get_service osv.

Du kan till exempel beskriva en klass för att läsa JSON (till exempel JSONStreamReader) i komponenten json.dll.
Klasser och instanser kan skapas från andra komponenter; de måste registreras i SCOM-maskinen:

SCOM_CLASS_ENTRY(JSONStreamReader)

Detta makro kommer att beskriva en speciell klass för statisk inspelare, vars konstruktor kommer att anropas när komponenten laddas in i minnet.
Efter detta kan du skapa en instans av det i en annan komponent:

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

För att stödja tjänster erbjuder SCOM ytterligare en ganska komplex infrastruktur. Centralt för det är konceptet med en SCOM-process, som fungerar som en behållare för att köra tjänster (dvs. spelar rollen som Service Locator), och som även innehåller en bindning till lokaliserade resurser. SCOM-processen är knuten till OS-tråden. Tack vare detta kan du i applikationen få tjänster som detta:

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

Dessutom, genom att byta logiska (SCOM) processer kopplade till en tråd, kan du få applikationer som är praktiskt taget oberoende ur informationsutrymmets synvinkel, som körs inom samma tråd. Så här fungerar vår tunna klient med en fildatabas - i en OS-process finns två SCOM-processer, en kopplad till klienten och den andra med servern. Detta tillvägagångssätt tillåter oss att förena skrivningen av kod som fungerar både på den lokala fildatabasen och i den "riktiga" klient-serverversionen. Priset för sådan enhetlighet är overhead, men praktiken visar att det är värt det.

Baserat på SCOM-komponentmodellen implementeras både affärslogiken och gränssnittsdelen av 1C: Enterprise.

Användargränssnitt

Förresten, om gränssnitt. Vi använder inte vanliga Windows-kontroller; våra kontroller implementeras direkt på Windows API. För Linuxversionen har ett lager gjorts som fungerar genom wxWidgets-biblioteket.
Biblioteket med kontroller är inte beroende av andra delar av 1C:Enterprise och används av oss i flera andra små interna verktyg.

Under årens utveckling av 1C:Enterprise har utseendet på kontroller förändrats, men en allvarlig förändring av principerna inträffade bara en gång, 2009, med lanseringen av version 8.2 och tillkomsten av "hanterade formulär". Förutom att ändra utseendet har principen för formlayout förändrats i grunden - det förekom ett förkastande av pixel-för-pixel-positionering av element till förmån för flödeslayout av element. Dessutom, i den nya modellen fungerar kontrollerna inte direkt med domänobjekt, utan med speciella DTO:er (Dataöverföringsobjekt).
Dessa ändringar gjorde det möjligt att skapa en 1C:Enterprise-webbklient som replikerar C++-logiken för JavaScript-kontroller. Vi försöker upprätthålla funktionell likvärdighet mellan tunna klienter och webbklienter. I de fall detta inte är möjligt, till exempel på grund av begränsningar av JavaScript API:et som finns tillgängligt (till exempel möjligheten att arbeta med filer är mycket begränsad), implementerar vi ofta den nödvändiga funktionaliteten med webbläsartillägg skrivna i C++. Vi stöder för närvarande Internet Explorer och Microsoft Edge (Windows), Google Chrome (Windows), Firefox (Windows och Linux) och Safari (MacOS).

Dessutom används teknologi för hanterade formulär för att skapa ett gränssnitt för mobilapplikationer på 1C-plattformen. På mobila enheter implementeras renderingen av kontroller med tekniker som är inbyggda i operativsystemet, men för formulärlayoutlogiken och gränssnittssvaret används samma kod som i den "stora" 1C:Enterprise-plattformen.

Plattform "1C: Enterprise" - vad finns under huven?
1C-gränssnitt på Linux OS

Plattform "1C: Enterprise" - vad finns under huven?
1C-gränssnitt på en mobil enhet

1C-gränssnitt på andra plattformar Plattform "1C: Enterprise" - vad finns under huven?
1C-gränssnitt på Windows OS

Plattform "1C: Enterprise" - vad finns under huven?
Gränssnitt 1C - webbklient

Öppen källa

Även om vi inte använder standardbibliotek för C++-utvecklare under Windows (MFC, kontroller från WinAPI) skriver vi inte alla komponenter själva. Biblioteket har redan nämnts wxWidgets, och vi använder även:

  • ringla för att arbeta med HTTP och FTP.
  • OpenSSL för att arbeta med kryptografi och upprätta TLS-anslutningar
  • libxml2 och libxslt för XML-tolkning
  • libetpan för att arbeta med e-postprotokoll (POP3, SMTP, IMAP)
  • mimetiska för att analysera e-postmeddelanden
  • sqllite för att lagra användarloggar
  • ICU för internationalisering

Listan fortsätter.
Dessutom använder vi en mycket modifierad version Google-test и Google Mock vid utveckling av enhetstester.
Biblioteken krävde anpassning för att vara kompatibla med SCOM-komponentens organisationsmodell.
Prevalensen av 1C gör plattformen till ett utmärkt styrketest för biblioteken som används i den. En mängd olika användare och scenarier avslöjar snabbt fel även i de mest sällan använda kodområdena. Vi korrigerar dem själva och försöker ge dem tillbaka till biblioteksförfattarna. Upplevelsen av interaktion visar sig vara väldigt olika.
Utvecklare ringla и libetpan svara snabbt på pull-förfrågningar, men patchen, till exempel, in OpenSSL Vi lyckades aldrig ge tillbaka den.

Slutsats

I artikeln berörde vi flera huvudaspekter av utvecklingen av 1C: Enterprise-plattformen. I artikelns begränsade omfattning berörde vi bara några intressanta, enligt vår mening, aspekter.
En allmän beskrivning av de olika plattformsmekanismerna finns här.
Vilka ämnen skulle vara intressanta för dig i framtida artiklar?

Hur implementeras den mobila 1C-plattformen?
Beskrivning av webbklientens interna struktur?
Eller kanske du är intresserad av processen att välja funktioner för nya releaser, utveckla och testa?

Skriv i kommentarerna!

Källa: will.com

Lägg en kommentar