Dubbo + Hystrix 實現服務熔斷

熔斷器簡介

在微服務架構中,根據業務來拆分成一個個的服務,服務與服務之間可以通過RPC相互調用。爲了保證其高可用,單個服務通常會集羣部署。由於網絡原因或者自身的原因,服務並不能保證 100% 可用,如果單個服務出現問題,調用這個服務就會出現線程阻塞,此時若有大量的請求湧入,Servlet容器的線程資源會被消耗完畢,導致服務癱瘓。服務與服務之間的依賴性,故障會傳播,會對整個微服務系統造成災難性的嚴重後果,這就是服務故障的 “雪崩”效應。

爲了解決這個問題,業界提出了熔斷器模型。

Netflix 開源了 Hystrix 組件,實現了熔斷器模式,Spring Cloud 對這一組件進行了整合。在微服務架構中,一個請求需要調用多個服務是非常常見的,如下圖:

在這裏插入圖片描述
較底層的服務如果出現故障,會導致連鎖故障。當對特定的服務的調用的不可用達到一個閥值(Hystrix 是 5 秒 20 次) 熔斷器將會被打開
在這裏插入圖片描述
熔斷器打開後,爲了避免連鎖故障,通過fallback方法可以直接返回一個固定值。

Dubbo Provider 中使用熔斷器

pom.xml中增加依賴

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    <version>2.0.1.RELEASE</version>
</dependency>

在 Application 中增加 @EnableHystrix 註解

package com.xyl.hello.dubbo.service.user.provider;

import com.alibaba.dubbo.container.Main;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;

@EnableHystrix
@SpringBootApplication
public class HelloDubboServiceUserProviderApplication {
    public static void main(String[] args) {
        SpringApplication.run(HelloDubboServiceUserProviderApplication.class, args);
        Main.main(args);
    }
}

在 Service 中增加 @HystrixCommand 註解

在調用方法上增加 @HystrixCommand配置,此時調用會經過Hystrix代理

package com.xyl.hello.dubbo.service.user.provider.api.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.xyyl.hello.dubbo.service.user.api.UserService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.beans.factory.annotation.Value;

@Service(version = "${user.service.version}")
public class UserServiceImpl implements UserService {

    @Value("${dubbo.protocol.port}")
    private String port;

    @HystrixCommand(commandProperties = {
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000")
    })
    @Override
    public String sayHi() {
//        return "Hello Dubbo, i am from port:" + port;
        throw new RuntimeException("Exception to show hystrix enabled.");
    }
}

測試熔斷器

此時我們再次請求服務提供者,瀏覽器會報 500 異常

Exception to show hystrix enabled.

Dubbo Consumer 中使用熔斷器

在 pom.xml 中增加依賴

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    <version>2.0.1.RELEASE</version>
</dependency>

在 Application 中增加 @EnableHystrix 註解

package com.xyl.hello.dubbo.service.user.consumer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;

@EnableHystrix
@SpringBootApplication
public class HelloDubboServiceUserConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(HelloDubboServiceUserConsumerApplication.class, args);
    }
}

在調用方法上增加 @HystrixCommand 註解,並指定 fallbackMethod 方法

package com.xyl.hello.dubbo.service.user.consumer.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.xyl.hello.dubbo.service.user.api.UserService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {

    @Reference(version = "${user.service.version}")
    private UserService userService;

    @HystrixCommand(fallbackMethod = "hiError")
    @RequestMapping(value = "hi")
    public String sayHi() {
        return userService.sayHi();
    }

    public String hiError() {
        return "Hystrix fallback";
    }
}

測試熔斷器

此時我們再次請求服務提供者,瀏覽器會顯示:

Hystrix fallback

至此,Dubbo + Hystrix 配置完成

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章