Vorwort
In diesem Artikel wird hauptsächlich die Fallstricke von @Scheduled und httpclient im Frühjahr vorgestellt. Wir werden sie für Ihre Referenz und Ihr Lernen teilen. Ich werde unten nicht viel sagen. Schauen wir uns die detaillierte Einführung zusammen an.
Ich trat einmal auf eine große Grube ein:
Aufgrund der Besonderheit des Geschäfts werden viele zeitgesteuerte Aufgaben regelmäßig ausgeführt und für Geschäftsdaten ausgeglichen.
Während der Frühlingsnutzung können wir mit der @Scheduled Annotation problemlos Zeitaufgaben implementieren.
Eines Morgens stellte ich plötzlich fest, dass von einem bestimmten Moment in der Nacht zuvor alle zeitgesteuerten Aufgaben festsitzen und aufgehörten, zu rennen.
@ScheduledDefault Single Thread
Nach der Untersuchung wurde festgestellt, dass, wenn wir @Scheduled Annotation verwenden, um die Standardkonfiguration zu erklären, alle Aufgaben von einem einzelnen Thread ausgeführt werden. Nach dem Schreiben einer Testaufgabe in den Schlaf ist leicht festzustellen, dass alle anderen Aufgaben zu Beginn nicht ausgelöst werden.
Wenn Sie Multi-Threading aktivieren müssen, müssen Sie die folgende Konfiguration ausführen und die Anzahl der Threads festlegen:
@ConfigurationPublic Class ScheduleConfig Implements SchedulingConFigurer {@Override public void configuretasks (plantedTaskRegistrar TaskRegistrar) {TaskRegistrar.SetScheduler (Executors.NewScheduledThreadpool (5)); }}Dies löst das Problem, dass eine Aufgabe, wenn sie stecken bleibt, alle Aufgaben stecken.
Aber warum stecken es Aufgaben?
HTTPCLIENT -Standardparameterkonfiguration
Es stellt sich heraus, dass einige Aufgaben die erholsame Schnittstelle externer Dienste regelmäßig anfordern und die Konfiguration von HTTPClient wie folgt lautet:
PoolinghttpclientConnectionManager connManager = new PoolinghttpclientConnectionManager (); connmanager.setMaxtotal (maxConnection); httpclient = httpclients.custom () .setConnectionManager (connmanager) .build ();
Als ich HTTPClient zum ersten Mal verwendet habe, habe ich nicht so viel darüber nachgedacht und die Standardkonfiguration im Grunde genommen verwendet.
Wenn Sie den Quellcode verfolgen, wird festgestellt, dass bei der Konfiguration der obigen Methode die Zeitüberschreitungszeit von httpclient tatsächlich -1 beträgt. Dies bedeutet, dass bei einem Problem mit dem Dienst der anderen Partei die Anfrage von httpclient nie Zeit abzielt und wartet. Der Quellcode lautet wie folgt:
Builder () {Super (); this.staleconnectionCheckenababled = false; this.redirectSenabled = true; this.maxredirects = 50; this.relativeredirectSallowed = true; this.authenticationEnabled = true; this.connectionRequestTimeout = -1; this.connectTimeout = -1; this.sockettimeout = -1; this.content compressionenabled = true;}Daher müssen wir zu diesem Zeitpunkt die Zeitüberschreitungszeit manuell angeben, und das Problem ist gelöst. Zum Beispiel:
PoolinghttpclientConnectionManager connManager = new PoolinghttpclientConnectionManager (); connmanager.setMaxtotal (maxConnection); RequestConfig defaUltrequestConfig = requestConfig.custom () .setsockettimeout (3000) .setConnectTimeout (3000) .SetConnectionRequestTimeout (3000) .build (); httpclient = httpclients.custom () .setDefaultrEquestConfig (DefaultrequestConfig) .SetConnectionManager (connManager) .build ();
Erinnerung an ein anderes Problem
Tatsächlich ist ein weiteres Konfigurationsproblem, das während der Verwendung von HTTPClient aufgetreten ist, der Parameter für StandardmaxPerRoute.
Ich habe diesen Parameter nicht beachtet, als ich ihn zum ersten Mal verwendet habe, aber ich habe nur die maximale Anzahl von Verbindungen im Maxtotal des Verbindungspools festgelegt.
Der Parameter DefaultMaxperRoute repräsentiert tatsächlich die maximale Anzahl von Verbindungen pro Route. Ihr System muss beispielsweise auf zwei weitere Dienste zugreifen: Google.com und Bing.com. Wenn Ihr Maxtotal auf 100 gesetzt ist und DefaultMaxperRoute auf 50 gesetzt ist, kann die maximale Anzahl von Anforderungen für jeden Dienst 50 betragen.
Wenn also defaultmaxPerRoute nicht gesetzt ist, verfolgen Sie den Quellcode:
public poolinghttpclientConnectionManager (endgültiger httpclientConnectionoperator httpclientConnectionoperator, endgültiger httpConnectionFactory <httProute, ManagedHttpclientConnection> connfactory, endgültiges Langzeit -Timetolive, endgültiges Zeitunit Tunit) {Super (); this.configData = new configData (); // Die hier verwendete CPool -Konstruktor -Methode ist der zweite Parameter defaultmaxPerRoute, der Standard ist. this.pool.setvalidateagonaktivität (2000); this.connectionoperator = args.notnull (httpclientConnectionoperator, "httpclientConnectionoperator"); this.isshutdown = neuer atomicboolean (false);}Hier wurde festgestellt, dass der Standardwert nur 2 betrug. Kein Wunder, dass es zu dieser Zeit immer eine Zeitüberschreitung in hoher Parallelitätssituationen gab. Maxtotal war eindeutig sehr hoch.
Wenn Ihr Dienst also auf viele verschiedene externe Dienste zugreift und eine große Parallelität aufweist, müssen Sie die beiden Parameter maximal und defaultmaxPerRoute konfigurieren.
Wenn Sie also später neue Dinge verwenden, sehen Sie sich genau an, welche Konfigurationen Sie haben. Wenn Sie Fragen haben, müssen Sie es zuerst überprüfen. Kopieren Sie keinen Code online und verwenden Sie es direkt. Es mag zu dieser Zeit in Ordnung sein, aber vielleicht werde ich in Zukunft betrogen.
Zusammenfassen
Das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, dass der Inhalt dieses Artikels einen gewissen Referenzwert für das Studium oder die Arbeit eines jeden hat. Wenn Sie Fragen haben, können Sie eine Nachricht zur Kommunikation überlassen. Vielen Dank für Ihre Unterstützung bei Wulin.com.