实现微服务的熔断机制
我们在上节已经基本了解了如何将Hystrix 集成进应用。我们也通过一个简单的例子,知道了如何通过Hystrix技术实现自己的断路器。总的来说,使用Hystrix是非常简单的。
本节我们将基于Hystrix技术来改造天气预报系统,使我们的服务在调用核心数据服务时,能够启用熔断机制,从而保护应用。
我们将要修改之前的天气预报微服务msa-weather- report- eureka feign-gateway,由于该服务分别依赖了天气数据API微服务msa-weather-data -eureka及城市数据API微服务msa-weather-city-eure-ka,所以,在调用这两个服务过程中,假如调用失败,就启用断路器。
新的天气预报微服务命名为 msa-weather-eport-eureka-feign-gateway-hytrix。
更改配置
要使用Hystrix,最简单的方式莫过于添加Hystrix依赖。
代码语言:javascript复制dependencies {
//添加Spring Cloud Starter Netflix Hystrix依赖
compile ('org. springframework. cloud: spring-cloud- starter-netflix-
hystrix')
}
使用Hystrix
要启用Hystrix,最简单的方式就是在应用的根目录的Application类上添加 org.springframe-work.cloud.client.circuitbreaker. EnableCircuitBreaker注解。
代码语言:javascript复制package com. waylau. spring. cloud. weather;
import org. springframework.boot . SpringAppl ication;
import org. springf r amework . boot . autoconfigure . Spr ingBootApplication;
import org. spr ing f ramework. cloud. client. circuitbreaker . Enable
CircuitBreaker;
import org. springframework.cloud.client. discovery . EnableDiscovery
Client;
import org. springframework.cloud. netflix. feign . EnableFeignClients;
/**
主应用程序.
@since 1.0.0 2017年11月12日
* @author <a href="https://waylau. com">Way Lau</a>
*/
@Spr ingBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@EnableCircuitBreaker
public class Application {
public static void main(String[] args) {
SpringAppl ication. run (Application.class, args) ;
}
}
实现断路器
Feign内建支持了对于Hystrix回调函数的支持。我们只需要在@FeignClient注解的fllback 中声明要回调的类。
代码语言:javascript复制package com.waylau. spring.cloud. weather .service;
import java.util.List;
import org . springf ramework. cloud. netflix. feign. FeignClient;
import org. springframework. web .bind. annotation. GetMapping;
import org. springf ramework. web .bind. annotation. PathVariable;
import com.waylau. spring.cloud.weather.vo.city;
import com. waylau. spring.cloud.weather .vo.WeatherResponse;
/**
★访问数据的客户端.
* @since 1.0.0 2017年11月6日
Cauthor <a href="https:/ /waylau. com">Way Lau</a>
*/
@FeignClient (name= "msa-weather-eureka-client-zuul", fallback=DataClient
Fallback.class)
public interface DataClient {
/**
获取城市列表
* @return
athrows Exception
*/
@GetMapping("/city/cities")
List<City> listCity() throws Exception;
*根据城市ID查询天气数据
@param cityId .
★@return
@GetMapping ("/data/weather/cityId/ {cityId}")
WeatherResponse getDataByCityId (@PathVariable("cityId") String
cityId) ;
}
在上述代码中,回调指向了DataClientFallback 类,该类是一个 Spring bean,实现了DataClient接口的方法。DataClientFallback 中的方法,即为断路器需要返回的执行方法。
代码语言:javascript复制package com. waylau. spring. cloud . weather . service;
import java.util.ArrayList;
import java.util.List;
import org.springframework. stereotype. Component;
import com. waylau.spring.cloud. weather. vo.City;
import com. waylau. spring.cloud . weather . vo. WeatherResponse;
/**
DataClient Fallback.
@since 1.0.0 2017年11月13日
@author <a href="https://waylau. com">Way Lau</a>
@Component
public class DataClientFallback implements DataClient {
@Override
public List<City> listCity() throws Exception {
List<city> cityList = null;
cityList = new ArrayList<>() ;
City city = new City() ;
city .setCityId ("101280601");
city. setCityName ("深圳") ;
cityList.add(city) ;
city = new City();
city. setCityId("101280301") ;
city. setCityName ("惠州");
cityList.add(city) ;
return cityList;
}
@Override
public WeatherResponse getDataByCityId(String cityId) {
return new WeatherResponse () ;
}
}
其中:
●listCity方法:在调用城市数据API微服务时需要实现断路器。在城市数据API微服务失败时,,我们就响应默认的城市列表给客户端;
●getDataByCityld方法:在调用天气数据API微服务时需要实现断路器。在调用天气数据API微服务失败时,我们就响应默认的null给客户端。
修改report.html页面
代码语言:javascript复制...
<div
th:if="$ {reportModel. report} != nul1">
<div class="row">
<h1 class="text-success" th:text="$ {reportModel. report.city}"></
h1>
</div>
<div class=" row">
<p>
空气质量指数: <span th:text="$ {reportModel. report.aqi}"></
span>
</p>
</div>
<div class="row">
<p>
当前温度: <span th: text="$ {reportModel . report . wendu}"></span>
</p>
</div>
<div class="row">
<p>
温馨提示: <span th: text="$ { reportModel . report.ganmao}">
</span>
</p>
</div>
<div class="row">
<div class="card border-info" th:each=" forecast : $ { reportModel .
report. forecast}">
<div class="card-body text- info">
p class="card-text" th:text="${ forecast.date}">周五</p>
p class="card-text" th: text="$ { forecast. type}">晴转多云
</p>
<p class="card-text" th:text="$ {forecast.high}">高温
28C</p>
P class="card-text" th:text="${ forecast.low}">低温
21C</p>
Kp class="card-text" th:text="$ {forecast. fengxiang}">无
持续风向微风</p>
</div>
</div>
</div>
</div>
<div th:if="${ reportModel . report} == null">
<div class="row">
天气数据API服务暂时不可用!
</p>
</div>
</div>
...
在该页面中,我们会用Thymeleaf条件运算符和比较表达式来对模型中report (天气数据)进行判断,如果不为空,就将天气信息显示出来;否则,就显示“天气数据API服务暂时不可用!”字样。
修改应用配置
应用配置修改如下。
代码语言:javascript复制#热部署静态文件
spring. thymeleaf . cache=false
spring. application. name: msa-weather- report-eureka-feign-gateway-
hystrix
eureka. cl ient. serviceUrl . defaultZone: http:/ /localhost:8761/eureka/
feign.client. config. fe ignName . connectTimeout: 5000
feign.client . config. feignName . readT imeout: 5000
feign.hystrix .enabled=true
其中: feign.hystrix.enabled 用于启用在Feign客户端中使用Hystrix。那么所有的Feign客户端异常,都会导致断路器的启用。
运行、测试
先启动Redis服务器。
再依次启动以下服务。
代码语言:javascript复制java -jar micro-weather-eureka-server-1.0.0.jar --server .port=8761
java -jar msa-weather-collection-eureka-feign-1.0.0.jar --server.
port=8081
java -jar msa-weather -collection-eureka-feign-1.0.0.jar --server.
port=8082
java -jar msa-weather -data-eureka-1.0.0.jar --server .port=8083
java -jar msa-weather-data-eureka-1.0.0.jar --server . port-8084
java -jar msa-weather-city-eureka-1.0.0.jar --server .port=8085
java -jar msa-weather-city-eureka-1.0.0.jar --server .port=8086
java -jar msa-weather-report-eureka- feign-gateway-hystrix-1.0.0.jar
--server .port=8087
java -jar msa-weather-report-eureka- feign-gateway-hystrix-1.0.0.jar
-- server . port=8088
java -jar msa-weather-eureka-client-zuul-1.0.0.jar --server .port=8089
我们关闭天气数据API微服务,以模拟天气数据API微服务故障的场景。在界面上,我们能看到如图15-4所示的默认信息。
我们关闭城市数据API微服务,以模拟城市数据API微服务故障的场景。在界面上,我们能看到如图15-5所示的城市列表。
本篇文章内容给大家讲解的是实现微服务的熔断机制
- 下篇文章给大家讲解的是分布式消息总线;
- 觉得文章不错的朋友可以转发此文关注小编;
- 感谢大家的支持!
本文就是愿天堂没有BUG给大家分享的内容,大家有收获的话可以分享下,想学习更多的话可以到微信公众号里找我,我等你哦。