使用Springboot和Hystrix构建API Gateway

1 篇文章 0 订阅

使用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
- 请求合并

目录

一个例子

在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

这里写图片描述

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot提供了与Hystrix的集成,以便在微服务架构中实现容错和故障保护。要整合Hystrix,首先需要在Spring Boot项目的pom.xml文件中添加HystrixHystrix Dashboard的依赖。 ```xml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId> </dependency> ``` 接下来,在Spring Boot应用程序的启动类上添加`@EnableCircuitBreaker`注解,以启用Hystrix断路器功能。 ```java import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @EnableCircuitBreaker public class YourApplication { public static void main(String[] args) { SpringApplication.run(YourApplication.class, args); } } ``` 然后,在需要应用Hystrix的方法上使用`@HystrixCommand`注解,以定义回退逻辑。 ```java import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; @RestController public class YourController { @GetMapping("/yourEndpoint") @HystrixCommand(fallbackMethod = "fallbackMethod") public String yourMethod() { // Your method logic here // ... } public String fallbackMethod() { // Fallback logic here // ... } } ``` 最后,启动应用程序并访问Hystrix Dashboard的URL(默认为`http://localhost:8080/hystrix`),在输入框中输入Hystrix流的URL(默认为`/actuator/hystrix.stream`),然后点击"Monitor Stream"按钮,即可监控Hystrix断路器的状态。 这就是Spring Boot整合Hystrix的基本步骤。通过使用Hystrix,可以实现对微服务的容错和故障保护,提高系统的可靠性和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值