Hystrix简介–总结
這是其他兩篇文章的后續(xù)文章– 動(dòng)機(jī) ,說明為什么在分布式系統(tǒng)中需要類似Hystrix的內(nèi)容,以及Hystrix的基本介紹 。
這將是我的Hystrix旅程的總結(jié),其中包含各種屬性的詳細(xì)信息,可以對(duì)這些屬性進(jìn)行調(diào)整以更改Hystrix的行為,并涉及一些高級(jí)概念
調(diào)整Hystrix行為
Hystrix的配置在此Wiki中進(jìn)行了解釋,簡(jiǎn)要介紹了兩個(gè)主要的組來控制Hystrix的屬性,
屬性遵循Wiki中說明的優(yōu)先順序,這里我將重點(diǎn)介紹通過屬性文件指定的屬性。
對(duì)于示例命令,定義了以下方式:
public class HelloWorldCommand extends HystrixCommand<String> {private static final Logger logger = LoggerFactory.getLogger(HelloWorldCommand.class);private final String name;public HelloWorldCommand(String name) {super(HystrixCommandGroupKey.Factory.asKey("default"));this.name = name;}@Overrideprotected String run() throws Exception {logger.info("HelloWorld Command Invoked");return "Hello " + name;} }可以調(diào)整的第一個(gè)行為是在線程池中執(zhí)行命令還是與調(diào)用方(SEMAPHORE策略類型)執(zhí)行線程相同。 如果執(zhí)行在線程池中,則可以設(shè)置請(qǐng)求超時(shí)。
hystrix.command.HelloWorldCommand.execution.isolation.strategy=THREAD hystrix.command.HelloWorldCommand.execution.isolation.thread.timeoutInMilliseconds=1000第二種行為是斷路器,它根據(jù)在滾動(dòng)時(shí)間窗內(nèi)收集的信息進(jìn)行工作,這種方式進(jìn)行配置,例如持續(xù)10秒:
hystrix.command.HelloWorldCommand.metrics.rollingStats.timeInMilliseconds=10000在此窗口中,如果一定百分比的故障(例如50%)發(fā)生在請(qǐng)求閾值(例如10秒內(nèi)發(fā)生20個(gè)故障),則電路斷開,其配置如下所示:
hystrix.command.HelloWorldCommand.circuitBreaker.requestVolumeThreshold=20 hystrix.command.HelloWorldCommand.circuitBreaker.errorThresholdPercentage=50電路斷開后,它將保持這種狀態(tài)并保持以下設(shè)置的時(shí)間,在這種情況下為5秒:
hystrix.command.HelloWorldCommand.circuitBreaker.sleepWindowInMilliseconds=5000線程池設(shè)置是使用指定的組密鑰控制的,在本示例中稱為默認(rèn)組密鑰。 不過,也可以將特定的“線程池鍵”指定為構(gòu)造函數(shù)的一部分。
hystrix.threadpool.default.coreSize=10 hystrix.threadpool.default.queueSizeRejectionThreshold=5在這里,可以并行運(yùn)行10個(gè)命令,而其他5個(gè)則保留在隊(duì)列中,超過該隊(duì)列將拒絕請(qǐng)求。
要求折疊
Tomaz Nurkiewicz在他的博客網(wǎng)站NoBlogDefFound中做了出色的解釋請(qǐng)求折疊的工作 。 我的示例有些簡(jiǎn)化,請(qǐng)考慮以下情況,其中有很多請(qǐng)求要檢索給定id的Person,方法如下:
public class PersonService {public Person findPerson(Integer id) {return new Person(id, "name : " + id);}public List<Person> findPeople(List<Integer> ids) {return ids.stream().map(i -> new Person(i, "name : " + i)).collect(Collectors.toList());} }該服務(wù)以固定響應(yīng)進(jìn)行響應(yīng),但假定該調(diào)用是對(duì)遠(yuǎn)程數(shù)據(jù)存儲(chǔ)的。 還可以看到,該服務(wù)實(shí)現(xiàn)了一個(gè)批處理方法,以在給定ID列表的情況下檢索人員列表。
請(qǐng)求折疊是一項(xiàng)功能,它將一段時(shí)間內(nèi)發(fā)生的多個(gè)用戶請(qǐng)求批處理為一個(gè)這樣的遠(yuǎn)程呼叫,然后將響應(yīng)散發(fā)回用戶。
可以通過以下方式定義獲取一組ID并獲取人員響應(yīng)的hystrix命令:
public class PersonRequestCommand extends HystrixCommand<List<Person>>{private final List<Integer> ids;private final PersonService personService = new PersonService();private static final Logger logger = LoggerFactory.getLogger(PersonRequestCommand.class);public PersonRequestCommand(List<Integer> ids) {super(HystrixCommandGroupKey.Factory.asKey("default"));this.ids = ids;}@Overrideprotected List<Person> run() throws Exception {logger.info("Retrieving details for : " + this.ids);return personService.findPeople(this.ids);} }到目前為止,非常簡(jiǎn)單,復(fù)雜的邏輯現(xiàn)在位于RequestCollapser中,如下所示:
package aggregate.commands.collapsed;import com.netflix.hystrix.HystrixCollapser; import com.netflix.hystrix.HystrixCollapserKey; import com.netflix.hystrix.HystrixCollapserProperties; import com.netflix.hystrix.HystrixCommand;import java.util.Collection; import java.util.List; import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors;public class PersonRequestCollapser extends HystrixCollapser<List<Person>, Person, Integer> {private final Integer id;public PersonRequestCollapser(Integer id) {super(Setter.withCollapserKey(HystrixCollapserKey.Factory.asKey("personRequestCollapser")).andCollapserPropertiesDefaults(HystrixCollapserProperties.Setter().withTimerDelayInMilliseconds(2000)));this.id = id;}@Overridepublic Integer getRequestArgument() {return this.id;}@Overrideprotected HystrixCommand<List<Person>> createCommand(Collection<CollapsedRequest<Person, Integer>> collapsedRequests) {List<Integer> ids = collapsedRequests.stream().map(cr -> cr.getArgument()).collect(Collectors.toList());return new PersonRequestCommand(ids);}@Overrideprotected void mapResponseToRequests(List<Person> batchResponse, Collection<CollapsedRequest<Person, Integer>> collapsedRequests) {Map<Integer, Person> personMap = batchResponse.stream().collect(Collectors.toMap(Person::getId, Function.identity()));for (CollapsedRequest<Person, Integer> cr: collapsedRequests) {cr.setResponse(personMap.get(cr.getArgument()));}} }這里發(fā)生了一些事情,首先,參數(shù)化類型簽名中的類型指示響應(yīng)的類型(List <Person>),調(diào)用方期望的響應(yīng)類型(Person)和請(qǐng)求的請(qǐng)求類型(請(qǐng)求的ID)。人)。 然后有兩種方法,一種創(chuàng)建批處理命令,第二種將響應(yīng)映射回原始請(qǐng)求。
現(xiàn)在,從用戶的角度來看,這沒有多大變化,就好像對(duì)單個(gè)命令一樣進(jìn)行調(diào)用,并且Request Collapsing處理批處理,分派和映射回響應(yīng)。 這是示例測(cè)試的樣子:
@Test public void testCollapse() throws Exception {HystrixRequestContext requestContext = HystrixRequestContext.initializeContext();logger.info("About to execute Collapsed command");List<Observable<Person>> result = new ArrayList<>();CountDownLatch cl = new CountDownLatch(1);for (int i = 1; i <= 100; i++) {result.add(new PersonRequestCollapser(i).observe());}Observable.merge(result).subscribe(p -> logger.info(p.toString()), t -> logger.error(t.getMessage(), t), () -> cl.countDown());cl.await();logger.info("Completed executing Collapsed Command");requestContext.shutdown(); }結(jié)論
Hystrix的功能遠(yuǎn)不止我在這里介紹的內(nèi)容。 它確實(shí)是一個(gè)很棒的庫,對(duì)于創(chuàng)建彈性系統(tǒng)至關(guān)重要。我已經(jīng)開始欣賞設(shè)計(jì)這個(gè)出色的庫所花費(fèi)的大量思考過程。
翻譯自: https://www.javacodegeeks.com/2015/11/gentle-introduction-to-hystrix-wrapup.html
總結(jié)
以上是生活随笔為你收集整理的Hystrix简介–总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 异步处理时的JPA
- 下一篇: jboss as安装配置_书评:JBos