Mūsu pieredze API Gateway izveidē

Dažas kompānijas, tostarp mūsu klients, attīsta produktu caur partneru tīklu. Piemēram, lieli interneta veikali ir integrēti ar piegādes pakalpojumu — jūs pasūtāt preci un drīz saņemat sūtījuma izsekošanas numuru. Vēl viens piemērs — kopā ar aviobiļeti jūs pērkat apdrošināšanu vai biļeti uz aeroekspresu.

Tās mērķim tiek izmantots viens API, kuru jādod partneriem caur API Gateway. Šo uzdevumu mēs arī atrisinājām. Šajā rakstā dalīsimies detaļās.

Doti: ekosistēma un API portāls ar interfeisu, kurā lietotāji ir reģistrēti, saņem informāciju utt. Mums jāizveido ērts un uzticams API Gateway. Procesā mums bija jānodrošina

  • reģistrācija,
  • kontrole pār pieslēgšanos API,
  • monitorings, kā lietotāji izmanto gala sistēmu,
  • biznesa rādītāju uzskaite.

Mūsu pieredze API Gateway izveidē

Rakstā mēs pastāstīsim par mūsu pieredzi API Gateway izveidē, kurā mēs risinājām šādus uzdevumus:

  • lietotāju autentifikācija,
  • lietotāju autorizācija,
  • iegūtā pieprasījuma modificēšana,
  • pieprasījuma proksēšana,
  • atbildes pēcapstrāde.


Ir divi API pārvaldības veidi:

1. Standarta, kas darbojas šādi: pirms pieslēgšanas lietotājs pārbauda iespējas, pēc tam maksā un integrē to savā mājaslapā. Visbiežāk to izmanto mazie un vidējie uzņēmumi.

2. Liels B2B API Management, kad kompānija vispirms pieņem biznesa lēmumu par pieslēgšanu, kļūst par partneri uzņēmumam ar līguma saistībām, pēc kā pieslēdzas API. Tikai pēc visu formalitāšu nokārtošanas kompānija saņem izmēģinājuma piekļuvi, veic testēšanu un pāriet uz ražošanas vidi. Bet tas nav iespējams bez vadības lēmuma par pieslēgšanu.

Mūsu pieredze API Gateway izveidē

Mūsu risinājums

Šajā daļā pastāstīsim par API Gateway izveidi.

Gala lietotāji izveidotajam API slieksnim ir mūsu klienta partneri. Katram no tiem jau ir saglabāti nepieciešamie līgumi. Mums vienkārši jāpaplašina funkcionalitāte, atzīmējot piešķirto piekļuvi slieksnim. Attiecīgi nepieciešams kontrollēts pieslēgšanās un pārvaldības process.

Bez šaubām, varēja izmantot kādu gatavu risinājumu API pārvaldības uzdevuma risināšanai un API Gateway izveidei. Piemēram, tas varētu būt Azure API Management. Mums tas nepiestāvēja, jo mūsu gadījumā jau bija API portāls un milzīga ekosistēma, kas bija ap to izveidota. Visi lietotāji jau bija reģistrējušies, un viņi jau saprata, kur un kā viņi var iegūt nepieciešamo informāciju. API portālā jau bija nepieciešamās saskarnes, mums vienkārši bija vajadzīgs API Gateway. Patiesībā tieši tā izstrādei mēs arī pievērsāmies.

Tas, ko mēs saucam par API Gateway, ir sava veida prokss. Šeit mums atkal bija izvēle — vai nu rakstīt savu prokss, vai izvēlēties jau ko gatavu. Šajā gadījumā mēs devāmies pa otro ceļu un izvēlējāmies nginxs+Lua. Kādēļ? Mums bija nepieciešams uzticams, testēts programmatūras risinājums, kas atbalsta mērogojamību. Mēs negribējām pēc ieviešanas pārbaudīt gan biznesa loģikas pareizību, gan prokss darbību.

Jebkuram tīmekļa serverim ir pieprasījuma apstrādes cauruļvads. Nginsā tas izskatās šādi:

Mūsu pieredze API Gateway izveidē

(shēma no GitHub Lua Nginx)

Mūsu mērķis bija iekļauties šajā cauruļvadā tajā brīdī, kad mēs varam modificēt sākotnējo pieprasījumu.

Mēs vēlamies izveidot caurspīdīgu prokss, lai funkcionāli pieprasījums paliktu tāds, kāds tas bija. Mēs tikai kontrolējam piekļuvi gala API, palīdzam pieprasījumam tam piekļūt. Ja pieprasījums bija nepareizs, kļūdu jāparāda gala API, nevis mums. Vienīgā iemesls, kāpēc mēs varam noraidīt pieprasījumu, ir klienta piekļuves trūkums.

Nginsam jau pastāv paplašinājums uz Lua. Lua ir skriptu valoda, tā ir ļoti viegla un viegli apgūstama. Tādējādi nepieciešamo loģiku mēs realizējām, izmantojot Lua.

Ngins konfigurācija (analogie lietojumprogrammas maršruti), kur tiek veikta visa darbība, ir diezgan saprotama. Ievērības cienīga ir pēdējā direktīva – post_action.

location /middleware {
      more_clear_input_headers Accept-Encoding;
      lua_need_request_body on;
      rewrite_by_lua_file 'middleware/rewrite.lua';
      access_by_lua_file 'middleware/access.lua';
      proxy_pass https://someurl.com;
      body_filter_by_lua_file 'middleware/body_filter.lua';
      post_action /process_session;
}

Apskatīsim, kas notiek šajā konfigurācijā:
more_clear_input_headers — notīra norādīto virsrakstu vērtību, kas seko direktīvai.
lua_need_request_body — nosaka, vai ir jāizlasa sākotnējā pieprasījuma ķermenis pirms direktīvu rewrite/access/access_by_lua izpildes. Ngins parasti nelasa klienta pieprasījuma ķermeni, un, ja jums ir jāiegūst pieeja tam, šai direktīvai jābūt ar vērtību on.
rewrite_by_lua_file — ceļš uz skriptu, kurā aprakstīta loģika pieprasījuma modifikācijai
access_by_lua_file — ceļš uz skriptu, kurā aprakstīta loģika, kas pārbauda piekļuves esamību resursam.
proxy_pass — url, uz kuru tiks proksēts pieprasījums.
body_filter_by_lua_file — ceļš uz skriptu, kurā aprakstīta loģika pieprasījuma filtrēšanai pirms atgriešanas klientam.
Un visbeidzot, post_action — oficiāli nedokumentēta direktīva, ar kuras palīdzību var veikt vēl citas darbības pēc tam, kad atbilde ir nodota klientam.

Tālāk pastāstīsim pa kārtai, kā mēs risinājām savas problēmas.

Autorizācija/aizsardzība un pieprasījuma modifikācija

Autorizācija

Autorizāciju un aizsardzību mēs izveidojām, izmantojot piekļuves sertifikātus. Ir saknes sertifikāts. Katram jaunam klientam tiek ģenerēts viņa personīgais sertifikāts, ar kuru viņš var piekļūt API. Šis sertifikāts tiek konfigurēts servera sadaļā nginx iestatījumos.

ssl on;
ssl_certificate /usr/local/openresty/nginx/ssl/cert.pem;
ssl_certificate_key /usr/local/openresty/nginx/ssl/cert.pem;
ssl_client_certificate /usr/local/openresty/nginx/ssl/ca.crt;
ssl_verify_client on;

Modifikācija

Var rasties pamatots jautājums: ko darīt ar sertificēto klientu, ja mēs pēkšņi vēlamies viņu atslēgt no sistēmas? Nevēlamies jau atkārtoti izsniegt sertifikātus visiem citiem klientiem.

Tādējādi mēs pakāpeniski piegājām pie nākamās problēmas — pamata pieprasījuma modifikācija. Klienta sākotnējais pieprasījums, būtībā, nav derīgs galīgajai sistēmai. Viena no problēmām ir rakstīt pieprasījumā trūkstošās daļas, lai padarītu to derīgu. Sāls ir tajā, ka trūkstošie dati ir atšķirīgi katram klientam. Mēs zinām, ka klients pie mums ierodas ar sertifikātu, no kura varam iegūt pirksta nospiedumu un izvilkt no datubāzes nepieciešamos klienta datus.

Ja kādā brīdī būs nepieciešams atslēgt klientu no mūsu pakalpojuma, viņa dati izzudīs no datubāzes un viņš neko nevarēs darīt.

Darbs ar klienta datiem

Mums bija jānodrošina augsta pieejamība risinājumam, īpaši tam, kā mēs iegūstam klienta datus. Grūtības ir tajā, ka šo datu avots ir trešās puses pakalpojums, kurš negarantē nepārtrauktību un pietiekami augstu darba ātrumu.

Tāpēc mums bija jānodrošina augsta klienta datu pieejamība. Par instrumentu mēs izvēlējāmies Hazelcast, kas nodrošina mums:

  • ātru piekļuvi datiem,
  • iespēju organizēt klasteri no vairākiem mezgliem ar replicētiem datiem dažādos mezglos.

Mēs izvēlējāmies vienkāršāko datu piegādes stratēģiju kešā:

Mūsu pieredze API Gateway izveidē

Darbs ar gala sistēmu notiek sesiju ietvaros, un ir ierobežojums maksimālajam skaitam. Ja klients nav slēdzis sesiju, tas būs jādara mums.

Dati par atvērtajām sesijām nāk no gala sistēmas un sākotnēji tiek apstrādāti Lua pusē. Mēs nolēmām izmantot Hazelcast, lai saglabātu šos datus ar uzdevumu, kas uzrakstīts .NET. Tad ar noteiktu biežumu mēs pārbaudām atvērtajām sesijām eksistences tiesības un slēdzam iznīcinātās.

Piekļuve Hazelcast gan no Lua, gan no .NET

Lua klientu, lai strādātu ar Hazelcast, nav, taču Hazelcast ir REST API, ko mēs nolēmām izmantot. .NET pusē ir klients, caur kuru mēs plānojām piekļūt Hazelcast datiem .NET pusē. Bet ne šajā gadījumā.

Mūsu pieredze API Gateway izveidē

Datu saglabāšanai caur REST un izguvei caur .NET klientu tiek izmantoti dažādi serializētāji un deserializētāji. Tāpēc nav iespējams saglabāt datus caur REST un iegūt tos caur .NET klientu un vice versa.

Ja kādam būs interese, tad sīkāk par šo problēmu pastāstīsim atsevišķā rakstā. Spoilera brīdis — shēmā.

Mūsu pieredze API Gateway izveidē

Izsistīšana un monitorings

Mūsu korporatīvais standarts izsistīšanai caur .NET ir Serilog, visi žurnāli galu galā nonāk Elasticsearch, to analīzi veicam caur Kibana. Ko līdzīgu vēlējāmies izdarīt arī šajā gadījumā. Vienīgais klients Lua pusē atklātais risinājums Elastic darbam, sabojājās pirmajā require. Un mēs izmantojām Fluentd.

Fluentd — atvērtā koda risinājums, kas nodrošina vienotu lietojumprogrammas izsistīšanas slāni. Ļauj vākt žurnālus no dažādiem lietojumprogrammas slāņiem un pēc tam translēt tos vienā avotā.

API Gateway darbojas K8S, tāpēc mēs nolēmām pievienot konteineru ar Fluentd tajā pašā podā, lai rakstītu žurnālus esošajā atvērtajā tcp portā Fluentd.

Mēs arī izpētījām, kā rīkosies Fluentd, ja tam nebūs saiknes ar Elasticsearch. Divu dienu laikā vārtiem nepārtraukti nāca pieprasījumi, Fluentd sūtīja žurnālus, bet Fluentd IP Elastikam tika nobloķēts. Pēc saiknes atjaunošanas Fluentd lieliski nodeva visus žurnālus Elastikam.

Secinājums

Izvēlētais īstenošanas pieejas veids ļāva mums piegādāt reāli funkcionējošu produktu ražošanas vidē tikai 2.5 mēnešu laikā.

Ja, kad jums kādreiz nāksies nodarboties ar līdzīgām lietām, iesakām vispirms skaidri saprast, kādu uzdevumu jūs risināt un kādi resursi jums jau ir pieejami. Esiet uzmanīgi pret integrācijas sarežģījumiem ar esošajām API pārvaldības sistēmām.

Saprotiet sev, ko tieši jūs plānojat izstrādāt — tikai biznesa loģiku pieprasījumu apstrādei vai, kā varēja būt mūsu gadījumā, pilns starpniekserveris. Neaizmirstiet, ka viss, ko jūs izdarīsiet paši, vēlāk ir jātestē rūpīgi.

Avots: habr.com

Iegādājieties uzticamu tīmekļa hostingu ar DDoS aizsardzību, VPS VDS serveriem 🔥 Iegādājieties uzticamu tīmekļa hostingu ar DDoS aizsardzību, VPS VDS serveriem | ProHoster