Mikhail Salosin. Golang Meetup. Uża Go fil-backend tal-applikazzjoni Ħares+

Mikhail Salosin (minn hawn 'il quddiem – MS): - Hi kollha! Jisimni Michael. Naħdem bħala żviluppatur backend f'MC2 Software, u se nitkellem dwar l-użu ta' Go fil-backend tal-applikazzjoni mobbli Look+.

Mikhail Salosin. Golang Meetup. Uża Go fil-backend tal-applikazzjoni Ħares+

Hawn xi ħadd jħobb il-hockey?

Mikhail Salosin. Golang Meetup. Uża Go fil-backend tal-applikazzjoni Ħares+

Imbagħad din l-applikazzjoni hija għalik. Huwa għal Android u iOS u jintuża biex tara xandiriet ta 'diversi avvenimenti sportivi onlajn u rreġistrati. L-applikazzjoni fiha wkoll statistika varji, xandiriet ta’ testi, tabelli għal konferenzi, tournaments u informazzjoni oħra utli għall-partitarji.

Mikhail Salosin. Golang Meetup. Uża Go fil-backend tal-applikazzjoni Ħares+

Fl-applikazzjoni wkoll hemm xi ħaġa bħal mumenti tal-vidjo, jiġifieri tista 'tara l-aktar mumenti importanti ta' logħbiet (goals, ġlied, shootouts, eċċ.). Jekk ma tridx tara x-xandira kollha, tista’ tara biss dawk l-aktar interessanti.

X'użajt fl-iżvilupp?

Il-parti ewlenija kienet miktuba f’Go. L-API li kkomunikaw magħha l-klijenti mobbli kienet miktuba f'Go. F’Go inkiteb ukoll servizz biex jintbagħtu notifiki push fuq il-mowbajls. Kellna wkoll niktbu l-ORM tagħna stess, li forsi nitkellmu dwaru xi darba. Ukoll, xi servizzi żgħar inkitbu f'Go: tibdil fid-daqs u tagħbija ta' immaġini għall-edituri...

Aħna użajna PostgreSQL bħala d-database. L-interface tal-editur inkiteb f'Ruby on Rails bl-użu tal-gem ActiveAdmin. L-importazzjoni tal-istatistika minn fornitur tal-istatistika hija wkoll miktuba b'Ruby.

Għat-testijiet tal-API tas-sistema, użajna Python unittest. Memcached jintuża biex jittrażżan is-sejħiet ta 'ħlas API, "Chef" jintuża biex jikkontrolla l-konfigurazzjoni, Zabbix jintuża biex jiġbor u jimmonitorja l-istatistika tas-sistema interna. Graylog2 huwa għall-ġbir ta 'zkuk, Slate hija dokumentazzjoni API għall-klijenti.

Mikhail Salosin. Golang Meetup. Uża Go fil-backend tal-applikazzjoni Ħares+

Għażla tal-Protokoll

L-ewwel problema li ltqajna magħhom: kellna nagħżlu protokoll għall-interazzjoni bejn il-klijenti backend u mobbli, ibbażat fuq il-punti li ġejjin...

  • L-iktar rekwiżit importanti: id-dejta dwar il-klijenti trid tiġi aġġornata f'ħin reali. Jiġifieri kull min bħalissa qed jara x-xandira għandu jirċievi aġġornamenti kważi istantanjament.
  • Biex nissimplifikaw l-affarijiet, asssumijna li data li hija sinkronizzata mal-klijenti ma titħassarx, iżda hija moħbija bl-użu ta 'bnadar speċjali.
  • Kull xorta ta' talbiet rari (bħal statistika, kompożizzjonijiet tat-tim, statistika tat-tim) jinkisbu minn talbiet GET ordinarji.
  • Barra minn hekk, is-sistema kellha tappoġġja faċilment 100 elf utent fl-istess ħin.

Abbażi ta’ dan, kellna żewġ għażliet ta’ protokoll:

  1. Websockets. Imma ma kellniex bżonn kanali mill-klijent sas-server. Għandna bżonn biss li nibagħtu aġġornamenti mis-server lill-klijent, għalhekk websocket hija għażla żejda.
  2. Avvenimenti Mibgħuta minn Server (SSE) ħarġu sewwa! Huwa pjuttost sempliċi u bażikament jissodisfa dak kollu li għandna bżonn.

Avvenimenti Mibgħuta minn Server

Ftit kelmiet dwar kif taħdem din il-ħaġa...

Hija taħdem fuq konnessjoni http. Il-klijent jibgħat talba, is-server jirrispondi b'Content-Type: text/event-stream u ma jagħlaqx il-konnessjoni mal-klijent, iżda jkompli jikteb id-dejta fil-konnessjoni:

Mikhail Salosin. Golang Meetup. Uża Go fil-backend tal-applikazzjoni Ħares+

Id-dejta tista’ tintbagħat f’format miftiehem mal-klijenti. Fil-każ tagħna, bgħatnieha f'din il-forma: l-isem tal-istruttura mibdula (persuna, plejer) intbagħat fil-qasam tal-avveniment, u JSON b'oqsma ġodda u mibdula għall-plejer intbagħat fil-qasam tad-dejta.

Issa ejja nitkellmu dwar kif taħdem l-interazzjoni nnifisha.

  • L-ewwel ħaġa li jagħmel il-klijent hija li jiddetermina l-aħħar darba li saret is-sinkronizzazzjoni mas-servizz: iħares lejn id-database lokali tiegħu u jiddetermina d-data tal-aħħar bidla rreġistrata minnu.
  • Hija tibgħat talba b'din id-data.
  • Bi tweġiba, aħna nibagħtulu l-aġġornamenti kollha li seħħew minn dik id-data.
  • Wara dan, jagħmel konnessjoni mal-kanal dirett u ma jagħlaqx sakemm ikollu bżonn dawn l-aġġornamenti:

Mikhail Salosin. Golang Meetup. Uża Go fil-backend tal-applikazzjoni Ħares+

Nibagħtulu lista ta’ bidliet: jekk xi ħadd jiskorja gowl, nibdlu l-iskor tal-partita, jekk iweġġa’, dan jintbagħat ukoll f’ħin reali. Għalhekk, il-klijenti jirċievu istantanjament dejta aġġornata fl-għalf tal-avveniment tal-partita. Perjodikament, sabiex il-klijent jifhem li s-server ma mietx, li ma ġaralu xejn, aħna nibagħtu timestamp kull 15-il sekonda - sabiex ikun jaf li kollox huwa fl-ordni u m'hemmx bżonn li terġa 'tikkonnettja.

Kif tiġi servita l-konnessjoni diretta?

  • L-ewwelnett, noħolqu kanal li fih jiġu riċevuti aġġornamenti buffered.
  • Wara dan, aħna tabbona għal dan il-kanal biex nirċievu aġġornamenti.
  • Aħna nissettjaw l-header korrett sabiex il-klijent ikun jaf li kollox huwa ok.
  • Ibgħat l-ewwel ping. Aħna sempliċiment nirreġistraw il-timestamp attwali tal-konnessjoni.
  • Wara dan, naqraw mill-kanal f'linja sakemm jingħalaq il-kanal tal-aġġornament. Il-kanal jirċievi perjodikament jew il-timestamp attwali jew bidliet li aħna diġà qed niktbu biex tiftaħ konnessjonijiet.

Mikhail Salosin. Golang Meetup. Uża Go fil-backend tal-applikazzjoni Ħares+

L-ewwel problema li ltqajna magħhom kienet din li ġejja: għal kull konnessjoni miftuħa mal-klijent, ħloqna tajmer li mmarka darba kull 15-il sekonda - jirriżulta li kieku kellna 6 elf konnessjoni miftuħa b'magna waħda (b'server API wieħed), 6 inħolqu elf tajmer. Dan wassal biex il-magna ma żżommx it-tagħbija meħtieġa. Il-problema ma kinitx daqshekk ovvja għalina, imma sibna ftit għajnuna u rranġawha.

Bħala riżultat, issa l-ping tagħna ġej mill-istess kanal li minnu ġej l-aġġornament.

Għaldaqstant, hemm tajmer wieħed biss li jimmarka darba kull 15-il sekonda.

Hemm bosta funzjonijiet awżiljarji hawn - tibgħat l-header, ping u l-istruttura nnifisha. Jiġifieri, l-isem tat-tabella (persuna, logħba, staġun) u l-informazzjoni dwar din l-entrata huma trażmessi hawn:

Mikhail Salosin. Golang Meetup. Uża Go fil-backend tal-applikazzjoni Ħares+

Mekkaniżmu biex jintbagħtu aġġornamenti

Issa ftit dwar minn fejn jiġu l-bidliet. Għandna diversi nies, edituri, li jaraw ix-xandira f'ħin reali. Huma joħolqu l-avvenimenti kollha: xi ħadd tkeċċa, xi ħadd weġġa’, xi tip ta’ sostitut...

Bl-użu ta' CMS, id-data tidħol fid-database. Wara dan, id-database tavża lis-servers tal-API dwar dan billi tuża l-mekkaniżmu Isma/Avviż. Is-servers tal-API diġà jibagħtu din l-informazzjoni lill-klijenti. Għalhekk, essenzjalment għandna biss ftit servers konnessi mad-database u m'hemm l-ebda tagħbija speċjali fuq id-database, minħabba li l-klijent ma jinteraġixxix direttament mad-database bl-ebda mod:

Mikhail Salosin. Golang Meetup. Uża Go fil-backend tal-applikazzjoni Ħares+

PostgreSQL: Isma'/Avża

Il-mekkaniżmu Isma/Avviż f'Postgres jippermettilek tinnotifika lill-abbonati tal-avvenimenti li xi avveniment inbidel - inħoloq xi rekord fid-database. Biex tagħmel dan, ktibna grillu u funzjoni sempliċi:

Mikhail Salosin. Golang Meetup. Uża Go fil-backend tal-applikazzjoni Ħares+

Meta ddaħħal jew nibdlu rekord, insejħu l-funzjoni ta 'notifika fuq il-kanal data_updates, u ngħaddu hemm l-isem tat-tabella u l-identifikatur tar-rekord li nbidel jew daħħal.

Għat-tabelli kollha li jridu jiġu sinkronizzati mal-klijent, aħna niddefinixxu grillu, li, wara li tbiddel / aġġorna rekord, isejjaħ il-funzjoni indikata fuq is-slide hawn taħt.
L-API kif tabbona għal dawn il-bidliet?

Jinħoloq mekkaniżmu Fanout - jibgħat messaġġi lill-klijent. Tiġbor il-kanali kollha tal-klijenti u tibgħat aġġornamenti li rċeviet permezz ta' dawn il-kanali:

Mikhail Salosin. Golang Meetup. Uża Go fil-backend tal-applikazzjoni Ħares+

Hawnhekk il-librerija standard pq, li tikkonnettja mad-database u tgħid li trid tisma 'l-kanal (data_updates), tiċċekkja li l-konnessjoni hija miftuħa u kollox huwa tajjeb. Qed inħalli barra l-iċċekkjar tal-iżbalji biex jiffranka l-ispazju (li ma ċċekkjax hija perikoluża).

Sussegwentement, aħna nissettjaw Ticker b'mod mhux sinkroniku, li se jibgħat ping kull 15-il sekonda, u nibdew nisimgħu l-kanal li abbonajna għalih. Jekk nirċievu ping, aħna nippubblikaw dan il-ping. Jekk nirċievu xi tip ta 'dħul, allura nippubblikaw din id-dħul lill-abbonati kollha ta' dan il-Fanout.

Kif jaħdem Fan-out?

Bir-Russu dan jittraduċi bħala "splitter". Għandna oġġett wieħed li jirreġistra l-abbonati li jridu jirċievu xi aġġornamenti. U hekk kif jasal aġġornament għal dan l-oġġett, iqassam dan l-aġġornament lill-abbonati kollha tiegħu. Sempliċi biżżejjed:

Mikhail Salosin. Golang Meetup. Uża Go fil-backend tal-applikazzjoni Ħares+

Kif hija implimentata f'Go:

Mikhail Salosin. Golang Meetup. Uża Go fil-backend tal-applikazzjoni Ħares+

Hemm struttura, hija sinkronizzata bl-użu ta 'Mutexes. Għandu qasam li jiffranka l-istat tal-konnessjoni ta 'Fanout mad-database, jiġifieri bħalissa qed jisma' u se jirċievi aġġornamenti, kif ukoll lista tal-kanali kollha disponibbli - mappa, li ċ-ċavetta tagħha hija l-kanal u l-istruttura fil-forma ta ' valuri (essenzjalment ma jintuża bl-ebda mod).

Żewġ metodi - Konnessi u Skonnettjati - jippermettulna ngħidu lil Fanout li għandna konnessjoni mal-bażi, deher u li l-konnessjoni mal-bażi nkisret. Fit-tieni każ, trid skonnettja l-klijenti kollha u tgħidilhom li ma jistgħux jisimgħu aktar minn xejn u li jerġgħu jgħaqqdu minħabba li l-konnessjoni magħhom tkun għalqet.

Hemm ukoll metodu Abbona li jżid il-kanal mas-"semmiegħa":

Mikhail Salosin. Golang Meetup. Uża Go fil-backend tal-applikazzjoni Ħares+

Hemm metodu Unsubscribe, li jneħħi l-kanal mis-semmiegħa jekk il-klijent jiskonnettja, kif ukoll metodu Publish, li jippermettilek li tibgħat messaġġ lill-abbonati kollha.

Mistoqsija: – X'jiġi trażmess permezz ta' dan il-kanal?

SINJORINA: – Il-mudell li nbidel jew ping jiġi trażmess (essenzjalment biss numru, numru sħiħ).

SINJORINA: - Tista 'tibgħat xi ħaġa, tibgħat kwalunkwe struttura, tippubblikaha - tinbidel biss f'JSON u dak hu.

SINJORINA: – Nirċievu notifika minn Postgres – fiha l-isem tat-tabella u l-identifikatur. Ibbażat fuq l-isem u l-identifikatur tat-tabella, aħna nġibu r-rekord li neħtieġu, u mbagħad nibagħtu din l-istruttura għall-pubblikazzjoni.

Infrastruttura

Kif jidher dan mill-perspettiva tal-infrastruttura? Għandna 7 servers tal-ħardwer: wieħed minnhom huwa kompletament iddedikat għad-database, is-sitta l-oħra jmexxu magni virtwali. Hemm 6 kopji tal-API: kull magna virtwali bl-API taħdem fuq server hardware separat - dan huwa għall-affidabbiltà.

Mikhail Salosin. Golang Meetup. Uża Go fil-backend tal-applikazzjoni Ħares+

Għandna żewġ frontends b'Keepalived installat biex intejbu l-aċċessibbiltà, sabiex jekk jiġri xi ħaġa, frontend wieħed jista' jissostitwixxi l-ieħor. Ukoll – żewġ kopji tas-CMS.

Hemm ukoll importatur tal-istatistika. Hemm DB Slave li minnu jsiru backups perjodikament. Hemm Pigeon Pusher, applikazzjoni li tibgħat notifiki push lill-klijenti, kif ukoll affarijiet infrastrutturali: Zabbix, Graylog2 u Chef.

Fil-fatt, din l-infrastruttura hija żejda, minħabba li 100 elf jistgħu jiġu moqdija b'inqas servers. Imma kien hemm ħadid - użajna (qalilna li kien possibbli - għaliex le).

Vantaġġi ta 'Go

Wara li ħdimna fuq din l-applikazzjoni, ħarġu vantaġġi ovvji bħal dawn ta 'Go.

  • Kessaħ http librerija. Biha tista 'toħloq pjuttost ħafna barra mill-kaxxa.
  • Barra minn hekk, kanali li ppermettewna nimplimentaw faċilment mekkaniżmu biex jintbagħtu notifiki lill-klijenti.
  • L-isbaħ ħaġa Race detector ippermetta li neliminaw diversi bugs kritiċi (infrastruttura ta 'staging). Jiġi mniedi dak kollu li jaħdem fuq il-waqfien, miġbur biċ-ċavetta Race; u aħna, għalhekk, nistgħu nħarsu lejn l-infrastruttura tal-waqfien biex naraw x'problemi potenzjali għandna.
  • Minimaliżmu u sempliċità tal-lingwa.

Mikhail Salosin. Golang Meetup. Uża Go fil-backend tal-applikazzjoni Ħares+

Qegħdin infittxu żviluppaturi! Jekk xi ħadd irid, jekk jogħġbok.

mistoqsijiet

Mistoqsija mill-udjenza (minn hawn 'il quddiem – B): – Jidhirli li tlift punt wieħed importanti rigward Fan-out. Jiena korrett meta nifhem li meta tibgħat tweġiba lil klijent, timblokka jekk il-klijent ma jridx jaqra?

SINJORINA: - Le, mhux qed nibblukkaw. L-ewwelnett, għandna dan kollu wara nginx, jiġifieri, m'hemm l-ebda problemi bi klijenti bil-mod. It-tieni, il-klijent għandu kanal b'buffer - fil-fatt, nistgħu npoġġu sa mitt aġġornament hemmhekk... Jekk ma nistgħux niktbu lill-kanal, allura jħassarha. Jekk naraw li l-kanal huwa mblukkat, allura aħna sempliċement nagħlqu l-kanal, u dak hu - il-klijent jerġa 'jikkonnettja jekk tinqala' xi problema. Għalhekk, fil-prinċipju, m'hemm l-ebda imblukkar hawn.

FI: – Ma jistax ikun possibbli li jintbagħat immedjatament rekord lil Isma/Avviż, u mhux tabella ta’ identifikaturi?

SINJORINA: – Isma/Avviż għandu limitu ta’ 8 elf bytes fuq il-preload li jibgħat. Fil-prinċipju, ikun possibbli li nibgħatu kieku nkunu qed nittrattaw ma 'ammont żgħir ta' dejta, iżda jidhirli li b'dan il-mod [il-mod kif nagħmluh] huwa sempliċement aktar affidabbli. Il-limitazzjonijiet huma f'Postgres innifsu.

FI: – Il-klijenti jirċievu aġġornamenti dwar logħbiet li mhumiex interessati fihom?

SINJORINA: - B'mod ġenerali, iva. Bħala regola, hemm 2-3 logħbiet għaddejjin b'mod parallel, u anke allura pjuttost rari. Jekk klijent qed jara xi ħaġa, allura ġeneralment ikun qed jara l-partita li tkun għaddejja. Imbagħad, il-klijent għandu database lokali li fiha dawn l-aġġornamenti kollha huma miżjuda, u anke mingħajr konnessjoni tal-Internet, il-klijent jista 'jara l-logħbiet kollha tal-passat li għalihom għandu aġġornamenti. Essenzjalment, aħna nissinkronizzaw id-database tagħna fuq is-server mad-database lokali tal-klijent sabiex ikun jista 'jaħdem offline.

FI: – Għaliex għamilt l-ORM tiegħek?

Alexey (wieħed mill-iżviluppaturi ta' Look+): – Dak iż-żmien (kien sena ilu) kien hemm inqas ORMs minn issa, meta hemm pjuttost ħafna minnhom. Il-ħaġa favorita tiegħi dwar il-biċċa l-kbira tal-ORMs hemmhekk hija li ħafna minnhom jaħdmu fuq interfaces vojta. Jiġifieri, il-metodi f'dawn l-ORMs huma lesti biex jieħdu kull ħaġa: struttura, punter ta' struttura, numru, xi ħaġa kompletament irrilevanti...

L-ORM tagħna jiġġenera strutturi bbażati fuq il-mudell tad-dejta. Jien stess. U għalhekk il-metodi kollha huma konkreti, ma jużawx riflessjoni, eċċ Jaċċettaw strutturi u jistennew li jużaw dawk l-istrutturi li ġejjin.

FI: – Kemm nies ħadu sehem?

SINJORINA: – Fl-istadju inizjali, ipparteċipaw żewġ persuni. Bdejna x'imkien f'Ġunju, u f'Awwissu l-parti prinċipali kienet lesta (l-ewwel verżjoni). Kien hemm rilaxx f'Settembru.

FI: – Fejn tiddeskrivi SSE, ma tużax timeout. Għalfejn?

SINJORINA: – Biex inkun onest, SSE għadu protokoll html5: l-istandard SSE huwa ddisinjat biex jikkomunika mal-browsers, sa fejn nifhem jien. Għandu karatteristiċi addizzjonali sabiex il-browsers jistgħu jerġgħu jgħaqqdu (u l-bqija), iżda m'għandniex bżonnhom, għaliex kellna klijenti li setgħu jimplimentaw kwalunkwe loġika għall-konnessjoni u r-riċeviment tal-informazzjoni. Aħna ma għamilniex SSE, iżda pjuttost xi ħaġa simili għal SSE. Dan mhuwiex il-protokoll innifsu.
Ma kienx hemm bżonn. Sa fejn nifhem, il-klijenti implimentaw il-mekkaniżmu ta 'konnessjoni kważi mill-bidu. Huma ma tantx jimpurtahom.

FI: – Liema utilitajiet addizzjonali użajt?

SINJORINA: – Aħna bl-aktar mod attiv użajna govet u golint biex nagħmlu l-istil unifikat, kif ukoll gofmt. Ma ntuża xejn ieħor.

FI: – X'użajt biex tiddibaggja?

SINJORINA: – Id-debugging fil-biċċa l-kbira sar bl-użu ta’ testijiet. Aħna ma użajna l-ebda debugger jew GOP.

FI: – Tista' tirritorna s-slide fejn hija implimentata l-funzjoni Ippubblika? Ismijiet varjabbli b'ittra waħda jħawduk?

SINJORINA: - Le. Għandhom skop ta 'viżibilità pjuttost "dejqa". Ma jintużawx imkien ieħor ħlief hawn (ħlief għall-intern ta 'din il-klassi), u huwa kompatt ħafna - jieħu biss 7 linji.

FI: – B’xi mod għadu mhux intuwittiv...

SINJORINA: - Le, le, dan huwa kodiċi reali! Mhuwiex dwar stil. Hija biss klassi utilitarja u żgħira ħafna - 3 oqsma biss ġewwa l-klassi...

Mikhail Salosin. Golang Meetup. Uża Go fil-backend tal-applikazzjoni Ħares+

SINJORINA: – B'mod ġenerali, id-dejta kollha li hija sinkronizzata mal-klijenti (logħbiet tal-istaġun, plejers) ma tinbidilx. Bejn wieħed u ieħor, jekk nagħmlu sport ieħor li fih irridu nbiddlu l-logħba, aħna sempliċement nikkunsidraw kollox fil-verżjoni l-ġdida tal-klijent, u l-verżjonijiet qodma tal-klijent jiġu pprojbiti.

FI: – Hemm xi pakketti ta' ġestjoni tad-dipendenza minn partijiet terzi?

SINJORINA: – Aħna użati go dep.

FI: – Kien hemm xi ħaġa dwar il-vidjo fis-suġġett tar-rapport, iżda ma kien hemm xejn fir-rapport dwar il-vidjo.

SINJORINA: – Le, m'għandi xejn fis-suġġett dwar il-video. Tissejjaħ "Ħares +" - dak huwa l-isem tal-applikazzjoni.

FI: – Inti għidt li hija streamed lill-klijenti?...

SINJORINA: – Aħna ma konniex involuti fl-istrimjar tal-vidjo. Dan sar kollu minn Megafon. Iva, ma għedtx li l-applikazzjoni kienet MegaFon.

SINJORINA: – Mur – biex tibgħat id-dejta kollha – dwar il-punteġġ, dwar l-avvenimenti tal-partiti, l-istatistika... Go hija l-backend kollu għall-applikazzjoni. Il-klijent irid ikun jaf minn x'imkien liema link juża għall-plejer sabiex l-utent ikun jista' jara l-partita. Għandna links għal videos u streams li ġew ippreparati.

Xi reklami 🙂

Grazzi talli bqajt magħna. Tħobb l-artikoli tagħna? Trid tara aktar kontenut interessanti? Appoġġuna billi tagħmel ordni jew tirrakkomanda lill-ħbieb, Cloud VPS għall-iżviluppaturi minn $4.99, analogu uniku ta 'servers ta' livell ta 'dħul, li ġie ivvintat minna għalik: Il-verità kollha dwar VPS (KVM) E5-2697 v3 (6 Cores) 10GB DDR4 480GB SSD 1Gbps minn $19 jew kif taqsam server? (disponibbli b'RAID1 u RAID10, sa 24 core u sa 40GB DDR4).

Dell R730xd 2 darbiet orħos fiċ-ċentru tad-dejta Equinix Tier IV f'Amsterdam? Hawn biss 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 TV minn $199 fl-Olanda! Dell R420 - 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB - minn $99! Aqra dwar Kif tibni l-infrastruttura corp. klassi bl-użu ta 'servers Dell R730xd E5-2650 v4 li jiswew 9000 ewro għal ċenteżmu?

Sors: www.habr.com

Żid kumment