SpringCloud?hystrix斷路器與全局解耦全面介紹
第七章中在ProductController 和OrderController 中都使用了局部服務(wù)降級(jí),但同時(shí)也導(dǎo)致兩個(gè)問(wèn)題, 通過(guò)觀察兩個(gè)局部降級(jí)的案例,可以發(fā)現(xiàn):
每個(gè)業(yè)務(wù)方法都對(duì)應(yīng)一個(gè)降級(jí)方法,會(huì)導(dǎo)致代碼膨脹業(yè)務(wù)邏輯方法和處理服務(wù)異常降級(jí)方法混在一起。
業(yè)務(wù)邏輯方法和處理服務(wù)異常降級(jí)方法混在一起,不便于維護(hù),為解決此問(wèn)題,可以使用注解 @FeignClient(value = "PRODUCT-SERVICE",fallback = xxx.class)在調(diào)用遠(yuǎn)端服務(wù)的接口上進(jìn)行指定服務(wù)降級(jí)方法解耦,并實(shí)現(xiàn)調(diào)用遠(yuǎn)端服務(wù)的接口的實(shí)現(xiàn)類,在實(shí)現(xiàn)類中統(tǒng)計(jì)管理服務(wù)降級(jí)解耦的方法。
進(jìn)行全局解耦,以 訂單服務(wù) OrderController 調(diào)用 商品服務(wù)ProductController 為案例,過(guò)程如下:
1、訂單服務(wù) 和 商品服務(wù)引入依賴
訂單服務(wù)引入依賴 openfegin , 商品服務(wù)分別引入依賴 Hystrix
2、清除OrderController 和 ProductController 所有降級(jí)方法
清除OrderController 所有降級(jí)方法
import com.hwadee.springcloud.entity.Product;
import com.hwadee.springcloud.service.IOrderFeignService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
IOrderFeignService orderFeignService;
@RequestMapping("/buy/{id}")
public Product buy(@PathVariable Long id) {
System.out.println("進(jìn)入OrderController的buy方法, orderFeignService 準(zhǔn)備調(diào)用遠(yuǎn)端接口 findById");
Product product = orderFeignService.findOrderById(id);
return product;
}
@RequestMapping(value = "/delete/{id}")
public Product deleteOrderById(@PathVariable Long id) {
System.out.println("進(jìn)入OrderController的deleteOrderById方法, orderFeignService 準(zhǔn)備調(diào)用遠(yuǎn)端接口deleteOrderById");
Product product = orderFeignService.deleteOrderById(id);
return product;
}
}清除 ProductController 所有降級(jí)方法
注意,若有全局或者專屬降級(jí)可以自己增加。此處為方便演示,不使用全局或者專屬。
import com.hwadee.springcloud.entity.Product;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.math.BigDecimal;
@RestController
@RequestMapping("/product")
public class ProductController {
//方便后面講負(fù)載均衡,查看ip,此處獲取配置中的端口號(hào)和ip
@Value("${server.port}")
private String port;
@Value("${spring.cloud.client.ip-address}")
private String ip;
@RequestMapping("/buy/{id}")
public Product findById(@PathVariable Long id) {
Product product = new Product();
product.setId(id);
// 后面需要測(cè)試負(fù)載均衡,所以返回 ip 地址及端口號(hào)
product.setName("當(dāng)前訪問(wèn)服務(wù)地址:" + ip + ":" + port + " " + "查詢商品訂單,訂單號(hào):" + id);
product.setPrice(new BigDecimal(10000.0));
System.out.println(product);
//測(cè)試超時(shí)熔斷
try {
Thread.sleep(5000);
//測(cè)試并發(fā)熔斷
//Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
return product;
}
@RequestMapping(value = "/delete/{id}")
public Product deleteOrderById(@PathVariable Long id) {
Product product = new Product();
product.setId(id);
// 后面需要測(cè)試負(fù)載均衡,所以返回 ip 地址及端口號(hào)
product.setName("當(dāng)前訪問(wèn)服務(wù)地址:" + ip + ":" + port + " " + "從購(gòu)物車刪除訂單,訂單號(hào):" + id);
product.setPrice(new BigDecimal(10000.0));
System.out.println(product);
//測(cè)試異常熔斷
System.out.println(10 / 0);
return product;
}
}2、定義Feign接口的實(shí)現(xiàn)類
因?yàn)橛唵畏?wù) OrderController中通過(guò) 接口IOrderFeignService和 注解@FeignClient 遠(yuǎn)程調(diào)用商品服務(wù)ProductController,因此當(dāng)訂單服務(wù) OrderController出現(xiàn)超時(shí)或異常,可以通過(guò)訂單服務(wù) OrderController中通過(guò) 接口IOrderFeignService的 實(shí)現(xiàn)類OrderFeignServiceFallBack 將務(wù)邏輯的處理方法 和 降級(jí)方法進(jìn)行解耦。
import com.hwadee.springcloud.entity.Product;
import com.hwadee.springcloud.service.IOrderFeignService;
import org.springframework.stereotype.Component;
@Component
public class OrderFeignServiceFallBack implements IOrderFeignService {
@Override
public Product findOrderById(Long id) {
Product product = new Product();
product.setId(id);
product.setName("當(dāng)前訂單服務(wù)訪問(wèn)/order/buy/1 超時(shí):"+id);
return product;
}
@Override
public Product deleteOrderById(Long id) {
Product product = new Product();
product.setId(id);
product.setName("當(dāng)前訂單服務(wù)訪問(wèn)/order/delete/1 10/0異常:"+id);
return product;
}
}3、修改IOrderFeignService代碼
在 接口IOrderFeignService的注解@FeignClient中指定服務(wù)解耦的類OrderFeignServiceFallBack 。
@Component // 讓 spring 可以識(shí)別,不加也行,但是在注入的時(shí)候 IDEA 會(huì)報(bào)錯(cuò),不會(huì)影響運(yùn)行,但有條紅線讓自己不舒服
@FeignClient(value = "PRODUCT-SERVICE",fallback = OrderFeignServiceFallBack.class)
public interface IOrderFeignService {
@RequestMapping(value = "/product/buy/{id}")
Product findOrderById(@PathVariable Long id);
@RequestMapping(value = "/product/delete/{id}")
Product deleteOrderById(@PathVariable Long id);
}4、定義 訂單服務(wù) 和 商品服務(wù)主啟動(dòng)類
由于訂單服務(wù)中引入的spring-cloud-starter-openfeign依賴中已經(jīng)集成了feign-hystrix,有了對(duì) Hystrix 的支持,所以不需要額外引入依賴項(xiàng)。如果需要開(kāi)啟 訂單服務(wù)端的hystrix服務(wù),只需要在訂單服務(wù)的配置文件配置feign-hystrix 進(jìn)行激活Hystrix,無(wú)需在主啟動(dòng)類中添加注解 @EnableHystrix 或 @EnableHystrix 來(lái)開(kāi)啟Hystrix服務(wù)。訂單服務(wù) 和 商品服務(wù)主啟動(dòng)類如下:
訂單服務(wù)主啟動(dòng)類 OrderServerApplication
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableEurekaClient// 啟動(dòng) eureka 客戶端
@EnableFeignClients // 啟動(dòng) feign
public class OrderServerApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServerApplication.class, args);
}
}商品服務(wù)主啟動(dòng)類 ProductServerApplication
@SpringBootApplication
@EnableEurekaClient// 啟動(dòng) eureka 客戶端
public class ProductServerApplication {
public static void main(String[] args) {
SpringApplication.run(ProductServerApplication.class, args);
}
}4、開(kāi)啟openfeign在調(diào)用服務(wù)過(guò)程中開(kāi)啟hystrix支持
由于前面引入的spring-cloud-starter-openfeign依賴中已經(jīng)集成了feign-hystrix,有了對(duì) Hystrix 的支持,所以不需要額外引入依賴項(xiàng)。只需要在訂單服務(wù)的 application.yml 配置文件中開(kāi)啟openfeign在調(diào)用服務(wù)過(guò)程中開(kāi)啟hystrix支持。
server:
port: 9000
spring:
application:
name: order-service # 為當(dāng)前訂單服務(wù)命名為 order-service# 配置eureka客戶端信息
eureka:
client:
service-url:
# 配置eureka客戶端服務(wù)order-service的注冊(cè)地址,與 eureka-server 中暴露地址要保持一致
defaultZone: http://localhost:8000/eureka/
instance:
prefer-ip-address: true # 是否使用 IP 地址注冊(cè),默認(rèn) false
# instance-id: order-service # 實(shí)例 id,服務(wù)的唯一標(biāo)識(shí),會(huì)自動(dòng)的找到order-service的ip和端口
instance-id: ${spring.cloud.client.ip-address}:${server.port} # 如果想在控制頁(yè)面看到服務(wù)地址與端口,可以將 instance-id 這樣配置feign:
hystrix:
enabled: true
5、修改訂單服務(wù)配置文件
由于訂單服務(wù)中引入的spring-cloud-starter-openfeign依賴中已經(jīng)集成了feign-hystrix,有了對(duì) Hystrix 的支持,所以不需要額外引入依賴項(xiàng)。如果需要開(kāi)啟 訂單服務(wù)端的hystrix服務(wù),只需要在訂單服務(wù)的配置文件配置feign-hystrix 進(jìn)行激活Hystrix,修改application.yml如下:
server:
port: 9000
spring:
application:
name: order-service # 為當(dāng)前訂單服務(wù)命名為 order-service# 配置eureka客戶端信息
eureka:
client:
service-url:
# 配置eureka客戶端服務(wù)order-service的注冊(cè)地址,與 eureka-server 中暴露地址要保持一致
defaultZone: http://localhost:8000/eureka/
instance:
prefer-ip-address: true # 是否使用 IP 地址注冊(cè),默認(rèn) false
# instance-id: order-service # 實(shí)例 id,服務(wù)的唯一標(biāo)識(shí),會(huì)自動(dòng)的找到order-service的ip和端口
instance-id: ${spring.cloud.client.ip-address}:${server.port} # 如果想在控制頁(yè)面看到服務(wù)地址與端口,可以將 instance-id 這樣配置feign:
hystrix:
enabled: true
6、進(jìn)行測(cè)試
分別訪問(wèn) http://localhost:9000/order/buy/1 和 http://localhost:9000/order/delete/1 查看瀏覽器結(jié)果如下:


到此這篇關(guān)于SpringCloud hystrix斷路器與全局解耦全面介紹的文章就介紹到這了,更多相關(guān)SpringCloud hystrix斷路器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用springboot單例模式與線程安全問(wèn)題踩的坑
這篇文章主要介紹了使用springboot單例模式與線程安全問(wèn)題踩的坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08
Java設(shè)計(jì)模式之適配器模式簡(jiǎn)介
這篇文章主要介紹了Java設(shè)計(jì)模式之適配器模式,需要的朋友可以參考下2014-07-07
springboot?使用clickhouse實(shí)時(shí)大數(shù)據(jù)分析引擎(使用方式)
這篇文章主要介紹了springboot?使用clickhouse實(shí)時(shí)大數(shù)據(jù)分析引擎的方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2022-02-02
對(duì)arraylist中元素進(jìn)行排序?qū)嵗a
這篇文章主要介紹了對(duì)arraylist中元素進(jìn)行排序?qū)嵗a,還是比較不錯(cuò)的,這里分享給大家,供需要的朋友參考。2017-11-11
簡(jiǎn)單了解spring cloud 網(wǎng)關(guān)服務(wù)
這篇文章主要介紹了簡(jiǎn)單了解spring cloud 網(wǎng)關(guān)服務(wù),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10

