亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > Java > 正文

詳解spring cloud hystrix 請求合并collapsing

2024-07-14 08:40:56
字體:
來源:轉載
供稿:網友

HystrixCommand之前可以使用請求合并器(HystrixCollapser就是一個抽象的父類)來把多個請求合并成一個然后對后端依賴系統發起調用。

下圖顯示了兩種情況下線程的數量和網絡的連接數的情況:第一種是不使用合并器,第二種是使用請求合并器(假設所有的鏈接都是在一個短的時間窗口內并行的,比如10ms內)。

spring,cloud,請求合并,hystrix,合并,springcloud,合并請求

為什么要使用請求合并?

使用請求合并來減少執行并發HystrixCommand執行所需的線程數和網絡連接數,請求合并是自動執行的,不會強制開發人員手動協調批處理請求。

全局上下文-global context(跨越所有Tomcat線程)

這種合并類型是在全局應用級別上完成的,因此任何Tomcat線程上的任何用戶的請求都可以一起合并。

例如,如果您配置一個HystrixCommand支持任何用戶請求依賴關系來檢索電影評級,那么當同一個JVM中的任何用戶線程發出這樣的請求時,Hystrix會將其請求與任何其他請求一起添加到同一個已折疊網絡通話。

用戶請求上下文-request context(單個Tomcat線程)

如果你配置一個HystrixCommand僅僅為一個單個用戶處理批量請求,Hystrix可以在一個Tomcat線程(請求)中合并請求。

例如,一個用戶想要加載300個視頻對象的書簽,不是去執行300次網絡請求,Hystrix能夠將他們合并成為一個。

Hystrix默認是的就是request-scope,要使用request-scoped的功能(request caching,request collapsing, request log)你必須管理HystrixRequestContext的生命周期(或者實現一個可替代的HystrixConcurrencyStrategy
這就意味你在執行一個請求之前需要執行以下的代碼:

 

復制代碼 代碼如下:
HystrixRequestContext  context=HystrixRequestContext.initializeContext();

 

并且在請求的結束位置執行:

context.shutdown();

在標準的JavaWeb應用中,你也可以使用一個Servlet過濾器來初始化這個生命周期

public class HystrixRequestContextServletFilter implements Filter { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)   throws IOException, ServletException {  HystrixRequestContext context = HystrixRequestContext.initializeContext();  try {   chain.doFilter(request, response);  } finally {   context.shutdown();  } }}

然后將它配置在web.xml中

 <filter>  <display-name>HystrixRequestContextServletFilter</display-name>  <filter-name>HystrixRequestContextServletFilter</filter-name>  <filter-class>com.netflix.hystrix.contrib.requestservlet.HystrixRequestContextServletFilter</filter-class> </filter> <filter-mapping>  <filter-name>HystrixRequestContextServletFilter</filter-name>  <url-pattern>/*</url-pattern> </filter-mapping>

如果你是springboot開發的話代碼如下:

@WebFilter(filterName = "hystrixRequestContextServletFilter",urlPatterns = "/*")public class HystrixRequestContextServletFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {  HystrixRequestContext context = HystrixRequestContext.initializeContext();  try{   filterChain.doFilter(servletRequest,servletResponse);  }finally {   context.shutdown();  } } @Override public void destroy() { }}
@SpringBootApplication@EnableDiscoveryClient@EnableFeignClients@EnableHystrix//這個是必須的,否則filter無效@ServletComponentScanpublic class Application { public static void main(String[] args) {  new SpringApplicationBuilder(Application.class).web(true).run(args); }}

請求合并的成本是多少?

啟用請求合并的成本是在執行實際命令之前的延遲。最大的成本是批處理窗口的大小,默認是10ms。

如果你有一個命令需要花費5ms去執行并且有一個10ms的批處理窗口,執行的時間最壞的情況是15ms,一般情況下,請求不會在批處理窗口剛打開的時候發生,所以時間窗口的中間值是時間窗口的一半,在這種情況下是5ms。

這個成本是否值得取決于正在執行的命令,高延遲命令不會受到少量附加平均延遲的影響。而且,給定命令的并發量也是關鍵:如果很少有超過1個或2個請求被組合在一起,那么這個成本就是不值得的。事實上,在一個單線程的順序迭代請求合并將會是一個主要的性能瓶頸,每一次迭代都會等待10ms的窗口等待時間。

但是,如果一個特定的命令同時被大量使用,并且可以同時批量打幾十個甚至幾百個呼叫,那么成本通常遠遠超過所達到的吞吐量的增加,因為Hystrix減少了它所需的線程數量,依賴。(這段話不太好理解,其實就是說如果并發比較高,這個成本是值得的,因為hystrix可以節省很多線程和連接資源)。

請求合并的流程(如下圖)

spring,cloud,請求合并,hystrix,合并,springcloud,合并請求

理論知識已經講完了,下面來看看例子,下面的例子集成了eureka+feign+hystrix,完整的例子請查看:https://github.com/jingangwang/micro-service

實體類

public class User { private Integer id; private String username; private Integer age; public User() { } public User(Integer id, String username, Integer age) {  this.id = id;  this.username = username;  this.age = age; } 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; } public Integer getAge() {  return age; } public void setAge(Integer age) {  this.age = age; } @Override public String toString() {  final StringBuffer sb = new StringBuffer("User{");  sb.append("id=").append(id);  sb.append(", username='").append(username).append('/'');  sb.append(", age=").append(age);  sb.append('}');  return sb.toString(); }}

服務提供者代碼

@RestController@RequestMapping("user")public class UserController { @RequestMapping("getUser") public User getUser(Integer id) {  return new User(id, "test", 29); } @RequestMapping("getAllUser") public List<User> getAllUser(String ids){  String[] split = ids.split(",");  return Arrays.asList(split)    .stream()    .map(id -> new User(Integer.valueOf(id),"test"+id,30))    .collect(Collectors.toList()); }}

消費者代碼

UserFeignClient

@FeignClient(name = "eureka-provider",configuration = FeignConfiguration.class)public interface UserFeignClient { /**  * 根據id查找用戶  * @param id 用戶id  * @return  User  */ @RequestMapping(value = "user/getUser.json",method = RequestMethod.GET) User findUserById(@RequestParam("id") Integer id); /**  * 超找用戶列表  * @param ids id列表  * @return 用戶的集合  */ @RequestMapping(value = "user/getAllUser.json",method = RequestMethod.GET) List<User> findAllUser(@RequestParam("ids") String ids);}

UserService(設置為全局上下文)

@Servicepublic class UserService { @Autowired private UserFeignClient userFeignClient; /**  * maxRequestsInBatch        該屬性設置批量處理的最大請求數量,默認值為Integer.MAX_VALUE  * timerDelayInMilliseconds       該屬性設置多長時間之內算一次批處理,默認為10ms  * @param id  * @return  */ @HystrixCollapser(collapserKey = "findCollapserKey",scope = com.netflix.hystrix.HystrixCollapser.Scope.GLOBAL,batchMethod = "findAllUser",collapserProperties = {   @HystrixProperty(name = "timerDelayInMilliseconds",value = "5000" ),   @HystrixProperty(name = "maxRequestsInBatch",value = "5" ) }) public Future<User> find(Integer id){  return null; } @HystrixCommand(commandKey = "findAllUser") public List<User> findAllUser(List<Integer> ids){  return userFeignClient.findAllUser(StringUtils.join(ids,",")); }}

FeignCollapserController

@RequestMapping("user")@RestControllerpublic class FeignCollapserController { @Autowired private UserService userService; @RequestMapping("findUser") public User getUser(Integer id) throws ExecutionException, InterruptedException {  return userService.find(id).get(); }

上面的代碼我們這是的是全局上下文(所有tomcat的線程的請求都可以合并),合并的時間窗口為5s(每一次請求都得等5s才發起請求),最大合并數為5。我們在postman中,5s之內發起兩次請求,用戶id不一樣。

localhost:8082/user/findUser.json?id=123189891

localhost:8082/user/findUser.json?id=222222

結果如下圖所示,兩次請求合并為一次請求批量請求。

spring,cloud,請求合并,hystrix,合并,springcloud,合并請求

我們再來測試一下請求上下文(Request-Scope)的情況,加入上面所提到的HystrixRequestContextServletFilter,并修改UserService

HystrixRequestContextServletFilter

/** * @author wjg * @date 2017/12/22 15:15 */@WebFilter(filterName = "hystrixRequestContextServletFilter",urlPatterns = "/*")public class HystrixRequestContextServletFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {  HystrixRequestContext context = HystrixRequestContext.initializeContext();  try{   filterChain.doFilter(servletRequest,servletResponse);  }finally {   context.shutdown();  } } @Override public void destroy() { }}

UserService(設置為請求上下文)

@Servicepublic class UserService { @Autowired private UserFeignClient userFeignClient; /**  * maxRequestsInBatch        該屬性設置批量處理的最大請求數量,默認值為Integer.MAX_VALUE  * timerDelayInMilliseconds       該屬性設置多長時間之內算一次批處理,默認為10ms  * @param id  * @return  */ @HystrixCollapser(collapserKey = "findCollapserKey",scope = com.netflix.hystrix.HystrixCollapser.Scope.REQUEST,batchMethod = "findAllUser",collapserProperties = {   @HystrixProperty(name = "timerDelayInMilliseconds",value = "5000" ),   @HystrixProperty(name = "maxRequestsInBatch",value = "5" ) }) public Future<User> find(Integer id){  return null; } @HystrixCommand(commandKey = "findAllUser") public List<User> findAllUser(List<Integer> ids){  return userFeignClient.findAllUser(StringUtils.join(ids,",")); }}

FeignCollapser2Controller

@RequestMapping("user")@RestControllerpublic class FeignCollapser2Controller { @Autowired private UserService userService; @RequestMapping("findUser2") public List<User> getUser() throws ExecutionException, InterruptedException {  Future<User> user1 = userService.find(1989);  Future<User> user2= userService.find(1990);  List<User> users = new ArrayList<>();  users.add(user1.get());  users.add(user2.get());  return users; }}

我們在postman中輸入:localhost:8082/user/findUser2.json

spring,cloud,請求合并,hystrix,合并,springcloud,合并請求

可以看到一個請求內的兩次連續調用被合并了。這個地方要注意,不能直接使用userServer.find(1989).get(),否則直接按同步執行處理,不會合并。如果兩個tab頁同時調用上述地址,發現發起了兩次批量請求,說明作用域是request范圍。

參考資料如下:

https://github.com/Netflix/Hystrix/wiki/How-To-Use
 

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
3344国产精品免费看| 欧美在线观看网站| 久久精品国产欧美激情| 久久久精品久久久久| 亚洲一区二区三区香蕉| 九九九久久国产免费| 在线视频中文亚洲| 久久中文字幕国产| 日韩在线视频观看| 亚洲精品国产综合久久| 国产亚洲综合久久| 国产精品久久久久9999| 国产精品视频公开费视频| 日韩网站免费观看| xxxx欧美18另类的高清| 国产精品久久久久77777| 日韩精品小视频| 日本精品久久久久影院| 亚洲电影免费观看高清完整版| 日韩黄色在线免费观看| 国产精品丝袜久久久久久高清| 欧美午夜宅男影院在线观看| 欧美国产日本高清在线| 国产精品www色诱视频| 国产欧美韩国高清| 欧美日韩国产精品一区| 亚洲视频电影图片偷拍一区| 色婷婷亚洲mv天堂mv在影片| 91在线视频成人| 日韩免费中文字幕| 国产成+人+综合+亚洲欧美丁香花| 91精品国产精品| 日韩av电影院| 欧美老女人www| 亚洲美女自拍视频| 日韩免费高清在线观看| 欧美日韩综合视频| 久久久av一区| 国产精品99久久久久久人| 精品视频9999| 久久6免费高清热精品| 91精品国产沙发| 欧美性极品xxxx娇小| 国产精品久久久91| 国产狼人综合免费视频| 亚洲视频第一页| 精品久久久久久中文字幕一区奶水| 日韩精品在线观| 中文字幕精品久久| 亚洲欧美另类自拍| 美女国内精品自产拍在线播放| 精品久久久久久久久久久久久久| 久久久精品国产亚洲| 亚洲影视中文字幕| 国产婷婷成人久久av免费高清| 亚洲精品小视频| 欧美另类在线播放| 免费av一区二区| 91中文精品字幕在线视频| 一区二区三区视频免费在线观看| 欧美激情啊啊啊| 欧美黑人一级爽快片淫片高清| 最新91在线视频| 国产精品劲爆视频| 亚洲伊人一本大道中文字幕| 国产精品99久久久久久久久| 亚洲自拍小视频免费观看| 国产精品夜间视频香蕉| 欧美俄罗斯性视频| 久久精品一偷一偷国产| 国产91在线高潮白浆在线观看| 欧美日韩中国免费专区在线看| 日韩一区二区福利| 亚洲精品99久久久久中文字幕| 欧美激情高清视频| 不卡中文字幕av| 色与欲影视天天看综合网| 久久久久久久激情视频| 乱亲女秽乱长久久久| 在线观看久久久久久| 91九色视频在线| 操人视频在线观看欧美| 亚洲一级一级97网| 欧美整片在线观看| 欧洲成人在线视频| 久久99热这里只有精品国产| 中文字幕在线观看亚洲| 91成人在线观看国产| 黄色一区二区在线观看| 欧美激情视频在线免费观看 欧美视频免费一| 97在线观看免费高清| 97精品视频在线观看| 国产精品久久不能| 欧美猛交ⅹxxx乱大交视频| 日韩美女在线看| 亚洲欧美成人在线| 国产精品一区二区三区免费视频| 一区国产精品视频| 免费av一区二区| 精品香蕉在线观看视频一| 欧美二区在线播放| 91av中文字幕| 国产97在线观看| 久色乳综合思思在线视频| 欧美老妇交乱视频| 中文字幕免费精品一区高清| 亚洲精品国产福利| 久久精品亚洲热| 韩日精品中文字幕| 57pao成人永久免费视频| 在线免费观看羞羞视频一区二区| 欧美高跟鞋交xxxxxhd| 美日韩精品免费观看视频| 91精品国产高清久久久久久久久| 91免费看国产| 国产精品美女午夜av| 中文字幕亚洲情99在线| 96国产粉嫩美女| 欧美日韩一二三四五区| 亚洲第一色在线| 成人日韩av在线| 国产精品视频资源| 久久精品在线播放| 久久综合国产精品台湾中文娱乐网| 国产精品久久久久久久久久东京| 久久亚洲一区二区三区四区五区高| 九九精品视频在线| 91久久国产婷婷一区二区| 国产亚洲欧美一区| 日韩高清免费观看| 久久精品亚洲94久久精品| 亚洲国产日韩欧美在线图片| 欧美电影在线观看| 日韩资源在线观看| 亚洲美女自拍视频| 国产美女扒开尿口久久久| 在线成人中文字幕| 精品国产乱码久久久久久虫虫漫画| 狠狠久久亚洲欧美专区| 性亚洲最疯狂xxxx高清| 色综久久综合桃花网| 日韩欧美在线国产| 日本精品中文字幕| 国产日韩欧美夫妻视频在线观看| 久久久这里只有精品视频| 国语自产精品视频在线看抢先版图片| 国内精品模特av私拍在线观看| 亚洲自拍偷拍在线| 77777亚洲午夜久久多人| 日韩亚洲精品视频| 亚洲精品自产拍| 粉嫩av一区二区三区免费野| 久久久久九九九九| 国产精品爽爽爽爽爽爽在线观看| 日韩成人免费视频| 国产精品91视频| 国内精品久久久久伊人av| 91久久久亚洲精品| 国产主播在线一区| 欧美亚洲国产日韩2020| 97久久精品国产| 91欧美精品午夜性色福利在线| 亚洲欧美国产精品| 精品国产一区二区三区久久久狼|