Kata pengantar
Artikel ini terutama memperkenalkan jebakan @scheduled dan httpClient di musim semi. Kami akan membagikannya untuk referensi dan pembelajaran Anda. Saya tidak akan mengatakan banyak hal di bawah ini, mari kita lihat perkenalan terperinci bersama.
Saya pernah menginjak lubang besar:
Karena kekhasan bisnis, banyak tugas waktu akan dijalankan secara teratur dan dikompensasi untuk data bisnis.
Selama penggunaan musim semi, kita dapat menggunakan anotasi @scheduled untuk dengan mudah mengimplementasikan tugas waktu.
Suatu pagi saya tiba -tiba menyadari bahwa dari saat tertentu malam sebelumnya, semua tugas waktunya macet dan berhenti berlari.
@ScheduledDefault utas tunggal
Setelah diselidiki, ditemukan bahwa jika kita menggunakan anotasi @scheduled untuk menjelaskan konfigurasi default, semua tugas akan dijalankan oleh satu utas. Setelah menulis tugas tes untuk tidur, mudah untuk menemukan bahwa semua tugas lain tidak dipicu ketika saatnya tiba.
Jika Anda perlu mengaktifkan multi-threading, Anda perlu melakukan konfigurasi berikut dan mengatur jumlah utas:
@ConfigurationPublic kelas jadwalconfig mengimplementasikan jadwalconfigurer {@override public void configureTasks (scheduleDtaskRrar TaskRegistrar) {TaskRegistrar.setscheduler (executors.newschedulThreadpool (5)); }}Ini memecahkan masalah bahwa jika suatu tugas macet, itu akan menyebabkan semua tugas macet.
Tapi mengapa ada tugas yang macet?
Konfigurasi parameter default httpclient
Ternyata beberapa tugas akan meminta antarmuka layanan eksternal yang tenang secara teratur, dan konfigurasi httpClient adalah sebagai berikut:
PoolingHttpClientConnectionManager ConnManager = new PoolingHttpClientConnectionManager (); ConnManager.SetMaxtotal (MaxConnection); httpClient = httpclients.custom () .setConnectionManager (ConnManager) .build ();
Ketika saya pertama kali menggunakan HTTPClient, saya tidak terlalu memikirkannya, dan pada dasarnya saya menggunakan konfigurasi default.
Melacak kode sumber dapat menemukan bahwa ketika mengonfigurasi menggunakan metode di atas, waktu batas waktu httpClient sebenarnya -1, yang berarti bahwa jika ada masalah dengan layanan pihak lain, permintaan httpClient tidak akan pernah habis dan akan menunggu. Kode sumber adalah sebagai berikut:
Builder () {super (); this.staleconnectionCheckEnabled = false; this.redirectsenabled = true; this.maxredirects = 50; this.relativeredirectsallowed = true; this.authenticationEnabled = true; this.connectionRequestTimeout = -1; this.connecttimeout = -1; this.socketTimeout = -1; this.contentCompressionEnabled = true;}Jadi kita harus secara manual menentukan waktu batas waktu saat ini, dan masalahnya terpecahkan. Misalnya:
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 ();
Ingatkan masalah lain
Faktanya, masalah konfigurasi lain yang dihadapi selama penggunaan httpClient, yang merupakan parameter DefaultMaxperroute.
Saya tidak memperhatikan parameter ini ketika saya pertama kali menggunakannya, tetapi saya hanya mengatur jumlah koneksi maksimum di maxtotal pool koneksi.
Parameter DefaultMaxperRoute sebenarnya mewakili jumlah maksimum koneksi per rute. Misalnya, sistem Anda perlu mengakses dua layanan lain: Google.com dan Bing.com. Jika maxtotal Anda diatur ke 100 dan DefaultMaxPerRoute diatur ke 50, maka jumlah maksimum permintaan untuk setiap layanan dapat 50.
Jadi jika DefaultMaxperRoute tidak diatur, lacak kode sumber:
PoolingHttpClientConnectionManager (final httpClientConnectionoperator httpClientConnectionoperator, httpConnectionFactory final <httproute, ManagedHttpClientConnection> ConnFactory, final long timetOlive, final timeunit tunit) {super tunit) {supers);); this.configData = configData baru (); // Metode konstruktor cpool yang digunakan di sini, parameter kedua adalah defaultMaxperroute, yang merupakan default adalah 2. This.pool = cpool baru (internalconnectionFactory baru (this.configdata, connfactory), 2, 20, timetolive, tunit); this.pool.setValidateAfterinActivity (2000); this.connectionoperator = args.notnull (httpClientConnectionoperator, "httpClientConnectionoperator"); this.isshutdown = atomicboolean baru (false);}Di sini ditemukan bahwa nilai default hanya 2. Tidak heran selalu ada batas waktu dalam situasi konkurensi tinggi pada waktu itu, maxtotal jelas ditetapkan sangat tinggi.
Jadi, jika layanan Anda mengakses banyak layanan eksternal yang berbeda dan memiliki konkurensi yang besar, Anda harus mengkonfigurasi dua parameter maxtotal dan defaultMaxperroute.
Jadi, ketika Anda menggunakan hal -hal baru nanti, Anda akan melihat dengan baik konfigurasi apa yang Anda miliki. Jika Anda memiliki pertanyaan, Anda harus memeriksanya terlebih dahulu. Jangan menyalin sepotong kode secara online dan menggunakannya secara langsung. Mungkin baik -baik saja pada waktu itu, tapi mungkin saya akan ditipu di masa depan.
Meringkaskan
Di atas adalah seluruh konten artikel ini. Saya berharap konten artikel ini memiliki nilai referensi tertentu untuk studi atau pekerjaan semua orang. Jika Anda memiliki pertanyaan, Anda dapat meninggalkan pesan untuk berkomunikasi. Terima kasih atas dukungan Anda ke wulin.com.