使用Springboot和Hystrix构建API Gateway
2016-06-02 11:25
531 查看
使用Hystrix构建API Gateway
随着MicroService架构越来越深入人心,如何构建一个高性能,错误容忍的API Gateway成了一个很多人都遇到的问题。Netflix开源了Hystrix来帮助我们实现API Gateway。这里提供一个Springboot+Hystrix的例子:
https://github.com/qmhu/SpringHystrixSample
关于微服务可以看一下这个系列的文章,讲的非常好:
http://dockone.io/article/394
Hystrix
提供了以下重要功能:- 同步/异步操作封装
- Fallback
- ThreadPool的隔离
- 请求Cache
- 请求合并
目录
使用Hystrix构建API GatewayHystrix
目录
一个例子
在pomxml里引入springboot和hystrix的依赖
启动springboot
定义CommandHttpCall
Future的方式进行异步调用
ObServe的方式进行异步调用
Dashboard
一个例子
在pom.xml里引入springboot和hystrix的依赖
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.springframework</groupId> <artifactId>gs-spring-boot</artifactId> <version>0.1.0</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.3.5.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.netflix.hystrix</groupId> <artifactId>hystrix-core</artifactId> <version>1.4.23</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.1</version> </dependency> <dependency> <groupId>com.netflix.hystrix</groupId> <artifactId>hystrix-metrics-event-stream</artifactId> <version>1.4.23</version> </dependency> </dependencies> <properties> <java.version>1.8</java.version> </properties> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
启动springboot
@SpringBootApplication public class Application { public static void main(String[] args) { ApplicationContext ctx = SpringApplication.run(Application.class, args); } }
定义CommandHttpCall
通过继承HystrixCommand定义了一个Command。这里封装了一个HttpCall的Command通过Setter配置了各种Group来做请求配置的隔离
配置了熔断器(CircuitBreaker),如果请求达到了熔断的条件会自动触发熔断机制
配置了fallback方法,如果熔断机制触发会返回fallback方法的结果
public class CommandHttpCall extends HystrixCommand<String>{ private final String url; private static final org.slf4j.Logger logger = LoggerFactory.getLogger(CommandHttpCall.class); public CommandHttpCall(String url) { super( Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("hystrix.command.http")) .andCommandKey(HystrixCommandKey.Factory.asKey("hystrix.command.http")) .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("hystrix.command.http")) .andCommandPropertiesDefaults( HystrixCommandProperties.Setter() .withCircuitBreakerRequestVolumeThreshold(2) .withCircuitBreakerSleepWindowInMilliseconds(60 * 1000). withFallbackEnabled(true). withExecutionIsolationThreadInterruptOnTimeout(true).withExecutionTimeoutInMilliseconds(5000))); this.url = url; } @Override protected String run() throws Exception { logger.info("Execution of Command: url={}", url); CloseableHttpClient httpclient = HttpClients.createDefault(); HttpGet httpGet = new HttpGet(url); try(CloseableHttpResponse response = httpclient.execute(httpGet)) { HttpEntity entity = (HttpEntity) response.getEntity(); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent())); String total = ""; String line = bufferedReader.readLine(); while (line != null){ total += line; line = bufferedReader.readLine(); } return total; } } @Override protected String getFallback() { return "failbackFor" + url; } }
Future的方式进行异步调用
Hystrix提供了java concurrency包标准的Future接口来获取一个异步调用的结果,这里首先请求了一个product service,等product service结果返回后再同时调用order service和cart service
@RequestMapping("/future") public String getFuture() throws InterruptedException { Future<String> productSyncCall = new CommandHttpCall("http://localhost:8091/product").queue(); try { String product = productSyncCall.get(); System.out.println("sync get product" + product); Future<String> orderSyncCall = new CommandHttpCall("http://localhost:8091/order").queue(); Future<String> cartSyncCall = new CommandHttpCall("http://localhost:8091/cart").queue(); System.out.println("sync get order" + orderSyncCall.get()); System.out.println("sync get cart" + cartSyncCall.get()); } catch (ExecutionException e) { e.printStackTrace(); } return new CommandHelloWorld("this is content for future").execute(); }
ObServe的方式进行异步调用
Hystrix还提供了Rxjava接口Observable的调用方式,这里首先同时调用了product和order service,等结果都complete后再调用cart service@RequestMapping("/observe") public String getObserve() throws InterruptedException { Observable<String> productCall = new CommandHttpCall("http://localhost:8091/product").observe(); Observable<String> orderCall = new CommandHttpCall("http://localhost:8091/order").observe(); Observable<String> cartCall = new CommandHttpCall("http://localhost:8091/cart").observe(); List<Observable<String>> result = new ArrayList<>(); result.add(productCall); result.add(orderCall); Observable.merge(result).subscribe(new Observer<String>() { @Override public void onCompleted() { System.out.println("product&order call complete"); cartCall.subscribe(new Observer<String>() { @Override public void onCompleted() { System.out.println("cart call complete"); } @Override public void onError(Throwable e) { } @Override public void onNext(String v) { System.out.println("onNext: " + v); } }); } @Override public void onError(Throwable e) { e.printStackTrace(); } @Override public void onNext(String v) { System.out.println("onNext: " + v); } }); return new CommandHelloWorld("this is content for observe").execute(); }
Dashboard
在spring boot里注册HystrixMetricsStreamServlet@Configuration @PropertySource("classpath:application.properties") class HystrixConfiguration extends SpringBootServletInitializer { /** * to expose stream endpoint */ @Bean public ServletRegistrationBean servletRegistrationBean() { return new ServletRegistrationBean(new HystrixMetricsStreamServlet(), "/hystrix.stream"); } }
配置好StreamServlet后就会在/hystrix.stream产生流数据,然后你只要再建一个dashboard并把当前的spring的url加入dashboard就可以看到很fancy的dashboard了。
搭建dashboard这块可以参考:
https://github.com/Netflix/Hystrix/tree/master/hystrix-dashboard
相关文章推荐
- Android Manifest 用法
- 什么是 GraphQL?
- Spark RDD API详解(一) Map和Reduce
- Spring Boot 开发微服务
- 喜欢 Netflix 么?你应该感谢 FreeBSD
- lwn拾遗:[sn3218 led drivers]-api解释-1
- 页面元素查找之Selectors API
- 网站502与504错误分析
- 一个小型js框架myJSFrame附API使用帮助
- 详细分析交换机、路由器、集线器的区别和联系
- PowerShell打开或关闭光驱
- 批处理的api WMIC学习体会有感第1/2页
- 批处理 API实现文件下载的代码第1/2页
- Lua教程(十七):C API简介
- 强制删除工具 xdelbox xdelbox1.5正式版下载
- 揪出交换机端口背后“凶手”导致网速太慢
- 电脑重启后突然检测不到硬盘的原因分析与解决办法
- C#中设计、使用Fluent API
- Google官方支持的NodeJS访问API,提供后台登录授权
- PQ分区出错! 巧用Ghost急速补救的绝妙办法