SpringCloud

一,概述

1.什么是微服务

要了解什么是微服务首先要了解什么是面向服务(SOA)

  面向服务就是将应用程序的不同功能单元(称之为服务)进行拆分,并将这些服务通过接口等联系起来(各服务之间松耦合),想要使用哪个功能,直接进行调用,不会将功能与整个项目紧紧绑定

微服务不是一种技术而是一种思想,是SOA架构下的产物,只要系统的架构符合这种思想,就可以说它是微服务 ,它是聚焦在单一的职责和业务功能,具有独立的进程,能够单独运行的服务,并且与外部服务是通过HTTP进行交互通信的服务

2.微服务与单体架构区别

(1)单体架构所有的模块全都耦合在一块,代码量大,维护困难。

(2)单体架构所有的模块都共用一个数据库,存储方式比较单一。

(3)单体架构所有的模块开发所使用的技术一样。微服务各功能模块可以使用 不同的技术

3.微服务架构的优点

  1. 易于开发和维护,一个微服务只关注一个业务,业务清晰,代码量少

  2. 单个微服务代码量少,启动快

  3. 局部修改容易部署

  4. 技术不受限制

二,SpringCloud介绍

    springcloud是一个完整的微服务架构,提供了所有功能,整个开发项目中所需要的架构功能微服务都有,也就是说整个springcloud就是一个完整的项目,这个架构已经搭建完毕了,用到了直接获取即可,只需要往架构中注入自己的业务代码就可以。

 springcloud是基于springboot 开发的微服务框架,是目前比较完整的微服务解决方案框架,它的内容包括:服务注册(eureka),服务调用(feign) ,负载均衡(Ribbon) ,熔断器(Hystrix)等

 组件介绍

  • 注册中心:Netflix Eureka;

  • 负载均衡:Netflix Ribbon(2020 版本前)、Spring Cloud Loadbalancer(2020 版本后);

  • 熔断器:Netflix Hystrix(2020 版本前)、Resilience4j(2020 版本后);

  • 声明式服务调用组件:Feign(最初属 Netflix 公司,后来移交给 OpenFeign 组织);

  • 网关:Netflix Zuul(2020 版本前)、Spring Cloud Gateway(2020 版本后);

  • 配置中心:Spring Cloud Config;

1.注册中心-Eureka

Spring Cloud Eureka 是 Spring Cloud Netflix 微服务套件的一部分,基于 Netflix Eureka 做了二次封装,主要负责实现微服务架构中的服务治理功能。

Spring Cloud Eureka 是一个基于 REST 的服务,并且提供了基于 Java 的客户端组件,能够非常方便地将服务注册到 Spring Cloud Eureka 中进行统一管理。

CAP原则

CAP 原则又称 CAP 定理,指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可得兼。

Eureka是基于AP原则建立的

为了保证高可用性,data1和data2都有在有限时间内返回。同样由于网络的不可靠,在有限时间内,data2有可能还没收到data1发来的数据更新消息,这时候返回给客户端的可能是旧的数据,和访问data1的数据是不一致的,也就是违法了C。

也就是说,在保证A和P的情况下,是无法同时保证C的。

 2.负载均衡-Ribbon

Ribbon 又叫 负载均衡器

负载均衡是我们处理高并发、缓解网络压力和进行服务器扩容的重要手段之一,但是一般情况下我们所说的负载均衡通常都是指服务器端负载均衡

目前主流的负载方案分为以下两种:

  • 集中式负载均衡,在消费者和服务提供方中间使用独立的代理方式进行负载,有硬件的(比如 F5),也有软件的(比如 Nginx)。

  • 客户端自己做负载均衡,根据自己的请求情况做负载,Ribbon 就属于客户端自己做负载。

Ribbon常用负载均衡策略

 主要使用轮询策略,轮询权重策略

配置负载均衡策略有很多种方式

①文件配置负载均衡策略

在yml文件中设置

#设置负载均衡策略 
eureka-client-user-service.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule 

②代码配置负载均衡策略

在代码中创建一个类

@Configuration
public class MyRule {
    @Bean
    public IRule iRule() {
        return new WeightedResponseTimeRule();
    }
}

并在springboot启动类加注解

@RibbonClient(name = "eureka-client-user-service", configuration = MyRule.class)

其中:name为服务提供者的名称,configuration为定义的策略类

③自定义负载均衡策略

通过实现 IRule 接口可以自定义负载策略,主要的选择服务逻辑在 choose 方法中。

超时配置

在进行服务调用的时候,如果网络情况不好,可能会出现超时问题,这里我们需要配置请求超时时间

调用服务连接数和并发处理配置一样也需要配置

ribbon.http.client.enabled=true
# 请求连接的超时时间(单位:毫秒)
ribbon.ConnectTimeout=2000
# 请求处理的超时时间(单位:毫秒)
ribbon.ReadTimeout=5000
# 并发最大连接数
ribbon.MaxTotalConnections=500
# 每个主机最大连接数
ribbon.MaxConnectionsPerHost=500

也可以为每个Ribbon客户端设置不同的超时时间, 通过服务名称进行指定:如下:

eureka-client-user-service 是服务提供者服务名称

eureka-client-user-service.ribbon.ConnectTimeout=2000
eureka-client-user-service.ribbon.ReadTimeout=5000

饥饿加载

在进行服务调用的时候,如果网络情况不好,超时的问题也是一样,Ribbon 的客户端是在第一次请求的时候初始化的,如果超时时间比较短的话,初始化 Client 的时间再加上请求接口的时间,就会导致第一次请求超时。除了采取更改超时时间以外,Spring Cloud 也提供了第二个种方式:饥饿加载,配置如下:

#开启 Ribbon 的饥饿加载模式
ribbon.eager-load.enabled=true
#指定需要饥饿加载的服务名,也就是你需要调用的服务,若有多个则用逗号隔开
ribbon.eager-load.clients=eureka-client-user-service 

3.声明式服务调用组件-Feign

Feign 是一个声明式的 REST 客户端,它能让 REST 调用更加简单。Feign 供了 HTTP 请求的模板,通过编写简单的接口和插入注解,就可以定义好 HTTP 请求的参数、格式、地址等信息。而 Feign 则会完全代理 HTTP 请求,我们只需要像调用方法一样调用它就可以完成服务请求及相关处理。

Spring Cloud对Feign进行了封装,Feign可以与Eureka、Ribbon和Hystrix组合使用,引入Feign依赖的同时这两个组件也会被一同引入。

Ribbon:利用负载均衡策略选定目标机器

Hystrix:根据熔断器的开启状态,决定是否发起此次调用。

 feign使用分为get请求和post请求

Get请求

1.在服务提供者项目中,定义提供数据的控制器方法

@RestController
public class UserController {
    @Value("${server.port}")
    private String port;
    @GetMapping("/user/hello")
    public String hello(String userName) {
        String info = "端口号:"+port+" 请求参数userName="+userName;
        return info;
    }
}

 2.在消费者项目,添加依赖

<!-- feign组件所需依赖-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>  

3.在消费者项目的启动类添加@EnableFeignClients 注解,该注解表示启动feign组件服务  

4.在消费者项目定义访问服务提供者项目的接口

@Component
@FeignClient(value = "eureka-client-user-service")//服务提供者服务名称
public interface FeignService {

    @GetMapping("/user/hello")
    String hello(@RequestParam("userName") String userName);
}

@FeignClient(value = "eureka-client-user-service") :连接服务提供者项目的服务,value的值是服务提供者项目的服务名称

@GetMapping("/user/hello") get提交方式注解 ,要和服务提供者项目的服务的控制器方法的提交注解一致,/user/hello 是服务提供者项目的服务的控制器方法的地址

@RequestParam("userName") 请求参数,该注解不能省略,"userName" 是服务提供者项目的服务的控制器方法的参数名称

5 在消费者项目中定义访问接口的控制器方法

@RestController
@RequestMapping("/feign")
public class FeignController {

    @Autowired
    FeignService feignService;

    @GetMapping("/hello")
    public String callHello(String userName) {

        return feignService.hello(userName);
    }
}

 Post请求:

与get请求大体相同,只是在接口中使用@RequestBody注解来描述方法参数

日志配置

有时候我们遇到 Bug,比如接口调用失败、参数没收到等问题,或者想看看调用性能,就需要配置 Feign 的日志了,以此让 Feign 把请求信息输出来。步骤如下:

1 定义一个日志配置类,注意Logger的包不要导错。

日志级别有4个:

  • NONE:不输出日志。

  • BASIC:只输出请求方法的 URL 和响应的状态码以及接口执行的时间。

  • HEADERS:将 BASIC 信息和请求头信息输出。

  • FULL:输出完整的请求信息。

配置步骤:

1.首先创建一个配置类

@Configuration
public class FeignConfiguration {
    /**
     * 日志级别
     *
     * @return
     */
    @Bean
    Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }
}

 2. 配置类建好后,我们需要在 启动类@FeignClient 注解中指定使用的配置类

@Component
@FeignClient(value = "eureka-client-user-service",configuration = FeignConfiguration.class)//FeignConfiguration是日志配置类
public interface FeignService {

    @PostMapping("/user/hello")
    String hello( UserInfo userInfo);
}

3.在yml配置文件中执行 Client 的日志级别才能正常输出日志,格式是“logging.level. 类地址=级别”

# 日志等级
logging.level.com.hqyj.service.FeignService=DEBUG  

4.熔断器- Hystrix

首先了解

雪崩效应: 一个微服务中可能会调用多个微服务接口才能完成, 形成复杂的链式调用. 当其中一个服务接口出现异常访问, 会导致整个线程堵塞. 越来越多的用户请求就会有越来越多的线程堵塞,资源无法释放, 导致当前微服务的服务器资源耗尽, 当前服务挂掉, 从而引起雪崩效应。

Hystrix 是 Netflix 针对微服务分布式系统采用的熔断保护中间件,相当于电路中的保险丝。

Hystrix 是一个库,通过添加延迟容忍和容错逻辑,帮助控制这些分布式服务之间的交互。Hystrix 通过隔离服务之间的访问点、停止级联失败和提供回退选项来实现这一点,所有这些都可以提高系统的整体弹性。

在微服务架构下,很多服务都相互依赖,如果不能对依赖的服务进行隔离,那么服务本身也有可能发生故障,Hystrix 通过 HystrixCommand 对调用进行隔离,这样可以阻止故障的连锁效应,能够让接口调用快速失败并迅速恢复正常,或者回退并降级。

熔断器原理

熔断器有三种状态, 关闭是说明请求访问正常

打开: 所有请求都被降级

关闭: 正常访问所有请求

半开状态: 不是长久状态, 熔断器打开后, 过了默认的时间会变成半开状态, 下一次被访问后, 如果访问成功则开关关闭, 如果失败则开关打开, 进行下一轮循环。

 熔断触发时机

  • 访问超时

  • 访问服务器抛异常

  • 访问服务器挂掉了

  • 错误次数达到了阈值

Feign整合Hystrix实现容错处理

1 消费者项目中 添加依赖

<!--熔断组件所需依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>

2 消费者项目中 配置yml文件,开启熔断组件

#开启熔断器组件
feign.hystrix.enabled=true  

3 创建处理熔断的熔断类FeignServiceFallBack,并加上注解@Service 或者@Component,该类要实现自定义的FeignService接口。熔断的业务逻辑在实现方法里写,这里就写个简单的逻辑,返回一个‘’服务停用‘提示

@Service
public class FeignServiceFallBack implements  FeignService {
    @Override
    public String hello(UserInfo userInfo) {
        return "服务停用!";
    }
    
}  

4 在自定义的FeignService的接口上的@FeignClient 注解里添加处理这个接口的熔断类:fallback = FeignServiceFallBack.class

@Component
@FeignClient(value = "eureka-client-user-service",fallback = FeignServiceFallBack.class)//服务提供者服务名称
public interface FeignService {

    @PostMapping("/user/hello")
    String hello( UserInfo userInfo);

}

5 控制器代码不变  

@RestController
@RequestMapping("/feign")
public class FeignController {

    @Autowired
    FeignService feignService;

    @PostMapping("/hello")
    public String callHello(UserInfo userInfo) {
        return feignService.hello(userInfo);
    }
}

Hystrix 降级处理

在微服务开发中,由于每个服务器的环境不一样,例如:网络延迟,可能会导致访问每个服务请求时间不同,有的服务处理请求时间快,有的服务处理请求时间慢,为了让用户有更好的服务体验,我们需要让处理请求慢的服务,把请求交给处理请求快的服务来做。

Feign降级超时配置

完成步骤如下:

1  在服务提供者,定义一个睡眠程序,模拟请求是 3秒后处理,代码如下


@GetMapping("/hello")
    public String hello(String userName) {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "端口:" + port + "userName:" + userName;
    }


2 在服务消费者的application.properties文件中配置如下信息: 


feign.hystrix.enabled=true
# 请求连接的超时时间(单位:毫秒),超时时间要大于程序执行时间,否则会被ribbon先熔断
ribbon.ConnectTimeout=5000
# 请求处理的超时时间(单位:毫秒)
ribbon.ReadTimeout=5000

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=4000   


或者

feign.hystrix.enabled=true
# 请求连接的超时时间(单位:毫秒),超时时间要大于程序执行时间,否则会被ribbon先熔断
feign.client.config.default.connect-timeout=5000
feign.client.config.default.read-timeout=5000
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=4000

feign和ribbon的配置二选一即可,因为这两个配置都相当于是ribbon的配置,不同点在于feign的配置在ribbon的基础上做了扩展,可以支持配置服务级别的超时时间。

如果没有设置过feign超时,也就是等于默认值的时候,就会读取ribbon的配置,使用ribbon的超时时间和重试设置。否则使用feign自身的设置。两者是二选一的,且feign优先。

hystrix配置的超时时间理论上应该要比 feign和ribbon的要大,因为feign和ribbon可以配置失败重试。当然最终的超时时间是以feign(或ribbon)和hystrix中最小时间为准。所以在设置hystrix超时时间时,如果设置的超时时间比feign的要小,则可以生效。如果设置的时间比feign的要大,则会以feign的超时时间为准。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cqq00

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值