springCloud笔记

springcloud的配置及使用

项目:

E:\weatherProject\micro-weather-basic-client 和

E:\weatherProject\micro-weather-eureka-client 一个项目 客户端

实现一个服务注册和发现

micro-weather-eureka-server 和 micro-weather-basic-server 是同一个项目 服务端

一:eureka

服务注册和发现

服务端

实现服务的注册与发现:helloworld的服务端实现

依赖项:

<dependencies>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        <version>2.1.0.RELEASE</version>
    </dependency>

</dependencies>
<!-- 添加cloud 依赖start -->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Greenwich</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
<!-- 添加cloud 依赖end -->

在application类中加入注解:

@EnableEurekaServer

@SpringBootApplication
@EnableEurekaServer
public class MicroWeatherBasic2Application {

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

}

配置文件:

server.port:8761
eureka.instance.hostname:localhost

#是否注册eureka
eureka.client.registerWithEureka:false

#是否启用获取服务注册信息
eureka.client.fetchRegistry:false

#注册和查询都需要依赖该地址,多个以逗号分隔。
eureka.client.serverUrl.defaultZone:http://${eureka.instance.hostname}:${server.port}/eureka/
#留存的服务实例低于多少比例进入保护模式,保护模式将不再注销已经停止心跳的服务来兼容片区故障。
eureka.server.renewal-percent-threshold=0.5
#是否开启保护模式
eureka.server.enable-self-preservation=false

客户端:

依赖项

	<dependency>
    	<groupId>org.springframework.cloud</groupId>
    	<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    	<version>2.1.0.RELEASE</version>
	</dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

配置文件

spring.application.name:micro-weather-eureka-client
eureka.client.service-url.defaultZone:http://localhost:8761/eureka/

主类:

@EnableDiscoveryClient

package mystudy.microweatherbasic2;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class MicroWeatherBasic2Application {

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

}

在命令行中运行各微服务jar包(目的是让个服务占用不同的端口)

2.切换到jar包所在目录执行(获得jar包方式见笔记maven):

java -jar xxx.jar --server.port=8081

二:Feign

项目:

micro-weather-eureka-client-feign(此项目演示如何调用其他已有的服务)

msa-weather-city-eureka

micro-weather-eureka-server

消费者模式之一的模式框架,集成了HttpClient和Ribbon

1.依赖

开发环境:

Spring Cloud Starter Netflix Eureka Client Finchley.M2

Spring Cloud Starter OpenFeign Finchley.M2

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
    <version>2.1.0.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    <version>2.1.0.RELEASE</version>
</dependency>

<!--Feign相关-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
    <version>2.1.0.RELEASE</version>
</dependency>

2.使用

(1)配置主class文件,加入 @EnableFeignClients

package mystudy.microweatherbasic2;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableDiscoveryClient//eureka注册客户端
@EnableFeignClients//Feign,调用服务端
public class MicroWeatherBasic2Application {

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

}

(2)新建接口类,调用服务

CityClient.java

package mystudy.microweatherbasic2.weatherDataService;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

@FeignClient("mas-weather-city-eureka")//指定要调用的服务的名称
public interface CityClient {
    @GetMapping("/cities")
    String listCity();
}

(3)创建controller类去使用上面的接口

package mystudy.microweatherbasic2.controller;

import mystudy.microweatherbasic2.weatherDataService.CityClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

//Controller类
@RestController
public class CityController {
    
    @Autowired
    private CityClient cityClient;
    @GetMapping("/cities")
    public String listCity(){
        //通过Feign客户端来查找城市相关信息
        String body = cityClient.listCity();
        return body;
    }
}

配置文件application.properties

spring.application.name:micro-weather-eureka-client-feign
eureka.client.service-url.defaultZone:http://localhost:8761/eureka/
feign.client.config.feignName.connect-timeout=5000
feign.client.config.geignName.read-timeout=5000

完成后将三个项目全部开启,注意端口需要设置不同,然后在浏览器中访问:

http://localhost:8080/cities

三:Zuul

功能

认证、压力测试、金丝雀测试、动态路由、负载削减、安全、静态响应处理、主动/主动交换管理

开发环境:

Spring Cloud Starter Netflix Zuul Finchley.M2

项目:micro-weather-eureka-zuul

1.依赖项:版本要对应


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <version>2.1.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
            <version>2.1.0.RELEASE</version>
        </dependency>

2.主类添加注释

@EnableZuulProxy

package mystudy.microweatherbasic2;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

@SpringBootApplication
@EnableDiscoveryClient
@EnableZuulProxy
public class MicroWeatherBasic2Application {

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

}

3.配置文件

spring.application.name:micro-weather-eureka-client-zuul
eureka.client.service-url.defaultZone:http://localhost:8761/eureka/
zuul.routes.hi.path:/hi/**
zuul.routes.hi.serviceId:msa-weather-city-eureka
#'hi'是自定义的路径名字

四:Spring Cloud config

集中化配置文件,从外部配置微服务的配置文件

Config Server (默认使用git)和Config Client

项目:

micro-weather-config-client

micro-weather-config-server

1.开发环境

Spring Cloud Config Server Finchley.M2

org-springframework.cloud:spring-cloud-config-server

org-springframework.cloud:spring-cloud-config-client

2.使用Config Server

(1)主类

@EnableConfigServer

package mystudy.microweatherbasic2;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.config.server.EnableConfigServer;

@SpringBootApplication
@EnableDiscoveryClient
@EnableConfigServer
public class MicroWeatherBasic2Application {

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

}

(2)配置文件application.properties

spring.application.name:micro-weather-config-server
server.port=8888
eureka.client.service-url.defaultZone:http://localhost:8761/eureka/
spring.cloud.config.server.git.uri=https://github.com/handingzhang/spring-cloud-micro-weather-development
spring.cloud.config.server.git.search-paths=config-repo

(3)依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    <version>2.1.0.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
    <version>2.1.0.RELEASE</version>
</dependency>

(4).测试

http://localhost:8888/auther/dev

3.使用Config Client

(1)主类

package mystudy.microweatherbasic2;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class MicroWeatherBasic2Application {

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

}

(2)配置类

spring.application.name:micro-weather-config-client
eureka.client.service-url.defaultZone:http://localhost:8761/eureka/
#下面是配置代码运行的环境,开发环境
spring.cloud.config.profile=dev
spring.cloud.config.uri=http://localhost:8888/

(3)依赖项

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    <version>2.1.0.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-client</artifactId>
    <version>2.1.0.RELEASE</version>
</dependency>

4.测试

项目:micro-weather-config-client

(1)github上配置文件

spring-cloud-micro-weather-development/config-repo/micro-weather-config-client-dev.properties

auther=zhanghanding

(2)测试依赖项

<dependency>
    <groupId>org.junit</groupId>
    <artifactId>junit-gradle</artifactId>
    <version>5.0.0-ALPHA</version>
</dependency>

(3)测试文件

package mystudy.microweatherbasic2;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class MicroWeatherBasic2ApplicationTests {

    @Value("${auther}")
    private String auther;
    @Test
    public void contextLoads() {
        assert auther.equals("zhanghanding");
    }

}

(4)运行

micro-weather-eureka-server

micro-weather-config-server

micro-weather-config-client

运行三个项目,client项目不报错则,配置中心的配置文件正确

五:熔断器(Hystrix)

断路器、断路器模式

概述

Microsoft Azure

hystrix

功能:

异常处理、日志功能、测试失败的操作、手动复位、并发、加速断路、重试失败请求

熔断与降级的区别:

相同的地方:

目的一致(都是保护系统)、表现类似(返回固定的信息)、粒度一致

区别:

触发条件不同:熔断是某个服务无法响应之后产生的,降级是整个系统的性能无法满足负载时产生的。

管理目标的层次不同:熔断是框架级的,每个微服务都需要熔断机制,无层次之分;降级是有层次的,一般从外围服务开始。

集成hystrix

项目

micro-weather-eureka-client-feign-hystrix

hystrix官网:

https://github.com/Netflix/Hystrix/wiki

hystrix配置:

https://github.com/Netflix/Hystrix/wiki/Configuration

(1)开发环境

Spring Cloud Starter Netflix Hystrix Finchley.M2

依赖:

org.springframework.cloud:spring-cloud-starter-netflix-hystrix

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    <version>2.1.0.RELEASE</version>
</dependency>

(2)使用

主类:

@EnableCircuitBreaker

package mystudy.microweatherbasic2;

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.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableDiscoveryClient//eureka注册客户端
@EnableFeignClients//Feign,调用服务端
@EnableCircuitBreaker//hystrix 断路器
public class MicroWeatherBasic2Application {

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

}
controller类:
重点
@GetMapping("/cities")
@HystrixCommand(fallbackMethod = "defaultCities")
public List<City> listCity(){
    //通过Feign客户端来查找城市相关信息
    List<City> cityList = cityClient.listCity();
    return cityList;
}
public String defaultCities(){
    //..
}
package mystudy.microweatherbasic2.controller;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import mystudy.microweatherbasic2.City;
import mystudy.microweatherbasic2.weatherDataService.CityClient;
import mystudy.microweatherbasic2.weatherDataService.GetWeatherDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

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

//Controller类
@RestController
public class CityController {

    @Autowired
    private CityClient cityClient;
    @Autowired
    private GetWeatherDataService getWeatherDataService;
    @GetMapping("/cities")
    @HystrixCommand(fallbackMethod = "defaultCities")
    public List<City> listCity(){
        //通过Feign客户端来查找城市相关信息
        List<City> cityList = cityClient.listCity();
        return cityList;
    }
    public List<City> defaultCities(){
        City city = new City();
        city.setCityId("0000000");
        city.setCityName("null");
        city.setCityPingyin("null");
        city.setProvinceCenter("null");
        List<City> cityList = new ArrayList<City>();
        cityList.add(0,city);
        return cityList;
    }

}
配置

基本和前面的项目一样

spring.application.name:micro-weather-eureka-client-feign-hystrix
eureka.client.service-url.defaultZone:http://localhost:8761/eureka/
feign.client.config.feignName.connect-timeout=5000
feign.client.config.geignName.read-timeout=5000

(3)测试

运行:

micro-weather-eureka-server

msa-weather-city-eureka

micro-weather-eureka-client-feign-hystrix

正常访问http://localhost:8080/cities后,关掉msa-weather-city-eureka服务

再次访问http://localhost:8080/cities,显示默认的city信息。

五(2)改造天气项目,加入hystrix

项目:msa-weather-report-eureka-feign-hystrix

微服务中使用@FeignClient处可以多加一个声明fallback = CityClientFallback.class, 而简化上面那样的设置fallback方法

依赖:与上面一样,在原来的依赖里多加一项

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    <version>2.1.0.RELEASE</version>
</dependency>

主类:

@EnableCircuitBreaker

package mystudy.microweatherbasic;

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.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@EnableCircuitBreaker
public class MicroWeatherBasicApplication {

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

}

配置文件:

增加
#此配置项使调用feign的类能调用fallback类,即让feign能使用断路器功能
feign.hystrix.enabled=true
spring.application.name:msa-weather-report-eureka-feign-hystrix
eureka.client.service-url.defaultZone:http://localhost:8761/eureka/
feign.client.config.feignName.connect-timeout=5000
feign.client.config.geignName.read-timeout=5000
#此配置项使调用feign的类能调用fallback类,即使feign能使用断路器功能
feign.hystrix.enabled=true

CityClient和WeatherDataClient接口

加入下面的注释,使之能被自动注入

@Component

CityClient

增加
@Component
@FeignClient(name="msa-weather-city-eureka",fallback = CityClientFallback.class)
package mystudy.microweatherbasic.weatherDataService;

import mystudy.microweatherbasic.city.City;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.List;
@Component
@FeignClient(name="msa-weather-city-eureka",fallback = CityClientFallback.class)
public interface CityClient {
    @GetMapping("/cities")
    List<City> getCityList() throws Exception;
}

WeatherDataClient

增加点
@Component
@FeignClient(name="msa-weather-data-eureka",fallback = WeatherDataClientFallback.class)
package mystudy.microweatherbasic.weatherDataService;

import mystudy.microweatherbasic.weather.Weather;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@Component
@FeignClient(name="msa-weather-data-eureka",fallback = WeatherDataClientFallback.class)
public interface WeatherDataClient {
    @GetMapping("/weather/cityID/{cityID}")
    Weather getWeatherById(@PathVariable("cityID") String cityId);
}

对应生成两个fallback类CityClientFallback和WeatherDataClientFallback

CityClientFallback.java
package mystudy.microweatherbasic.weatherDataService;
//CityClient接口的fallback类

import mystudy.microweatherbasic.city.City;
import org.springframework.stereotype.Component;

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

@Component//是spring的bean,所以要加此注释
public class CityClientFallback implements CityClient {

    @Override
    public List<City> getCityList() throws Exception {

        City city = new City();
        city.setCityId("0000000");
        city.setCityName("null");
        city.setCityPingyin("null");
        city.setProvinceCenter("null");
        List<City> cityList = new ArrayList<City>();
        cityList.add(0,city);
        return cityList;
    }
}
WeatherDataClientFallback
package mystudy.microweatherbasic.weatherDataService;

import mystudy.microweatherbasic.weather.Data;
import mystudy.microweatherbasic.weather.Forecast;
import mystudy.microweatherbasic.weather.Weather;
import mystudy.microweatherbasic.weather.Yesterday;
import org.springframework.stereotype.Component;

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

@Component
public class WeatherDataClientFallback implements WeatherDataClient{
    @Override
    public Weather getWeatherById(String cityId) {
        Weather weather = new Weather();
        Data data = new Data();
        Forecast forecast = new Forecast();
        forecast.setDate("null");
        forecast.setFengli("null");
        forecast.setFengxiang("null");
        forecast.setHigh("null");
        forecast.setLow("null");
        forecast.setType("null");
        Yesterday yesterday = new Yesterday();
        yesterday.setDate("null");
        yesterday.setFl("null");
        yesterday.setFx("null");
        yesterday.setHigh("null");
        yesterday.setLow("null");
        yesterday.setType("null");
        List<Forecast> forecastList =new ArrayList<>();
        forecastList.add(0,forecast);
        data.setCity("null");
        data.setForecast(forecastList);
        data.setGanmao("null");
        data.setWendu("null");
        data.setYesterday(yesterday);
        weather.setData(data);
        return weather;
    }
}

hystrix补充:

依赖改成:

<!--hystrix相关-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-hystrix</artifactId>
    <version>1.4.6.RELEASE</version>
</dependency>

配置:

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=1
hystrix.threadpool.default.coreSize=1
hystrix.threadpool.default.maxQueueSize=1
hystrix.threadpool.default.maximumSize=1

hystrix.command.default.circuitBreaker.errorThresholdPercentage=1
hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds=100000

添加注解:

package com.mooc.house.api.dao;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Repository;

import com.mooc.house.api.common.RestResponse;
import com.mooc.house.api.config.GenericRest;
import com.mooc.house.api.model.Agency;
import com.mooc.house.api.model.ListResponse;
import com.mooc.house.api.model.User;
import com.mooc.house.api.utils.Rests;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;

@Repository
//定制化的配置,让spring识别出这个类是一个Hystrix 的command类
@DefaultProperties(groupKey="userDao",
commandProperties={@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="2000")},
threadPoolProperties={@HystrixProperty(name="coreSize",value="10")
,@HystrixProperty(name="maxQueueSize",value="1000")},
threadPoolKey="userDao"
)
public class UserDao {

  @Autowired
  private GenericRest rest;
  
  @Value("${user.service.name}")
  private String userServiceName;
    
  ...
  //回调方法
  public User getUserByTokenFb(String token){
    return new User();
  }
  
  /**
   * 调用鉴权服务
   * @param token
   * @return
   */
  @HystrixCommand(fallbackMethod="getUserByTokenFb")//声明回调哪个方法
  public User getUserByToken(String token) {
    String url = "http://" + userServiceName + "/user/get?token=" + token;
    ResponseEntity<RestResponse<User>> responseEntity = rest.get(url, new ParameterizedTypeReference<RestResponse<User>>() {});
    RestResponse<User> response = responseEntity.getBody();
    if (response == null || response.getCode() != 0) {
       return null;
    }
    return response.getResult();
  }
      
  @HystrixCommand(fallback="getUserByTokenFb",ignoreException=IOException.class)//可以忽略这种异常
  public User getAgentById(Long id) {
   return Rests.exc(() ->{
      String url = Rests.toUrl(userServiceName, "/agency/agentDetail?id=" +id);
      ResponseEntity<RestResponse<User>> responseEntity =
          rest.get(url, new ParameterizedTypeReference<RestResponse<User>>() {});
      return responseEntity.getBody();
    }).getResult();
  }
    
  ...
      
  public String getEmail(String key) {
    return Rests.exc(() -> {
      String url = Rests.toUrl(userServiceName, "/user/getKeyEmail?key=" + key);
      ResponseEntity<RestResponse<String>> responseEntity =
          rest.get(url,new ParameterizedTypeReference<RestResponse<String>>() {});
      return responseEntity.getBody();
    }).getResult();
  }
  
}

Hystrix搭建监控面板

新建一个springboot项目

主类上添加:

@EnableHystrixDashboard

依赖:

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-hystrix</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

浏览器输入:localhost:9097/hystrix/moniter

前端页面改造

thymeleaf使用if(idea中是xhtml)

增加判断if,report为空则返回固定的信息,但为了不出现空指针异常,熔断机制默认后端返回的report总是有值的

<!DOCTYPE html>
<html xmlns:th="http://www.w3.org/1999/xhtml">
<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://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css"
          integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb"
          crossorigin="anonymous">

    <title>天气预报</title>
</head>
<body>
<div class="container">
    <div class="row">
        <h3 th:text="${reportModel.title}">waylau</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 class="row">
        <h1 class="text-success" th:text="${reportModel.report.city}">深圳</h1>
    </div>
    <div th:if="${reportModel.report} !=null">
        <div class="row">
            <p>
                空气质量指数:<span>无此项</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>
            天气数据暂时无法访问到
        </div>
    </div>
</div>

<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
        integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
        crossorigin="anonymous"></script>
<script
        src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js"
        integrity="sha384-vFJXuSJphROIrBnz7yo7oB41mKfc8JzQZiCq4NCceLEaO4IHwicKwpJf9c9IpFgh"
        crossorigin="anonymous"></script>
<script
        src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js"
        integrity="sha384-alpBpkh1PFOepccYVYDB4do5UnbKysX5WZXm3XxPqe5iKTfUKjNkCk9SaVuEZflJ"
        crossorigin="anonymous"></script>
<!-- Optional JavaScript -->
<script type="text/javascript" th:src="@{/js/report.js}"></script>
</body>
</html>

测试

http://localhost:8080/report/cityID/101280903

运行整个天气系统,用msa-weather-report-eureka-feign-hystrix代替msa-weather-report-eureka-feign在idea中运行,成功后,依次手动关掉city和weather两个msa服务,就可以看出效果

六、自动扩展

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值