麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 開發(fā) > Java > 正文

詳解spring cloud hystrix 請(qǐng)求合并collapsing

2024-07-14 08:40:56
字體:
供稿:網(wǎng)友

HystrixCommand之前可以使用請(qǐng)求合并器(HystrixCollapser就是一個(gè)抽象的父類)來把多個(gè)請(qǐng)求合并成一個(gè)然后對(duì)后端依賴系統(tǒng)發(fā)起調(diào)用。

下圖顯示了兩種情況下線程的數(shù)量和網(wǎng)絡(luò)的連接數(shù)的情況:第一種是不使用合并器,第二種是使用請(qǐng)求合并器(假設(shè)所有的鏈接都是在一個(gè)短的時(shí)間窗口內(nèi)并行的,比如10ms內(nèi))。

spring,cloud,請(qǐng)求合并,hystrix,合并,springcloud,合并請(qǐng)求

為什么要使用請(qǐng)求合并?

使用請(qǐng)求合并來減少執(zhí)行并發(fā)HystrixCommand執(zhí)行所需的線程數(shù)和網(wǎng)絡(luò)連接數(shù),請(qǐng)求合并是自動(dòng)執(zhí)行的,不會(huì)強(qiáng)制開發(fā)人員手動(dòng)協(xié)調(diào)批處理請(qǐng)求。

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

這種合并類型是在全局應(yīng)用級(jí)別上完成的,因此任何Tomcat線程上的任何用戶的請(qǐng)求都可以一起合并。

例如,如果您配置一個(gè)HystrixCommand支持任何用戶請(qǐng)求依賴關(guān)系來檢索電影評(píng)級(jí),那么當(dāng)同一個(gè)JVM中的任何用戶線程發(fā)出這樣的請(qǐng)求時(shí),Hystrix會(huì)將其請(qǐng)求與任何其他請(qǐng)求一起添加到同一個(gè)已折疊網(wǎng)絡(luò)通話。

用戶請(qǐng)求上下文-request context(單個(gè)Tomcat線程)

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

例如,一個(gè)用戶想要加載300個(gè)視頻對(duì)象的書簽,不是去執(zhí)行300次網(wǎng)絡(luò)請(qǐng)求,Hystrix能夠?qū)⑺麄兒喜⒊蔀橐粋€(gè)。

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

 

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

 

并且在請(qǐng)求的結(jié)束位置執(zhí)行:

context.shutdown();

在標(biāo)準(zhǔn)的JavaWeb應(yīng)用中,你也可以使用一個(gè)Servlet過濾器來初始化這個(gè)生命周期

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開發(fā)的話代碼如下:

@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//這個(gè)是必須的,否則filter無效@ServletComponentScanpublic class Application { public static void main(String[] args) {  new SpringApplicationBuilder(Application.class).web(true).run(args); }}

請(qǐng)求合并的成本是多少?

啟用請(qǐng)求合并的成本是在執(zhí)行實(shí)際命令之前的延遲。最大的成本是批處理窗口的大小,默認(rèn)是10ms。

如果你有一個(gè)命令需要花費(fèi)5ms去執(zhí)行并且有一個(gè)10ms的批處理窗口,執(zhí)行的時(shí)間最壞的情況是15ms,一般情況下,請(qǐng)求不會(huì)在批處理窗口剛打開的時(shí)候發(fā)生,所以時(shí)間窗口的中間值是時(shí)間窗口的一半,在這種情況下是5ms。

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

但是,如果一個(gè)特定的命令同時(shí)被大量使用,并且可以同時(shí)批量打幾十個(gè)甚至幾百個(gè)呼叫,那么成本通常遠(yuǎn)遠(yuǎn)超過所達(dá)到的吞吐量的增加,因?yàn)镠ystrix減少了它所需的線程數(shù)量,依賴。(這段話不太好理解,其實(shí)就是說如果并發(fā)比較高,這個(gè)成本是值得的,因?yàn)閔ystrix可以節(jié)省很多線程和連接資源)。

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

spring,cloud,請(qǐng)求合并,hystrix,合并,springcloud,合并請(qǐng)求

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

實(shí)體類

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(); }}

服務(wù)提供者代碼

@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()); }}

消費(fèi)者代碼

UserFeignClient

@FeignClient(name = "eureka-provider",configuration = FeignConfiguration.class)public interface UserFeignClient { /**  * 根據(jù)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(設(shè)置為全局上下文)

@Servicepublic class UserService { @Autowired private UserFeignClient userFeignClient; /**  * maxRequestsInBatch        該屬性設(shè)置批量處理的最大請(qǐng)求數(shù)量,默認(rèn)值為Integer.MAX_VALUE  * timerDelayInMilliseconds       該屬性設(shè)置多長(zhǎng)時(shí)間之內(nèi)算一次批處理,默認(rèn)為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的線程的請(qǐng)求都可以合并),合并的時(shí)間窗口為5s(每一次請(qǐng)求都得等5s才發(fā)起請(qǐng)求),最大合并數(shù)為5。我們?cè)趐ostman中,5s之內(nèi)發(fā)起兩次請(qǐng)求,用戶id不一樣。

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

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

結(jié)果如下圖所示,兩次請(qǐng)求合并為一次請(qǐng)求批量請(qǐng)求。

spring,cloud,請(qǐng)求合并,hystrix,合并,springcloud,合并請(qǐng)求

我們?cè)賮頊y(cè)試一下請(qǐng)求上下文(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(設(shè)置為請(qǐng)求上下文)

@Servicepublic class UserService { @Autowired private UserFeignClient userFeignClient; /**  * maxRequestsInBatch        該屬性設(shè)置批量處理的最大請(qǐng)求數(shù)量,默認(rèn)值為Integer.MAX_VALUE  * timerDelayInMilliseconds       該屬性設(shè)置多長(zhǎng)時(shí)間之內(nèi)算一次批處理,默認(rèn)為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; }}

我們?cè)趐ostman中輸入:localhost:8082/user/findUser2.json

spring,cloud,請(qǐng)求合并,hystrix,合并,springcloud,合并請(qǐng)求

可以看到一個(gè)請(qǐng)求內(nèi)的兩次連續(xù)調(diào)用被合并了。這個(gè)地方要注意,不能直接使用userServer.find(1989).get(),否則直接按同步執(zhí)行處理,不會(huì)合并。如果兩個(gè)tab頁同時(shí)調(diào)用上述地址,發(fā)現(xiàn)發(fā)起了兩次批量請(qǐng)求,說明作用域是request范圍。

參考資料如下:

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

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持VeVb武林網(wǎng)。


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到JAVA教程頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 亚洲五码在线观看视频 | 国产午夜亚洲精品 | 欧洲精品色| 亚洲午夜激情网 | 精品中文字幕久久久久四十五十骆 | 一级外国毛片 | 嫩草影院在线观看网站成人 | 91久久久国产精品 | 在线视频 中文字幕 | 国产精品影视 | 在线91视频| 怦然心动50免费完整版 | 性aaa| 全黄性性激高免费视频 | 美女黄页网站免费进入 | 国产精品视频一区二区三区综合 | 亚洲午夜久久久精品一区二区三区 | 久久国产精品二国产精品中国洋人 | 成人午夜精品 | 毛片在线免费 | 久久久久国产成人精品亚洲午夜 | 一本一本久久a久久精品综合小说 | 亚洲成人免费电影 | 久久久久久久久久久亚洲 | 一级黄片毛片免费看 | 成人视屏在线 | 久久精品伊人网 | 欧美a级在线免费观看 | 黄色特级片黄色特级片 | 精品国产一区二区三区久久久 | 亚洲成人福利电影 | 亚洲人成网在线观看 | 视屏一区 | 香蕉成人在线视频 | 日本不卡二区 | 免费看性xxx高清视频自由 | 亚洲精品久久久久www | 精品国产一区二区三区在线观看 | 7m视频成人精品分类 | 久久久三区| 一区www|