SpringCloud

2024-11-23 12:04

服务注册中心

eureka

ap 高可用 分布式容错

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
eureka:
  instance:
    hostname: eureka7003.com #eureka服务端的实例名称
    instance-id: payment8001 
    prefer-ip-address: true
  client:
    register-with-eureka: false     #false表示不向注册中心注册自己。
    fetch-registry: false     #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
    service-url:
      #集群指向其它eureka
      #defaultZone: http://eureka7002.com:7002/eureka/
      #单机就是7001自己
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
    #server:
    #关闭自我保护机制,保证不可用服务被及时踢除
    #enable-self-preservation: false
    #eviction-interval-timer-in-ms: 2000

Ribbon 启用负载均衡

@EnableEurekaServer
@EnableDiscoveryClient

@LoadBalanced
public RestTemplate getTemp() {
    return new RestTemplate();
}

zookepper

cp 强一致 分布式容错

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.6.1</version>
</dependency>
spring:
  application:
    name: cloud-zoo-consumer-order
  cloud:
    zookeeper:
      connect-string: 192.168.10.58:2181
@SpringBootApplication
@EnableDiscoveryClient

consul

cp 强一致 分布式容错

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
spring:
  application:
    name: consul-payment-provider
  cloud:
    consul:
      host: 192.168.10.58
      port: 8500
      discovery:
        service-name: ${spring.application.name}
@SpringBootApplication
@EnableDiscoveryClient

服务调用负载均衡

Ribbon

Ribbon 切换 负载规则

1.在springboot 包扫描外层建立 配置

@Configuration
public class Myrule {
    @Bean
    public IRule initRule() {
        return new RandomRule();
    }
}

2.启动类给指定服务加载随机方法

@RibbonClient(name = "CLOUD-PAYMENT-SERVICE", configuration = Myrule.class)

OpenFeign

1.添加maven依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

2.启动类启用Feign

@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
@EnableFeignClients

3.新建接口 并注册Feign信息

@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")  //提供方服务名
public interface Service {
    @GetMapping(value = "/payment/get/{id}")
    Response<Payment> getPaymentById(@PathVariable("id") Long id);
}

4.提供方接口演示

@GetMapping(value = "/payment/get/{id}")
public Response<Payment> getPaymentById(@PathVariable("id") Long id) {
    Payment payment = paymentService.getPaymentById(id);

    if (payment != null) {
        return Result.success(200, "查询成功,serverPort:  " + serverPort, payment);
    } else {
        return Result.success(444, "没有对应记录,查询ID: " + id, null);
    }
}

OpenFeign超时设置

ribbon:
#指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间
  ReadTimeout: 5000
#指的是建立连接后从服务器读取到可用资源所用的时间
  ConnectTimeout: 5000

OpenFeign 日志打印功能

1.配置Openfeign 日志级别

@Configuration
public class FeignLogConfig {
    @Bean
    public Logger.Level getLevel() {
        return Logger.Level.FULL;
    }
}

2.yml 项目配置文件中,给指定Feign interface 配置日志级别

logging:
  level:
    ml.ytooo.feignservice.Service: debug

Hystrix 服务治理

  • 服务降级 出险异常时,返回友好提示,防止程序异常或者阻塞

  • 服务熔断 保险丝,当超出服务承载能力时,返回提示,拒绝请求

  • 服务限流 闸门,配置服务承载能力

Hystrix

服务降级

当服务处理超时或者运行异常时,启动备选方案返回给调用者预期结果

主方法

@EnableCircuitBreaker

需要降级处理的程序

其中

  • paymentInfo_TimeOut 为预计超时程序

  • paymentInfo_TimeOut_Handler 为超时备选方案

@HystrixCommand(fallbackMethod = "paymentInfo_TimeOut_Handler", commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")})
public String paymentInfo_TimeOut(Integer id) {

    int time = 5;
    try { 
        TimeUnit.MILLISECONDS.sleep(time * 1000); 
    } catch (InterruptedException e) { 
        e.printStackTrace(); 
    }
    return "线程池:  " + Thread.currentThread().getName() + " paymentInfo_TimeOut,id:  " + id + "\t" + "O(∩_∩)O哈哈~" + "  耗时(秒): " + time;
}

public String paymentInfo_TimeOut_Handler(Integer id) {
    return "线程池:  " + Thread.currentThread().getName() + " paymentInfo_TimeOut_Handler,id:  " + id + "\t" + "o(╥﹏╥)o";
}

全局降级处理

配置 defaultFallback 的走自己的降级方法,未配置的走 默认@DefaultProperties 指定的降级方法

@RestController
@Slf4j
@DefaultProperties(defaultFallback = "globle",commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1500")})
public class Controller {
    @HystrixCommand
    @GetMapping("/timeout/{id}")
    public String paymentInfo_TimeOut(@PathVariable("id") Integer id) {
        String result = feignService.paymentInfo_TimeOut(id);
        log.info("*****result: " + result);
        return result;
    }
    public String globle() {
        return "全局";
    }
}

通过OpenFeign 配置其提供方全局降级配置

1.新增feign调用接口的实现类 FeignServiceImpl,实现全部方法并做降级处理

@Service
public class FeignServiceImpl implements FeignService {
    @Override
    public String paymentInfo_OK(Integer id) {
        return "降级 -- paymentInfo_OK";
    }
    @Override
    public String paymentInfo_TimeOut(Integer id) {
        return "降级 -- paymentInfo_TimeOut";
    }
}

2.feign调用接口添加注解

@FeignClient(value = "CLOUD-PROVIDER-HYSTYRIX-PAYMENT",fallback = FeignServiceImpl.class)

服务熔断

  • 服务过载时,拒绝连接请求直接调用降级方法,返回异常

  • 请求下降时,慢慢恢复该服务访问,直达完全恢复

配置服务的熔断:

一下配置在 10s 内 ,10次请求有60% 失败,则熔断

HystrixProperty 配置位于 HystrixCommandProperties.class 类中

//=服务熔断
@HystrixCommand(fallbackMethod = "paymentCircuitBreaker_fallback",commandProperties = { //
        @HystrixProperty(name = "circuitBreaker.enabled",value = "true"),// 是否开启断路器
        @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"),// 请求次数
        @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "10000"), // 时间窗口期
        @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "60"),// 失败率达到多少百分百后跳闸
})
public String paymentCircuitBreaker(@PathVariable("id") Integer id)
{
    if(id < 0)
    {
        throw new RuntimeException("******id 不能负数");
    }
    String serialNumber = IdUtil.simpleUUID();

    return Thread.currentThread().getName()+"\t"+"调用成功,流水号: " + serialNumber;
}
public String paymentCircuitBreaker_fallback(@PathVariable("id") Integer id) //熔断后降级方法
{
    return "id 不能负数,请稍后再试,/(ㄒoㄒ)/~~   id: " +id;
}

效果: 当连续使用 -100 请求时, 返回 "id 不能负数", 使用100请求也返回 "id 不能负数" ,继续连续使用 100请求, 服务慢慢恢复

服务限流

使用 springcloud 阿里巴巴 sentinel 替代

Gateway 网关

Gateway

Gateway 项目配置

1.添加maven依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

2.移除以下依赖

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

3.yml 配置 (后续移步配置中心)

spring:
  application:
    name: cloud-gateaway-gateaway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
      routes:
        - id: payment_get
        #   uri: http://127.0.0.1:8001    #单一节点
          uri : lb://CLOUD-PAYMENT-SERVICE  /#启用 注册中心集群
          predicates:
            - Path=/payment/get/**

4.注册进 Eureka 注册中心

Gateway 动态路由

1.开启 网关发现注册中心服务

spring:
  application:
    name: cloud-gateaway-gateaway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true

Gateway 断言

1.断言是判断转发请求的条件

predicates:
 - After=2020-02-21T15:51:37.485+08:00[Asia/Shanghai]

2.After,Before,Between 配置转发生效时间

public static void main(String[] args) {
    ZonedDateTime now = ZonedDateTime.now();
    System.out.println(now);
}
// 2020-08-24T14:23:57.171+08:00[Asia/Shanghai]

3.Cookie 请求需携带指定Cookie才可以访问

predicates:
  - Cookie=name,ytooo   # key,value

4.Header ≈ Cookie

predicates:
  - Header=name,ytooo   # key,value

Gateway 过滤器

1.(默认过滤器) 官方提供一系列过滤器,供我们 在请求转发之前,对请求进行加工处理

filters:
  - AddRequestParamter=rowid,1024

2.自定义过滤器

自定义全局过滤器

@Component
@Slf4j
public class GatewayLogFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("=====================进入全局过滤器=====================");
        String name = exchange.getRequest().getQueryParams().getFirst("name");
        if (null == name) {
            exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }
}

SpringCloud Config 分布式配置中心, BUS 消息总线

分布式配置中心 SpringCloud Config

服务端配置

1.建立git仓库 https://github.com/sunshinelyz/cloud-config

2.引入 maven

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
</dependency>

3.启动类使配置生效

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

4.配置 配置文件

spring:
  application:
    name: cloud-config-center
  cloud:
    config:
      server:
        git:
          uri: https://github.com/sunshinelyz/cloud-config
          search-paths:
            - cloud-config
      label: master

5.请求访问 : http://127.0.0.1:3344/master/config-dev.yml

客户端配置

1.引入 maven

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-client</artifactId>
</dependency>

2.配置 配置文件

spring:
  application:
    name: cloud-condig-client
  cloud:
    config:
      label: master  # 分支
      name: config # 配置文件名称
      profile: dev   # 版本
      uri: http://127.0.0.1:3344 # config服务端地址

手动刷新客户端配置

不建议使用

消息总线 Bus

设计逻辑

使用消息总线触发服务端的 bus/refresh 端点,刷新所有客户端config配置

初始条件

客户端,服务端都需要实现Springcloud Config功能

服务端配置

1.引入maven依赖

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>

2.配置文件中配置消息队列信息

# 配置消息队列
rabbitmq:
  host: 192.168.10.58
  port: 5672
  username: ytooo
  password: ytooo

3.配置文件中配置BUS总线暴露信息

# 配置bus暴露端点
management:
  endpoints:
    web:
      exposure:
        include: "bus-refresh"

4.配置文件预览

server:
  port: 3344
spring:
  application:
    name: cloud-config-center
  cloud:
    config:
      server:
        git:
          uri: https://github.com/sunshinelyz/cloud-config
          search-paths:
            - cloud-config
      label: master
  # 配置消息队列
  rabbitmq:
    host: 192.168.10.58
    port: 5672
    username: ytooo
    password: ytooo
eureka:
  instance:
    prefer-ip-address: true
    instance-id: cloud-config-center-3344
  client:
    fetch-registry: true
    register-with-eureka: true
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/ #,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
# 配置bus暴露端点
management:
  endpoints:
    web:
      exposure:
        include: "bus-refresh"

客户端配置

1.引入maven依赖

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>

2.配置文件中配置消息队列信息

# 配置消息队列
rabbitmq:
  host: 192.168.10.58
  port: 5672
  username: ytooo
  password: ytooo

3.配置暴露端点

# 配置暴露端点
management:
  endpoints:
    web:
      exposure:
        include: "*"

4.调用配置类添加 @RefreshScope

@RestController
@RefreshScope
public class Controller {
    @Value("${config.info}")
    private String configInfo;
    @GetMapping(value = "/test")
    public String test() {
        return configInfo;
    }
}

刷新配置

POST 请求config服务端 http://127.0.0.1:3344/actuator/bus-refresh

刷新成功

定点通知

POST 请求config服务端 http://127.0.0.1:3344/actuator/bus-refresh/{destination}

destination: 注册中心服务名称:端口号

http://127.0.0.1:3344/actuator/bus-refresh/cloud-condig-client:3366

SpringCloud Stream 消息驱动

消息驱动,统一各种消息中间件中的差异,提供统一简单的调用方式,屏蔽消息中间件具体调用实现

SpringCloud Stream 消息提供者项目配置 (简单使用)

1.添加maven依赖

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>

2.配置文件添加Stream配置

spring:
  application:
    name: cloud-stream-provider
  cloud:
    stream:
      binders: # 在此处配置要绑定的rabbitmq的服务信息;
        defaultRabbit: # 表示定义的名称,用于于binding整合
          type: rabbit # 消息组件类型
          environment: # 设置rabbitmq的相关的环境配置
            spring:
              rabbitmq:
                host: 192.168.10.58
                port: 5672
                username: ytooo
                password: ytooo
      bindings: # 服务的整合处理
        output: # 这个名字是一个通道的名称
          destination: studyExchange # 表示要使用的Exchange名称定义
          content-type: application/json # 设置消息类型,本次为json,文本则设置“text/plain”
          binder: defaultRabbit # 设置要绑定的消息服务的具体设置

3.定义消息推送管道

@EnableBinding(Source.class) //定义消息推送管道
public class MsgProviderImpl implements MsgProvider {
}

4.定义消息发送管道

@Autowired
private MessageChannel out; //定义消息发送管道

5.build消息实体并发送

Message<String> message = MessageBuilder.withPayload(msg).build();
out.send(message);

6.消息接收方 yml 配置

spring:
  application:
    name: cloud-stream-rabbitmq-consumer
  cloud:
    stream:
      binders: # 在此处配置要绑定的rabbitmq的服务信息;
        defaultRabbit: # 表示定义的名称,用于于binding整合
          type: rabbit # 消息组件类型
          environment: # 设置rabbitmq的相关的环境配置
            spring:
              rabbitmq:
                host: 192.168.10.58
                port: 5672
                username: ytooo
                password: ytooo
      bindings: # 服务的整合处理
        input: # 这个名字是一个通道的名称                                   
          destination: studyExchange # 表示要使用的Exchange名称定义       需与提供方相同
          content-type: application/json # 设置消息类型,本次为json,文本则设置“text/plain”
          binder: defaultRabbit # 设置要绑定的消息服务的具体设置

7.接收方监听接口配置

@EnableBinding(Sink.class)
public class ReceiveMsgImpl implements ReceiveMsg {
}

8.接收方注解

@StreamListener(Sink.INPUT)
public void receive(Message<String> message) {
    System.out.println("客服端8803收到消息: " + message.getPayload());
}

SpringCloud Stream 分组消费 & 持久化

  • 对于不同的组中,消息是会被重复消费的(重复消费)

  • 同一个组内,服务之间存在竞争关系,只被消费一次(集群环境,避免重复消费)

分组配置文件配置

bindings: # 服务的整合处理
  input: # 这个名字是一个通道的名称
    destination: studyExchange # 表示要使用的Exchange名称定义
    content-type: application/json # 设置消息类型,本次为json,文本则设置“text/plain”
    binder: defaultRabbit # 设置要绑定的消息服务的具体设置
    group: ytooo           #  配置接收方所在组

group分组 持久化

当不配置分组时,重启服务,不会自动获取之前未消费的服务 反之,配置了分组,启动时,自动获取之前未消费的消息

Sleuth 分布式请求链路跟踪

在服务中加上依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>

修改application.yml配置文件,添加以下内容

spring:  
  zipkin:
    base-url: http://localhost:9411
  sleuth:
    sampler:
      probability: 1 # 采样率值介于0~1之间,1表示全部采集

SpringCloud的五大核心组件

SpringCloud的五大核心组件为Eureka、Fegin、Ribbon、Hystrix、Zull

SpringCloud说明

springcloud是什么?

  • Spring Cloud就是微服务系统架构的一站式解决方案,是各个微服务架构落地技术的集合体,俗称微服务全家桶

  • 在平时我们构建微服务的过程中需要做如服务发现注册、配置中心、负载均衡、断路器、数据监控等操作, 而Spring Cloud 为我们提供了一套简易的编程模型,使我们能在 Spring Boot 的基础上轻松地实现微服务项目的构建

什么是分布式?

  • 将各个组件分开部署,某个组件占一个服务器,互相独立,互相调用,可以将组件的功能发挥强大

  • 一个业务分拆多个子业务,部署在不同的服务器上(不同的服务器,运行不同的代码,为了同一个目的)

优点:

  1. 模块之间独立,各做各的事,便于扩展,复用性高

  2. 高吞吐量。某个任务需要一个机器运行20个小时,将该任务用10台机器的分布式跑 (将这个任务拆分成10个小任务),可能2个小时就跑完了

什么是集群?

  • 同一个业务,部署在多个服务器上(不同的服务器运行同样的代码,干同一件事)

优点:

  1. 通过多台计算机完成同一个工作,达到更高的效率。

  2. 两机或多机内容、工作过程等完全一样。如果一台死机,另一台可以起作用。

分布式与集群

  • 集群和分布式并不冲突,可以有分布式集群

我们可以把java,前端,测试看成是分布式,把都在做java的看成是集群

202411231220

什么是微服务?

  • 简单来说微服务就是很小的服务,小到一个服务只对应一个单一的功能,只做一件事

  • 将一个大的项目,按照需求(业务服务)模块拆解成一个个独立小模块(微小服务),然后独立部署,它们之间独立又相互调用

SpringBoot和SpringCloud有啥关系?

  • SpringBoot专注于快速、方便的开发单个微服务个体,SpringCloud关注全局的服务治理框架。

区别:SpringBoot可以离开SpringCloud独立使用开发项目,但是SpringCloud离不开SpringBoot,属于依赖的关系。

SpringCloud的组成:

img

五大组件运行流程

img

Eureka(注册中心)

SpringCloud提供了多种注册中心的支持,这其中就包括Eureka、ZooKeeper等,我们平时常用的也是这两种

回归正题,Eureka主要就是用来注册服务的,其中包括两部分:Eureka Client、Eureka Server

  • Eureka Client:包含服务提供者、服务消费者,主要负责服务注册、心跳续约与健康状况查询

  • Eureka Server:提供注册服务,各个节点启动后,都会在Eureka Server中注册,可用的节点信息可以在

  • Eureka Server中的服务注册表中找到(Eureka Server之间通过复制的方式来完成数据的同步)

触发了保护机制,Eureka将暂时把这些失效的服务保护起来,不让其过期,但这些服务也并不是永远不会过期。Eureka在启动完成后,每隔60秒会检查一次服务健康状态,如果这些被保护起来失效的服务过一段时间后(默认90秒)还是没有恢复,就会把这些服务剔除。如果在此期间服务恢复了并且实例心跳占比高于85%时,就会自动关闭自我保护机制。

应用启动后,Eureka Client会向Eureka Server发送心跳,一般默认周期为30秒,如果Eureka在多个心跳周期内(一般为90秒)没有接受到某个节点的心跳,Eureka就会进入自我保护机制。

zookeeper和Eureka的区别

  1. zookeeper保证cp原则(一致性)而Eureka保证的是ap原则(可用性)

  2. zookeeper在选举期间注册服务瘫痪不可用,而Eureka各个节点平等,只要一台就能保证服务可以,但查询到的数据不一定是最新的,可以很好的应对网络故障导致的部分节点失联

  3. zookeeper有header和follower角色(当header挂掉,会从剩下的follower里面选举一个header),Eureka各个节点平等

  4. zookeeper采用半数存活原则(避免脑裂),Eureka采用自我保护机制来解决分区问题

  5. kafka就是使用的zookeeper作为注册中心,理论上Eureka更适合作为注册中心

Feign

Feign是一个HTTP请求的轻量级客户端框架。通过 接口+注解 的方式发起HTTP请求的调用,而不是像Java中通过封装HTTP请求报文的方式直接调用。


Feign执行流程:

  • 在主程序上添加@EnableFeignClients注解开启对已经加@FeignClient注解的接口进行扫描加载

  • 调用接口中的方法时,基于JDK动态代理的方式,通过InvokeHandler调用处理器分发远程调用,生成具体的RequestTemplate

  • RequestTemplate生成Request请求,结合Ribbon实现服务调用负载均衡策略

Feign最核心的就是动态代理,同时整合了Ribbon和Hystrix,具备负载均衡、隔离、熔断和降级功能。

Ribbon

  • Ribbon是一个客户端的负载均衡器,他提供对大量的HTTP和TCP客户端的访问控制

  • Ribbon负载均衡策略:简单轮询、权重、随机、重试等多种策略

  1. 服务器端的负载均衡

    首先来看平时说的服务器负载均衡。

    • 主要有硬件方面,比如:F5、Array等;

    • 还有软件方面,比如:LVS、Nginx等。

  2. 客户端的负载均衡

    客户端的负载均衡是在spring-cloud后出现的,在spring-cloud中有ribbon组件来负责负载均衡。spring的负载均衡需要用到服务注册中心eruka。

    • 服务提供方:将自己注册到服务注册中心eruka

    • 服务消费方:从服务注册中心中获取服务列表,使用服务。

客户端的负载均衡流程如下:

  • 服务消费方通过ribbon先从服务注册中心获取服务列表,根据一定的负载均衡算法,分发请求到不同的服务提供方。

  • 可以理解成学生(服务消费方)在进入饭堂(服务注册中心)后根据自己的想法(负载均衡策略)选择合适的窗口(服务提供方)

总结

  • 服务器负载均衡需要多加一台负载均衡服务器来进行,流程是客户端->负载均衡服务器->应用服务器

  • 客户端负载均衡通过自己完成(先从服务注册中心获取服务列表),流程是客户端->应用服务器

Hystrix

img

  • Hystrix提供两个命令,分别是HystrixCommand、HystrixObservableCommand,通常是在Spring中通过注解和AOP来实现对象的构造

  • 熔断:简单来说,就是我们生活中的“保险丝”。如果熔断器打开,就会执行短路,直接进行降级;如果熔断器关闭,就会进入隔离逻辑。默认触发熔断器的条件为:最近一个时间窗口(默认为10秒),总请求次数大于等于circuitBreakerRequestVolume Threshold(默认为20次)并且异常请求比例大于circuitBreakerError ThresholdPercentage(默认为50%),此时熔断器触发

  • 隔离:一般分为两种:线程池隔离和信号量隔离。线程池隔离指的是每个服务对应一个线程池,线程池满了就会降级;信号量隔离是基于tomcat线程池来控制的,当线程达到某个百分比,走降级流程

  • 降级:作为Hystrix中兜底的策略,当出现业务异常、线程池已满、执行超时等情况,调用fallback方法返回一个错误提示。

Zull

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

主要功能:统一管理微服务请求、负载均衡、动态路由、权限控制、监控、静态资源处理等

  • 负载均衡:为每一种负载类型分配对应的容量,并弃用超出限定值的请求

  • 动态路由:根据需要动态的将路由请求到后台不同的集群

  • 权限控制:可以识别认证需要的信息和拒绝不满足条件的请求

  • 监控:追踪有意义的数据和统计结果

  • 静态资源处理:直接在Zull中处理静态资源,从而避免其转发到内部集群

网关 GateWay 的使用详解、路由、过滤器、跨域配置图片

👉这是一个或许对你有用的开源项目

国产 Star 破 10w+ 的开源项目,前端包括管理后台 + 微信小程序,后端支持单体和微服务架构。

功能涵盖 RBAC 权限、SaaS 多租户、数据权限、商城、支付、工作流、大屏报表、微信公众号等等功能:

  • Boot 地址:https://gitee.com/zhijiantianya/ruoyi-vue-pro

  • Cloud 地址:https://gitee.com/zhijiantianya/yudao-cloud

  • 视频教程:https://doc.iocoder.cn

相关文章
热点文章
精彩视频
Tags

站点地图 在线访客: 今日访问量: 昨日访问量: 总访问量: