Sebelum HystrixCommand , Anda dapat menggunakan merger permintaan ( HystrixCollapser adalah kelas induk abstrak) untuk menggabungkan beberapa permintaan menjadi satu dan kemudian memulai panggilan ke sistem ketergantungan backend.
Gambar di bawah ini menunjukkan jumlah utas dan jumlah koneksi jaringan dalam dua kasus: yang pertama adalah tidak menggunakan merger, dan yang kedua adalah menggunakan merger permintaan (dengan asumsi bahwa semua tautan paralel dalam jendela waktu singkat, seperti dalam 10ms).
Mengapa Menggunakan Permintaan Gabungan?
Permintaan gabungan digunakan untuk mengurangi jumlah utas dan koneksi jaringan yang diperlukan untuk melakukan eksekusi HystrixCommand secara bersamaan. Permintaan penggabungan dilakukan secara otomatis dan tidak memaksa pengembang untuk mengoordinasikan permintaan batch secara manual.
Konteks global - konteks global (mencakup semua utas Tomcat)
Jenis penggabungan ini dilakukan di tingkat aplikasi global, sehingga permintaan pengguna apa pun pada utas Tomcat apa pun dapat digabungkan bersama.
Misalnya, jika Anda mengkonfigurasi HystrixCommand untuk mendukung dependensi permintaan pengguna untuk mengambil peringkat film, ketika ada utas pengguna dalam JVM yang sama membuat permintaan seperti itu, Hytrix menambahkan permintaannya bersama dengan permintaan lain ke panggilan jaringan yang sama.
Konteks Permintaan Pengguna - Konteks Permintaan (utas Tomcat tunggal)
Jika Anda mengkonfigurasi HystrixCommand untuk menangani permintaan batch hanya untuk satu pengguna, Hystrix dapat menggabungkan permintaan di utas Tomcat (permintaan).
Misalnya, jika pengguna ingin memuat bookmark 300 objek video, alih -alih mengeksekusi 300 permintaan jaringan, Hystrix dapat menggabungkannya menjadi satu.
Hystrix adalah scope-scope secara default. Untuk menggunakan fungsi permintaan-scoped (permintaan caching, runtuhnya permintaan, log permintaan) Anda harus mengelola siklus hidup HystrixRequestContext (atau mengimplementasikan alternatif HystrixConcurrencyStrategy )
Ini berarti bahwa Anda perlu menjalankan kode berikut sebelum melaksanakan permintaan:
Salinan kode adalah sebagai berikut: hystrixRequestContext Context = hystrixRequestContext.initializeContext ();
Dan mengeksekusi di akhir permintaan:
context.shutdown ();
Dalam aplikasi Javaweb standar, Anda juga dapat menggunakan filter servlet untuk menginisialisasi siklus hidup ini
Kelas Publik HystrixRequestContextServerFilter mengimplementasikan filter {public void dofilter (permintaan servletRequest, respons servletResponse, filterchain rantai) melempar ioException, servletException {hystrixRequestContext context = hystrixRixRequestContext.initializeizealizeizeizeizeizeizeizezecontext (hystrixRixRixText.initializeizeizeizeizeizeizeizeNizeNIzeNIZENIZE ( coba {chain.dofilter (permintaan, respons); } akhirnya {context.shutdown (); }}}Kemudian konfigurasinya di web.xml
<nilter> <preach-name> hystrixRequestContextServerFilter </play- <filter-name> hystrixRequestContextServerFilter </tiler-name> <RURL-PATERS>/*</RURL-PATERS> </TERFERTER-MAPPING>
Jika Anda mengembangkan springboot, kode ini adalah sebagai berikut:
@WebFilter (filtername = "hystrixRequestContextSerVleTfilter", urlpatterns = "/*") kelas publik hystrixRequestContextServerFilter mengimplementasikan filter {@override public init (filterconfig filterconfig) melempar servletException {overRide @eoverRide @eoverrleD @ @overrEpryreFigrig) Layanan Layanan @OVERRIDEFLOVIG @OVERRIDEVIG @EVERREFIG @EVERREVIG) ServletResponse ServletResponse, FilterChain FilterChain) melempar IoException, ServletException {HyStrixRequestContext Context = HystrixRequestContext.initializeContext (); coba {filterchain.dofilter (servletRequest, servletResponse); } akhirnya {context.shutdown (); }} @Override public void dashar () {}} @SpringbootApplication@enableDiscoveryclient@enablefeignclients@enableHystrix // Ini diperlukan, jika tidak, filternya tidak valid @SerVletComponentScanPlic Public Class Application {public static Main (String [] args) {new springApplicationBuilder (application.class). }}Berapa biaya meminta penggabungan?
Biaya penggabungan permintaan yang memungkinkan adalah penundaan sebelum perintah aktual dieksekusi. Biaya terbesar adalah ukuran jendela batch, yaitu 10ms secara default.
Jika Anda memiliki perintah yang membutuhkan 5ms untuk dieksekusi dan memiliki jendela batch 10ms, kasus terburuk waktu eksekusi adalah 15ms. Secara umum, permintaan tidak akan terjadi ketika jendela batch baru saja dibuka, sehingga nilai perantara jendela waktu adalah setengah dari jendela waktu, dalam hal ini adalah 5ms.
Apakah biaya ini layak tergantung pada perintah yang dieksekusi, dan perintah latensi tinggi tidak terpengaruh oleh sejumlah kecil penundaan rata-rata tambahan. Selain itu, jumlah konkurensi perintah yang diberikan juga merupakan kunci: jika kurang dari 1 atau 2 permintaan digabungkan, maka biayanya tidak sepadan. Bahkan, permintaan iterasi berurutan bergabung dalam satu utas akan menjadi hambatan kinerja utama, dan setiap iterasi akan menunggu waktu tunggu jendela 10ms.
Namun, jika perintah tertentu digunakan dalam jumlah besar secara bersamaan dan dapat membuat lusinan atau bahkan ratusan panggilan dalam batch pada saat yang sama, biaya biasanya lebih dari peningkatan throughput yang dicapai, karena Hystrix mengurangi jumlah utas yang dibutuhkan, ketergantungan. (Perikop ini tidak mudah dimengerti. Faktanya, jika konkurensi relatif tinggi, biayanya sepadan, karena Hystrix dapat menghemat banyak utas dan sumber daya koneksi).
Proses meminta penggabungan (seperti yang ditunjukkan di bawah)
Pengetahuan teoretis telah dijelaskan. Mari kita lihat contoh di bawah ini. Contoh -contoh di bawah ini mengintegrasikan Eureka+Petera+Hystrix. Sebagai contoh lengkap, silakan periksa: https://github.com/jingangwang/micro-service
Kelas Entitas
Pengguna kelas publik {private integer ID; nama pengguna string pribadi; usia bilangan bulat pribadi; pengguna publik () {} pengguna publik (ID integer, string nama pengguna, usia integer) {this.id = id; this.username = nama pengguna; this.age = usia; } public integer getId () {return id; } public void setid (integer id) {this.id = id; } public string getUserName () {return username; } public void setusername (string username) {this.username = username; } getage integer publik () {usia kembali; } public void setage (usia integer) {this.age = usia; } @Override public String toString () {final StringBuffer sb = new StringBuffer ("user {"); sb.append ("id ="). append (id); sb.append (", username = '"). append (username) .append ('/''); SB.Append (", usia ="). Append (usia); SB.Append ('}'); return sb.tostring (); }}Kode Penyedia Layanan
@Restcontroller @requestMapping ("user") kelas publik usercontroller {@requestmapping ("getUser") pengguna publik getUser (integer id) {return baru pengguna (id, "test", 29); } @RequestMapping ("getAllUser") Daftar publik <user> getAllUser (string id) {string [] split = ids.split (","); return arrays.aslist (split) .stream () .map (id -> pengguna baru (integer.valueof (id), "test"+id, 30)) .collect (collectors.tolist ()); }}Kode Konsumen
Userfeignclient
@FeignClient(name = "eureka-provider",configuration = FeignConfiguration.class)public interface UserFeignClient { /** * Find user by id* @param id User id * @return User */ @RequestMapping(value = "user/getUser.json",method = RequestMethod.GET) User findUserById(@RequestParam("id") Integer id); /*** Melebihi Daftar Pengguna* Daftar ID ID @Param* @Return Koleksi Pengguna*/@RequestMapping (value = "user/getalluser.json", Method = requestMethod.get) Daftar <User> findAllUser (@RequestParam ("IDS") string IDS);}UserserService (diatur ke konteks global)
@ServicePublic kelas UserserService {@Autowired private userfeignClient userfeignClient; / ** * MaxRequestSinBatch Properti ini menetapkan jumlah maksimum permintaan untuk pemrosesan batch, nilai defaultnya adalah integer.max_value * timerDelayInmilliseconds Properti ini menetapkan berapa lama "colapkkey" @param id * @return */ @hystrixcon, colapkkey "@param id * @return */ @hystrixcol com.netflix.hystrix.hystrixcollapser.scope.global, batchmethod = "findAllUser", collapserproperties = {@hystrixproperty (name = "timerDelayInmillisConds", value = "5000 Masa Depan Publik <User> Temukan (ID Integer) {return null; } @HyStrixCommand (CommandKey = "FindAllUser") Daftar Publik <User> findAllUser (Daftar <Integer> id) {return userfeignClient.findallUser (stringutils.join (id, ",", ")); }}FegnCollapSerController
@RequestMapping ("user") @restcontrollerPublic kelas feigncollapsercontroller {@Autowired private userserverService UserService; @RequestMapping ("FindUser") Pengguna Publik GetUser (Integer ID) melempar ExecutionException, InterruptedException {return userservice.find (id) .get (); } Dalam kode di atas, kami berada dalam konteks global (semua permintaan dari utas Tomcat dapat digabungkan), jendela waktu penggabungan adalah 5s (setiap permintaan harus menunggu 5s sebelum permintaan dimulai), dan jumlah maksimum penggabungan adalah 5. Di postman, kami memulai dua permintaan dalam 5s, tetapi ID pengguna berbeda.
LocalHost: 8082/user/findUser.json? Id = 123189891
LocalHost: 8082/user/findUser.json? ID = 222222
Hasilnya ditunjukkan pada gambar di bawah ini, dan kedua permintaan digabungkan menjadi satu permintaan permintaan batch.
Mari kita uji konteks permintaan (permintaan-scope), tambahkan HystrixRequestContextServletFilter yang disebutkan di atas, dan ubah UsersEver
HystrixRequestContextSerVletFilter
/** * @author wjg * @date 2017/12/22 15:15 */ @webfilter (filtername = "hystrixRequestContextServerFilter", UrlPatterns = "/ *") PublicflexconFionficonFionficonfiFonFixconFIlconfilter @ @ @ @ @exrixRide PublicConFion {} @Override public void dofilter (servletRequest servletRequest, servletResponse servletResponse, filterchain filterchain) melempar ioException, servletException {hystrixRequestContext context = hystrixRequestContext.initializecext ();); coba {filterchain.dofilter (servletRequest, servletResponse); } akhirnya {context.shutdown (); }} @Override public void dashar () {}}UserserService (ditetapkan sebagai konteks permintaan)
@ServicePublic kelas UserserService {@Autowired private userfeignClient userfeignClient; / ** * MaxRequestSinBatch Properti ini menetapkan jumlah maksimum permintaan untuk pemrosesan batch, nilai defaultnya adalah integer.max_value * timerDelayInmilliseconds Properti ini menetapkan berapa lama "colapkkey" @param id * @return */ @hystrixcon, colapkkey "@param id * @return */ @hystrixcol com.netflix.hystrix.hystrixcollapser.scope.request, batchmethod = "findAllUser", collapserproperties = {@hystrixproperty (name = "timerDelayInmilliseconds", value = "5000 Masa Depan Publik <User> Temukan (ID Integer) {return null; } @HyStrixCommand (CommandKey = "FindAllUser") Daftar Publik <User> findAllUser (Daftar <Integer> id) {return userfeignClient.findallUser (stringutils.join (id, ",", ")); }}FegnCollapser2Controller
@RequestMapping ("user") @restcontrollerPublic kelas feigncollapser2Controller {@Autowired private userserverService UserService; @RequestMapping ("FindUser2") Daftar Publik <User> getUser () melempar ExecutionException, InterruptedException {Future <User> user1 = Userservice.find (1989); Masa Depan <User> User2 = Userservice.find (1990); Daftar <User> user = new ArrayList <> (); user.add (user1.get ()); user.add (user2.get ()); Pengguna yang kembali; }} Kami mengetik pos: localhost: 8082/user/finduser2.json
Anda dapat melihat bahwa dua panggilan berturut -turut dalam suatu permintaan digabungkan. Perhatikan bahwa ini tidak mungkin untuk menggunakan usererver.find (1989) .get () secara langsung, jika tidak pemrosesan akan dilakukan secara langsung sesuai dengan sinkronisasi dan tidak akan digabungkan. Jika dua halaman tab memanggil alamat di atas pada saat yang sama, ditemukan bahwa dua permintaan batch telah dimulai, yang berarti bahwa ruang lingkup adalah ruang lingkup permintaan.
Referensi adalah sebagai berikut:
https://github.com/netflix/hystrix/wiki/how-to-use
//www.vevb.com/article/140530.htm
Di atas adalah semua konten artikel ini. Saya berharap ini akan membantu untuk pembelajaran semua orang dan saya harap semua orang akan lebih mendukung wulin.com.