spring cloud調(diào)用方法異常怎么辦--Hystrix使用講解

關(guān)于spring cloud的組件前面已經(jīng)介紹兩個了, 學習的過程也是循序漸進的, 如果前面寫的關(guān)于Eureka和Feign兩個組件還沒有看的同學,可以點擊以下鏈接進行學習;
spring cloud之Eureka--服務治理
spring cloud使用過Eureka怎么進行服務間相互訪問--Feign
下面是我自己在github上的spring cloud的demo
spring_cloud_demo
下面進入正題;

1.Hystrix

Hystrix

Hystrix對應的中文名字是“豪豬”,豪豬周身長滿了刺,能保護自己不受天敵的傷害,代表了一種防御機制,這與Hystrix本身的功能不謀而合,因此Netflix團隊將該框架命名為Hystrix,并使用了對應的卡通形象做作為logo

1.1什么是Hystrix

在一個分布式系統(tǒng)里,許多依賴不可避免的會調(diào)用失敗,比如超時、異常等,如何能夠保證在一個依賴出問題的情況下,不會導致整體服務失敗,這個就是Hystrix需要做的事情。Hystrix提供了熔斷、隔離、Fallback、cache、監(jiān)控等功能,能夠在一個、或多個依賴同時出現(xiàn)問題時保證系統(tǒng)依然可用。

1.2為什么使用Hystrix

在微服務架構(gòu)中,根據(jù)業(yè)務來拆分成一個個的服務,服務與服務之間可以相互調(diào)用(RPC) 。為了保證其高可用,單個服務通常會集群部署。由于網(wǎng)絡原因或者自身的原因,服務并不能保證100%可用,如果單個服務出現(xiàn)問題,調(diào)用這個服務就會出現(xiàn)線程阻塞,此時若有大量的請求涌入,Servlet容器的線程資源會被消耗完畢,導致服務癱瘓。服務與服務之間的依賴性,故障會傳播,會對整個微服務系統(tǒng)造成災難性的嚴重后果,這就是服務故障的“雪崩”效應。

如下圖所示:A作為服務提供者,B為A的服務消費者,C和D是B的服務消費者。A不可用引起了B的不可用,并將不可用像滾雪球一樣放大到C和D時,雪崩效應就形成了。

雪崩效應

1.3Hystrix是如何實現(xiàn)

(1)通過HystrixCommand或者HystrixObservableCommand來封裝對外部依賴的訪問請求,這個訪問請求一般會運行在獨立的線程中,資源隔離
(2)對于超出我們設(shè)定閾值的服務調(diào)用,直接進行超時,不允許其耗費過長時間阻塞住。這個超時時間默認是99.5%的訪問時間,但是一般我們可以自己設(shè)置一下
(3)為每一個依賴服務維護一個獨立的線程池,或者是semaphore,當線程池已滿時,直接拒絕對這個服務的調(diào)用
(4)對依賴服務的調(diào)用的成功次數(shù),失敗次數(shù),拒絕次數(shù),超時次數(shù),進行統(tǒng)計
(5)如果對一個依賴服務的調(diào)用失敗次數(shù)超過了一定的閾值,自動進行熔斷,在一定時間內(nèi)對該服務的調(diào)用直接降級,一段時間后再自動嘗試恢復
(6)當一個服務調(diào)用出現(xiàn)失敗,被拒絕,超時,短路等異常情況時,自動調(diào)用fallback降級機制
(7)對屬性和配置的修改提供近實時的支持

2.項目中使用Hystrix

2.1添加依賴

<!--添加熔斷器依賴-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
        </dependency>

該依賴加在我的demo中的父項目中

2.2添加注解

在spring boot的啟動類上添加注解@EnableHystrix

package cn.cooplan.order;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@EnableHystrix //開啟熔斷器
@EnableFeignClients
@EnableEurekaClient //開啟Eureka客戶端服務
@SpringBootApplication
public class OrderApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }
     //Feigx依賴的請求對象
    @Bean
    RestTemplate restTemplate (){
        return new RestTemplate();
    }
}

2.3測試+解釋

需要在你請求的方法上添加 @HystrixCommand("發(fā)生異常時訪問的方法名") 在同一個類中編寫異常時進行的方法處理, 具體實現(xiàn)如下:

package cn.cooplan.order.service.impl;

import cn.cooplan.order.feign.GoodsFeignClient;
import cn.cooplan.order.service.OrderService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import dao.OrderDao;
import dao.OrderGoodsDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import pojo.Goods;
import pojo.Order;
import pojo.OrderGoods;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author MaoLG
 * @Date 2018/12/7  14:03
 */
@Service
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderDao orderDao;

    @Autowired
    private OrderGoodsDao orderGoodsDao;

    @Autowired
    private GoodsFeignClient goodsFeignClient;

  /*在你請求的方法上添加@HystrixCommand注解, 參數(shù)指定發(fā)生錯誤時調(diào)取的方法
    該方法要保持參數(shù)列表相同, 返回值相同, 拋出異常相同, 非靜態(tài)方法;
    總結(jié)的說就是除了方法名不一樣,其他都一樣;
*/
    @HystrixCommand(fallbackMethod = "getOrderInGoodsHystrix")
    @Override
    public List<Goods> getOrderInGoods(Integer orderId) {
        OrderGoods o = new OrderGoods();
        o.setOrderId(orderId);
        QueryWrapper queryWrapper = new QueryWrapper(o);
        List<OrderGoods> ogs = orderGoodsDao.selectList(queryWrapper);
        List<Goods> goodses = new ArrayList<>();
        for (OrderGoods og: ogs) {
            Goods goods = goodsFeignClient.getGoodsById(og.getGoodsId());
            goodses.add(goods);
        }
        return goodses;
    }

  //請求的方法發(fā)生錯誤/請求超時調(diào)取該方法
    public List<Goods> getOrderInGoodsHystrix(Integer orderId){
        List<Goods> goodses = new ArrayList<>();
        Goods goods = new Goods();
        goods.setName("商品錯誤");
        goodses.add(goods);
        return goodses;
    }
}

Hystrix成功后:
無異常情況

無異常.jpg

異常情況
進入的方法:
進入方法.jpg

異常效果
有錯誤.jpg

詳細請見github上的spring cloud的demo
spring_cloud_demo
歡迎大家在下面留言討論;

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容