Η εμπειρία μας στη δημιουργία API Gateway

Ορισμένες εταιρείες, συμπεριλαμβανομένου του πελάτη μας, αναπτύσσουν το προϊόν μέσω ενός δικτύου συνεργατών. Για παράδειγμα, τα μεγάλα ηλεκτρονικά καταστήματα είναι ενσωματωμένα με την υπηρεσία παράδοσης - παραγγέλνετε ένα προϊόν και σύντομα λαμβάνετε έναν αριθμό παρακολούθησης για το πακέτο. Ένα άλλο παράδειγμα είναι όταν αγοράζετε ασφάλεια ή εισιτήριο Aeroexpress μαζί με το αεροπορικό σας εισιτήριο.

Για αυτό, χρησιμοποιείται ένα API, το οποίο πρέπει να εκδοθεί σε συνεργάτες μέσω του API Gateway. Έχουμε λύσει αυτό το πρόβλημα. Σε αυτό το άρθρο θα σας πούμε τις λεπτομέρειες.

Δεδομένα: ένα οικοσύστημα και μια πύλη API με διεπαφή όπου οι χρήστες εγγράφονται, λαμβάνουν πληροφορίες κ.λπ. Πρέπει να δημιουργήσουμε μια βολική και αξιόπιστη πύλη API. Στην πορεία χρειάστηκε να παρέχουμε

  • εγγραφή,
  • Έλεγχος σύνδεσης API,
  • παρακολούθηση του τρόπου με τον οποίο οι χρήστες χρησιμοποιούν το τελικό σύστημα,
  • λογιστική για τους επιχειρηματικούς δείκτες.

Η εμπειρία μας στη δημιουργία API Gateway

Στο άρθρο θα μιλήσουμε για την εμπειρία μας στη δημιουργία API Gateway, κατά την οποία λύσαμε τις ακόλουθες εργασίες:

  • έλεγχος ταυτότητας χρήστη,
  • εξουσιοδότηση χρήστη,
  • τροποποίηση του αρχικού αιτήματος,
  • αίτηση πληρεξουσίου,
  • μεταεπεξεργασία απάντησης.


Υπάρχουν δύο τύποι διαχείρισης API:

1. Πρότυπο, το οποίο λειτουργεί ως εξής. Πριν συνδεθεί, ο χρήστης δοκιμάζει τις δυνατότητες, στη συνέχεια πληρώνει και ενσωματώνει στον ιστότοπό του. Τις περισσότερες φορές χρησιμοποιούνται σε μικρές και μεσαίες επιχειρήσεις.

2. Διαχείριση μεγάλων B2B API, όταν η εταιρεία παίρνει για πρώτη φορά μια επιχειρηματική απόφαση για σύνδεση, γίνεται συνεργάτης της εταιρείας με συμβατική υποχρέωση και στη συνέχεια συνδέεται με το API. Και αφού διευθετηθούν όλες οι διατυπώσεις, η εταιρεία λαμβάνει δοκιμαστική πρόσβαση, περνάει τις δοκιμές και μπαίνει στην παραγωγή. Αλλά αυτό δεν είναι δυνατό χωρίς απόφαση διαχείρισης για σύνδεση.

Η εμπειρία μας στη δημιουργία API Gateway

Η λύση μας

Σε αυτό το μέρος, θα μιλήσουμε για τη δημιουργία μιας πύλης API.

Οι τελικοί χρήστες της πύλης API που δημιουργήθηκε είναι συνεργάτες του πελάτη μας. Έχουμε ήδη τα απαραίτητα συμβόλαια για καθένα από αυτά. Θα χρειαστεί μόνο να επεκτείνουμε τη λειτουργικότητα επισημαίνοντας την παραχωρημένη πρόσβαση στην πύλη. Κατά συνέπεια, απαιτείται μια ελεγχόμενη διαδικασία σύνδεσης και διαχείρισης.

Φυσικά, ήταν δυνατό να ληφθεί κάποια έτοιμη λύση για την επίλυση του προβλήματος της διαχείρισης API και τη δημιουργία μιας πύλης API ειδικότερα. Για παράδειγμα, αυτό θα μπορούσε να είναι Διαχείριση Azure API. Δεν μας ταίριαζε, γιατί στην περίπτωσή μας είχαμε ήδη μια πύλη API και ένα τεράστιο οικοσύστημα χτισμένο γύρω της. Όλοι οι χρήστες έχουν ήδη εγγραφεί, έχουν ήδη καταλάβει πού και πώς μπορούν να λάβουν τις απαραίτητες πληροφορίες. Οι απαραίτητες διεπαφές υπήρχαν ήδη στην πύλη API, χρειαζόμασταν μόνο το API Gateway. Στην πραγματικότητα, ασχολούμαστε με την ανάπτυξή του.

Αυτό που ονομάζουμε πύλη API είναι ένα είδος διακομιστή μεσολάβησης. Εδώ είχαμε πάλι μια επιλογή - μπορείτε να γράψετε το δικό σας πληρεξούσιο ή μπορείτε να επιλέξετε κάτι έτοιμο. Σε αυτήν την περίπτωση, ακολουθήσαμε τον δεύτερο τρόπο και επιλέξαμε το πακέτο nginx + Lua. Γιατί; Χρειαζόμασταν αξιόπιστο, δοκιμασμένο λογισμικό που υποστηρίζει κλιμάκωση. Μετά την υλοποίηση, δεν θέλαμε να ελέγξουμε τόσο την ορθότητα της επιχειρηματικής λογικής όσο και την ορθότητα του διακομιστή μεσολάβησης.

Κάθε διακομιστής ιστού έχει μια διοχέτευση επεξεργασίας αιτημάτων. Στην περίπτωση του nginx, μοιάζει με αυτό:

Η εμπειρία μας στη δημιουργία API Gateway

(διάγραμμα από GitHub Lua Nginx)

Στόχος μας ήταν να χωρέσουμε σε αυτόν τον αγωγό σε ένα σημείο όπου μπορούμε να τροποποιήσουμε το αρχικό αίτημα.

Θέλουμε να δημιουργήσουμε έναν διαφανή διακομιστή μεσολάβησης, ώστε το αίτημα να παραμείνει λειτουργικά το ίδιο με αυτό που ήρθε. Ελέγχουμε μόνο την πρόσβαση στο τελικό API, βοηθούμε το αίτημα να φτάσει σε αυτό. Σε περίπτωση που το αίτημα ήταν λανθασμένο, το τελικό API θα πρέπει να εμφανίζει το σφάλμα, αλλά όχι εμείς. Ο μόνος λόγος που μπορούμε να απορρίψουμε ένα αίτημα είναι επειδή ο πελάτης δεν έχει πρόσβαση.

Υπάρχει ήδη για το nginx επέκταση επί Λουά. Η Lua είναι μια γλώσσα σεναρίου, είναι πολύ ελαφριά και εύκολη στην εκμάθηση. Έτσι, εφαρμόσαμε την απαραίτητη λογική χρησιμοποιώντας το Lua.

Η διαμόρφωση του nginx (αναλογία με τη διαδρομή της εφαρμογής), όπου γίνεται όλη η εργασία, είναι αρκετά κατανοητή. Αξίζει να σημειωθεί εδώ η τελευταία οδηγία - 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;
}

Σκεφτείτε τι συμβαίνει σε αυτήν τη διαμόρφωση:
more_clear_input_headers — διαγράφει την τιμή των κεφαλίδων που καθορίζονται μετά την οδηγία.
lua_need_request_body - ελέγχει εάν το αρχικό σώμα αιτήματος πρέπει να διαβαστεί πριν από την εκτέλεση των οδηγιών rewrite/access/access_by_lua ή όχι. Από προεπιλογή, το nginx δεν διαβάζει το σώμα ενός αιτήματος πελάτη και εάν χρειάζεται να αποκτήσετε πρόσβαση σε αυτό, τότε αυτή η οδηγία θα πρέπει να είναι ενεργοποιημένη.
rewrite_by_lua_file - τη διαδρομή προς το σενάριο, η οποία περιγράφει τη λογική για την τροποποίηση του αιτήματος
access_by_lua_file — η διαδρομή προς το σενάριο, η οποία περιγράφει τη λογική που ελέγχει την πρόσβαση στον πόρο.
διακομιστής μεσολάβησης — url στην οποία θα αποσταλεί το αίτημα.
body_filter_by_lua_file — τη διαδρομή προς το σενάριο, η οποία περιγράφει τη λογική για το φιλτράρισμα της αίτησης πριν την επιστροφή της στον πελάτη.
Και, τελικά, post_action - μια επίσημα μη τεκμηριωμένη οδηγία με την οποία μπορείτε να εκτελέσετε κάποιες άλλες ενέργειες αφού δοθεί η απάντηση στον πελάτη.

Στη συνέχεια, θα περιγράψουμε με τη σειρά πώς λύσαμε τα προβλήματά μας.

Εξουσιοδότηση/έλεγχος ταυτότητας και αίτημα τροποποίησης

Είσοδος

Δημιουργήσαμε εξουσιοδότηση και έλεγχο ταυτότητας χρησιμοποιώντας πρόσβαση στο πιστοποιητικό. Υπάρχει πιστοποιητικό ρίζας. Για κάθε νέο πελάτη του πελάτη, δημιουργείται το προσωπικό του πιστοποιητικό, με το οποίο μπορεί να έχει πρόσβαση στο API. Αυτό το πιστοποιητικό έχει διαμορφωθεί στην ενότητα διακομιστή των ρυθμίσεων nginx.

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;

Τροποποίηση

Μπορεί να προκύψει ένα δίκαιο ερώτημα: τι να κάνουμε με έναν πιστοποιημένο πελάτη εάν ξαφνικά θέλουμε να τον αποσυνδέσουμε από το σύστημα; Μην επανεκδίδετε πιστοποιητικά για όλους τους άλλους πελάτες.

Έτσι, προσεγγίσαμε ομαλά την επόμενη εργασία - την τροποποίηση του αρχικού αιτήματος. Το αρχικό αίτημα του πελάτη, γενικά, δεν ισχύει για το τελικό σύστημα. Μία από τις εργασίες είναι να προσθέσετε τα μέρη που λείπουν στο αίτημα για να είναι έγκυρο. Το θέμα είναι ότι τα δεδομένα που λείπουν είναι διαφορετικά για κάθε πελάτη. Γνωρίζουμε ότι ένας πελάτης έρχεται σε εμάς με ένα πιστοποιητικό από το οποίο μπορούμε να πάρουμε ένα δακτυλικό αποτύπωμα και να εξαγάγουμε τα απαραίτητα δεδομένα πελάτη από τη βάση δεδομένων.

Εάν κάποια στιγμή χρειαστεί να αποσυνδέσετε τον πελάτη από την υπηρεσία μας, τα δεδομένα του θα εξαφανιστούν από τη βάση δεδομένων και δεν θα μπορεί να κάνει τίποτα.

Εργασία με δεδομένα πελατών

Χρειαζόμασταν να κάνουμε τη λύση εξαιρετικά διαθέσιμη, ειδικά τον τρόπο με τον οποίο λαμβάνουμε δεδομένα πελατών. Η δυσκολία είναι ότι η κύρια πηγή αυτών των δεδομένων είναι μια υπηρεσία τρίτου μέρους που δεν εγγυάται αδιάλειπτη και επαρκώς υψηλή ταχύτητα.

Ως εκ τούτου, έπρεπε να διασφαλίσουμε υψηλή διαθεσιμότητα δεδομένων πελατών. Ως εργαλείο έχουμε επιλέξει φουντουκιάπου μας παρέχει:

  • γρήγορη πρόσβαση στα δεδομένα
  • τη δυνατότητα οργάνωσης ενός συμπλέγματος πολλών κόμβων με δεδομένα που αναπαράγονται σε διαφορετικούς κόμβους.

Ακολουθήσαμε την απλούστερη στρατηγική για την παράδοση δεδομένων στην κρυφή μνήμη:

Η εμπειρία μας στη δημιουργία API Gateway

Η εργασία με το τελικό σύστημα πραγματοποιείται εντός συνεδριών και υπάρχει όριο στον μέγιστο αριθμό. Εάν ο πελάτης δεν έχει κλείσει τη συνεδρία, θα πρέπει να το κάνουμε αυτό.

Τα δεδομένα ανοιχτής περιόδου λειτουργίας προέρχονται από το τελικό σύστημα και υφίστανται επεξεργασία αρχικά από την πλευρά Lua. Αποφασίσαμε να χρησιμοποιήσουμε το Hazelcast για να αποθηκεύσουμε αυτά τα δεδομένα με μια εργασία .NET. Στη συνέχεια, σε κάποια χρονικά διαστήματα ελέγχουμε το δικαίωμα στη ζωή των ανοιχτών συνεδριών και κλείνουμε τις σάπιες.

Πρόσβαση στο Hazelcast τόσο από το Lua όσο και από το .NET

Δεν υπάρχουν πελάτες Lua για να συνεργαστούν με το Hazelcast, αλλά το Hazelcast έχει ένα REST API, το οποίο αποφασίσαμε να χρησιμοποιήσουμε. Για .NET υπάρχει πελάτης, μέσω του οποίου σχεδιάζαμε να αποκτήσουμε πρόσβαση στα δεδομένα Hazelcast στην πλευρά του .NET. Αλλά δεν ήταν εκεί.

Η εμπειρία μας στη δημιουργία API Gateway

Κατά την αποθήκευση δεδομένων μέσω REST και την ανάκτηση δεδομένων μέσω ενός προγράμματος-πελάτη .NET, χρησιμοποιούνται διαφορετικοί σειριοποιητές και αποσειριοποιητές. Επομένως, είναι αδύνατο να τοποθετήσετε δεδομένα μέσω REST, αλλά να τα λάβετε μέσω του προγράμματος-πελάτη .NET και αντίστροφα.

Εάν ενδιαφέρεστε, θα σας πούμε περισσότερα για αυτό το πρόβλημα σε ξεχωριστό άρθρο. Spoiler - στο σχηματικό.

Η εμπειρία μας στη δημιουργία API Gateway

Καταγραφή και παρακολούθηση

Το εταιρικό μας πρότυπο για την καταγραφή μέσω .NET είναι το Serilog, όλα τα αρχεία καταγραφής καταλήγουν στο Elasticsearch και τα αναλύουμε μέσω του Kibana. Θα ήθελα να κάνω κάτι παρόμοιο σε αυτή την περίπτωση. Ο μοναδικός πελάτης να συνεργαστεί με την Elastic στο Lua, το οποίο βρέθηκε, έσπασε με την πρώτη κιόλας απαίτηση. Και χρησιμοποιήσαμε το Fluentd.

Άπταιστα - Λύση ανοιχτού κώδικα για την παροχή ενός ενιαίου επιπέδου καταγραφής εφαρμογών. Σας επιτρέπει να συλλέγετε αρχεία καταγραφής από διαφορετικά επίπεδα της εφαρμογής και στη συνέχεια να τα μεταδίδετε σε μία μόνο πηγή.

Το API Gateway λειτουργεί στο K8S, γι' αυτό αποφασίσαμε να προσθέσουμε ένα κοντέινερ με fluentd στο ίδιο pody για να γράψουμε αρχεία καταγραφής στην υπάρχουσα ανοιχτή θύρα tcp fluentd.

Εξερευνήσαμε επίσης πόσο άπταιστα θα συμπεριφερόταν αν δεν είχε σύνδεση με το Elasticsearch. Για δύο ημέρες, τα αιτήματα αποστέλλονταν συνεχώς στην πύλη, τα αρχεία καταγραφής στάλθηκαν στο fluentd, αλλά το fluentd αποκλείστηκε από το IP Elastic. Μετά την αποκατάσταση της σύνδεσης, το fluentd ξεπέρασε τέλεια όλα τα κούτσουρα στο Elastic.

Συμπέρασμα

Η επιλεγμένη προσέγγιση εφαρμογής μας επέτρεψε να παραδώσουμε ένα πραγματικά λειτουργικό προϊόν στο περιβάλλον μάχης σε μόλις 2.5 μήνες.

Εάν κάποια μέρα τύχει να κάνετε τέτοια πράγματα, σας συμβουλεύουμε να καταλάβετε πρώτα από όλα ξεκάθαρα ποιο πρόβλημα λύνετε και ποιους πόρους έχετε ήδη. Έχετε επίγνωση της πολυπλοκότητας της ενοποίησης με τα υπάρχοντα συστήματα διαχείρισης API.

Κατανοήστε μόνοι σας τι ακριβώς πρόκειται να αναπτύξετε - μόνο την επιχειρηματική λογική για την επεξεργασία των αιτημάτων ή, όπως θα μπορούσε να είναι στην περίπτωσή μας, ολόκληρο το proxy. Μην ξεχνάτε ότι ό,τι κάνετε μόνοι σας πρέπει να δοκιμαστεί διεξοδικά στη συνέχεια.

Πηγή: www.habr.com

Προσθέστε ένα σχόλιο