SpringCloud

目录

什么是SpringCloud?

SpringCloud 的优缺点?

SpringCloud你用过哪些组件?

Spring Cloud 与 Dubbo 对比

断路器 Hystrix

谈谈服务雪崩效应

服务雪崩效应产生的原因

什么是服务熔断?什么是服务降级?

Hystrix 实现容错机制

隔离

负载平衡 Ribbon

Ribbon 负载平衡的意义什么?

如何开启客户端负载均衡?

Ribbon是什么?

Ribbon底层实现原理

Nginx与Ribbon的区别

ribbon 负载均衡策略

网关 Gateway

什么是网关?作用是什么?

路由转发

网关解决跨域:

自定义全局过滤:

限流-令牌桶算法

注册中心 Eureka

什么是Eureka?

Eureka如何实现高可用

Eureka的自我保护模式

Eureka和ZooKeeper的区别

CAP理论:

MyCat

MyCat 的原理?


什么是SpringCloud?

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

 

SpringCloud 的优缺点?

微服务的框架那么多比如:dubbo、Kubernetes,为什么就要使用 Spring Cloud 的呢?

优点:

  1. 产出于 Spring 大家族,Spring 在企业级开发框架中无人能敌,来头很大,可以保 证后续的更新、完善;
  2. 组件丰富,功能齐全。Spring Cloud 为微服务架构提供了非常完整的支持。例如、 配置管理、服务发现、断路器、微服务网关等;
  3. Spring Cloud 社区活跃度很高,教程很丰富,遇到问题很容易找到解决方案;
  4. 服务拆分粒度更细,耦合度比较低,有利于资源重复利用,有利于提高开发效率;
  5. 可以更精准的制定优化服务方案,提高系统的可维护性;
  6. 减轻团队的成本,可以并行开发,不用关注其他人怎么开发,先关注自己的开发;
  7. 微服务可以是跨平台的,可以用任何一种语言开发;
  8. 适于互联网时代,产品迭代周期更短;

缺点:

  1. 微服务过多,治理成本高,不利于维护系统;
  2. 分布式系统开发的成本高(容错,分布式事务等)对团队挑战大;

 

SpringCloud你用过哪些组件?

Eureka:服务注册与发现

GateWay:服务网关

Ribbon:客户端负载均衡

Feign:声明性的Web服务客户端

Hystrix:断路器

Config:分布式统一配置管理

Bus:消息总线

 

Spring Cloud 与 Dubbo 对比

相同点:Spring Cloud 与 Dubbo 都是实现微服务有效的工具。

不同点:

  1. Dubbo 只是实现了服务治理,而 Spring Cloud 子项目分别覆盖了微服务架构下的众多部件。
  2. 注册中心,dubbo 是zookeeper, springcloud是eureka,也可以是zookeeper。
  3. Dubbo 使用 RPC 通讯协议,Spring Cloud 使用 RESTful 完成通信,Dubbo 效率略高于 Spring Cloud。

小结

  • 微服务就是将项目的各个模块拆分为可独立运行、部署、测试的架构设计风格。
  • Spring 公司将其他公司中微服务架构常用的组件整合起来,并使用 SpringBoot 简化其开发、配置。称为 Spring Cloud。
  • Spring Cloud 与 Dubbo都是实现微服务有效的工具。Dubbo 性能更好,而 Spring Cloud 功能更全面。

断路器 Hystrix

Hystix 是 Netflix 开源的一个延迟和容错库,用于隔离访问远程服务、第三方库,防止出现级联失败(雪崩)。

  • 在分布式系统,我们一定会依赖各种服务,那么这些个服务一定会出现失败的情况,就会导致雪崩,Hystrix就是这样的一个工具,防雪崩利器,它具有服务降级,服务熔断,服务隔离,监控等一些防止雪崩的技术。
  • Hystrix有四种防雪崩方式:
    • 服务降级:接口调用失败就调用本地的方法返回一个空。
    • 服务熔断:接口调用失败就会进入提前定义好的一个熔断的方法,返回错误信息。
    • 服务隔离:隔离服务之间相互影响。
    • 服务监控:在服务发生调用时,会将每秒请求数、成功请求数等运行指标记录下来。

 

谈谈服务雪崩效应

雪崩效应是在大型互联网项目中,当某个服务发生宕机时,调用这个服务的其他服务也会发生宕机,大型项目的微服务之间的调用是互通的,这样就会将服务的不可用逐步扩大到各个其他服务中,从而使整个项目的服务宕机崩溃.发生雪崩效应的原因有以下几点。

  • 单个服务的代码存在bug。
  • 请求访问量激增导致服务发生崩溃(如大型商城的枪红包,秒杀功能)。
  • 服务器的硬件故障也会导致部分服务不可用。

 

服务雪崩效应产生的原因

因为Tomcat默认情况下只有一个线程池来维护客户端发送的所有的请求,这时候某一接口在某一时刻被大量访问就会占据tomcat线程池中的所有线程,其他请求处于等待状态,无法连接到服务接口。

 

什么是服务熔断?什么是服务降级?

  • 服务降级:当客户端请求服务器端的时候,如果请求异常,防止客户端一直等待,进入提前定义好的降级方法,返回一个错误提示给客户端。
  • 服务熔断是在服务降级的基础上更直接的一种保护方式,当在一个时间范围内的请求失败数量达到设定值或当前的请求错误率达到设定的错误率阈值时开启断路,之后的请求直接走fallback方法,在设定时间后尝试恢复。
  • 服务隔离就是Hystrix为隔离的服务开启一个独立的线程池,这样在高并发的情况下不会影响其他服务。服务隔离有线程池和信号量两种实现方式,一般使用线程池方式。

 服务降级,分为服务消费端降级和服务提供端降级

服务消费端和提供端区分:

A服务器有一个接口:http://8080/goods/findOne 用于查询商品。

B服务器要远程调用这个微服务的端口,那么就需要用Feign接口去调用

A服务器就叫服务提供端  B服务器就叫服务消费端

服务提供端降级:

在服务启动类加上注解@EnableCircuitBreaker,启动Hystrix服务


@RestController
public class TestController {

   @Autowired
   private TestService testService ;

    /**
     * 使用Hystrix熔断器,当调用findUserById失败后,调用forbackFindUserById方法
     * @param id
     * @return
     */
    @HystrixCommand(fallbackMethod = "forbackFindUserById")
    @RequestMapping(value = "/find/user/{id}",method = RequestMethod.GET)
    public User findUserById(@PathVariable("id") Long id){
        User user = testService .findUserById(id);
        int a = 4/0;
        return user;
    }

    //当调用发生异常时调用该方法
    public User forbackFindUserById(Long id){
        User user = new User();
        user.setId(-400L);
        user.setUsername("异常调用");
        return  user;
    }
}

这样就完成了服务提供端降级

服务消费端降级:

在服务消费端我们是用Feign接口去请求服务的,而Feign组件已经集成了Hystrix组件

消费端接口:什么都不用做,全部交给Feign去做

@Autowired
private GoodsFeignClient goodsFeignClient;

@GetMapping("/goods/{id}")
public Goods findGoodsById(@PathVariable("id") int id){

    Goods goods = goodsFeignClient.findGoodsById(id);
    return goods;
}

Feign接口:在FeignClient注解中配置降级方法,当方法调用出问题,就会去找降级方法。

@FeignClient(value = "FEIGN-PROVIDER",fallback = GoodsFeignClientFallback.class)
public interface GoodsFeignClient {

    @GetMapping("/goods/findOne/{id}")
    Goods findGoodsById(@PathVariable("id") int id);
}
/**
 * Feign 客户端的降级处理类
 * 1. 定义类 实现 Feign 客户端接口
 * 2. 使用@Component注解将该类的Bean加入SpringIOC容器
 */
@Component
public class GoodsFeignClientFallback implements GoodsFeignClient {
    @Override
    public Goods findGoodsById(int id) {
        Goods goods = new Goods();
        goods.setTitle("又被降级了~~~");
        return goods;
    }
}

服务熔断:

在服务提供方配置:当在5秒内失败20次,就会打开断路器,后面的请求直接走降级方法,在一定时间后自动开始尝试看请求是否可以正常,知道请求正常,关闭熔断器。

    @HystrixCommand(fallbackMethod = "findOne_fallback",commandProperties = {
            //设置Hystrix的超时时间,默认1s
            @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value = "3000"),
            //监控时间 默认5秒
            @HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds",value = "5000"),
            //失败次数。默认20次
            @HystrixProperty(name="circuitBreaker.requestVolumeThreshold",value = "20"),
            //失败率 默认50%
            @HystrixProperty(name="circuitBreaker.errorThresholdPercentage",value = "50")

    })

Hystrix 实现容错机制

Hystrix 是一个实现了超时机制和断路模式的工具类库。 Hystrix 是由 Netflix 开源的一个延迟和容错库,用于隔离访问远程系统、服务或者第三方库,防止级联失败,从而提升系统的可用性与容错性。Hystrix 主要通过以下几点实现延迟和容错。

1 包裹请求:使用 HystrixCommand 包裹对依赖的调用逻辑,每个命令在独立线程中执行。这使用了设计模式中的“命令模式”。

2 跳闸机制:当某服务的错误率超过一定的阈值时,Hystrix 可以自动或手动跳闸,停止请求该服务一段时间。

3 资源隔离:Hystrix 为每个依赖都维护了一个小型的线程池(或者信号量)。如果该线程池已满,发往该依赖的请求就被立即拒绝,而不是排队等待,从而加速失败判定。

4 监控:Hystrix 可以近乎实时地监控运行指标和配置的变化,例如成功、失败、超时、以及被拒绝的请求等。

5 回退机制:当请求失败、超时、被拒绝,或当断路器打开时,执行回退逻辑。回退逻辑由开发人员自行提供,例如返回一个缺省值。

6 自我修复:断路器打开一段时间后,会自动进入“半开”状态。

 

隔离

当部署完一个服务后,这个服务会向外界开放多个接口,比如一个商城系统可能有订单查询接口, 个人中心接口,付款接口,商品查询接口。当服务部署好之后,tomcat默认开启一个线程池,这个线程池中有200个线程供使用。也就是说这四个接口共享一个线程池。当访问量小的时候系统没有问题,但是遇到比如一类爆款商品降价,导致了商品查询接口访问量激增。商品查询接口占用了线程池中大量的线程,导致其他三个接口抢不到线程从而没有线程可用,进而导致自身功能不可用。

线程池隔离

线程池隔离的思想是: 把tomcat中先一个线程池分成两个线程池. 比如tomcat线程池中初始有200个线程, 分成两个线程池A , B后, A线程池有50个线程可以用,  B线程池有150个线程可以用. 将访问量较大的接口单独配置给一个线程池,  其他接口使用另一个线程池。

然后, 将访问量暴增的接口访问交给A线程池,其他接口的访问交给B线程池。A,B两个线程池是相互隔离的, 互不影响。这时候, 如果商品查询接口访问量激增,被挤爆的线程池也只是A线程池, A,B线程池互不影响, 所以其他接口如: 个人中心接口, 付款接口, 订单查询接口依然可用。

线程池隔离主要针对客户端用户对服务的访问. 线程池隔离起到分流的作用。

信号量隔离

可以把信号量理解成一个计数器 , 对这个计数器规定一个计数上限, 代表一个接口被访问的最大量。

假定设置付款接口的信号量最大值为10,(这个接口最多占用线程池中10个线程) 初始值为0。 每调用一次接口信号量加一,接口处理完后信号量减一。当信号量值达到最大时,(10时) ,对后续的调用请求拒接处理。

信号量隔离主要是针对各个服务内部的调用处理, 起到限流的作用。

负载平衡 Ribbon

Ribbon 负载平衡的意义什么?

  • 简单来说: 先将集群,集群就是把一个的事情交给多个人去做,假如要做1000个产品给一个人做要10天,我叫10个人做就是一天,这就是集群,负载均衡的话就是用来控制集群,他把做的最多的人让他慢慢做休息会,把做的最少的人让他加量让他做多点。
  • 在计算中,负载平衡可以改善跨计算机,计算机集群,网络链接,中央处理单元或磁盘驱动器等多种计算资源的工作负载分布。负载平衡旨在优化资源使用,最大化吞吐量,最小化响应时间并避免任何单一资源的过载。使用多个组件进行负载平衡而不是单个组件可能会通过冗余来提高可靠性和可用性。负载平衡通常涉及专用软件或硬件,例如多层交换机或域名系统服务器进程。

如何开启客户端负载均衡?

在服务消费端启动类加上@LoadBalanced(name ="eureka-provider",configuration = MyRule.class)

写一个均衡策略类:默认是轮询,改成随机。

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyRule {
    @Bean
    public IRule rule(){
        return new RandomRule();
    }
}

这样服务消费端就可以随机去找提供端服务器了,减轻了单服务器的压力。

策略:RoundRobinRule  简单轮询

           RandomRule 随机

           WeightedResponseTimeRule  为每个服务器设置一个权重值,然后随机

           BestAvailableRule  自动选择并发较低的服务器

Ribbon是什么?

  • Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法
  • Ribbon客户端组件提供一系列完善的配置项,如连接超时,重试等。简单的说,就是在配置文件中列出后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随即连接等)去连接这些机器。我们也很容易使用Ribbon实现自定义的负载均衡算法。(有点类似Nginx)

Ribbon底层实现原理

Ribbon使用discoveryClient从注册中心读取目标服务信息,对同一接口请求进行计数,使用%取余算法获取目标服务集群索引,返回获取到的目标服务信息。

 

Nginx与Ribbon的区别

Nginx是反向代理同时可以实现负载均衡,nginx拦截客户端请求采用负载均衡策略根据upstream配置进行转发,相当于请求通过nginx服务器进行转发。Ribbon是客户端负载均衡,从注册中心读取目标服务器信息,然后客户端采用轮询策略对服务直接访问,全程在客户端操作。

 

ribbon 负载均衡策略

  1. RoundRobinRule 简单轮询服务列表来选择服务器。它是Ribbon默认的负载均衡规则。
  2. AvailabilityFilteringRule 对以下两种服务器进行忽略:

(1)在默认情况下,这台服务器如果3次连接失败,这台服务器就会被设置为“短路”状态。短路状态将持续30秒,如果再次连接失败,短路的持续时间就会几何级地增加。注意:可以通过修改配置loadbalancer.<clientName>.connectionFailureCountThreshold来修改连接失败多少次之后被设置为短路状态。默认是3次。

(2)并发数过高的服务器。如果一个服务器的并发连接数过高,配置了AvailabilityFilteringRule规则的客户端也会将其忽略。并发连接数的上线,可以由客户端的<clientName>.<clientConfigNameSpace>.ActiveConnectionsLimit属性进行配置。

  1. WeightedResponseTimeRule 为每一个服务器赋予一个权重值。服务器响应时间越长,这个服务器的权重就越小。
  2. RandomRule 随机选择一个可用的服务器。
  3. BestAvailableRule 忽略哪些短路的服务器,并选择并发数较低的服务器。

网关 Gateway

什么是网关?作用是什么?

网关相当于一个网络服务架构的入口,所有网络请求必须通过网关转发到具体的服务。

统一管理微服务请求,权限控制、负载均衡、路由转发、监控、安全控制黑名单和白名单等。

Spring Cloud Gateway旨在为微服务架构提供简单、有效和统一的API路由管理方式,Spring Cloud Gateway作为Spring Cloud生态系统中的网关,目标是替代Netflix Zuul,网关作为流量的,在微服务系统中有着非常作用,网关常见的功能有路由转发、权限校验、限流控制等作用。(路由和过滤)。

路由转发

spring:
  application:
    name: spring-cloud-gateway-sample
  cloud:
    gateway:
      routes:
        - id: blog
          uri: http://blog.yuqiyu.com
          predicates:
            # 匹配路径转发
            - Path=/api-boot-datasource-switch.html
# 端口号
server:
  port: 8080

先来解释下route的组成部分:

  • id:路由的ID
  • uri:匹配路由的转发地址
  • predicates:配置该路由的断言,通过PredicateDefinition类进行接收配置。

在上面的配置中,当访问http://localhost:8080/api-boot-datasource-switch.html时就会被自动转发到http://blog.yuqiyu.com/api-boot-datasource-switch.html,这里要注意完全匹配Path的值时才会进行路由转发。
 

网关解决跨域:

在application.yml里配置:

cloud:
    gateway:
      globalcors:
        cors-configurations:

          '[/**]': # 匹配所有请求
            allowedOrigins: "*" #跨域处理 允许所有的域

            allowedMethods: # 支持的方法
            - GET
            - POST
            - PUT
            - DELETE

 

自定义全局过滤:

定义接口实现GlobalFilter, Ordered,通过

@Component
public class MyFilter implements GlobalFilter, Ordered{

   @Override
   public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
       return chain.filter(exchange);//放行
   }

    //过滤器排序
    //@return 数值越小 越先执行
   @Override
   public int getOrder() {
       return 0;
   }
}

限流-令牌桶算法

spring:
  cloud:
    gateway:
      routes:
      - id: requestratelimiter_route
        uri: lb://pigx-upms
        order: 10000
        predicates:
        - Path=/admin/**
        filters:
        - name: RequestRateLimiter
          args:
            redis-rate-limiter.replenishRate: 1  # 令牌桶的容积
            redis-rate-limiter.burstCapacity: 3  # 流速 每秒
            key-resolver: "#{@remoteAddrKeyResolver}" #SPEL表达式去的对应的bean
        - StripPrefix=1

注册中心 Eureka

什么是Eureka?

  • Eureka:就是服务注册中心(可以是一个集群),对外暴露自己的地址
  • 提供者:启动后向 Eureka 注册自己信息(地址,提供什么服务)
  • 消费者:向 Eureka 订阅服务,Eureka 会将对应服务的所有提供者地址列表发送给消费者,并且定期更新
  • 心跳(续约):提供者定期通过 http 方式向 Eureka 刷新自己的状态

 

Eureka如何实现高可用

  1. 准备多个Eureka Server 进行配置;
  2. 把SpringCloud服务分别相互注册;
  3. Eureka Client 分别注册到这两个 Eureka Server中,按照Eureka的顺序来访问。

 

Eureka的自我保护模式

默认情况下,如果Eureka Service在一定时间内没有接收到某个微服务的心跳,Eureka Service会进入自我保护模式,在该模式下Eureka Service会保护服务注册表中的信息,不在删除注册表中的数据,当网络故障恢复后,Eureka Servic 节点会自动退出自我保护模式。

 

Eureka和ZooKeeper的区别

  1. ZooKeeper中的节点服务挂了就要选举。 在选举期间注册服务瘫痪,虽然服务最终会恢复,但是选举期间不可用的,选举就是该微服务做了集群,必须有一台主节点其他的都是从节点。
  2. Eureka各个节点是平等关系,服务器挂了没关系,只要有一台Eureka就可以保证服务可用,数据都是最新的。 如果查询到的数据并不是最新的,就是因为Eureka的自我保护模式导致的。
  3. Eureka本质上是一个工程,而ZooKeeper只是一个进程。
  4. Eureka可以很好的应对因网络故障导致部分节点失去联系的情况,而不会像ZooKeeper 一样使得整个注册系统瘫痪一段时间。
  5. ZooKeeper保证的是CP,Eureka保证的是AP

CAP理论:

C:一致性>Consistency;

一致性就是说,我们读写数据必须是一摸一样的。

比如一条数据,分别存在两个服务器中,server1和server2。
我们此时将数据a通过server1修改为数据b。此时如果我们访问server1访问的应该是b。
当我们访问server2的时候,如果返回的还是未修改的a,那么则不符合一致性,如果返回的是b,则符合数据的一致性。

A:可用性>Availability;

只要我对服务器,发送请求,服务器必须对我进行相应,保证服务器一直是可用的。

P:分区容错性>Partition tolerance;

一般来说,分布式系统是分布在多个位置的。比如我们的一台服务器在北京,一台在上海。可能由于天气等原因的影响。造成了两条服务器直接不能互相通信,数据不能进行同步。这就是分区容错。我们认为,分区容错是不可避免的。也就是说 P 是必然存在的。

MyCat

MyCat 是一个开源的分布式数据库系统,是一个实现了 MySQL 协议的服务器。但是因为数据库一般都有自己的数据库引擎,而 Mycat 并没有属于自己的独有数据库引擎,所有严格意义上说并不能算是一个完整的数据库系统,只能说是一个在应用和数据库之间起桥梁作用的中间件。

 

MyCat 的原理?

MyCat 技术原理中最重要的一个动词是“拦截”,它拦截了用户发送过来的 SQL 语句,首先 对 SQL 语句做了一些特定的分析:如分片分析、路由分析、读写分离分析、缓存分析等,然 后将此 SQL 发往后端的真实数据库,并将返回的结果做适当的处理,最终再返回给用户。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值