Mūsu pieredze, radot API Gateway

Dažas uzņēmums, tostarp mūsu klients, attīsta produktu caur partneru tīklu. Piemēram, lieli interneta veikali ir integrēti ar piegādes dienestu — 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 gaisa ekspresi.

Tādēļ tiek izmantots viens API, kuru nepieciešams piegādāt partneriem caur API Gateway. Šo uzdevumu mēs arī risinājām. Šajā rakstā mēs pastāstīsim sīkāk.

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

  • reģistrācija,
  • savienojuma kontrole ar API,
  • monitorings par to, kā lietotāji izmanto beigu sistēmu,
  • biznesa rādītāju uzskaite.

Mūsu pieredze, radot API Gateway

Rakstā mēs pastāstīsim par mūsu pieredzi, radot API Gateway, kuras laikā mēs risinājām sekojošus uzdevumus:

  • lietotāja autentifikācija,
  • lietotāja autorizācija,
  • iegūtā pieprasījuma modificēšana,
  • pieprasījuma starpniekošana,
  • atbildes apstrāde.


Ir divi veidi API pārvaldības:

1. Standarta, kas darbojas šādi. Pirms piekļuves lietotājs pārbauda iespējas, pēc tam maksā un integrē savā vietnē. Visbiežāk to izmanto mazajos un vidējos uzņēmumos.

2. Liels B2B API vadības risinājums, kad uzņēmums vispirms pieņem biznesa lēmumu par savienojumu, kļūst par uzņēmuma partneri ar līgumisku saistību, pēc tam pieslēdzas API. Un tikai pēc visu formalitāšu nokārtošanas uzņēmums saņem testa piekļuvi, veic testēšanu un nonāk ražošanas vidē. Bet tas nav iespējams bez vadības lēmuma par savienojumu.

Mūsu pieredze, radot API Gateway

Mūsu risinājums

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

Galīgie lietotāji izveidotajam API grozam ir mūsu klienta partneri. Katram no viņiem jau ir saglabāti nepieciešamie līgumi. Mums būs tikai jāpaplašina funkcionalitāte, norādot piešķirto piekļuvi grozam. Tādējādi nepieciešams kontrolēts savienojuma un pārvaldības process.

Neapšaubāmi, mēs varējām izvēlēties kādu gatavu risinājumu API vadības uzdevuma un konkrēti API Gateway izveides risināšanai. Piemēram, tas varētu būt Azure API Management. Tas mums nederēja, jo mūsu gadījumā jau bija API portāls un liela ekosistēma, kas tika veidota ap to. Visi lietotāji jau bija reģistrēti, viņi jau saprata, kur un kā viņi var saņemt nepieciešamo informāciju. API portālā jau bija nepieciešamie interfeisi, mums tikai vajadzēja API Gateway. Faktiski tieši tā izstrāde arī bija mūsu uzdevums.

To, ko mēs saucam par API Gateway, var uzskatīt par sava veida proksī. Šeit mums atkal bija izvēle — vai nu rakstīt savu proksī, vai arī izvēlēties jau kādu gatavu risinājumu. Šajā gadījumā mēs izvēlējāmies otro ceļu un izvēlējāmies kombināciju nginx+Lua. Kāpēc? Mums bija nepieciešams uzticams, pārbaudīts programmatūras risinājums, kas atbalsta mērogojamību. Mēs nevēlējāmies pēc realizācijas pārbaudīt ne biznesa loģikas korektumu, ne proksī darbību.

Jebkuram tīmekļa serverim ir pieprasījumu apstrādes cauruļvads. Nginx gadījumā tas izskatās šādi:

Mūsu pieredze, radot API Gateway

(shēma no GitHub Lua Nginx)

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

Mēs vēlamies izveidot caurspīdīgu proksī, lai funkcionāli pieprasījums paliktu tāds, kāds tas bija, kad ieradās. Mēs tikai kontrolējam piekļuvi galīgajam API, palīdzam pieprasījumam nonākt pie tā. Ja pieprasījums bija nepareizs, kļūda jāparāda galīgajam API, nevis mums. Vienīgā iemesla dēļ, kāpēc mēs varam noraidīt pieprasījumu, ir klienta piekļuves trūkums.

Nginx jau pastāv paplašinājums uz Lua. Lua ir skripta valoda, tā ir ļoti viegla un viegli apgūstama. Tādējādi nepieciešamo loģiku mēs īstenojām ar Lua palīdzību.

nginx konfigurācija (analogija lietotnes maršrutam), kur tiek veikta visa darbs, ir pilnīgi saprotama. Šeit ir interesanta 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 — noņem norādīto virsrakstu vērtības.
lua_need_request_body — regulē, vai pirms rewrite/access/access_by_lua direktīvu izpildes jāizlasa sākotnējais pieprasījuma ķermenis vai nē. Noklusējumā nginx neizlasa klienta pieprasījuma ķermeni, un, ja jums ir nepieciešams piekļūt tam, šai direktīvai jābūt vērtībai on.
rewrite_by_lua_file — ceļš uz skriptu, kurā aprakstīta loģika pieprasījuma modificēšanai.
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 pārsūtī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 neizdokumentē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 stāstīsim secīgi, kā mēs risinājām savas problēmas.

Autorizācija/auditi un pieprasījuma modificēšana

Autorizācija

Autorizāciju un autentifikāciju mēs veicām, izmantojot piekļuves sertifikātus. Ir galvenais 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 iestatīts nginx servera iestatījumu sadaļā.

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;

Modificēšana

Var rasties pamatots jautājums: ko darīt ar sertificētu klientu, ja mēs pēkšņi vēlamies viņu atslēgt no sistēmas? Vai tad nevajadzētu izsniegt jaunus sertifikātus visiem pārējiem klientiem.

Tādējādi mēs pakāpeniski nonācām pie nākamā uzdevuma — modificēt sākotnējo pieprasījumu. Sākotnējais klienta pieprasījums vispārīgi nav derīgs gala sistēmai. Viens no uzdevumiem ir papildināt pieprasījumā trūkstošās daļas, lai padarītu to derīgu. Jāatceras, ka trūkstošie dati ir atšķirīgi katram klientam. Mēs zinām, ka klients pie mums nāk ar sertifikātu, no kura varam iegūt pirkstu nospiedumu un izvilkt nepieciešamos klienta datus no datu bāzes.

Ja kādā brīdī būs nepieciešams atslēgt klientu no mūsu pakalpojuma, viņa dati pazudīs no datu bāzes un viņš nekam nevarēs darboties.

Darbs ar klienta datiem

Mums bija jānodrošina augsta risinājuma pieejamība, īpaši attiecībā uz to, kā mēs iegūstam klienta datus. Grūtības ir tādas, ka šo datu primārais avots ir trešā puse, kas negarantē nepārtrauktu un pietiekami augstu darbības ātrumu.

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

  • Ātru piekļuvi datiem,
  • Iespēju izveidot klasteri no vairākām mezglām ar replikējiem uz dažādiem mezgliem datiem.

Mēs devāmies uz vienkāršāko datu piegādes stratēģiju kešā:

Mūsu pieredze, radot API Gateway

Darbs ar gala sistēmu notiek sesiju ietvaros, un ir ierobežojums uz maksimālo skaitu. Ja klients nav aizvēris sesiju, to būs jāizdara mums.

Dati par atvērtu sesiju 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 jobā, kas uzrakstīts .NET. Pēc tam ar zināmu periodiskumu mēs pārbaudām atvērtu sesiju esamību un aizveram beigušās.

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

Lua klientu darbam ar Hazelcast nav, taču Hazelcast ir REST API, kuru mēs nolēmām izmantot. Savukārt .NET ir klients, caur kuru mēs plānojām piekļūt Hazelcast datiem .NET pusē. Bet tas nesanāca.

Mūsu pieredze, radot API Gateway

Saglabājot datus caur REST un izņemot caur .NET klientu tiek izmantoti atšķirīgi serializatori/deserializatori. Tāpēc nav iespējams ievietot datus caur REST un izņemt caur .NET klienta, un otrādi.

Ja būs interese, mēs sīkāk pastāstīsim par šo problēmu atsevišķā rakstā. Spoilera brīdinājums — diagrammā.

Mūsu pieredze, radot API Gateway

Logēšana un uzraudzība

Mūsu korporatīvais standarts logu reģistrēšanai caur .NET ir Serilog, visi žurnāli nonāk Elasticsearch, un to analīzi veicam caur Kibanu. Ko līdzīgu gribējām izdarīt arī šajā gadījumā. Vienīgais klients risinājums darbam ar Elastic Lua, kas tika atrasts, sabojājās pirmajā require. Un mēs izmantojām Fluentd.

Fluentd — atvērtā koda risinājums, lai nodrošinātu vienotu lietojumprogrammas logu slāni. Tas ļauj vākt logus no dažādiem lietojumprogrammas slāņiem un pēc tam pārraidīt tos vienotā avotā.

API Gateway darbojas K8S, tādēļ nolēmām pievienot konteineru ar fluentd tajā pašā podā, lai rakstītu logus esošajā atvērtajā tcp portā fluentd.

Mēs arī izpētījām, kā rīkosies fluentd, ja tas zaudēs savienojumu ar Elasticsearch. Divu dienu laikā vārtiem nepārtraukti nāca pieprasījumi, fluentd sūtīja logus, bet fluentd IP adresei bija bloķēta savienojums ar Elastic. Pēc savienojuma atjaunošanas fluentd lieliski pārraidīja visus logus uz Elastic.

Secinājums

Izvēlētais pielietojuma veids ļāva mums piegādāt patiešām funkcionējošu produktu ražošanas vidē tikai 2,5 mēnešu laikā.

Ja kādreiz jums radīsies iespēja nodarboties ar līdzīgām lietām, iesakām vispirms skaidri saprast, kādu uzdevumu risināt un kādi resursi jums jau ir. Esiet uzmanīgi pret integrācijas grūtībām ar esošajiem API pārvaldības sistēmām.

Saproti sev, ko tieši tu plāno izstrādāt — tikai biznesa loģiku pieprasījumu apstrādei vai, kā tas varēja būt mūsu gadījumā, pašu proksi. Neaizmirsti, ka viss, ko tu izdarīsi pats, vēlāk ir rūpīgi jāpārbauda.

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