Spring Cloud学习笔记24——天气预报系统微服务实现熔断机制

创建项目

以之前的msa-weather-report-eureka-feign-gateway为蓝本,创建msa-weather-report-eureka-feign-gateway-hystrix项目
在这里插入图片描述
修改build.gradle配置,添加Hystrix依赖:

//依赖关系
dependencies {

    //该依赖用于编译阶段
	compile('org.springframework.boot:spring-boot-starter-web')

    //添加Spring Boot Thymeleaf Starter的依赖
    compile('org.springframework.boot:spring-boot-starter-thymeleaf')

    //Eureka Client
    compile('org.springframework.cloud:spring-cloud-starter-netflix-eureka-client')

    //Feign
    compile('org.springframework.cloud:spring-cloud-starter-openfeign:2.0.0.M3')

    //Hystrix
    compile('org.springframework.cloud:spring-cloud-starter-netflix-hystrix')


    //该依赖用于测试阶段
    testCompile('org.springframework.boot:spring-boot-starter-test')
}

修改com.study.spring.cloud.weather包下的Application类,加入@EnableCircuitBreaker注解:

package com.study.spring.cloud.weather;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;

/*
 * @SpringBootApplication注解声明Spring Boot应用
 * 作用等同于@Configuration, @EnableAutoConfiguration, @ComponentScan,
 * 简化Spring配置
*/
@SpringBootApplication
//启用可发现的客户端
@EnableDiscoveryClient
//启用Feign
@EnableFeignClients
//启用Hystrix
@EnableCircuitBreaker
//Application类一定要处于整个工程的根目录下,这样它才能根据配置去扫描子节点下的Spring的Bean
public class Application {

	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
	}
}

com.study.spring.cloud.weather.service包下新建类DataClientFallback

package com.study.spring.cloud.weather.service;

import com.study.spring.cloud.weather.vo.City;
import com.study.spring.cloud.weather.vo.WeatherResponse;
import org.springframework.stereotype.Component;

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

//声明为Bean
@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("101020100");
		city.setCityName("上海");
		cityList.add(city);

		city=new City();
		city.setCityId("101010100");
		city.setCityName("北京");
		cityList.add(city);

		return cityList;
	}

	@Override
	public WeatherResponse getDataByCityId(String cityId) {
		return null;
	}
}

修改com.study.spring.cloud.weather.service包下的WeatherReportServiceImpl类:

package com.study.spring.cloud.weather.service;

import com.study.spring.cloud.weather.vo.Weather;
import com.study.spring.cloud.weather.vo.WeatherResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class WeatherReportServiceImpl implements WeatherReportService {

	@Autowired
	private DataClient dataClient;

	@Override
	public Weather getDataByCityId(String cityId) {

		//由天气数据API微服务来提供数据
		WeatherResponse resp=dataClient.getDataByCityId(cityId);
		Weather data=null;
		if(resp!=null){
			data=resp.getData();
		}
		return data;
	}
}

修改com.study.spring.cloud.weather.service包下的DataClient接口:

package com.study.spring.cloud.weather.service;

import com.study.spring.cloud.weather.vo.City;
import com.study.spring.cloud.weather.vo.WeatherResponse;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

import java.util.List;

@FeignClient(name = "msa-weather-eureka-client-zuul",fallback = DataClientFallback.class)
public interface DataClient {

	//获取城市列表
	@GetMapping("/city/cities")
	List<City> listCity() throws Exception;

	//根据城市id查询天气数据
	@GetMapping("/data/weather/cityId/{cityId}")
	WeatherResponse getDataByCityId(@PathVariable("cityId") String cityId);
}

修改前端页面report.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">

    <title>天气预报</title>
</head>
<body>
    <div class="container">
        <div class="row">
            <h3 th:text="${reportModel.title}">天气</h3>
            <select class="custom-select" id="selectCityId">
                <option th:each="city : ${reportModel.cityList}"
                        th:value="${city.cityId}" th:text="${city.cityName}"
                        th:selected="${city.cityId eq reportModel.cityId}"></option>
            </select>
        </div>

        <div th:if="${reportModel.report}!=null">
            <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}">最高温度</p>
                        <p class="card-text" th:text="${forecast.low}">最低温度</p>
                        <p class="card-text" th:text="${forecast.fengxiang}">风向</p>
                    </div>
                </div>
            </div>
        </div>

        <div th:if="${reportModel.report}==null">
            <div class="row">
                <p>
                    天气数据API微服务暂不可用!
                </p>
            </div>
        </div>

    </div>

    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>

    <!-- Optional JavaScript -->
    <script type="text/javascript" th:src="@{/js/weather/report.js}"></script>
</body>
</html>

修改application.properties配置文件:

#热部署静态文件
spring.thymeleaf.cache=false

#应用名称
spring.application.name=msa-weather-report-eureka-feign-gateway-hystrix

#注册服务器的URL
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/

#请求服务时的超时时间
feign.client.config.feignName.connect-timeout=5000

#读数据时的超时时间
feign.client.config.feignName.read-timeout=5000

#在feign客户端中启用断路器功能
feign.hystrix.enabled=true

运行

  1. 启动Redis
  2. IDE上运行micro-weather-eureka-server
  3. 通过命令行指定80818082端口运行msa-weather-collection-eureka-feign
  4. 通过命令行指定80838084端口运行msa-weather-data-eureka
  5. 通过命令行指定80858086端口运行msa-weather-city-eureka
  6. 通过命令行指定80878088端口运行msa-weather-report-eureka-feign-gateway-hystrix
  7. 通过命令行指定8089端口运行msa-weather-eureka-client-zuul

访问http://localhost:8761页面,可以看到Eureka的管理页面:
在这里插入图片描述
访问http://localhost:8088/report/cityId/101020100页面:
在这里插入图片描述
在页面中切换选中城市:
在这里插入图片描述

  1. 停掉80858086两个端口的msa-weather-city-eureka微服务

刷新http://localhost:8088/report/cityId/101020100页面:
在这里插入图片描述

  1. 停掉80838084两个端口的msa-weather-data-eureka微服务

刷新http://localhost:8088/report/cityId/101020100页面:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_43415405/article/details/84072269
今日推荐