hystrix应用介绍(二)
上篇博客中讲了hystrix在公司中的一些应用场景,由于保密的原因没办法贴出优化的代码,这里专门写一篇hystrix代码的demo,供大家在使用的过程中快速上手
Hystrix有两个请求命令 HystrixCommand(该方式代码的执行由新创建的线程执行)、HystrixObservableCommand(该方式代码的执行还是在主线程中执行)。
HystrixCommand用在依赖服务返回单个操作结果的时候。有两种执行方式
-execute():同步执行。从依赖的服务返回一个单一的结果对象,或是在发生错误的时候抛出异常。
-queue();异步执行。直接返回一个Future对象,其中包含了服务执行结束时要返回的单一结果对象。
HystrixObservableCommand 用在依赖服务返回多个操作结果的时候。它也实现了两种执行方式
-observe():返回Obervable对象,他代表了操作的多个结果,他是一个HotObservable
-toObservable():同样返回Observable对象,也代表了操作多个结果,但它返回的是一个Cold Observable
下边以注解和非注解两种形式演示
第一步引入所依赖的pom
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-core</artifactId>
<version>${hystrix-version}</version>
</dependency>
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-metrics-event-stream</artifactId>
<version>${hystrix-version}</version>
</dependency>
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-javanica</artifactId>
<version>${hystrix-version}</version>
</dependency>
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-servo-metrics-publisher</artifactId>
<version>${hystrix-version}</version>
</dependency>
第二步:在spring的xml配置中引入相关注解
<!-- 配置成注解方式寻找要被代理的对象 -->
<aop:aspectj-autoproxy/>
<!-- hystrix -->
<bean id="hystrixAspect" class="com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect"></bean>
<context:annotation-config/>
HystrixCommand代码演示
一、下边先演示 HystrixCommand的注解方式
import javafx.application.Application;
import org.hope.hystrix.example.HystrixApplication;
import org.hope.hystrix.example.model.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration; import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future; /**
*
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = HystrixApplication.class)
public class UserServiceTest { @Autowired
private UserService userService; /**
* 测试同步
*/
@Test
public void testGetUserId() {
System.out.println(Thread.currentThread().getName());
System.out.println("=================" + userService.getUserId("hystrix"));
} /**
* 测试异步
*/
@Test
public void testGetUserName() throws ExecutionException, InterruptedException {
Future<String> fuature = userService.getUserName(30L,"hellow");
System.out.println("=================" + fuature.get());
}
}
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.ObservableExecutionMode;
import com.netflix.hystrix.contrib.javanica.command.AsyncResult;
import org.springframework.stereotype.Service;
import rx.Observable;
import rx.Subscriber; import java.util.concurrent.Future; /**
* 用@HystrixCommand的方式来实现
*/
@Service
public class UserService {
/**
* 同步的方式。
* fallbackMethod定义降级
*/
@HystrixCommand(fallbackMethod = "helloFallback")
public String getUserId(String name) {
System.out.println(Thread.currentThread().getName());
int i = 1/0; //此处抛异常,测试服务降级
return "hellow:" + name;
} public String helloFallback(String name) {
return "error" + name;
} //异步的执行
@HystrixCommand(fallbackMethod = "getUserNameError")
public Future<String> getUserName(final Long id, String name) {
return new AsyncResult<String>() {
@Override
public String invoke() {
int i = 1/0;//此处抛异常,测试服务降级
return "你好:" + id; }
};
} public String getUserNameError(Long id, String name) {
return "触发熔断啦!!!!";
}
}
二、HystrixCommand的非注解方式
import org.junit.Test;
import rx.Observable;
import rx.Observer;
import rx.Subscription;
import rx.functions.Action1; import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future; import static org.junit.Assert.assertEquals; /**
*
*/
public class CommandHelloWorldTest { /**
* 测试同步执行
*/
@Test
public void testSynchronous() { System.out.println(new CommandHelloWorld("World").execute());
} /**
* 测试异步执行
*/
@Test
public void testAsynchronous() throws ExecutionException, InterruptedException {
Future<String> fWorld = new CommandHelloWorld("World").queue();
System.out.println(fWorld.get()); //一步执行用get()来获取结果
} }
import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandKey;
import com.netflix.hystrix.HystrixRequestCache;
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategyDefault;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.client.RestTemplate; /**
* HystrixCommand用在命令服务返回单个操作结果的时候
*/
public class CommandHelloWorld extends HystrixCommand<String> {
private final String name; public CommandHelloWorld(String name) {
super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
this.name = name;
} @Override
protected String run() throws Exception {
int i = 1/0;
return "Hello " + name + "!";
} /**
* 降级。Hystrix会在run()执行过程中出现错误、超时、线程池拒绝、断路器熔断等情况时,
* 执行getFallBack()方法内的逻辑
*/
@Override
protected String getFallback() {
return "faild";
}
}
HystrixObservableCommand代码演示
import org.junit.Test;
import rx.Observable; import java.util.Iterator; /**
*/
public class ObservableCommandHelloWorldTest { @Test
public void testObservable() {
Observable<String> observable= new ObservableCommandHelloWorld("World").observe();
Iterator<String> iterator = observable.toBlocking().getIterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
} @Test
public void testToObservable() {
Observable<String> observable= new ObservableCommandHelloWorld("World").observe();
Iterator<String> iterator = observable.toBlocking().getIterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
} }
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixObservableCommand;
import rx.Observable;
import rx.Subscriber;
import rx.schedulers.Schedulers; /**
*/
public class ObservableCommandHelloWorld extends HystrixObservableCommand<String> { private final String name; public ObservableCommandHelloWorld(String name) {
super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
this.name = name;
} @Override
protected Observable<String> construct() {
return Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
try {
if(!subscriber.isUnsubscribed()) {
subscriber.onNext("Hello");
int i = 1 / 0; //模拟异常
subscriber.onNext(name + "!");
subscriber.onCompleted();
}
} catch (Exception e) {
subscriber.onError(e);
}
}
}).subscribeOn(Schedulers.io());
} /**
* 服务降级
*/
@Override
protected Observable<String> resumeWithFallback() {
return Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
try {
if (!subscriber.isUnsubscribed()) {
subscriber.onNext("失败了!");
subscriber.onNext("触发熔断啦");
subscriber.onCompleted();
}
} catch (Exception e) {
subscriber.onError(e);
}
}
}).subscribeOn(Schedulers.io());
}
}
基于注解HystrixObservableCommand
package org.hope.hystrix.example.service; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.ObservableExecutionMode;
import org.springframework.stereotype.Service;
import rx.Observable;
import rx.Subscriber; @Service
public class ObservableUserService {
/**
* EAGER参数表示使用observe()方式执行
*/
@HystrixCommand(observableExecutionMode = ObservableExecutionMode.EAGER, fallbackMethod = "observFailed") //使用observe()执行方式
public Observable<String> getUserById(final Long id) {
return Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
try {
if(!subscriber.isUnsubscribed()) {
subscriber.onNext("张三的ID:");
int i = 1 / 0; //抛异常,模拟服务降级
subscriber.onNext(String.valueOf(id));
subscriber.onCompleted();
}
} catch (Exception e) {
subscriber.onError(e);
}
}
});
} private String observFailed(Long id) {
return "observFailed---->" + id;
} /**
* LAZY参数表示使用toObservable()方式执行
*/
@HystrixCommand(observableExecutionMode = ObservableExecutionMode.LAZY, fallbackMethod = "toObserbableError") //表示使用toObservable()执行方式
public Observable<String> getUserByName(final String name) {
return Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
try {
if(!subscriber.isUnsubscribed()) {
subscriber.onNext("找到");
subscriber.onNext(name);
int i = 1/0; ////抛异常,模拟服务降级
subscriber.onNext("了");
subscriber.onCompleted();
}
} catch (Exception e) {
subscriber.onError(e);
}
}
});
} private String toObserbableError(String name) {
return "toObserbableError--->" + name;
} }
package org.hope.hystrix.example.service; import org.hope.hystrix.example.HystrixApplication;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import java.util.Iterator; @RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = HystrixApplication.class)
public class ObservableUserServiceTest { @Autowired
private ObservableUserService observableUserService; @Test
public void testObserve() {
Iterator<String> iterator = observableUserService.getUserById(30L).toBlocking().getIterator();
while(iterator.hasNext()) {
System.out.println("===============" + iterator.next());
}
} @Test
public void testToObservable() {
Iterator<String> iterator = observableUserService.getUserByName("王五").toBlocking().getIterator();
while(iterator.hasNext()) {
System.out.println("===============" + iterator.next());
}
}
}
项目中大多情况下都是用使用基于注解 HystrixCommand,上边说了HystrixCommand使用的是异步,代码逻辑的执行是在新的线程中执行的,可是释放掉当前的主线程,可以更大程度的提升代码的并发
原文地址:https://www.cnblogs.com/happyflyingpig/p/8079308.html
hystrix应用介绍(二)的更多相关文章
- hystrix基本介绍和使用(1)
一.hystrix基本介绍 Hystrix(https://github.com/Netflix/Hystrix)是Netflix(https://www.netflix.com/global)的一个 ...
- hystrix应用介绍(一)
声明:本文仅做个人的一次接口重构过程记录,期间参考了一些写的不错的博客,如果存在抄袭,请留言. hystrix基本介绍 hystrix 是一个开源的容灾框架,目的是为了解决当依赖服务出现故障或者接口响 ...
- Lucene.Net 2.3.1开发介绍 —— 二、分词(六)
原文:Lucene.Net 2.3.1开发介绍 -- 二.分词(六) Lucene.Net的上一个版本是2.1,而在2.3.1版本中才引入了Next(Token)方法重载,而ReusableStrin ...
- Lucene.Net 2.3.1开发介绍 —— 二、分词(五)
原文:Lucene.Net 2.3.1开发介绍 -- 二.分词(五) 2.1.3 二元分词 上一节通过变换查询表达式满足了需求,但是在实际应用中,如果那样查询,会出现另外一个问题,因为,那样搜索,是只 ...
- Lucene.Net 2.3.1开发介绍 —— 二、分词(三)
原文:Lucene.Net 2.3.1开发介绍 -- 二.分词(三) 1.3 分词器结构 1.3.1 分词器整体结构 从1.2节的分析,终于做到了管中窥豹,现在在Lucene.Net项目中添加一个类关 ...
- Lucene.Net 2.3.1开发介绍 —— 二、分词(四)
原文:Lucene.Net 2.3.1开发介绍 -- 二.分词(四) 2.1.2 可以使用的内置分词 简单的分词方式并不能满足需求.前文说过Lucene.Net内置分词中StandardAnalyze ...
- Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
原文:Lucene.Net 2.3.1开发介绍 -- 二.分词(二) 1.2.分词的过程 1.2.1.分词器工作的过程 内置的分词器效果都不好,那怎么办?只能自己写了!在写之前当然是要先看看内置的分词 ...
- Lucene.Net 2.3.1开发介绍 —— 二、分词(一)
原文:Lucene.Net 2.3.1开发介绍 -- 二.分词(一) Lucene.Net中,分词是核心库之一,当然,也可以将它独立出来.目前Lucene.Net的分词库很不完善,实际应用价值不高.唯 ...
- {Django基础十之Form和ModelForm组件}一 Form介绍 二 Form常用字段和插件 三 From所有内置字段 四 字段校验 五 Hook钩子方法 六 进阶补充 七 ModelForm
Django基础十之Form和ModelForm组件 本节目录 一 Form介绍 二 Form常用字段和插件 三 From所有内置字段 四 字段校验 五 Hook钩子方法 六 进阶补充 七 Model ...
- MySQL之多表查询一 介绍 二 多表连接查询 三 符合条件连接查询 四 子查询 五 综合练习
MySQL之多表查询 阅读目录 一 介绍 二 多表连接查询 三 符合条件连接查询 四 子查询 五 综合练习 一 介绍 本节主题 多表连接查询 复合条件连接查询 子查询 首先说一下,我们写项目一般都会建 ...
随机推荐
- equals和==的区别 (Java基础)
1. == 是一个运算符.2.Equals则是string对象的方法,可以.(点)出来. 我们比较无非就是这两种 1.基本数据类型比较 2.引用对象比较 1.基本数据类型比较 ==和Equals都比较 ...
- Java编码思想之什么是高内聚低耦合?
分别描述的是模块内部特征,和模块外部引用关系. 内聚就是一个模块内各个元素彼此结合的紧密程度,高内聚就是一个模块内各个元素彼此结合的紧密程度高. 内聚是就其中任何一个模块的内部特征而言的. 耦合是就多 ...
- 洛谷 P3806 【模板】点分治1
P3806 [模板]点分治1 题目背景 感谢hzwer的点分治互测. 题目描述 给定一棵有n个点的树 询问树上距离为k的点对是否存在. 输入输出格式 输入格式: n,m 接下来n-1条边a,b,c描述 ...
- 「十二省联考 2019」字符串问题——SAM+DAG
题目 [题目描述] Yazid 和 Tiffany 喜欢字符串问题.在这里,我们将给你介绍一些关于字符串的基本概念. 对于一个字符串 $S$, 我们定义 $\lvert S\rvert$ 表示 $S$ ...
- Xml Helper
类的完整代码: using System;using System.Collections;using System.Xml; namespace Keleyi.Com.XmlDAL{public c ...
- 【Leetcode】Combinations
Given two integers n and k, return all possible combinations of k numbers out of 1 ... n. For exampl ...
- P4173 残缺的字符串(FFT)
[Luogu4173] 题解 \(1.\)定义匹配函数 \(2.\)定义完全匹配函数 \(3.\)快速计算每一位的完全匹配函数值 #include<cstdio> #include< ...
- 封装OkHttp,通过改造Callback接口实现
1:实现Callback回调接口import android.os.Handler;import android.os.Looper;import android.os.Message; import ...
- 一个简单的基于MINI2440开发板的启动代码
1. S3C2440大概的启动流程(NAND启动): ①设置CPU为SVC模式 ②关闭看门狗 ③屏蔽中断 ④关闭MMU ⑤初始化时钟 ⑥初始化内存(SDRAM) ⑦初始化栈指针(SP, R13) ⑧初 ...
- sql运算符优先级及逻辑处理顺序--查询sql执行顺序
sql逻辑处理顺序 --开启和关闭查询 --SET STATISTICS TIME ON---------------------------------------------请先来看看SET ST ...