Hej, jeg er Stanislav Yablonskiy, Lead Server Developer hos Pixonic (MY.GAMES). Microservices er en tilgang til softwareudvikling (primært backend udvikling), hvor funktionalitet er opdelt i de mindste mulige komponenter, som hver især opererer uafhængigt. Microservices er meget populære i dag, men deres brug indfører betydelig overhead i form af netværk, hukommelse og CPU. Hvert opkald bliver til behovet for serialisering, udsendelse og modtagelse af data over netværket.Derudover er det ikke længere muligt at bruge klassiske databasetransaktioner, hvilket fører til enten distribuerede transaktioner eller eventuel konsistens. Distribuerede transaktioner er langsomme og dyre, mens eventuel sammenhæng betyder, at resultaterne af operationer måske ikke vises med det samme, og data kan midlertidigt være inkonsekvente. Brug af microservices tvinger udviklere til at skrive mere kode i hver enkelt tjeneste på grund af vanskelighederne med at få adgang til allerede skrevet logik fra andre tjenester.Nogle gange er det svært at genbruge eksisterende kode, eller du kan ikke engang vide, at den eksisterer - da andre mennesker måske arbejder på et andet projekt. Microservices’ overheads Debug overhead Debugging bliver meget sværere med microservices. En regelmæssig debugger er næsten ubrugelig i sådanne forhold, da du ikke kan debugge alle tjenester på én gang. Det betyder, at du har brug for et specielt miljø, hvor ikke kun den debuggerede tjeneste kører, men også alle dens afhængigheder (andre tjenester, databaser, køer osv.). HTTP overhead HTTP-protokollen har en masse indbygget funktionalitet. Den understøtter forskellige ruter, parameterpassingsmetoder, responskoder og understøttes af mange klar til brug tjenester (herunder proxyer). men det er ikke let – det tvinger hver tjeneste til at implementere en masse ikke-så-effektiv kode til at analysere og generere veje, overskrifter og så videre. Test af Protobuf Overhead Serialisering til netværkskommunikation og deserialisering ved modtagelse af beskeder er påkrævet. Når du bruger protobuf til meddelelsesudveksling, skal du: at skabe genstande, Omdanne dem til bytte arrayer, Kast dem straks efter brug. Dette skaber en masse ekstra arbejde for skraldesamleren eller den dynamiske hukommelsesmanager. Netværk overhead Overførsel af data over netværket øger serviceresvaretiden.Det øger hukommelsen og CPU-forbruget, selv om microservices kører på samme vært. Overhead hukommelse At sende og modtage meddelelser kræver vedligeholdelse af yderligere datastrukturer, ved hjælp af separate tråde og synkronisering af dem. Hver separat proces, især en, der kører i en beholder, forbruger en betydelig mængde hukommelse bare ved eksisterende. CPU overhoved Naturligvis kræver al denne inter-proces og inter-container kommunikation beregningsmæssige ressourcer. Database overhead Normale transaktioner er umulige, når operationer spænder over flere microservices. Distribuerede transaktioner er meget langsommere og kræver kompleks – ofte manuel – koordinering. Netværksdisk overhead Microservice containere kører ofte på netværksmonterede diske, hvilket øger forsinkelsen, reducerer ydeevnen (IOPS) og gør det uforudsigeligt. Projekt Grænser Overhead Udformning og udvikling af mikroservices medfører vanskeligheder i udviklingen og omformningen af et projekt. Det er ikke let at ændre ansvarsområdet for en tjeneste. Du kan ikke blot flytte kode fra en tjeneste til en anden. Dette kræver normalt: meget tid og indsats, flere forskellige versioner, og komplekse migrationer, før funktionaliteten kan omfordeles mellem tjenester. Hvis du også vil opdatere eller udskifte et bibliotek, skal du gøre det på tværs af alle projekter, ikke kun et. Infrastruktur overhovedet Du kan ikke bare "gøre microservices." du har brug for infrastruktur - nej, INFRASTRUKTUR: containere (hver indeholder kopier af delte biblioteker), af Kubernets, cloud tjenester, Køer (RabbitMQ og Kafka) Konfigurationssynkronisering værktøjer (Zookeeper, Etcd, Consul), og så videre. Alt dette kræver enorme ressourcer fra både maskiner og mennesker. Uafhængig udstationering overhead Støtte til uafhængige implementeringer betyder: Hver tjeneste skal kunne implementeres separat. Hver skal have sin egen CI/CD-rørledning, Og den sværeste del - API versionering. Hver tjeneste skal understøtte flere API-versioner samtidigt, og opkaldere skal spore disse versioner og opdatere deres opkald i tide. Distribueret bold af mud I stedet for rene microservices ender du med en distribueret kugle mudder – hvor funktionaliteten er dårligt fordelt, eksterne opkald udløser hele kæder af interne serviceopkald, og det hele er forfærdeligt langsomt. Er Monolith virkelig så skræmmende? Modulære Monoliths Modulære monoliths giver dig mulighed for at undgå det meste af microservice overhead - mens du stadig giver adskillelse, der kan bruges senere, hvis det er nødvendigt. Denne tilgang indebærer at skrive applikationen (primært backend) som en enkelt tjeneste opdelt i individuelle moduler med: klart definerede grænser, og Minimum afhængighed af hinanden. Dette gør det muligt at opdele dem i tjenester, hvis skalering virkelig kræver det. Vent, kan du gøre det? Mange fordele, der tilskrives mikroservicearkitektur, kan opnås i en monolit: Modularitet kan implementeres med sprogfunktioner: klasser, navneområder, projekter og assembler. Flere databaser – muligt, hvis det virkelig er nødvendigt Flere sprog – også muligt, for eksempel, at kombinere C/C++/C#/Java med scripting sprog som JavaScript, Python eller Erlang til udvikling på højere niveau; Interop – mange platforme understøtter opkald til C/C++ fra Java, C#, Python, JavaScript eller Erlang; Meddelelse køer – brug bare den rigtige data struktur. Og når du ønsker at debugge - et tastatur, og hele applikationen er lige ved hånden. Udøvende rammer Actor Frameworks giver dig mulighed for at opbygge microservices - uden microservices. Al logik er opdelt i klasser (aktører), der kun kommunikerer via en meddelelsesbus (kæder). Disse aktører kan: eksisterer inden for en enkelt proces, eller De er fordelt på flere processer. På denne måde får du mikroprogrammeringsmodellen, men størstedelen af infrastrukturen håndteres af selve rammen. Conclusion Konklusionen Arkitekturen skal vælges ud fra: projektets krav, tilgængelige ressourcer, og teamets ekspertise. De er nyttige for store projekter og teams - men monolithen er ikke forældet og er ikke teknisk gæld som standard. Det vigtigste er balancen mellem fleksibilitet og kompleksitet, skalerbarhed og vedligeholdelighed – så det system, du bygger, er effektivt og bæredygtigt.