Hystrix-服务容错处理:什么是Hystrix

四、 线程隔离策略配置

系统默认采用线程隔离策略,我们可以通过andThreadPoolPropertiesDefaults配置线程池的一些参数,如以下代码所示:

public MyHystrixCommand(String name) {
super(HystrixCommand.Setter.withGroupKey (
HystrixCommandGroupKey.Factory .asKey( “MyGroup”))
.andCommandPropertiesDefaults (
HystrixCommandProperties.Setter()
.withExecutionIsolationStrategy (
HystrixCommandProperties.ExecutionIsolationStrategy.THREAD
)
) . andThreadPoolPropertiesDefaults (
HystrixThreadPoolProperties. Setter()
. withCoreSize(10 )
. withMaxQueueSize(100)
.withMax. imumSize(100)
)
);
this.name = name ;
}

五、 结果缓存

缓存在开发中经常用到,我们常用Redis这种第三方的缓存数据库来对数据进行缓存处理。Hystrix 中也为我们提供了方法级别的缓存。通过重写getCacheKey来判断是否返回缓存的数据,getCacheKey 可以根据参数来生成,这样同样的参数就可以都用到缓存了。

改造之前的 MyHystrixCommand ,在其中增加 getCacheKey 的重写实现,如以下代码所示:

@verride
protected String getCacheKey() {
return String.valueOf(this.name);
}

在上面的代码中,我们创建对象时传进来的name参数作为缓存的key。

为了证明能够用到缓存,在run方法中加一行输出,在调用多次的情况下,如果控制台只输出了一次,那么可以知道后面的都是走的缓存逻辑,如以下代码所示:

@override
protected String run() {
System.err.print1n(“get data”);
return this.name + “:” + Thread. currentThread().getName();
}

执行main方法,发现报错了:

根据错误提示可以知道,缓存的处理取决于请求的上下文,我们必须初始化Hystrix-RequestContext

改造main方法中的调用代码,初始化HystrixRequestContext,如以下代码所示:

public static void main(String[] args)throws InterruptedException, ExecutionException {
HystrixRequestContext context = HystrixRequestContext. initializeContext();
String result = new MyHystrixCommand(“yinjihuan”).execute();
System.out.println(result);
Futurefuture = new MyHystrixCommand(“yinjihuan”) .queue();
System.out.println(future.get());
context . shutdown() ;
}

改造完之后重写执行main方法,可以做正常运行了,输出结果如下

可以看到只输出一次 get data ,缓存生效。

六、 缓存清除

在上一节中我们学习了如何使用Hystrix来实现数据缓存功能。有缓存必然就有清除缓存的动作,当数据发生变动时,必须将缓存中的数据也更新掉,不然就会产生脏数据的问题。同样,Hystrix 也有清除缓存的功能。

增加一个支持缓存清除的类,如以下代码所示:

public class ClearCacheHystrixCommand extends HystrixCommand {
private final String name ;
private static final HystrixCommandKey GETTER_ KEY =
HystrixCommandKey.Factory . asKey(“MyKey”);
public ClearCacheHystrixCommand (String name) {
super ( HystrixCommand . Setter .withGroupKey ( HystrixCommandGroupKey .
Factory .asKey( “MyGroup” )) . andCommandKey (GETTER_ KEY )
);
this.name = name;
}
public static void fushCache(String name) {
HystrixRequestCache.getInstance ( GETTER_ KEY ,HystrixConcurrencyStrategyDefault. getInstance()). clear (name);
}

@Override
protected String getCacheKey() {
return String.valueOf(this.name);
}

@Override
protected String run() {
System.err.println(“get data”);
return this.name + “:” + Thread.currentThread(). getName();
}
@Override
protected String getFallback() {
return “失败了”;
}
}

flushCache方法就是清除缓存的方法,通过HystrixRequestCache来执行清除操作,根据getCacheKey返回的key来清除。

修改调用代码来验证清除是否有效果,如以下代码所示:

HystrixRequestContext context = HystrixRequestContext.initializeContext();
String result = new ClearCacheHystrixCommand(“yinjihuan”). execute();
System.out.println(result);
ClearCacheHystrixCommand.flushCache(“yinjihuan”);
Future future = new ClearCacheHystrixCommand(“yinjihuan”).queue();
System.out.println( future.get());

执行两次相同的key,在第二次执行之前调用缓存清除的方法,也就是说第二次用不到缓存,输出结果如下:

由上可以看到,输出两次get data,这证明缓存确实被清除了。可以把ClearCache-HystrixCommandflushCache这行代码注释掉再执行一次,就会发现只输出了一次get data,缓存是有效的,输入结果如下:

get data
yinjihuan:hystrix-MyGroup-1
yinjihuan:hystrix-MyGroup-1

七、 合并请求

Hystrix支持将多个请求自动合并为一个请求(见下方代码),利用这个功能可以节省网络开销,比如每个请求都要通过网络访问远程资源。如果把多个请求合并为一个一起执行,将多次网络交互变成一次,则会极大节省开销。

public class MyHystrixCollapser extends HystrixCollapser<List,String, String>{
private final String name;
public MyHystrixCollapser(String name) {
this.name = name;
}

@Override
public String getRequestArgument() {
return name;
}

@Override
protected HystrixCommand<List>createCommand( final Collection<CollapsedRequest<String,String>> requests){
return new BatchCommand(requests);
}

@override
protected void mapResponseToRequests(ListbatchResponse,Collection<CollapsedRequest<string, String>> requests){
int count = 0;
for (CollapsedRequest<string, String> request : requests) {
request.setResponse(batchResponse.get(count++));
}
}

private static final class BatchCommand extends HystrixCommand<List>{
private final Collection<CollapsedRequest<String,String>> requests;
private BatchCommand(Collection<CollapsedRequest<String, String>> requests) {
super(Setter.withGroupKey(HystrixComnandGroupKey.Factory.asKey(”ExampleGroup"))
.andCommandKey (
HystrixCommandKey.Factory.asKey(“GetValueForKey”)));
this. requests = requests;
}

@Override
protected List run() {
System.out.println(“真正执行请求…”);
ArrayList response = new ArrayList();
for(CollapsedRequest<string, String> request : requests){
response.add(“返回结果:”+ request.getArgument());
}
return response;
}
}
}

response = new ArrayList();
for(CollapsedRequest<string, String> request : requests){
response.add(“返回结果:”+ request.getArgument());
}
return response;
}
}
}

  • 10
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值