springcloud学习笔记

一·微服务架构与springcloud

  1. 微服务架构概述

  2. springcloud是什么?

    springcloud=分布式微服务架构的一站式解决方案,是多种微服务架构落地技术的集合体,俗称微服务全家桶。
    

二·springboot和springcloud的版本选择

1.springcloud使用英国伦敦地铁站名称来命名,并由地铁站名称字母A-Z以此类推的形式来发布迭代版本。springcloud版本采用率名称而非版本号的命名,这些版本的名字采用了伦敦地铁站的名字,根据字母表的瞬息来对应版本时间顺序。
2.springboot和springcloud的版本对应关系
版本截图
3.本次学习的版本选择

springcloud版本:Hoxton.SR1
springboot版本:2.2.2.RELEASE
cloud alibaba:2.1.0.RELEASE
java:java8
Maven:3.5及以上
msyql:5.7及以上

三·关于cloud各种组件的停更/升级/替换

服务注册中心:Eureka(×),替代产品,Zookeeper(√),Consul(√),Nacos(√,重点)
服务调用:Ribbon在被LoadBalancer逐渐替换
服务调用:Feign(×),OpenFeign(√)
服务降级:Hystrix(×),resilience4j(√),sentienl(√,推荐使用)
服务网关:Zuul(×),gateway(√,主流)
服务配置:Config(×),Nacos(√)
服务总线:Bus(×),Nacos(√)

四·微服务架构编码构建
1.约定>配置>编码

设置字符编码

在这里插入图片描述

注解生效激活

在这里插入图片描述

java编译版本选8

在这里插入图片描述

File Type 过滤,设置之后不显示.idea和.iml文件

在这里插入图片描述
2.maven的pom.xml文件中的dependencyManagement与dependencies的区别

	dependencyManagement元素能让所有子项目中引用一个依赖而不用显式的列出版本号,maven会沿着父子层次向上
走,直到找到拥有dependencyManagement元素的项目,然后它就会使用这个dependencyManagement元素中指定的版本
号。
	如果子项目想用自己的版本,也可以自己指定依赖版本。
	dependencyManagement只是声明依赖,而不实现引入,因此子项目需要显示的声明需要用的依赖。
	如果子项目中不声明依赖,是不会从父项目中继承依赖的;只有在子项目中声明了该依赖项,并且没有指定版本号,才会
从父项目中继承该依赖,并且version和scope都读自父项目pom文件。

3.maven中跳过单元测试
在这里插入图片描述
4.微服务模块(如cloud-provider-payment8001)的创建步骤

建模块maven工程
改pom文件
写yml配置
springboot主启动类
业务类
测试

5.遇到的一些知识点

 public CommonResult(Integer code,String message){
        //super(参数):调用父类中的某一个构造函数(应该为构造函数中的第一条语句)。
        //this(参数):调用本类中另一种形式的构造函数(应该为构造函数中的第一条语句)。
        this(code,message,null);
    }
super和this的异同:
	super(参数):调用基类中的某一个构造函数(应该为构造函数中的第一条语句) 
	this(参数):调用本类中另一种形成的构造函数(应该为构造函数中的第一条语句)
	super: 它引用当前对象的直接父类中的成员(用来访问直接父类中被隐藏的父类中成员数据或函数,基类与派生类中有相同成员定义时如:super.变量名    super.成员函数据名(实参)
	this:它代表当前对象名(在程序中易产生二义性之处,应使用this来指明当前对象;如果函数的形参与类中的成员数据同名,这时需用this来指明成员变量名)
调用super()必须写在子类构造方法的第一行,否则编译不通过。每个子类构造方法的第一条语句,都是隐含地调用super(),如果父类没有这种形式的构造函数,那么在编译的时候就会报错。
	super()和this()类似,区别是,super()从子类中调用父类的构造方法,this()在同一类内调用其它方法。
	super()和this()均需放在构造方法内第一行。
	尽管可以用this调用一个构造器,但却不能调用两个。
	this和super不能同时出现在一个构造函数里面,因为this必然会调用其它的构造函数,其它的构造函数必然也会有super语句的存在,所以在同一个构造函数里面有相同的语句,就失去了语句的意义,编译器也不会通过。
	this()和super()都指的是对象,所以,均不可以在static环境中使用。包括:static变量,static方法,static语句块。
从本质上讲,this是一个指向本对象的指针, 然而super是一个Java关键字。
<insert id="create" parameterType="Payment" useGeneratedKeys="true" keyProperty="id">

</insert>
<!--:对于支持自动生成记录主键的数据库,如:MySQL,SQL Server,此时设置useGeneratedKeys参数值为true,
在执行添加记录之后可以获取到数据库自动生成的主键ID,并通过keyProperty设置将自动生成的主键ID赋给java实体
类(此例中是Payment)的id属性。-->

6.使用devtools实现热部署

添加依赖到相应的子模块pom文件中
 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
 </dependency>
添加plugin到父工程的pom文件中
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <configuration>
          <fork>true</fork>
          <addResources>true</addResources>
        </configuration>
      </plugin>
    </plugins>
  </build>
开启自动编译的权限

在这里插入图片描述

update the value of
ctrl+shift+Alt+/ 进入一下界面进行操作

在这里插入图片描述

在这里插入图片描述
7.首说RestTemplate

RestTemplate提供了多种便捷访问远程http服务的方法,是一种简单便捷的访问restful服务模板类,是spring提供的
用于访问Rest服务的客户端模板工具集。
使用方法:直接依赖注入,然后调用方法发送请求。

五·Eureka服务注册与发现
1.Eureka的基础知识

什么是服务注册与发现?
	Eureka采用了c/s的设计架构,Eureka Server作为服务注册功能的服务器,它是服务注册中心。而系统中的其他微服务,
使用Eureka的客户端连接到Eureka并维持心跳连接。这样系统的维护人员就可以通过Eureka Server来监控系统中各个
微服务是否正常运行。
	eureka包括两个组件:Eureka Server和Eureka Client
	Eureka Server提供服务注册服务,各个微服务节点通过配置质启动后,会在EurekaServer中进行注册,这样
EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务街店信息可以在界面中直观看到。
	Eureka Client 通过注册中心进行访问。它是一个java客户端,用于简化EurekaServer的交互,客户端同时也具备一
个内置的,使用轮询负载算法的负载均衡器。在应用启动后,将会向EurekaServer发送心跳(默认周期为30秒)。如果
EurekaServer在多个心跳周期内没有接收到某个节点的心跳,EurekaServer将会从服务注册表中把这个服务节点移除
(默认90秒)。

2.单机eureka构建步骤

1.创建子模块cloud-eureka-server7001作为Eureka Server,

	添加依赖`
	 <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>`

	修改yml文件`
	eureka:
	  instance:
	    hostname: localhost   #eureka服务端的实例名字
	  client:
	    register-with-eureka: false    #表识不向注册中心注册自己
	    fetch-registry: false   #表示自己就是注册中心,职责是维护服务实例,并不需要去检索服务
	    service-url:
	      #集群指向其它eureka
	      #defaultZone: http://eureka7002.com:7002/eureka/    #设置与eureka server交互的地址查询服务和注册服务都需要依赖这个地址
	      #单机就是7001自己
	      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/`

	启动类上加注解@EnableEurekaServer  //eureka注册中心
	
2.配置子模块cloud-provider-payment8001为Eureka Client
	添加依赖`    
	<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
      </dependency>`
      
	修改yml文件
	eureka:
	  client:
	    #表示是否将自己注册进EurekaServer默认为true。
	    register-with-eureka: true
	    #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
	    fetchRegistry: true
	    service-url:
	      #单机版
	      defaultZone: http://localhost:7001/eureka
	   
	主启动类上加注解@EnableEurekaClient //eureka的client

3.集群Eureka的构建步骤

原理:各个注册中心互相注册,相互守望
步驟:
新建一个模块作为第二个注册中心Eureka Server,并修改pom文件
修改映射配置

在这里插入图片描述

写yml文件

在这里插入图片描述
在这里插入图片描述

修改两个eureka client 的yml配置文件,让每个client同时注册到两个注册中心中
eureka:
  client:
    #表示是否将自己注册进EurekaServer默认为true。
    register-with-eureka: true
    #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
    fetchRegistry: true
    service-url:
      #单机版
      #defaultZone: http://localhost:7001/eureka
      # 集群版
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
	创建另一个模块cloud-provider-payment8002作为 eureka client,该模块的内容与cloud-provider-payment8001
基本一致,只是将端口号改为了8002,这是为了模拟客户端集群的效果。
	此时通过cloud-consumer-order80模块访问provider中的方法时,应该是eureka实现负载均衡,使用轮询算法随机调用
8001和8002端口的provider,但是由于在cloud-consumer-order80中的controller中将url写死为8001,即public static 
final String PAYMENT_URL = "http://localhost:8001" ;,所以未能达到负载均衡的效果,只是调用了8001中的方法
	所以将url修改为  public static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE" ;

在这里插入图片描述

此时按理说会根据在eureka中注册的服务名CLOUD-PAYMENT-SERVICE轮询调用8001和8002的方法。
但是报错了

在这里插入图片描述

错误原因:并不知道服务名CLOUD-PAYMENT-SERVICE下有多少个端口,也不知道是哪个端口会执行方法。
解决:使用@LoadBalanced注解赋予RestTemplate负载均衡的能力。

在这里插入图片描述
4.服务发现discovery

对于注册在eureka里面的微服务,可以通过服务发现来获取该服务的信息,比如ip,端口号等等
步骤:
	修改client(以8001为例)的controller
 	  @Autowired
		private DiscoveryClient discoveryClient ;
		通过discoveryclient可以拿到服务信息,通过以下代码测试
    @GetMapping("/discovery")
    public Object discovery(){
        List<String> services = discoveryClient.getServices();//拿到eureka注册表中的所有服务
        for (String service : services) {
            log.info("*********service"+service);
        }
        List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");//拿到eureka注册表中的某个服务的所有实例
        for (ServiceInstance instance : instances) {
            log.info("*****instance"+instance);
            log.info("****"+instance.getInstanceId()+"***"+instance.getHost()+"***"+instance
                    .getPort()+"****"+instance.getUri());
        }
        return this.discoveryClient ;
    }
	主启动类上加注解@EnableDiscoveryClient

5.Eureka的自我保护机制

在eureka的界面上看到如下信息,就说明eureka启动了自我保护机制
EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.
自我保护机制:某时刻某一个微服务不可用了,eureka不会立刻清零,依旧会对该微服务的信息进行保存,属于CAP原理	
中的AP分支。
他的设计哲学就是:宁可保留错误的服务注册信息,也不盲目注销任何可能健康的服务实例。
停止自我保护机制的步骤:
eureka server 的yml文件中:
	eureka.server.enable-self-preservation: false  //关闭自我保护机制
	eureka.eviction-interval-timer-in-ms: 2000 //设置时间,2000ms检测不到服务,就注销该服务。

6.Eureka的停更

六·服务注册与发现zookeeper

单机版构建步骤:
	docker启动zookeeper,
	新建子模块cloud-provider-payment8004,修改pom文件,添加zookeeper的相关依赖,修改yml配置文件,添加
	zookeeper的相关配置,主启动类上添加注解@EnableDiscoveryClient。
注意:zookeeper相关依赖中的zookeeper版本是3.5.3,而docker中的zookeeper版本是3.4.9,所以应该排除自带的版本,添加3.4.9的zookeeper版本
<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
            <!--先排除自带的zookeeper3.5.3-->
            <exclusions>
                <exclusion>
                    <groupId>org.apache.zookeeper</groupId>
                    <artifactId>zookeeper</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--添加zookeeper3.4.9版本-->
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.9</version>
        </dependency>
测试zookeeper是否使用成功:
docker exec -it zk02(docker中zookeeper的别名)/bin/bash
cd bin
ls
./zkCli.sh
ls /
ls /services
ls /services/cloud-provider-payment
get  /services/cloud-provider-payment/...(得到json串)
其他注意事项:怎么退出zookeeper容器 ctrl+D/C 然后 exit
问题:此时停掉8004服务,那么zookeeper中是否会立即注销cloud-provider-payment服务?(即以上方式创建的zook服务时持久的还是临时的?)
答:临时的
创建另一个模块cloud-consumerzk-order80也注册到zookeeper中,之后类似于单机版的eureka,使用resttemplate
调用8004中的方法,注意加@LoadBalanced注解。

七·Consul服务注册与发现

1.consul的安装:官网下载压缩包,解压得到exe文件,cmd在命令行输入:consul agent -dev启动consul,在浏览器
打开8500端口就会看到consul的界面。
2.添加consul的依赖,修改yml文件,主启动类上加注解,测试(同上)
3.eureka,zookeeper,consu三个注册中心的异同:
		
	组件名   		语言  		CAP  		服务健康检查 				对外暴露接口				SpringCloud集成
	Eureka 			java		AP			可配支持						HTTP					已集成
	zookeeper		go			CP			支持						HTTP/DNS				已集成
	consul			java       	CP			支持						客户端					已集成

八·Ribbon负载均衡服务调用

1.bbon概述:springcloud ribbon是基于Netflix Ribbon实现的一套客户端 负载均衡的工具。
简单的说,ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法和服务调用。Ribbon客户端
提供一系列完善的配置项如连接超时,重试等,。也就是在配置文件中列出Load Banlancer后面所有的机器,Ribbon会
自动的帮助你基于某种规则,如简单轮询,随机连接等,去连接这些机器。
所谓的ribbon就是负载均衡+RestTemplate调用。
2.LB负载均衡:简单的事就是讲用户的请求平摊分配到多个服务上去,从而达到系统的HA高可用。
常见的负载均衡负载均衡软件有Nginx,LVS,硬件,F5等
Ribbon本地负载均衡客户端  VS  Nginx服务端负载均衡区别:
	Nginx是服务器负载均衡,客户端所有请求都会交给nginx,然后由nginx实现转发请求。即负载均衡是由服务
端实现的,属于。
	Ribbon本地负载均衡,在调用微服务接口的时候,会在注册中心上获取注册信息服务列表之后缓存到JVM本地,
从而在本地实现RPC远程服务调用技术。属于进程内LB。
	
	集中式LB:即在服务的消费方和提供方之间使用独立的LB设施,可以是硬件,如F5,也可以说是软件,如nginx,
由该设施负责把访问请求通过某种策略转发至服务的提供方。
	进程内LB:将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的服务器。
3.eureka已经集成了ribbon,所以在eureka配合使用ribbon时,不用引入ribbon依赖。
4.二说RestTemplate
	resttemplate的getForObject方法和getForEntity方法
 //getForObject方法返回对象为响应体中数据转化成的对象,基本上可以理解为json
    @GetMapping("/payment/getPaymentById/{id}")
    public CommonResult<Payment> getPaymentById(@PathVariable(value = "id") Long id){
        return restTemplate.getForObject(PAYMENT_URL+"/payment/getPaymentById/"+id,CommonResult
                .class);
    }
    
    //getForEntity方法返回对象为ResponseEntity对象,该对象中包含了响应中的一些重要信息,比如响应头,响应状态码,响应体等
    @GetMapping("/payment/getPaymentByIdForEntity/{id}")
    public CommonResult<Payment> getPaymentById2(@PathVariable(value = "id") Long id){
        ResponseEntity<CommonResult> entity = restTemplate.getForEntity(PAYMENT_URL + "/payment/getPaymentById/" + id, CommonResult.class);
        if(entity.getStatusCode().is2xxSuccessful()){
            return entity.getBody();
        }else {
            return new CommonResult<>(444,"操作失败");
        }
5.	Ribbon核心组件IRule
	IRule:根据特定算法从服务列表中选取一个要访问的服务。
	有哪些算法:
			com.netflix.loadbalancer.RoundRobinRule 轮询(ribbon默认使用的规则)
			com.netflix.loadbalancer.RandomRule 随机
			com.netflix.loadbalancer.RetryRule  先按照RoundRobinRule的策略获取服务,如果获取服务失败则在指定时间内会进行重试,获取可用的服务。
			com.netflix.loadbalancer.WeightedResponseTimeRule  对RoundRobinRule的扩展,响应速度越快的实例选择权重越大,越容易被选择。
			com.netflix.loadbalancer.BestAvailableRule  会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务。
			com.netflix.loadbalancer.AvailabilityFilteringRule 先过滤掉故障实例,再选择并发较小的实例
			com.netflix.loadbalancer.ZoneAvoidanceRule   默认规则,复合判断server所在区域的性能和server的可用性选择服务器。
6.	Ribbon负载规则替换
	新建package,不能被@ComponentScanponentScan注解扫描到,在该包下新建MySelfRule规则类,主启动类上加注解@RibbonClient(name = "CLOUD-PAYMENT-SERVICE",configuration = MySelfRule.class)

在这里插入图片描述

7.Ribbon负载均衡算法
	轮询负载均衡算法原理:rest接口第几次请求%服务器集群总数量=实际调用服务器位置下标,每次服务重启动后
rest接口计数从1开始。
	源码:RoundRobinRule.class
    public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null) {
            log.warn("no load balancer");
            return null;
        } else {
            Server server = null;
            int count = 0;

            while(true) {
                if (server == null && count++ < 10) {
                    List<Server> reachableServers = lb.getReachableServers();
                    List<Server> allServers = lb.getAllServers();
                    int upCount = reachableServers.size();
                    int serverCount = allServers.size();
                    if (upCount != 0 && serverCount != 0) {
                        int nextServerIndex = this.incrementAndGetModulo(serverCount);
                        server = (Server)allServers.get(nextServerIndex);
                        if (server == null) {
                            Thread.yield();
                        } else {
                            if (server.isAlive() && server.isReadyToServe()) {
                                return server;
                            }

                            server = null;
                        }
                        continue;
                    }

                    log.warn("No up servers available from load balancer: " + lb);
                    return null;
                }

                if (count >= 10) {
                    log.warn("No available alive servers after 10 tries from load balancer: " + lb);
                }

                return server;
            }
        }
    }
	//轮询算法得到下标
    private int incrementAndGetModulo(int modulo) {
        int current;
        int next;
        do {
            current = this.nextServerCyclicCounter.get();
            next = (current + 1) % modulo;
        } while(!this.nextServerCyclicCounter.compareAndSet(current, next));

        return next;
    }
手写负载均衡算法
	80服务中的ApplicationContextConfig去掉注解@@LoadBalanced
	写LoadBalancer接口

在这里插入图片描述

实现类
@Component
public class MyLB implements LoadBalancer {

    private AtomicInteger atomicInteger = new AtomicInteger(0);

    public final int getAndIncrement(){
        int current ;
        int next ;
        do {
            current = this.atomicInteger.get() ;
            next = current >= 2147483647?0:current+1 ;
        }while (!this.atomicInteger.compareAndSet(current,next));
        System.out.println("第几次访问次数"+next);
        return next ;
    }
    @Override
    public ServiceInstance instances(List<ServiceInstance> serviceInstances) {
        int index = getAndIncrement() % serviceInstances.size() ;
        return serviceInstances.get(index);
    }
}
controller中

@Autowired
private LoadBalancer loadBalancer ;

@Autowired
private DiscoveryClient discoveryClient ;
@GetMapping("/payment/lb")
public String getPaymentLB(){
    List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
    if(instances == null || instances.size() <= 0){
        return null ;
    }
    ServiceInstance instance = loadBalancer.instances(instances);
    URI uri = instance.getUri();
    return restTemplate.getForObject(uri+"/payment/lb",String.class) ;
}

九·服务调用OpenFeign

1.概述
		Feign是一个声明式的WebService客户端。使用Feign能让编写Web Service客户端更加简单。
		它的使用方法是定义一个服务接口然后在上面添加注解。Feign也支持可拔插式的编码器和解码器。
		SpringCloud对Feign进行了封装,使其支持SpringMvc标准注解和HttpMessageConverters。Feign可以与
		Eureka和Ribbon组合使用以支持负载均衡。
2.Feign能干什么?
		前面在使用Ribbon+RestTemplate时,利用RestTemplate对http请求的封装处理,形成了一套模板化的调用
		方法。但是在实际开发中,由于对服务依赖的调用可能不止一处,往往一个接口会被多处调用,所以通常都会
		针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用。所以Feign在此基础上做了进一步的封装,
		由它来帮助我们定义和实现依赖服务接口的定义。在feign的实现下,我们只需要创建一个接口并使用注解的
		方式来配置它(以前是Dao接口上面标注mapper注解,现在是一个微服务接口上面标注一个Feign注解即可。)
		,即可完成对服务提供方的接口绑定,简化了使用SPring Cloud Ribbon时,自动封装服务调用客户端的开发量。

		Feign集成了Ribbon,利用Ribbon维护了服务列表信息,并且通过轮询的方式事项了客户端的负载。

3.OpenFeign使用步骤:
		新建模块cloud-consumer-feign-order80,改pom加openfeign的依赖,写yml,主启动类上加注解
		@EnableFeignClients
		创建业务类

在这里插入图片描述

	controller层

在这里插入图片描述

4.OpenFeign的超时控制
	OpenFeign的默认等待时间是1秒钟,超时就会报错。默认Feign客户端值等待1秒钟,但是服务端处理需要超过
	1秒钟,导致Feign客户端不想等待了,直接返回报错。
	可以在ynl文件中配置OpenFeign的超时时间
		#设置feign客户端超时时间(OpenFeign默认支持ribbon)
		ribbon:
		  #指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间
		  ReadTimeout: 5000
		  #指的是建立连接后从服务器读取到可用资源所用的时间
		  ConnectTimeout: 5000
5.OpenFeign的日志打印功能
		日志级别:
			NONE: 默认的,不显示任何日志
			BASIC:仅记录请求方法,URL,响应状态码及执行时间
			HEADERS:处理BASIC中定义的信息之外,还有请求和响应的头信息。
			FULL:除了HEADERS中定义的信息之外,还有请求和响应的正文和元数据。
		
		使用步骤:
			编写配置类

@Configuration
public class FeignConfig {

    @Bean
    Logger.Level feignLoggerLevel(){

        return Logger.Level.FULL ;
    }
}
yml文件中配置
logging:
  level:
    # feign日志以什么级别监控哪个接口
    com.xidian.springcloud.service.PaymentFeignService: debug

十· Hystrix断路器

1.概述
	分布式系统面临的问题:复杂的分布式系统结构中的应用程序有数十个的依赖关系,每个依赖关系在某些时候将
	不可避免地失败。
	服务雪崩:多个微服务至今调用的时候,假设微服务A调用微服务B和微服务C,服务B和C又调用其它的微服务,
	这就是所谓的“扇出”。如果扇出的链路上某个微服务的调用响应时间过长或者不可用,对服务A的调用就会占用越来
	越多的系统资源,进而引起系统崩溃,所谓的雪崩效应。
	对于高流量的应用来说,单一的后端依赖可能会导致所有服务器上的所有资源都在几秒钟内饱和。比失败更糟糕的是,	
	这些应用程序还可能导致服务之间的延迟增加,备份队列,线程和其他系统资源紧张,导致整个系统产生更多的级联
	故障。这些都表示需要对故障和延迟进行隔离和管理,以便单个依赖关系的失败,不能取消整个应用程序或系统。
2.Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统中,许多依赖不可避免的会调用失败,比如
超时,异常等,Hystrix能够保证在一个依赖出问题时,不会导致整体服务的失败,避免了级联故障,以提高分布式系统
的弹性。
断路器本身是一种开关装置,向调用方返回一个符合预期的,可处理的备选响应(FallBack),而不是长时间的等待
或者抛出调用方法无法处理的异常,这样就保证了服务调用方的线程不会被尝试将,不必要的占用,从而避免了故障
在分布式系统中的蔓延,乃至雪崩。

3.Hystrix重要概念:
	服务降级:fallback 
		哪些情况下会发生服务降级:
				程序运行异常
				超时
				服务熔断触发服务降级
				线程池/信号量打满也会导致服务降级
	服务熔断:达到最大服务访问后,直接拒绝访问,然后调用服务降级的方法并返回友好提示
	服务限流:秒杀高并发等操作,有序进行
4.hystrix服务降级案例
	构建子模块cloud-provider-hystrix-payment8001,改pom,写yml,主启动
	业务类,使用jmeter模拟高并发,发现响应速度变慢。
5.服务熔断
		是应对雪崩效应的一种微服务链路保护机制。当扇出链路的某个微服务出错不可用或者响应时间太长时,会进行
	服务降级,进而熔断该节点微服务的调用,快速返回错误的响应信息。
		当检测到该节点微服务调用响应正常后,恢复调用链路。
		在springcloud中,熔断机制通过Hystrix实现。Hystrix会监控微服务调用的状况,当失败的调用到一定阈值,缺省是5秒内20次调用失败,就会启动熔断机制。熔断机制的注解是@HystrixCommand
		熔断类型:
			熔断打开 请求不再进行调用当前服务,内部设置时钟一般为MTTR(平均故障处理时间),当打开时长达到
			所设时钟则进入半熔断状态。
			熔断关闭:熔断关闭不会对服务进行熔断
			熔断半开:部分请求根据规则调用当前服务,如果请求成功且符合规则则认为当前服务恢复正常,关闭熔断。
6.hystrix工作流程:
7.服务监控hystrixDashBoard
	除了隔离依赖服务的调用以外,Hystrix还提供了准实时的调用监控,它会持续地记录所有通过Hystrix发起的请求的执行信息

十一·服务网关gateway

1.概述简介
	SpringCloudGateway使用的Webflux中的reactor-netty响应式编程组件,底层使用了Netty的通讯框架。
2.三大核心概念:
	route路由:路由是构建网管的基本模块,它由ID,目标URI,一系列的断言和过滤器组成,如果断言为true则匹配该路由。
	predicate断言:开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数),如果请求和断言相匹配则进行路由。
	filter过滤:指的是spring框架中的GatawayFilter的实例,使用过滤器,可以在请求被路由之前或之后对请求进行修改。

十二·服务配置config
十三·服务驱动springcloudstream
十四·springcloudsleuth分布式请求链路跟踪

1.概述
		提供了一整台完整的服跟踪的解决方案,在分布式系统中提供跟踪解决方案并且兼容支持了zipkin

十五·SpringCloud Alibaba

1.Nacos
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值