Dalam arsitektur Microservice, kami membagi proyek menjadi banyak modul independen, yang bekerja bersama melalui panggilan jarak jauh. Namun, dalam kasus konkurensi yang tinggi, peningkatan jumlah komunikasi akan menyebabkan peningkatan total waktu komunikasi. Pada saat yang sama, sumber daya kumpulan utas juga terbatas. Lingkungan konkurensi yang tinggi akan menyebabkan sejumlah besar utas berada dalam keadaan menunggu, yang akan menyebabkan penundaan respons. Untuk menyelesaikan masalah ini, kita perlu memahami permintaan Hystrix.
Permintaan Penggabungan di Hystrix adalah menggunakan prosesor gabungan untuk menggabungkan permintaan berturut -turut yang diprakarsai oleh layanan yang sama ke dalam satu permintaan pemrosesan (jendela waktu untuk permintaan berkelanjutan ini adalah 10ms secara default). Salah satu kelas inti yang terlibat dalam proses ini adalah hystrixcollapser, OK. Selanjutnya, mari kita lihat cara menerapkan penggabungan permintaan Hystrix.
Antarmuka Penyedia Layanan
Saya perlu menyediakan dua antarmuka di penyedia layanan untuk dihubungi konsumen layanan, sebagai berikut:
@RequestMapping ("/getBook6") Daftar publik <Book> Book6 (ID String) { System.out.println ("ids >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 33, Hu Shi "," None ")); House Publishing Literature 2 "); Buku Pengembalian;}Antarmuka pertama adalah antarmuka batch dan antarmuka kedua adalah antarmuka yang menangani satu permintaan. Dalam antarmuka batch, format parameter IDS yang dikirim oleh konsumen layanan adalah 1, 2, 3, 4 ... format ini. Dalam keadaan normal, kita perlu menanyakan data yang sesuai berdasarkan IDS, dan kemudian merakitnya menjadi set untuk kembali. Demi pemrosesan yang mudah, saya akan mengembalikan set data yang sama, apa pun permintaan apa; Antarmuka untuk memproses satu permintaan relatif sederhana, jadi saya tidak akan mengulanginya.
Melayani konsumen
OK, setelah penyedia layanan menanganinya, mari kita lihat bagaimana layanan konsumen harus menanganinya.
BookService
Pertama, tambahkan dua metode ke BookService untuk memanggil antarmuka yang disediakan oleh penyedia layanan, sebagai berikut:
Test Buku Publik8 (ID Panjang) {return resttemplate.getForObject ("http: // hello-service/getBook6/{1}", book.class, id);} Daftar publik <Book> test9 (daftar <long> {System.out.println ("test9 ---------"+IDS) {System.Out.println ("Test9 -----------"+IDS+"+IDS). Thread.currentThread (). GetName ()); Buku [] buku = restTemplate.getForObject ("http: // hello-service/getBook6? Ids = {1}", book []. Class, stringutils.join (id, ",")); return arrays.aslist (buku);}Test8 digunakan untuk memanggil antarmuka yang menyediakan ID tunggal, Test9 digunakan untuk memanggil antarmuka yang diproses batch. Di Test9, saya mencetak utas di mana Test9 dieksekusi untuk memfasilitasi kami untuk mengamati hasil eksekusi. Selain itu, di RestTemplate, jika nilai pengembalian adalah koleksi, kita harus menerimanya terlebih dahulu dengan array, dan kemudian mengonversinya menjadi koleksi (mungkin ada metode lain, teman memiliki saran yang lebih baik untuk dibuat).
BookBatchCommand
OK, setelah metode di BookService siap, kita dapat membuat BookBatchCommand, yang merupakan perintah batch, sebagai berikut:
Kelas Publik BookBatchCommand memperluas HystrixCommand <Daftar <Book>> {Daftar Privat <long> IDS; BUKU BUKU PRIBADI BUKU BUKU; Public BookBatchCommand (daftar <long> IDS, BookService Bookservice) {super (setter.withgroupkey (hystrixcommandgroupkey.factory.askey ("collapsinggroup"))) .andcommandkey (hystrixcommandkey.factory.askey ("collapsingkey"));); this.ids = id; this.bookservice = bookservice; } @Override Daftar Protected <Book> run () melempar Exception {return bookservice.test9 (IDS); }}Kelas ini sebenarnya mirip dengan kelas yang kami perkenalkan di blog sebelumnya. Keduanya diwarisi dari HystrixCommand dan digunakan untuk menangani permintaan gabungan dan memanggil metode test9 di BookService dalam metode RUN.
Bookcollapsecommand
Selanjutnya kita perlu membuat BookCollapsecommand yang diwarisi dari HystrixCollapser untuk mengimplementasikan permintaan gabungan. sebagai berikut:
Kelas Publik BookCollapsecommand memperluas hystrixcollapseer <list <Book>, buku, long> {private bookservice service; ID Panjang Pribadi; BookCollapsecommand publik (BookService Bookservice, Long ID) {super (setter.withcollapserKey (hystrixcollapserkey.factory.askey ("bookcollapsecommand")). andcollapserpropertiesdefaults (hystrixcollapserproperties.setter (). this.bookservice = bookservice; this.id = id; } @Override public long getRequestArgument () {return id; } @Override Dilindungi HystrixCommand <Daftar <Book>> CreateCommand (Koleksi <CollapsedRequest <Book, Long >> CollapsedRequests) {List <long> ids = Daftar Array baru <> (collapsedRequests.size ()); ids.addall (collapsedRequests.stream (). peta (collapsedRequest :: getargument) .collect (collectors.tolist ())); BookBatchCommand bookbatchCommand = new BookBatchCommand (IDS, BookService); Return BookBatchCommand; } @Override Void yang dilindungi MapResponsetorequests (Daftar <Book> BatchResponse, Koleksi <CollapsedRequest <Book, Long >> CollapsedRequests) {System.out.println ("MapResponsetorequests"); Int Count = 0; for (collapsedRequest <book, long> collapsedRequest: collapsedRequests) {Book Book = BatchResponse.get (Count ++); CollapsedRequest.SetResponse (Buku); }}}Mengenai kelas ini, saya akan mengatakan poin -poin berikut:
1. Pertama -tama, dalam metode konstruksi, kami mengatur jendela waktu permintaan ke 100ms, yaitu, permintaan dengan interval waktu permintaan dalam 100ms akan digabungkan menjadi satu permintaan.
2. Metode CreateCommand terutama digunakan untuk menggabungkan permintaan, mendapatkan ID dari setiap permintaan di sini, masukkan ID tunggal ini ke dalam koleksi, dan kemudian buat objek BookBatchCommand, dan gunakan objek ini untuk memulai permintaan batch.
3. Metode MapResponsetorequests terutama digunakan untuk mengatur hasil permintaan untuk setiap permintaan. Parameter pertama dari metode ini mewakili hasil dari permintaan batch, dan parameter kedua CollapsedRequests mewakili setiap permintaan gabungan. Kemudian kami menetapkan hasil permintaan untuk collapsedRequests dengan melintasi respons batch.
Oke, setelah semua operasi ini selesai, kita bisa datang dan mengujinya.
tes
Kami membuat antarmuka akses di sisi konsumen layanan untuk menguji permintaan gabungan. Antarmuka uji adalah sebagai berikut:
@RequestMapping ("/test7")@responseBodypublic void test7 () melempar ExecutionException, InterruptedException {HyStrixRequestContext Context = HyStrixRixRequestContext.initializeContext (); BookCollapsecommand BC1 = BookCollapsecommand baru (BookService, 1L); BookCollapsecommand BC2 = BookCollapsecommand baru (BookService, 2L); BookCollapsecommand BC3 = BookCollapsecommand baru (BookService, 3L); BookCollapsecommand BC4 = BookCollapsecommand baru (BookService, 4L); Masa depan <Book> q1 = bc1.queue (); Masa depan <Book> q2 = bc2.queue (); Masa depan <Book> q3 = bc3.queue (); Buku buku1 = q1.get (); Buku buku2 = q2.get (); Buku buku3 = q3.get (); Thread.sleep (3000); Future <Book> q4 = bc4.queue (); Buku buku4 = q4.get (); System.out.println ("Book1 >>>"+Book1); System.out.println ("Book2 >>>"+Book2); System.out.println ("Book3 >>>"+Book3); System.out.println ("Book4 >>>"+Book4); context.close ();}Mengenai antarmuka tes ini, saya mengatakan dua poin berikut:
1. Pertama, Anda perlu menginisialisasi hystrixRequestContext
2. Buat contoh kelas BookCollapsecommand untuk memulai permintaan, kirim 3 permintaan terlebih dahulu, kemudian tidur selama 3 detik, dan kemudian memulai permintaan. Dengan cara ini, 3 permintaan pertama akan digabungkan menjadi satu permintaan. Permintaan keempat tidak akan digabungkan karena interval di antara mereka relatif panjang, tetapi akan membuat utas untuk memprosesnya secara terpisah.
Oke, mari kita lihat hasil eksekusi, sebagai berikut:
Permintaan gabungan diimplementasikan melalui anotasi
OK, metode penggabungan permintaan di atas sedikit merepotkan untuk ditulis, kita dapat menggunakan anotasi untuk mengimplementasikan fungsi ini lebih elegan. Pertama, tambahkan dua metode di BookService, sebagai berikut:
@HyStrixCollapser (BatchMethod = "Test11", CollapserProperties = {@HyStrixProperty (name = "TimerDelayInmillIseconds", value = "100")}) Masa Depan Publik <Book> Test10 (Buku Panjang) {return null;}@hystrixcommand System.out.println ("test9 ----------"+id+"thread.currentThread (). GetName ():"+thread.currentThread (). GetName ()); Buku [] buku = restTemplate.getForObject ("http: // hello-service/getBook6? Ids = {1}", book []. Class, stringutils.join (id, ",")); return arrays.aslist (buku);}Tambahkan anotasi @HyStrixCollapser untuk mengimplementasikan permintaan gabungan pada metode test10, gunakan atribut BatchMethod untuk menunjukkan metode pemrosesan setelah penggabungan permintaan, dan atribut CollapserProperties untuk menentukan atribut lain.
OK, setelah menulisnya di BookService, sebut saja secara langsung, sebagai berikut:
@RequestMapping ("/test8")@responseBodypublic void test8 () melempar ExecutionException, InterruptedException {HyStrixRequestContext Context = HyStrixRixRixRixContext.initializeContext (); Masa Depan <Book> F1 = Bookservice.test10 (1L); Masa Depan <Book> F2 = Bookservice.test10 (2L); Future <Book> f3 = bookservice.test10 (3l); Buku b1 = f1.get (); Buku b2 = f2.get (); Buku b3 = f3.get (); Thread.sleep (3000); Masa Depan <Book> F4 = Bookservice.test10 (4L); Buku b4 = f4.get (); System.out.println ("B1 >>>"+B1); System.out.println ("B2 >>>"+B2); System.out.println ("B3 >>>"+B3); System.out.println ("B4 >>>"+B4); context.close ();}Seperti yang sebelumnya, tiga permintaan pertama akan digabungkan, dan permintaan keempat akan dieksekusi secara terpisah. OK, dan hasil eksekusi adalah sebagai berikut:
Meringkaskan
Keuntungan dari permintaan merger, teman-teman telah melihat bahwa banyak permintaan digabungkan ke dalam permintaan untuk pemrosesan satu kali, yang secara efektif dapat menyimpan bandwidth jaringan dan sumber daya kumpulan utas. Namun, ada kelebihan dan kekurangan. Setelah menyiapkan penggabungan permintaan, permintaan mungkin telah selesai dalam 5ms, tetapi sekarang Anda harus menunggu 10ms lagi untuk melihat apakah ada permintaan lain bersama. Dengan cara ini, konsumsi waktu permintaan akan meningkat dari 5ms menjadi 15ms. Namun, jika perintah yang akan kami inisiasi adalah perintah penundaan tinggi, maka Anda dapat menggunakan permintaan gabungan saat ini, karena konsumsi waktu jendela waktu tidak signifikan saat ini. Selain itu, konkurensi tinggi juga merupakan skenario yang sangat penting untuk merger permintaan.
Oke, itu saja untuk permintaan kami untuk bergabung. Jika Anda memiliki pertanyaan, silakan tinggalkan pesan dan diskusikan. Saya berharap ini akan membantu untuk pembelajaran semua orang, dan saya harap semua orang akan lebih mendukung wulin.com.