1.GitHub地址
https://github.com/Netflix/Hystrix
https://github.com/Netflix/Hystrix/wiki
官方文檔
2.為什么要用Hystrix?
在一個分布式系統里,一個服務依賴多個服務,可能存在某個服務調用失敗,
比如超時,異常等,如何能保證在一個依賴出問題的情況下,不會導致整體服務失敗,
通過Hystrix就可以解決
3.功能
提供熔斷,隔離,Fallback,cache,監控等功能
4.熔斷后怎么處理?
出現錯誤后,可以Fallback錯誤的處理信息
5.代碼實現
1)添加依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.28</version> </dependency>
2)啟動類添加@EnableCircuitBreaker
import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; import org.springframework.cloud.openfeign.EnableFeignClients; @SpringBootApplication @MapperScan("cn.ytheng.order_service") @EnableFeignClients @EnableCircuitBreaker public class OrderServiceApplication { public static void main(String[] args) { SpringApplication.run(OrderServiceApplication.class, args); } }
3)添加ProductOrder訂單實體類
import lombok.Data; import java.io.Serializable; import java.util.Date; /** * 商品訂單實體類 */ @Data public class ProductOrder implements Serializable { private String id; private int userId; private String productName; private String tradeNo; private Date createTime; public ProductOrder() { } }
4)添加feign,為了測試Product服務掛掉時,降級處理的情況
import cn.theng.order_service.fallback.ProductFallback; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; /** * * 商品服務客戶端 * product-service: 調用服務名稱,即spring.application.name * ProductFallback:需要繼承當前FeignClient的類 * */ @FeignClient(name = "product-service", fallback = ProductFallback.class) public interface ProductClient { @GetMapping("/api/v1/product/find") String getById(@RequestParam("id") int id); }
5)添加針對product-service服務的降級處理類
import cn.theng.order_service.service.ProductClient; import org.springframework.stereotype.Component; /** * * 針對商品服務,做降級處理 * */ @Component public class ProductFallback implements ProductClient { //當調用product-service的getById接口出現錯誤時,就會執行該方法 @Override public String getById(int id) { System.out.println("feign 調用product-service服務異常..."); return "null"; } }
6)添加ProductOrderService接口
import cn.theng.order_service.domain.ProductOrder; /** * 訂單業務類 */ public interface ProductOrderService { /** * 下單接口 */ ProductOrder save(int userId, int productId); }
7)添加ProductOrderServiceImpl接口實現類import cn.theng.order_service.domain.ProductOrder;import cn.theng.order_service.mapper.ProductOrderMapper;
import cn.theng.order_service.service.ProductClient; import cn.theng.order_service.service.ProductOrderService; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.Date; import java.util.UUID; @Service public class ProductOrderServiceImpl implements ProductOrderService { @Autowired private ProductClient productClient; @Override public ProductOrder save(int userId, int productId) { String data = productClient.getById(productId);
// 下面代碼會報錯,觸發熔斷
JSONObject product = JSON.parseObject(data); ProductOrder order = new ProductOrder(); order.setTradeNo(UUID.randomUUID().toString()); order.setProductName(product.getString("productName")); order.setCreateTime(new Date()); return order; } }
8)添加controller
package cn.theng.order_service.controller; import cn.theng.order_service.domain.ProductOrder; import cn.theng.order_service.service.ProductClient; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; import java.util.Map; @RestController @RequestMapping("/api/v1/order") public class ProductOrderController { @Autowired private ProductOrderService productOrderService; @PostMapping("/test2") @HystrixCommand(fallbackMethod = "getProductFail") public Object test2(@RequestParam("product_id") int productId) { //如果test2內有報錯,則會執行getProductFail方法 ProductOrder order = productOrderService.save(1, productId); return "success"; } //方法簽名一定要與上面方法保持一致 public Object getProductFail(int productId) { Map<String, Object> map = new HashMap<>(); map.put("code", -1); map.put("msg", "目前排隊人數過多,請稍后再試..."); return map; } }
9)修改application.yml配置
server: port: 8781 eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/ spring: application: name: order-service #設置調用服務超時時間 #product-service為服務名稱,也可以設置為默認值default #默認配置下,feign的hystrix配置是關閉的 feign: hystrix: enabled: true client: config: product-service: connectTimeout: 5000 readTimeout: 11000
10)訪問地址

