{"id":12328,"date":"2021-12-17T07:00:44","date_gmt":"2021-12-17T06:00:44","guid":{"rendered":"https:\/\/sii.pl\/blog\/?p=12328"},"modified":"2025-05-07T11:08:41","modified_gmt":"2025-05-07T09:08:41","slug":"od-monolitu-na-wcf-do-mikroserwisow-na-grpc","status":"publish","type":"post","link":"https:\/\/sii.pl\/blog\/od-monolitu-na-wcf-do-mikroserwisow-na-grpc\/","title":{"rendered":"Od monolitu na WCF do mikroserwis\u00f3w na gRPC"},"content":{"rendered":"\n<p>Wielu z Was zapewne nie raz spotka\u0142a si\u0119 z systemem wykorzystuj\u0105cym architektur\u0119 monolitu. Na pocz\u0105tku prac nad projektem IT, jest to jedno z najlepszych rozwi\u0105za\u0144 ze wzgl\u0119du na prostot\u0119 oraz \u0142atwo\u015b\u0107 w projektowaniu, a to wszystko dzi\u0119ki braku zb\u0119dnych powi\u0105za\u0144.<\/p>\n\n\n\n<p>Im d\u0142u\u017cej jednak projekt \u017cyje, tym bardziej system si\u0119 rozrasta. Dochodz\u0105 nowe funkcjonalno\u015bci, nowe zale\u017cno\u015bci, a kodu w monolicie przybywa, co nie u\u0142atwia, a wr\u0119cz znacznie utrudnia prac\u0119 z takim projektem. Niekt\u00f3rzy okre\u015blaj\u0105 taki monolit &#8222;wielk\u0105 kul\u0105 b\u0142ota&#8221;, poniewa\u017c ca\u0142a implementacja znajduje si\u0119 w jednym projekcie, a zale\u017cno\u015bci pomi\u0119dzy ro\u017cnymi bibliotekami przeplataj\u0105 si\u0119 w wielu klasach.<\/p>\n\n\n\n<p>Aby poprawi\u0107 jako\u015b\u0107 takiego systemu <strong>zgodnie ze sztuk\u0105 refaktoryzacji<\/strong>, oczywistym krokiem by\u0142oby rozbicie monolitu na modu\u0142y w wybranym przez nas kierunku podzia\u0142u. Co je\u015bli jednak klient wymaga dodania nowej funkcjonalno\u015bci do projektu i nie chce czeka\u0107, a\u017c uporamy si\u0119 z refaktoryzacj\u0105? Argument\u00f3w blokuj\u0105cych refaktoryzacj\u0119, kt\u00f3ra z regu\u0142y dla klienta jest zb\u0119dn\u0105 strat\u0105 czasu, mo\u017ce by\u0107 du\u017co wi\u0119cej, ale oczekiwanie na now\u0105 funkcjonalno\u015b\u0107 pozostaje.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Zmiana technologii z WCF na gRPC<\/strong><\/h2>\n\n\n\n<p>Taka sytuacja spotka\u0142a mnie bardzo kr\u00f3tko po do\u0142\u0105czeniu do projektu. Nie chc\u0105c komplikowa\u0107 ju\u017c i tak sporego kawa\u0142ka kodu, w kt\u00f3rym rozszerzenie mia\u0142o by\u0107 wykorzystywane, przygotowa\u0142em najpierw propozycj\u0119 zmian, ale w taki spos\u00f3b, \u017ceby jego implementacja znajdowa\u0142a si\u0119 poza aktualnym projektem. Dodatkowo, przygotowa\u0142em dla klienta propozycj\u0119 wykorzystywania technologii innej ni\u017c WCF, kt\u00f3ra by\u0142a u\u017cywana do tamtej chwili.<\/p>\n\n\n\n<p>Istotnym argumentem za zmian\u0105 technologii by\u0142 koniec wsparcia dla WCF ze strony Microsoftu. Wyb\u00f3r pad\u0142 na gRPC ze wzgl\u0119du na podobie\u0144stwo do WCF. Taka argumentacja u\u015bwiadomi\u0142a klientowi, \u017ce <strong>trzeba rozpocz\u0105\u0107 przepisywanie systemu na nowsz\u0105 technologi\u0119<\/strong>. Zwr\u00f3ci\u0142em uwag\u0119 klienta r\u00f3wnie\u017c na to, \u017ce warto zacz\u0105\u0107 to robi\u0107 stopniowo, z mo\u017cliwo\u015bci\u0105 r\u00f3wnoleg\u0142ej pracy starego systemu opartego na WCF oraz systemu, kt\u00f3ry b\u0119dzie zawiera\u0142 te same funkcjonalno\u015bci lub nowe, jednak wykorzystuj\u0105ce ju\u017c technologi\u0119 gRPC.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full wp-image-12329\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/12\/gRpc.png\"><img decoding=\"async\" width=\"451\" height=\"301\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/12\/gRpc.png\" alt=\"Schemat wymiany danych w protokole gRPC\" class=\"wp-image-12329\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/12\/gRpc.png 451w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/12\/gRpc-300x200.png 300w\" sizes=\"(max-width: 451px) 100vw, 451px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 1 Schemat wymiany danych w protokole gRPC<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Czym jest gRPC i dlaczego warto z niego korzysta\u0107?<\/strong><\/h2>\n\n\n\n<p>gRPC jest to <strong>system zdalnego wywo\u0142ania procedur<\/strong> (Remote Procedure Call), pierwotnie opracowany przez Google. Gdy system ten sta\u0142 si\u0119 ju\u017c dojrza\u0142y, zosta\u0142 udost\u0119pniony w ramach projektu typu open-source. Taki krok pozwoli\u0142 protoko\u0142owi zyska\u0107 popularno\u015b\u0107 oraz wsparcie ze strony spo\u0142eczno\u015bci, a to przyci\u0105gn\u0119\u0142o do niego jeszcze wi\u0119ksz\u0105 rzesz\u0119 zwolennik\u00f3w.<\/p>\n\n\n\n<p>gRPC jest wykorzystywane m.in. przez Netflix i Cisco, co potwierdza potencja\u0142 tej technologii. Du\u017cym plusem dla programist\u00f3w WCF jest r\u00f3wnie\u017c <strong>podobie\u0144stwo w definiowaniu kontraktu wymiany informacji pomi\u0119dzy dostawc\u0105 i odbiorc\u0105<\/strong>. W przypadku gRPC kontrakt jest zdefiniowany z u\u017cyciem specjalnego j\u0119zyka \u201eProto\u201d oraz przetrzymywany w pliku o rozszerzeniu *.proto. Istnieje jednak mo\u017cliwo\u015b\u0107 implementacji kontraktu w niemal identyczny spos\u00f3b jak odbywa si\u0119 to w WCF, jednak trzeba zachowa\u0107 kilka regu\u0142. Wi\u0119cej informacji <a href=\"https:\/\/docs.microsoft.com\/pl-pl\/aspnet\/core\/grpc\/code-first?view=aspnetcore-5.0\" rel=\"nofollow\" >mo\u017cna znale\u017a\u0107 w materia\u0142ach<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Zastosowanie gRPC w dzia\u0142aj\u0105cym systemie<\/strong><\/h2>\n\n\n\n<p>Aby umo\u017cliwi\u0107 wykorzystanie gRPC w aktualnie dzia\u0142aj\u0105cym systemie, zastosowa\u0142em wzorzec projektowy Po\u015brednik (Proxy). Zak\u0142ada on wykorzystanie obiektu po\u015brednicz\u0105cego pomi\u0119dzy klientem, kt\u00f3ry wywo\u0142uje operacj\u0119 a rzeczywistym obiektem, kt\u00f3ry zapewnia wymagan\u0105 funkcjonalno\u015b\u0107. Taka architektura przydaje si\u0119, gdy nie chcemy wi\u0105za\u0107 si\u0119 z konkretnym obiektem po stronie klienta lub gdy rzeczywisty obiekt znajduje si\u0119 na zdalnym systemie.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full wp-image-12330\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/12\/ProxyDiagram.png\"><img decoding=\"async\" width=\"601\" height=\"401\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/12\/ProxyDiagram.png\" alt=\"Diagram klas dla wzorca po\u015brednik\" class=\"wp-image-12330\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/12\/ProxyDiagram.png 601w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/12\/ProxyDiagram-300x200.png 300w\" sizes=\"(max-width: 601px) 100vw, 601px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 2 Diagram klas dla wzorca po\u015brednik<\/figcaption><\/figure>\n\n\n\n<p>Do istniej\u0105cej ju\u017c solucji doda\u0142em projekt biblioteki typu .NET Standard 2.1. Taka wersja frameworku pozwoli\u0142a na u\u017cycie technologii gRPC w oparciu o ASP.NET oraz jego referencj\u0119 w g\u0142\u00f3wnym projekcie (monolicie), kt\u00f3ry wykorzystuje .NET Framework 4.7.<\/p>\n\n\n\n<p>W nowym projekcie zaimplementowany zosta\u0142 obiekt Proxy, kt\u00f3ry jednocze\u015bnie jest klientem gRPC. Jego implementacja sk\u0142ada si\u0119 z kilku metod, kt\u00f3re wykorzystuj\u0105 klienta gRPC. W starym projekcie, wykorzystuj\u0105cym WCF, tworzona jest instancja obiektu Proxy, kt\u00f3ra, po wywo\u0142aniu odpowiedniej metody, po\u015bredniczy w wys\u0142aniu pro\u015bby o wykonanie zdalnej procedury do serwera gRPC, a nast\u0119pnie konsumuje otrzymane informacje w celu przygotowania odpowiedzi.<\/p>\n\n\n\n<p>Poniewa\u017c w technologii gRPC komunikacja pomi\u0119dzy klientem, a serwerem odbywa si\u0119 poprzez protok\u00f3\u0142 HTTP, serwer gRPC mo\u017ce by\u0107 umieszczony w dowolnym miejscu, a technologia u\u017cyta do jego implementacji nie jest ograniczona przez technologi\u0119 u\u017cyt\u0105 do implementacji klienta.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full wp-image-12331\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/12\/BackendProxyMicroserviceSequence.png\"><img decoding=\"async\" width=\"531\" height=\"681\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/12\/BackendProxyMicroserviceSequence.png\" alt=\"Diagram sekwencji z uwzgl\u0119dnieniem po\u015brednika i mikroserwis\u00f3w\" class=\"wp-image-12331\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/12\/BackendProxyMicroserviceSequence.png 531w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/12\/BackendProxyMicroserviceSequence-234x300.png 234w\" sizes=\"(max-width: 531px) 100vw, 531px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 3 Diagram sekwencji z uwzgl\u0119dnieniem po\u015brednika i mikroserwis\u00f3w<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Uniezale\u017cnienie od wcze\u015bniejszych decyzji projektowych<\/strong><\/h2>\n\n\n\n<p>Nowa funkcjonalno\u015b\u0107, kt\u00f3rej dodania wymaga\u0142 od nas klient, zosta\u0142a zaimplementowana w ramach serwera gRPC. W naszym przypadku serwer pocz\u0105tkowo dzia\u0142a\u0142 jako lokalny serwis Windowsa, wykorzystuj\u0105cy technologi\u0119 ASP.NET 5 i hostowany by\u0142 za pomoc\u0105 wbudowanego serwera Kestrel. Ograniczy\u0142o to instalowanie dodatkowych serwer\u00f3w WWW oraz ich administracj\u0119. Aby jeszcze bardziej uniezale\u017cni\u0107 si\u0119 od narzuconych wcze\u015bniej decyzji projektowych, aktualnie serwer gRPC dzia\u0142a w kontenerze Docker. Zalet\u0105 takiego rozwi\u0105zania jest mo\u017cliwo\u015b\u0107 hostowania serwisu, kt\u00f3ry jest cz\u0119\u015bci\u0105 naszego systemu na innych maszynach ni\u017c lokalny serwer, jak r\u00f3wnie\u017c w chmurze.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>gRPC \u2013 co dalej?<\/strong><\/h2>\n\n\n\n<p>Na ten moment system posiada ju\u017c 3 osobne mikroserwisy, kt\u00f3re przez ca\u0142y czas s\u0105 rozwijane i usprawniane. Opisana tutaj architektura pozwala na rozw\u00f3j funkcjonalno\u015bci istniej\u0105cego ju\u017c systemu oraz na mo\u017cliwo\u015b\u0107 przeprowadzenia r\u00f3wnoleg\u0142ych prac nad przepisaniem systemu z dzia\u0142aj\u0105cego w technologii WCF do gRPC.<\/p>\n\n\n\n<p>Docelowo, ca\u0142y system b\u0119dzie hostowany w chmurze, jednak jego migracja nast\u0119puje stopniowo. Krokiem po\u015brednim b\u0119dzie hostowanie mikroserwis\u00f3w w kontenerach w infrastrukturze chmury, a cz\u0119\u015b\u0107 systemu nadal b\u0119dzie hostowana w lokalnej infrastrukturze.<\/p>\n\n\n\n<p>Mo\u017cliwo\u015b\u0107 korzystania z najnowszych technologii zach\u0119ci dodatkowe osoby do pracy w naszym projekcie, poniewa\u017c WCF ju\u017c od jakiego\u015b czasu nie jest wykorzystywany w nowych projektach. R\u00f3wnie\u017c brak ogranicze\u0144 architektonicznych przez u\u017cycie technologii gRPC zwi\u0119ksza swobod\u0119 w rozbudowie zespo\u0142u o osoby nie maj\u0105ce wcze\u015bniej do czynienia z technologi\u0105 Microsoft WCF, a nawet z .NET Framework.<\/p>\n\n\n<div class=\"kk-star-ratings kksr-auto kksr-align-left kksr-valign-bottom\"\n    data-payload='{&quot;align&quot;:&quot;left&quot;,&quot;id&quot;:&quot;12328&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;bottom&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;7&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;5&quot;,&quot;starsonly&quot;:&quot;&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;11&quot;,&quot;greet&quot;:&quot;&quot;,&quot;legend&quot;:&quot;5\\\/5 ( votes: 7)&quot;,&quot;size&quot;:&quot;18&quot;,&quot;title&quot;:&quot;Od monolitu na WCF do mikroserwis\u00f3w na gRPC&quot;,&quot;width&quot;:&quot;139.5&quot;,&quot;_legend&quot;:&quot;{score}\\\/{best} ( {votes}: {count})&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>\n            \n<div class=\"kksr-stars\">\n    \n<div class=\"kksr-stars-inactive\">\n            <div class=\"kksr-star\" data-star=\"1\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"2\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"3\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"4\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"5\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n    \n<div class=\"kksr-stars-active\" style=\"width: 139.5px;\">\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n                \n\n<div class=\"kksr-legend\" style=\"font-size: 14.4px;\">\n            5\/5 ( votes: 7)    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>Wielu z Was zapewne nie raz spotka\u0142a si\u0119 z systemem wykorzystuj\u0105cym architektur\u0119 monolitu. Na pocz\u0105tku prac nad projektem IT, jest &hellip; <a class=\"continued-btn\" href=\"https:\/\/sii.pl\/blog\/od-monolitu-na-wcf-do-mikroserwisow-na-grpc\/\">Continued<\/a><\/p>\n","protected":false},"author":325,"featured_media":12341,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_editorskit_title_hidden":false,"_editorskit_reading_time":0,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","inline_featured_image":false,"footnotes":""},"categories":[1314],"tags":[560,1157,1178],"class_list":["post-12328","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development-na-twardo","tag-architektura-it","tag-developer","tag-refaktoryzacja"],"acf":[],"aioseo_notices":[],"republish_history":[],"featured_media_url":"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/12\/szablon.png","category_names":["Development na twardo"],"_links":{"self":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/12328"}],"collection":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/users\/325"}],"replies":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/comments?post=12328"}],"version-history":[{"count":2,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/12328\/revisions"}],"predecessor-version":[{"id":22284,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/12328\/revisions\/22284"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media\/12341"}],"wp:attachment":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media?parent=12328"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/categories?post=12328"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/tags?post=12328"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}