Αυτό το άρθρο είναι ένα άρθρο καθρέφτη της αυτόματης μετάφρασης, κάντε κλικ εδώ για να μεταβείτε στο αρχικό άρθρο.

Άποψη: 6079|Απάντηση: 4

[Πηγή] Η εσφαλμένη χρήση του HttpClient μπορεί να καταστρέψει το λογισμικό σας

[Αντιγραφή συνδέσμου]
Δημοσιεύτηκε στις 14/5/2022 5:11:56 μ.μ. | | | |
Χρησιμοποιώ λανθασμένα το HttpClient εδώ και χρόνια, αλλά τελικά ήρθε ο εφιάλτης. Ο ιστότοπός μου ήταν ασταθής και οι πελάτες μου ήταν πολύ θυμωμένοι και με μια απλή επιδιόρθωση, η απόδοση βελτιώθηκε σημαντικά και η αστάθεια εξαλείφθηκε.



Ταυτόχρονα, βελτίωσα πραγματικά την απόδοση της εφαρμογής μου με πιο αποτελεσματική χρήση πρίζας.

Οι μικροϋπηρεσίες μπορεί να είναι ένα δύσκολο πρόβλημα στην αντιμετώπιση. Καθώς προστίθενται περισσότερες υπηρεσίες και αποσυντίθενται μονολιθικές εφαρμογές, τείνουν να υπάρχουν όλο και περισσότερες διαδρομές επικοινωνίας μεταξύ των υπηρεσιών. Υπάρχουν πολλές επιλογές επικοινωνίας, αλλά το HTTP είναι μια πολύ δημοφιλής επιλογή. Εάν η μικροϋπηρεσία είναι ενσωματωμένη σε C# ή σε οποιαδήποτε γλώσσα .NET, το πιθανότερο είναι ότι χρησιμοποιείτε ήδη το HttpClient.


Το πρόβλημα έγκειται

Η δήλωση χρήσης είναι μια δυνατότητα C# που χειρίζεται αντικείμενα μίας χρήσης. Μόλις ολοκληρωθεί το μπλοκ χρήσης, τότε το αντικείμενο μίας χρήσης (σε αυτήν την περίπτωση το HttpClient) είναι εκτός πεδίου εφαρμογής και απορρίπτεται. Καλέστε τη μέθοδο απόρριψης και καθαρίστε τυχόν πόρους που χρησιμοποιούνται. Αυτό είναι ένα πολύ τυπικό μοτίβο στο .NET που χρησιμοποιούμε για τα πάντα, από τη βάση δεδομένων έως το πρόγραμμα εγγραφής ροής. Στην πραγματικότητα, κάθε αντικείμενο με εξωτερικό πόρο που πρέπει να καθαριστεί χρησιμοποιεί αυτό το IDisposable διεπαφή.

Και δεν μπορείτε να κατηγορηθείτε που θέλετε να το τυλίξετε στη χρήση. Πρώτον, θεωρείται καλή πρακτική να γίνει αυτό. Στην πραγματικότητα, η επίσημη τεκμηρίωση της Microsoft που χρησιμοποιεί:


Γενικά, όταν χρησιμοποιείτε ένα αντικείμενο με δυνατότητα αναγνώρισης, θα πρέπει να δηλώνεται και να δημιουργείται στη δήλωση χρήσης.
Δεύτερον, όλος ο κώδικας που μπορεί να έχετε δει...... Η αρχή του HttpClient θα σας πει να χρησιμοποιήσετε το μπλοκ εντολών χρήσης, συμπεριλαμβανομένης της πιο πρόσφατης τεκμηρίωσης ASP.NET τον ίδιο τον ιστότοπο. Το ίδιο λέγεται και στο άρθρο στο Διαδίκτυο.

Αλλά το HttpClient είναι διαφορετικό. Αν και υλοποιεί τη διεπαφή IDisposable, είναι στην πραγματικότητα ένα κοινόχρηστο αντικείμενο. Αυτό σημαίνει ότι στα παρασκήνια είναι επανεισερχόμενο και ασφαλές για νήματα. Θα πρέπει να κάνετε κοινή χρήση μιας παρουσίας του HttpClient καθ' όλη τη διάρκεια ζωής της εφαρμογής σας, αντί να δημιουργείτε μια νέα παρουσία για κάθε εκτέλεση. HttpClient ας δούμε γιατί.

Κοιταξε και μονος σου

Ακολουθεί ένα απλό πρόγραμμα για την επίδειξη του HttpClient:

Αυτό θα απευθύνεται σε  http://aspnetmonsters.comΑνοίξτε 10 αιτήματα και κάντε GET, απλώς εκτυπώνουμε τον κωδικό κατάστασης, ώστε να γνωρίζουμε ότι λειτουργεί. Η έξοδος θα είναι:

Περιμένετε, υπάρχουν περισσότερα!

Όλη η δουλειά και όλα είναι σωστά για τον κόσμο. μόνο που δεν είναι. Αν βγάλουμε το εργαλείο netstat και δούμε την κατάσταση υποδοχής στο μηχάνημα που το εκτελεί, θα δούμε:

C:\code\socket>NETSTAT.EXE
...
  Πρώτη Τοπική Διεύθυνση Ξένη Διεύθυνση Πολιτεία
  TCP 10.211.55.6:12050 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12051 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12053 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12054 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12055 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12056 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12057 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12058 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12059 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12060 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12061 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12062 waws-prod-bay-017:http TIME_WAIT
  TCP 127.0.0.1:1695 SIMONTIMMS742B:1696 ΙΔΡΎΘΗΚΕ
...
Λοιπόν, είναι περίεργο...... Η εφαρμογή έχει βγει, αλλά εξακολουθούν να υπάρχουν πολλές από αυτές τις συνδέσεις ανοιχτές στο μηχάνημα Azure που φιλοξενεί τον ιστότοπο ASP.NET Monsters. Βρίσκονται σεTIME_WAITκατάσταση, που σημαίνει ότι η σύνδεση έχει κλείσει από τη μία πλευρά (τη δική μας), αλλά ακόμα περιμένουμε να δούμε αν θα μπουν άλλα πακέτα γιατί μπορεί να έχουν καθυστερήσει κάπου στο δίκτυο. Ακολουθεί ένα διάγραμμα της κατάστασης TCP/IP:



Τα Windows θα παραμείνουν συνδεδεμένα σε αυτήν την κατάσταση για 240 δευτερόλεπτα (όπως ορίζεται από τη ρύθμιση [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpTimedWaitDelay]). Τα Windows έχουν ένα όριο στο πόσο γρήγορα μπορείτε να ανοίξετε μια νέα υποδοχή, επομένως εάν εξαντληθούν οι χώροι συγκέντρωσης σύνδεσης, τότε ενδέχεται να δείτε ένα σφάλμα όπως αυτό:

Δεν είναι δυνατή η σύνδεση στον απομακρυσμένο διακομιστή
System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted.
Η αναζήτησή του στο Google θα σας δώσει μερικές κακές συμβουλές σχετικά με τη μείωση των χρονικών ορίων σύνδεσης. Στην πραγματικότητα, όταν εκτελείται σωστά σε διακομιστή με HttpClient ή παρόμοια κατασκευασμένη εφαρμογή, η μείωση των χρονικών ορίων μπορεί να οδηγήσει σε άλλες δυσμενείς συνέπειες. Πρέπει να καταλάβουμε τι σημαίνει «σωστό» και να λύσουμε το υποκείμενο πρόβλημα, όχι να πειραματιζόμαστε με μεταβλητές σε επίπεδο μηχανής.

Διορθώστε το

Εάν μοιραζόμαστε μια παρουσία του HttpClient, τότε μπορούμε να μειώσουμε τη σπατάλη υποδοχών επαναχρησιμοποιώντας τα:

Σημειώστε ότι για ολόκληρη την εφαρμογή, έχουμε μόνο μία κοινόχρηστη παρουσία. Το HttpClient εξακολουθεί να λειτουργεί όπως πριν (στην πραγματικότητα λίγο πιο γρήγορα λόγω της επαναχρησιμοποίησης της υποδοχής). Το Netstat δείχνει πλέον μόνο:

TCP 10.211.55.6:12254 waws-prod-bay-017:http ΙΔΡΥΘΗΚΕ
Σε ένα σενάριο παραγωγής, ο αριθμός των υποδοχών μου είναι κατά μέσο όρο περίπου 4000 και κορυφώνεται σε πάνω από 5000, συμπιέζοντας ουσιαστικά τους διαθέσιμους πόρους στον διακομιστή, προκαλώντας τη διακοπή λειτουργίας της υπηρεσίας. Μετά την εφαρμογή της αλλαγής, ο αριθμός των υποδοχών που χρησιμοποιούνται μειώθηκε από κατά μέσο όρο πάνω από 4000 σε σταθερά λιγότερες από 400, συνήθως περίπου 100.

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




Ήταν δραματικό. Εάν έχετε οποιοδήποτε είδος φορτίου, πρέπει να έχετε υπόψη σας αυτά τα δύο πράγματα:

Κάντε το HttpClient σας στατικό.
Μην απορρίπτετε ή συσκευάζετε τη χρήση σας, εκτός εάν αναζητάτε ρητά μια συγκεκριμένη συμπεριφορά (όπως η πρόκληση αποτυχίας της υπηρεσίας σας). Πελάτης Http


περίληψη

Το πρόβλημα εξάντλησης της πρίζας με το οποίο παλεύαμε εδώ και μήνες έχει φύγει και οι πελάτες μας έχουν μια εικονική παρέλαση. Δεν μπορώ να υποτιμήσω πόσο απροφανές είναι αυτό το λάθος. Με τα χρόνια, έχουμε συνηθίσει να ασχολούμαστε με υλοποιημένα αντικείμενα, IDisposable και πολλά εργαλεία ανακατασκευής όπως το R# και το CodeRush σας προειδοποιούν πραγματικά εάν δεν το κάνετε. Σε αυτήν την περίπτωση, η απόρριψη του HttpClient είναι λάθος προσέγγιση. Το HttpClient υλοποιεί το IDisposable και ενθαρρύνει την κακή συμπεριφορά είναι ατυχές

Αρχικός:Η σύνδεση με υπερσύνδεσμο είναι ορατή.




Προηγούμενος:Το ASP.NET Core φιλοξενεί τα μοντέλα In-Process και Out-Of-Process στις υπηρεσίες IIS
Επόμενος:Το ASP.NET Core (XV) χρησιμοποιεί το HttpClient για την αποστολή αιτημάτων HTTP
 Σπιτονοικοκύρης| Δημοσιεύτηκε στις 14/5/2022 5:25:22 μ.μ. |
Το TCP TIME_WAIT είναι μια κανονική λειτουργία πρωτοκόλλου TCP, που σημαίνει ότι μετά την ολοκλήρωση του τελευταίου FIN-ACK, ο υπολογιστής-πελάτης θα περιμένει να περάσει ο χρόνος διπλής μέγιστης διάρκειας ζωής (MSL) για να διασφαλίσει ότι το απομακρυσμένο TCP θα λάβει μια επιβεβαίωση της αίτησης τερματισμού της σύνδεσής του. Από προεπιλογή, το MSL είναι 2 λεπτά. Μπορείτε να μείνετε σε TIME_WAIT για έως και 4 λεπτά, γνωστά ως δύο MSL.

https://docs.microsoft.com/en-us ... t-from-netstat.html
Δημοσιεύτηκε στις 14/5/2022 10:35:22 μ.μ. |
Μαθαίνω να μαθαίνω
Δημοσιεύτηκε στις 19/5/2022 9:39:05 π.μ. |
Είναι όλα κινέζικα, αλλά δεν μπορώ να τα καταλάβω όταν συνδέονται με προτάσεις
 Σπιτονοικοκύρης| Δημοσιεύτηκε στις 6/11/2023 7:16:05 π.μ. |
δοκιμή
Αποκήρυξη:
Όλο το λογισμικό, το υλικό προγραμματισμού ή τα άρθρα που δημοσιεύονται από το Code Farmer Network προορίζονται μόνο για μαθησιακούς και ερευνητικούς σκοπούς. Το παραπάνω περιεχόμενο δεν θα χρησιμοποιηθεί για εμπορικούς ή παράνομους σκοπούς, άλλως οι χρήστες θα υποστούν όλες τις συνέπειες. Οι πληροφορίες σε αυτόν τον ιστότοπο προέρχονται από το Διαδίκτυο και οι διαφορές πνευματικών δικαιωμάτων δεν έχουν καμία σχέση με αυτόν τον ιστότοπο. Πρέπει να διαγράψετε εντελώς το παραπάνω περιεχόμενο από τον υπολογιστή σας εντός 24 ωρών από τη λήψη. Εάν σας αρέσει το πρόγραμμα, υποστηρίξτε γνήσιο λογισμικό, αγοράστε εγγραφή και λάβετε καλύτερες γνήσιες υπηρεσίες. Εάν υπάρχει οποιαδήποτε παραβίαση, επικοινωνήστε μαζί μας μέσω email.

Mail To:help@itsvse.com