SpringCloud入门笔记

一、SpringCloud简介

1、什么是SpringCloud?

Spring Cloud是分布式系统的整体解决方案底层用的SpringBoot来构建项目,Cloud新增很多的分布式的starter,包括这些starter的自动配置; 本质是一系列框架的有序集合,根据不同组件的配合,简化了分布式系统的开发。

    Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如 服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。Spring并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包

    “微服务架构”在这几年非常的火热,以至于关于微服务架构相关的开源产品被反复的提及(比如:netflix、dubbo),Spring Cloud也因Spring社区的强大知名度和影响力也被广大架构师与开发者备受关注。

    那么什么是“微服务架构”呢?简单的说,微服务架构就是将一个完整的应用从数据存储开始垂直拆分成多个不同的服务,每个服务都能独立部署、独立维护、独立扩展,服务与服务间通过诸如RESTful API的方式互相调用。

2、为什么要用SpringCloud

Spring Cloud对于中小型互联网公司来说是一种福音,因为这类公司往往没有实力或者没有足够的资金投入去开发自己的分布式系统基础设施,使用Spring Cloud一站式解决方案能在从容应对业务发展的同时大大减少开发成本。同时,随着近几年微服务架构和Docker容器概念的火爆,也会让Spring Cloud在未来越来越“云”化的软件开发风格中立有一席之地,尤其是在目前五花八门的分布式解决方案中提供了标准化的、全站式的技术方案,意义可能会堪比当前Servlet规范的诞生,有效推进服务端软件系统技术水平的进步。

3、应用Spring Cloud

Spring Cloud Netflix项目是Spring Cloud的子项目之一,主要内容是对Netflix公司一系列开源产品的包装,它为Spring Boot应用提供了自配置的Netflix OSS整合。通过一些简单的注解,开发者就可以快速的在应用中配置一下常用模块并构建庞大的分布式系统。

五大组件

  • 服务发现(Netflix Eureka
  • 断路器(Netflix Hystrix
  • 智能路由(网关)(Netflix Zuul
  • 客户端负载均衡(Netflix Ribbon
  • 分布式配置(Spring Cloud Config)等。

在这里插入图片描述

图片转自:https://baijiahao.baidu.com/s?id=1621651597363566701

3.1、SpringBoot&Spring什么关系?

SpringBoot底层就是Spring,简化使用Spring的方式而已,多加了好多的自动配置;

3.2、Spring Cloud&SpringBoot什么关系?

Spring Cloud是分布式系统的整体解决方案,底层用的SpringBoot来构建项目,Cloud新增很多的分布式的starter,包括这些starter的自动配置;

二、(转载+参考)SpringCloud入门详解

很全面的一个回答:Spring cloud应该怎么入门? - Java3y的回答 - 知乎 https://www.zhihu.com/question/283286745/answer/763040709

三、SpringCloud五大组件

参考知乎回答:Spring cloud应该怎么入门? - Java3y的回答 - 知乎 https://www.zhihu.com/question/283286745/answer/763040709

1、Eureka(注册中心)

是SpringCloud的一款 服务治理框架 ,类似于Zookeeper,用来注册服务和发现服务。

Eureka 专门用于给其他服务注册的称为Eureka Server(服务注册中心),其余注册到Eureka Server的服务称为Eureka Client

在这里插入图片描述

Eureka Client 分为服务提供者和服务消费者。

  • 一个服务,可能既是服务提供者又是服务消费者
  • 也可能只是单纯的服务消费者,单纯的服务消费者无需对外提供服务,也就无须注册到Eureka中了。
    eureka:
      client:
        register-with-eureka: false  # 当前微服务不注册到eureka中(消费端)
        service-url: 
          defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
    

1、Eureka的治理机制:

1. 服务提供者
  • 服务注册启动的时候会通过发送REST请求的方式将自己注册到Eureka Server上,同时带上了自身服务的一些元数据信息。
  • 服务续约: 在注册完服务之后,服务提供者会维护一个心跳 (心跳机制) 用来持续告诉Eureka Server: "我还活着 ”
  • 服务下线当服务实例进行正常的关闭操作时,它会触发一个服务下线的REST请求给Eureka Server, 告诉服务注册中心:“我要下线了 ”。
2. 服务消费者
  • 获取服务:当我们启动服务消费者的时候,它会发送一个REST请求给服务注册中心,来获取上面注册的服务清单
  • 服务调用:服务消费者在 获取服务清单后,通过服务名 可以获得具体提供服务的实例名和该实例的元数据信息。在进行服务调用的时候,优先访问同处一个Zone中的服务提供方(通过服务名拿到 提供者的地址端口等信息,然后请求该服务,不是eureka server请求转发的)
3. Eureka Server(服务注册中心):
  • 失效剔除:默认每隔一段时间(默认为60秒) 将当前清单中超时(默认为90秒)没有续约的服务剔除出去
  • 自我保护:。EurekaServer 在运行期间,会统计心跳失败的比例在15分钟之内是否低于85%(通常由于网络不稳定导致)。 Eureka Server会将当前的实例注册信息保护起来, 让这些实例不会过期,尽可能保护这些注册信息

在这里插入图片描述

2、案例:父工程搭建(parent工程)

在这里插入图片描述
修改pom文件:
将package改为pom
添加dependencyManagement,具体配置如下

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <modules>
        <module>eureka-server</module>
    </modules>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.10.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.springcloud</groupId>
    <artifactId>springcloud_hello</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springcloud_hello</name>
    <description>The parent project of demo project for Spring Cloud</description>

    <packaging>pom</packaging>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

</project>

3、案例:(EurekaServer)注册中心

1、创建注册中心模块eureka-server
(Eureka :创建一个名字叫 eureka-server 的 jar工程 的 模块 module)
创建一个springcloud_helloworld的 子module,为maven项目
在这里插入图片描述

2、引入eureka-server模块pom.xml

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

3、创建application.yml
在resources目录下创建application.yml配置文件

spring:
  application:
    name: EurekaServer  #应用名称
server:
  port: 8761  #内置的tomcat服务启动监听端口号

eureka:
  instance:
    hostname: localhost
  client:
    register-with-eureka: false #此EurekaServer不再注册到其他的注册中心
    fetch-registry: false       #不再从其他中心中心拉取服务器信息
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka

4、编写启动类

创建包 com.springcloud,创建类EurekaServerStart

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerStart {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerStart.class);
    }
}

5、测试
启动运行启动类,浏览器地址栏输入 http://localhost:8761

4、案例:( 服务提供者)电影服务模块(EurekaClient-provider)

在这里插入图片描述

1、创建springcloud-hello的子module,jar工程(provider-movie),提供查询电影功能

2、引入provider-movie模块的pom依赖

	<dependencies>
        <!-- springboot web依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- eurekaclient依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <!-- lombok插件 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.6</version>
        </dependency>

    </dependencies>

3、创建实体类 Movie(com.springcloud.pojo)

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Movie implements Serializable {
    private Integer id;
    private String movieName;
}

4、创建Dao,模拟dao层(com.springcloud.dao)

@Repository
public class MovieDao {

    public Movie getNewMovie() {
        Movie movie = new Movie();
        movie.setId(1);
        movie.setMovieName("战狼");
        return movie;
    }
}

5、创建Service层(com.springcloud.service)

@Service
public class MovieService {
    @Autowired
    private MovieDao movieDao;

    public Movie getNewMovie() {
        return movieDao.getNewMovie();
    }

}

6、创建Controller层(com.springcloud.controller)

@RestController
public class MovieController {

    @Autowired
    private MovieService movieService;

    @GetMapping("/movie")
    public Movie getNewMovie(){
        return movieService.getNewMovie();
    }
}

7、创建ProviderMovieStart启动类(com.springcloud)

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

8、启动 测试
这时,启动的只是一个普通的springboot的web工程,跟eureka没有任何关系。springboot-web 默认是8080端口,直接访问http://localhost:8080/movie

9、创建application.yml配置文件(配置eurekaclient的服务注册)
在resources目录下

#spring应用名
spring:
  application:
    name: ProviderMovie
# 服务端口号
server:
  port: 8000

# eureka客户端设置 ,设置要注册到的eurekaserver地址
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true #注册服务使用IP的方式

10、修改启动类(添加 @EnableDiscoveryClient注解)

@SpringBootApplication
@EnableDiscoveryClient
public class ProviderMovieStart {
    public static void main(String[] args) {
        SpringApplication.run(ProviderMovieStart.class,args);
    }
}

11、启动注册中心和服务
再重新刷新 EurekaServer监控中心
在这里插入图片描述

5、案例:(服务消费者)用户服务模块

1、创建子module consumer-user。(jar工程,提供查询用户,买电影票功能)

2、添加pom依赖(与movie模块一样)

3、创建实体类User

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {
    private Integer id;
    private String userName;
}

4、创建Dao层

@Repository
public class UserDao {
    public User getUser(Integer id) {
        User user = new User();
        user.setId(id);
        user.setUserName("张三");
        return user;
    }
}

5、创建Service层

@Service
public class UserService {
    @Autowired
    private UserDao userDao;

    /**
     * 根据ID得到用户对象
     *
     * @param id
     * @return
     */
    public User getUserById(Integer id) {
        User user = userDao.getUser(id);
        return user;
    }

    /**
     * 购买最新的电影票
     * @param id 用户ID
     * @return
     */
    public Map<String, Object> buyMovie(Integer id) {
        Map<String, Object> result = new HashMap<>();
        //1.查询用户信息
        User user = this.getUserById(id);
        result.put("user", user);
        //2.查到最新电影票
        //TODO 暂时为null
        result.put("movie", null);
        return result;
    }
}

6、创建Controller层

@RestController
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("/user/{id}")
    public User getUser(@PathVariable("id") Integer id) {
        User user = userService.getUserById(id);
        return user;
    }

    @GetMapping("/buyMovie/{id}")
    public Map<String, Object> buyMovie(@PathVariable("id") Integer userId) {
        Map<String, Object> map = userService.buyMovie(userId);
        return map;
    }
}

7、创建application.yml配置文件

#spring应用名
spring:
  application:
    name: ConsumerUser
# 服务端口号
server:
  port: 9000

# eureka客户端设置
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-addre

8、创建、配置 启动类(@EnableDiscoveryClient)

@SpringBootApplication
@EnableDiscoveryClient
public class ConsumerUserStart {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerUserStart.class,args);
    }
}

9、测试

http://localhost:9000/user/1
在这里插入图片描述

http://localhost:9000/buyMovie/1

20200921230600943 😃
在这里插入图片描述

6、@EnableDiscoveryClient和@EnableEurekaClient的区别

他们在功能上是一致的:写在启动类的上,开启服务注册发现功能

@EnableDiscoveryClient基于spring-cloud-commons, @EnableEurekaClient基于spring-cloud-netflix。

其实用更简单的话来说,就是
如果选用的注册中心是eureka,那么就推荐@EnableEurekaClient,
如果是其他的注册中心,那么推荐使用@EnableDiscoveryClient。

官方推荐使用:@EnableDiscoveryClient

@EnableDiscoveryClient与@EnableEurekaClient区别:https://www.jianshu.com/p/f6db3117864f
在老版的@EnableEurekaClient中 包含了 @EnableDiscoveryClient

更详细的帖子:https://blog.youkuaiyun.com/boling_cavalry/article/details/82668480

7、Eureka的超时重试机制

使用ribbon负载调用服务的时候,可能会出现一次请求,服务多次被调用的问题,原因就是Eureka的超时重试机制。跟dubbo的超时调用机制 类似。

简书:《Spring Cloud 》Eureka服务调用服务超时重试机制https://www.jianshu.com/p/81976ff84e92
eureka重试机制:https://blog.youkuaiyun.com/caoxuecheng001/article/details/103873780

dubbo超时调用机制:https://blog.youkuaiyun.com/BigDevil_/article/details/108711731

2、Ribbon负载均衡和RestTemplate调用

Spring Cloud Ribbon是基于Netflix Ribbon实现的一套 客户端负载均衡 的工具。它是一个基于HTTP和TCP的客户端负载均衡器。
Ribbon客户端组件提供一系列完善的配置选项,比如连接超时、重试、重试算法等。Ribbon内置可插拔、可定制的负载均衡组件。 (超时重试机制;默认的负载均衡策略是轮询,可自定义负载策略

自定义负载均衡策略:https://blog.youkuaiyun.com/dkbnull/article/details/89506462

RestTemplate是spring封装的工具类,进行rest调用远程服务。

使用restTemplate访问restful接口非常的简单粗暴无脑。 ·(url, requestMap,ResponseBean.class)·这三个参数分别代表 REST请求地址、请求参数、HTTP响应转换被转换成的对象类型。

RestTemplate例:

	// 传统的方式,直接显示写死IP是不好的!
    //private static final String REST_URL_PREFIX = "http://localhost:8001";
	
	// 服务实例名
    private static final String REST_URL_PREFIX = "http://MICROSERVICECLOUD-DEPT";
    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping(value = "/consumer/dept/add")
    public boolean add(Dept dept) {
        return restTemplate.postForObject(REST_URL_PREFIX + "/dept/add", dept, Boolean.class);
    }

案例:consumer_user案例中使用ribbon负载 并用 rest调用远程服务

ribbon是客户端负载均衡,是 服务消费者 负载调用 服务提供者,所以只需在服务消费者上配置ribbon

1、引入pom依赖

<!-- 引入ribbon实现远程调用和负载均衡功能 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>

2、修改启动类
在启动类中 RestTemplate注入到容器中,并添加@LoadBalanced注解 开启负载调用

@LoadBalanced   //负载均衡
@Bean
public RestTemplate getRestTemplate(){
    return new RestTemplate();
}

3、修改UserService

  1. 拷贝Movie实体类到consumer-user模块
  2. UserService依赖注入RestTemplate
  3. RestTemplate提交远程服务请求
	@Autowired
    private RestTemplate restTemplate;


    /**
     * 购买最新的电影票
     * @param id 用户ID
     * @return
     */
    public Map<String, Object> buyMovie(Integer id) {
        Map<String, Object> result = new HashMap<>();
        //1.查询用户信息
        User user = this.getUserById(id);
        result.put("user", user);
        //2.查到最新电影票
        
        //PROVIDERMOVIE为注册到eureka中的提供者服务名
        Movie movie = restTemplate.getForObject("http://PROVIDERMOVIE/movie", Movie.class);
        
        result.put("movie", movie);
        return result;
    }

4、测试
在这里插入图片描述

5、修改电影服务(MovieService 类)中打印服务端口,方便监控服务执行情况。

@Value("${server.port}")
private String port;

public Movie getNewMovie() {
    System.out.println("当前电影服务的端口:"+port);
    return movieDao.getNewMovie();
}

6、将电影服务项目启动多次,测试负载均衡
复制多个providerMovie,然后分别修改providerMovie的端口号
如:VM options:-Dserver.port=8001

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
注册了3个providermovie服务提供者

然后分别启动,然后开始多次请求consumer的http://localhost:9000/buyMovie/1

第一次请求:
在这里插入图片描述
第二次:
在这里插入图片描述
第三次:
在这里插入图片描述

3、(不是五大组件之一)Feign服务调用(ribbon+feign)

Feign是一个 声明性的web服务客户端 ,它使编写web服务客户机变得更容易。使用Feign创建接口并对其进行注释,就可以通过该接口调用生产者提供的服务。Spring Cloud对Feign进行了增强,使得Feign支持了Spring MVC注解。
两点:

  • 1、Feign采用的是接口加注解(声明式服务调用,不用RestTemplate了);
  • 2、Feign 整合了ribbon
  • 3、Feign整合了hystrix(需要手动配置)

(个人理解:Feign通过springmvc注解,和接口方法等 自动拼接url,进行远程调用

1、Feign远程调用原理

Feign远程调用原理https://www.jianshu.com/p/e0218c142d03

2、Feign使用步骤:

  1. 在启动类使用@EnableFeignClients启用feign客户端
  2. 使用注解@FeignClient 定义feign客户端 ;(通过 动态代理 给加@FeignClient的接口创建 实现类)
    创建接口,接口定义的方法 与 服务提供者的service方法一致,方法上的SpringMVC注解 与 服务提供者的controller方法一致
  3. 在消费者service中 使用注解@Autowired注入上面所定义feign的客户端,并进行远程调用

3、注解 @EnableFeignClients 工作原理

注解@EnableFeignClients:扫描和注册feign客户端bean定义
注解@EnableFeignClients告诉框架扫描所有使用注解@FeignClient定义的feign客户端。

参考:https://blog.youkuaiyun.com/andy_zhang2007/article/details/86680622

4、案例:(Feign调用)consumer-user-feign项目

1、创建子模块,consumer-user-feign
2、引入pom依赖

<dependencies>
        <!-- springboot web依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- eurekaclient依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <!-- 引入ribbon实现远程调用和负载均衡功能 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>

        <!-- 打开feign调用 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

        <!-- lombok插件 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.6</version>
        </dependency>

    </dependencies>

3、添加application.yml

spring:
  application:
    name: ConsumerUserFeign

server:
  port: 7000

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true

4、编写启动类 ConsumerUserFeignStart

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients  //开启Feign功能
public class ConsumerUserFeignStart {

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

@EnableFeignClients //开启Feign功能

不加这个注解时,不会注入加@FeignClient的接口

注入MovieServiceFeign接口的时候,idea会报错提示不能autowire注入。
启动时报错,提示com.springcloud.service.MovieServiceFeign这个bean类型找不到

5、复制consumer-user的pojo,dao,service,controller
在这里插入图片描述
6、将RestTemplate方式改成Feign方式进行远程调用(新建MovieServiceFeign接口,修改MovieService)

  1. 创建MovieServiceFeign接口

    /**
     * 调用指定服务名称 “PROVIDERMOVIE” 的 @GetMapping("/movie") 映射方法
     * 这个方法声明与电影服务端Controller映射的方法声明一致即可。
     */
     
    @FeignClient(value = "PROVIDERMOVIE")  //与被调用的服务名称一致
    public interface MovieServiceFeign {
    
        @GetMapping("/movie")
        public Movie getNewMovie();  //与被调用服务端映射方法一致
        // 即 与 provider-movie中的MovieService的方法一致
    }
    
    
  2. 修改UserService 代码

    	
    	// 如果启动类不开启EnableFeignClients注解,这个接口不能被注入
    	@Autowired
        private MovieServiceFeign  movieServiceFeign;   //调用Feign接口;其实就是调用远程服务
    
    	 /**
         * 购买最新的电影票
         * @param id 用户ID
         * @return
         */
        public Map<String, Object> buyMovie(Integer id) {
            Map<String, Object> result = new HashMap<>();
            //1.查询用户信息
            User user = this.getUserById(id);
            result.put("user", user);
            //2.查到最新电影票
            //PROVIDERMOVIE为注册到eureka中的提供者服务名
            //Movie movie = restTemplate.getForObject("http://PROVIDERMOVIE/movie",Movie.class);
            
            //---feign调用
            Movie movie = movieServiceFeign.getNewMovie();
            
            
            result.put("movie", movie);
            return result;
        }
    
    
    

7、启动服务,测试调用与负载均衡效果

4、Hystrix熔断器组件

什么是hystrix熔断器?
Spring Cloud 实现了断路器、线程隔离等一系列服务保护功能的组件。

为什么用hystrix组件?
在高并发的情况下,由于单个服务的延迟,可能导致所有的请求都处于延迟状态,甚至在几秒钟就使服务处于负载饱和的状态,资源耗尽,直到不可用,最终导致这个分布式系统都不可用,这就是“雪崩”。

hystrix的功能:

  • Fallback(失败快速返回):当某个服务单元发生故障(类似用电器发生短路)之后,通过断路器的故障监控(类似熔断保险丝), 向调用方返回一个错误响应, 而不是长时间的等待。这样就不会使得线程因调用故障服务被长时间占用不释放,避免了故障在分布式系统中的蔓延
  • 资源/依赖隔离(线程池隔离):它会为每一个依赖服务创建一个独立的线程池,这样就算某个依赖服务出现延迟过高的情况,也只是对该依赖服务的调用产生影响, 而不会拖慢其他的依赖服务

hystrix原理:
在这里插入图片描述
在这里插入图片描述

https://www.jianshu.com/p/e07661b9bae8

1、案例:Hystrix+Ribbon+TestTemplate调用

在consumer-user工程中 使用hystrix熔断

1、引入Hystrix pom依赖

<!--  引入hystrix进行服务熔断 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

2、启动类:开启断路保护功能@EnableCircuitBreaker。(CircuitBreaker:断路器)

@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker  //开启断路保护功能
public class ConsumerUserStart {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerUserStart.class);
    }

    @LoadBalanced   //负载均衡
    @Bean
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}

3、修改UserService

  1. 在方法上标注@HystrixCommand(fallbackMethod=“xxx”)来指定出错时调用xx方法

    // fallbackMethod 指定回调方法,当执行失败或超时后,调用的方法
    @HystrixCommand(fallbackMethod = "buyMovieFallbackMethod")
    public Map<String, Object> buyMovie(Integer id) {
        Map<String, Object> result = new HashMap<>();
        //1.查询用户信息
        User user = this.getUserById(id);
        result.put("user", user);
        //2.查到最新电影票
        Movie movie = restTemplate.getForObject("http://PROVIDERMOVIE/movie",Movie.class);
        result.put("movie", movie);
        return result;
    }
    
  2. 在本类编写回调xx方法,方法的参数、返回值和原来一样即可
    (编写buyMovieFallbackMethod回调方法,参数返回值与buyMovie保持一致)

    public Map<String,Object> buyMovieFallbackMethod(Integer id){
        User user = new User();
        user.setId(-1);
        user.setUserName("未知用户");
        Movie movie = new Movie();
        movie.setId(-100);
        movie.setMovieName("无此电影");
        Map<String,Object> result = new HashMap<>();
        result.put("user",user);
        result.put("movice",movie);
        return result;
    }
    
    

4、测试正常调用&停止user服务,测试异常调用&启动user服务过一段时间测试是否正常
http://localhost:9000/buyMovie/1

2、案例:Hystrix+Ribbon+feign调用

feign集成了hystrix,@FieldClient注解中直接配置他的fallback属性,指定这个feign客户端的实现类的Class类型。
feign客户端 是feign调用指定 提供服务者的 一个 接口。

consumer-user-feign工程中,使用hystrix熔断

1、添加hystrix依赖

<!--  引入hystrix进行服务熔断 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

2、配置application.yml,打开feign的hystrix熔断功能

# 开启Feign的熔断功能
feign:
  hystrix:
    enabled: true  

3、启动类,开启熔断器功能@EnableCircuitBreaker

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients  //开启Feign功能
@EnableCircuitBreaker  //开启断路保护功能
public class ConsumerUserFeignStart {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerUserFeignStart.class,args);
    }
}

4、添加MovieServiceFeign的@FeignClient注解的fallback属性

Feign已经集成了Hystrix,使用起来非常简单
@FeignClient(name=“provider-user”,fallback=“异常处理类”)

@FeignClient(value = "PROVIDERMOVIE",fallback = MovieFeignExceptionHandlerService.class)  //与被调用的服务名称一致
public interface MovieServiceFeign {

    @GetMapping("/movie") // 注解与 被调用服务的controller层注解一致
    public Movie getNewMovie();  //与被调用服务端映射方法一致
    // 即 与 provider-movie中的MovieService的方法一致
}

5、创建feign的回调 异常处理类

fallback="异常处理类"指定的异常处理类实现这个Feign客户端接口即可,并且放在容器中,需要增加@Component注解

这个异常处理类,就是远程服务的一个本地实现,如果调用出错或失败或超时,都会调用这个实现类的 对应方法。

@Component
public class MovieFeignExceptionHandlerService implements  MovieServiceFeign{
   /**
    * 远程服务的本地实现,如果调用远程服务失败或超时等,就会调用本地实现
    */
    @Override
    public Movie getNewMovie() {
        return new Movie(-100,"无此电影");
    }
}

6、测试正常调用&停止user服务,测试异常调用&启动user服务过一段时间测试是否正常

3、Hystrix Dashboard(熔断器的仪表盘)

除了隔离依赖服务的调用以外,Hystrix还提供了近实时的监控,Hystrix会实时、累加地记录所有关于HystrixCommand的执行信息,包括每秒执行多少请求,多少成功,多少失败等。Netflix通过hystrix-metrics-event-stream项目实现了对以上指标的监控

案例:Hystrix Dashboard

在consumer-user-feign工程中,配置hystrix仪表盘

1、引入pom 依赖(actuator

<!-- actuator是用来监控SpringBoot服务 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

注意:

  1. actuator是用来监控SpringBoot服务的,注意路径问题,具体的版本可能不一样,参考启动日志
    http://localhost:7000/actuator/health

  2. 可提供的监控服务
    在这里插入图片描述

2、修改application.yml,暴露数据监控流

# 暴露hystrix数据监控流
management:
  endpoints:
    web:
      exposure:
        include: hystrix.stream #访问/actuator/hystrix.stream能看到不断更新的监控流

3、浏览器访问http://localhost:7000/actuator/hystrix.stream 可以看到打印(测试数据监控流是否成功暴露

4、引入HystrixDashboard 依赖

<!-- hystrix 监控面板 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>

5、开启可视化监控功能

  1. 修改主启动类ConsumerUserFeignStart 添加@EnableHystrixDashboard 注解,打开hystrix dashboard

  2. 访问http://localhost:7000/hystrix,将Hystrix的stream地址输入(http://localhost:7000/actuator/hystrix.stream ),点击monitor按钮即可监控
    在这里插入图片描述

  3. 监控中,服务器正常
    需要首先访问消费者接口: http://localhost:7000/buyMovie/1
    可以看到没有打开断路器,可以正常访问
    在这里插入图片描述

  4. 监控中,关闭provider,断路器就被打开了。再访问http://localhost:7000/buyMovie/1。就可以看到100%打开了断路器
    在这里插入图片描述

5、Zuul网关(路由,网关)

  • SpringCloud Zuul通过与SpringCloud Eureka进行整合,将自身注册为Eureka服务治理下的应用,同时从Eureka中获得了所有其他微服务的实例信息。外层调用都必须通过API网关,使得将维护服务实例的工作交给了服务治理框架自动完成。
  • 在API网关服务上进行统一调用来对微服务接口做前置过滤,以实现对微服务接口的拦截和校验
    Zuul也是支持Hystrix和Ribbon

6、SpringCloud Config

Spring Cloud Config项目是一个解决分布式系统的配置管理方案。它包含了Client和Server两个部分,server提供配置文件的存储、以接口的形式将配置文件的内容提供出去,client通过接口获取数据、并依据此数据初始化自己的应用。

  • 简单来说,使用Spring Cloud Config就是将配置文件放到统一的位置管理(比如GitHub),客户端通过接口去获取这些配置文件。
  • 在GitHub上修改了某个配置文件,应用加载的就是修改后的配置文件。

(老)通信模式
在这里插入图片描述
(新)现在由于配置客户端(1,2…n)非常多,则基于消息中线的方式通信模型为:
在这里插入图片描述

图片来源https://blog.youkuaiyun.com/it_lihongmin/article/details/91466638

SpringCloud中ConfigBus的理論及使用 (配置中心 实时更新 基于mq)https://blog.youkuaiyun.com/weixin_42236165/article/details/93844970

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值