java B2B2C Springcloud電子商城系統-斷路器(Hystrix)

原理
在微服務架構中,服務之間形成調用鏈路,鏈路中的任何一個服務提供者都可能面臨着相應超時、宕機等不可用的情況,在高併發的情況下,這種情況會隨着併發量的上升惡化,形成“雪崩效應”,而斷路器hystrix正是用來解決這一個問題的組件。

斷路器基本原理爲:

正常情況下,斷路器關閉,服務消費者正常請求微服務

一段事件內,失敗率達到一定閾值(比如50%失敗,或者失敗了50次),斷路器將斷開,此時不再請求服務提供者,而是隻是快速失敗的方法(斷路方法)

斷路器打開一段時間,自動進入“半開”狀態,此時,斷路器可允許一個請求方法服務提供者,如果請求調用成功,則關閉斷路器,否則繼續保持斷路器打開狀態。

斷路器hystrix是保證了局部發生的錯誤,不會擴展到整個系統,從而保證系統的即使出現局部問題也不會造成系統雪崩。

配置/使用

下面講解在restTemplate和feign中斷路器的配置和使用步驟

restTemplate+ribbon整合Hystrix

引入hystrix依賴

  <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
   </dependency>

雖然Eureka依賴了ribbon,ribbon依賴了hystrix-core,但還是要引用了上面的maven依賴,因爲下面用到的@HystrixCommand註解用到了hystrix-javanica包

啓動類加上@EnableCircuitBreaker註解(@EnableHystrix也可以)

修改HelloWorldController的入口請求方法

@GetMapping("/message")
    @HystrixCommand(fallbackMethod = "getMessageFallback")
    public HelloworldMessage getMessage() {
        HelloMessage hello = getMessageFromHelloService();
        WorldMessage world = getMessageFromWorldService();
        HelloworldMessage helloworld = new HelloworldMessage();
        helloworld.setHello(hello);
        helloworld.setWord(world);
        log.debug("Result helloworld message:{}", helloworld);
        return helloworld;
    }

    /**
     * 斷路方法
     * @return
     */
    public HelloworldMessage getMessageFallback(){
       HelloMessage helloMessage=new HelloMessage();
       helloMessage.setName("hello");
       helloMessage.setMessage("error occurs");

       WorldMessage worldMessage=new WorldMessage();
       worldMessage.setMessage("world error occurs");
       HelloworldMessage helloworldMessage=new HelloworldMessage();
       helloworldMessage.setHello(helloMessage);
       helloworldMessage.setWord(worldMessage);
       return helloworldMessage;
    }

通過@HystrixCommand註解的fallbackMethod指向斷路方法,該方法會在調用hello服務或者world服務失敗時被調用。

@HystrixCommand 註解還可以配置超時事件等其他屬性。

測試

1)依次啓動eureka server:discovery/trace/hello/world/helloword項目

2)在瀏覽器輸入地址http:\localhost:8020/message,則返回正確的結果

3)停止hello項目,再次輸入上述地址,則執行斷路器中的方法。

feign下整合Hystrix

feign禁用Hystrix

在Spring Cloud中,只要Hystrix在項目的classpath中,Feign就會用斷路器包裹Feign客戶端的所有方法,如果要禁用Hystrix則可以通過自定義feign的配置來解決。

@Configuration
public class FeignConfiguration{
     @Bean
     @Scope("prototype")
     public Feign Builder feignBuilder(){
           return Feign.builder();
     }
}

要禁用Hystrix的接口引用該配置即可

@FeignClient(name="hello",configuration=FeignConfiguration.class)
public interface HelloService{
    ......
}

feign使用Hystrix

啓用Hystrix

默認情況下feign已經整合了Hystrix,在配置文件中開啓即可(本人用的的Dalston.SR2版本的Spring Cloud,需要在配置文件開啓)

feign:
  hystrix:
    enabled: true

接口指定回退類

在HelloService中修改FeignClient類,指定fallback的類

package com.example.helloworldfeign.service;

import com.example.helloworldfeign.model.HelloMessage;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

/**
 * @author billjiang [email protected]
 * @create 17-8-23
 */
@FeignClient(value="hello",fallback = HelloServiceFallback.class)
public interface HelloService {

    @GetMapping("/message")
    HelloMessage hello();


}

實現了接口fallback的類的實現:

package com.example.helloworldfeign.service;

import com.example.helloworldfeign.model.HelloMessage;
import org.springframework.stereotype.Component;

/**
 * @author billjiang [email protected]
 * @create 17-8-28
 */
@Component
public class HelloServiceFallback implements HelloService {
    @Override
    public HelloMessage hello() {
        HelloMessage helloMessage=new HelloMessage();
        helloMessage.setName("hello");
        helloMessage.setMessage("error occurs");
        return helloMessage;
    }
}

world項目同上

測試

1)依次啓動eureka server:discovery/trace/hello/world/helloword-feing項目

2)在瀏覽器輸入地址http:\localhost:8030/message,則返回正確的結果

3)停止hello項目,再次輸入上述地址,則執行斷路器中的方法。

查看斷路器錯誤日誌

如果要查看詳細的斷路器的日誌,可以通過註解@FeignClient的fallbackFactory來實現,如下代碼所示:

import com.example.helloworldfeign.model.HelloMessage;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

/**
 * @author billjiang [email protected]
 * @create 17-8-23
 */
@FeignClient(value="hello",fallbackFactory = HelloServiceFallbackFactory.class)
public interface HelloService {

    @GetMapping("/message")
    HelloMessage hello();


}


HelloServiceFallbackFactory類:
package com.example.helloworldfeign.service;

import com.example.helloworldfeign.model.HelloMessage;
import feign.hystrix.FallbackFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * @author billjiang [email protected]
 * @create 17-8-28
 */
@Component
public class HelloServiceFallbackFactory implements FallbackFactory<HelloService> {
    private final static Logger LOGGER= LoggerFactory.getLogger(HelloServiceFallbackFactory.class);
    @Override
    public HelloService create(Throwable throwable) {
        return new HelloService() {
            @Override
            public HelloMessage hello() {
                //print the error
                LOGGER.error("fallback ,the result is:",throwable);
                HelloMessage helloMessage=new HelloMessage();
                helloMessage.setName("hello");
                helloMessage.setMessage("error occurs");
                return helloMessage;
            }
        };

//需要JAVA Spring Cloud大型企業分佈式微服務雲構建的B2B2C電子商務平臺源碼 一零三八七七四六二六
    }
}

這樣會在控制檯把具體導致熔斷的信息輸出,以便跟蹤錯誤。

 java B2B2C springmvc mybatis電子商務平臺源碼 

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