Κατά τη δημιουργία μιας εφαρμογής με ASP.NET, χρησιμοποιείται μια παρουσία της κλάσης HttpClient για την υποβολή αιτήματος HTTP. Η χρήση του HttpClient μπορεί να φαίνεται απλή. Ωστόσο, ορισμένα πιθανά ζητήματα δεν παρατηρούνται έως ότου η εφαρμογή είναι υπό μεγάλο φορτίο.
Ζητήματα που σχετίζονται με την αρχική κλάση HttpClient που παρέχεται στο .NET:Η σύνδεση με υπερσύνδεσμο είναι ορατή.
HttpClient, κατά την υλοποίηση του IDisposable, η δήλωση και η ενσάρκωσή του στη δήλωση χρήσης δεν είναι προτιμώμενη λειτουργία, επειδήΚατά την απελευθέρωση ενός αντικειμένου HttpClient, η υποκείμενη υποδοχή δεναμέσωςελευθερώνω, που μπορεί να προκαλέσει προβλήματα εξάντλησης της πρίζας.
Το πρόβλημα δεν είναι πραγματικά το ίδιο το HttpClient, αλλά ο προεπιλεγμένος κατασκευαστής του HttpClient, καθώς δημιουργεί μια νέα πραγματική παρουσία HttpMessageHandler με τα ζητήματα "εξάντλησης υποδοχής" και αλλαγής DNS που αναφέρθηκαν παραπάνω.
Απευθείας δημιουργία HttpClient (λανθασμένη χρήση)
Δημιουργήστε απευθείας το αντικείμενο HttpClient και προσθέστε χρησιμοποιώντας για να εγγυηθείτε την κλήση στη μέθοδο Dispose, ο κώδικας έχει ως εξής:
Καλέστε τη διεπαφή 5 φορές, στείλτε ένα αίτημα HTTP χρησιμοποιώντας το HttpClient και ελέγξτε τη σύνδεση δικτύου με την ακόλουθη εντολή:
Μπορείτε να δείτε ότι όταν αποδεσμευτεί το HttpClient, η σύνδεση μεταξύ του τοπικού υπολογιστή και του διακομιστή προορισμού είναιTIME_WAITΣε περίπτωση υψηλής ταυτόχρονης εκτέλεσης, το σφάλμα θα αναφέρεται ως εξής:
Δεν είναι δυνατή η σύνδεση στον απομακρυσμένο διακομιστή
System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted.
Για ερωτήσεις, μπορείτε επίσης να ανατρέξετε στο:
Δημιουργία HttpClinet με το IHttpClientFactory (σωστή χρήση)
Χρησιμοποιώντας την έγχυση εξάρτησης DI Το IHttpClientFactory είναι το ίδιο με το HttpLinet, το οποίο δημιουργείται χρησιμοποιώντας το IHttpClientFactory.
Προσθέστε την υπηρεσία στο αρχείο εκκίνησης, ο κώδικας είναι ο εξής:
Ο κωδικός του χειριστηρίου HomeController είναι ο εξής:
Χρησιμοποιούμε επίσης το HttpClinet για να στείλουμε 5 αιτήματα μέσω της διεπαφής κλήσης και το μηχάνημα δημιουργεί μόνο μια σύνδεση με τον διακομιστή προορισμού και η σύνδεση επαναχρησιμοποιείται κατά τη διαδικασία αιτήματος. Οπως φαίνεται παρακάτω:
Το IHttpClientFactory συγκεντρώνει παρουσίες HttpMessageHandler που έχουν δημιουργηθεί από το εργοστάσιο σε μια ομάδα για να μειώσει την κατανάλωση πόρων. Όταν δημιουργείτε μια νέα παρουσία HttpClient, μπορείτε να χρησιμοποιήσετε ξανά την παρουσία HttpMessageHandler στο χώρο συγκέντρωσης, εάν δεν έχει λήξει η διάρκεια ζωής.
{ "Lifetime": "Σίνγκλετον", "ServiceType": "System.Net.Http.IHttpClientFactory", "ImplementationType": "Microsoft.Extensions.Http.DefaultHttpClientFactory" }, { "Lifetime": "Σίνγκλετον", "ServiceType": "System.Net.Http.IHttpMessageHandlerFactory", "ImplementationType": "Microsoft.Extensions.Http.DefaultHttpClientFactory" } Το IHttpClientFactory υλοποιείται από προεπιλογή ως DefaultHttpClientFactory, με τη διεύθυνση πηγαίου κώδικα:Η σύνδεση με υπερσύνδεσμο είναι ορατή.
Χρησιμοποιώντας το IHttpClientFactory σε μια εφαρμογή με δυνατότητα DI, μπορείτε να αποφύγετε:
- Λύστε το πρόβλημα της εξάντλησης των πόρων με κοινή χρήση της παρουσίας HttpMessageHandler.
- Επιλύστε το πρόβλημα του DNS κάνοντας περιοδική επανάληψη στις παρουσίες του HttpMessageHandler.
Επιπλέον, υπάρχουν και άλλοι τρόποι επίλυσης των παραπάνω προβλημάτων χρησιμοποιώντας παρουσίες SocketsHttpHandler μεγάλης διάρκειας ζωής.
- Δημιουργήστε μια παρουσία του SocketsHttpHandler κατά την εκκίνηση της εφαρμογής και χρησιμοποιήστε την σε όλο τον κύκλο ζωής της εφαρμογής.
- Ρυθμίστε τις παραμέτρους του PooledConnectionLifetime στην κατάλληλη τιμή με βάση τον χρόνο ανανέωσης DNS.
- Δημιουργήστε μια παρουσία του HttpClient χρησιμοποιώντας νέο HttpClient(handler, disposeHandler: false) όπως απαιτείται.
Η παραπάνω προσέγγιση επιλύει προβλήματα διαχείρισης πόρων με παρόμοιο τρόπο με το IHttpClientFactory.
- SocketsHttpHandler μεταξύ των παρουσιών HttpClientΚοινόχρηστες συνδέσεις。 Αυτή η κοινή χρήση αποτρέπει την εξάντληση της πρίζας.
- Το SocketsHttpHandler αναβράζει τις συνδέσεις με βάση το PooledConnectionLifetime για να αποφύγει το στασιμότητα του DNS.
Για περισσότερη χρήση και διαμόρφωση, ανατρέξτε στο:
Η σύνδεση με υπερσύνδεσμο είναι ορατή.
Η σύνδεση με υπερσύνδεσμο είναι ορατή.
|