springCloud

Spring Cloud微服务

一 微服务架构

  • 拆分粒度更微小、服务更独立、服务之间往往通过Restfu轻量级通信
  • 微服务架构强调的⼀个重点是业务需要彻底的组件化和服务化

二 Spring Cloud 综述

  • Spring Cloud其实是一套规范,是一套用于构建微服务架构的规范

  • Spring Cloud 解决什么问题:

    • Distributed/versioned configuration (分布式/版本化配置)
    • Service registration and discovery (服务注册和发现)
    • Routing (智能路由)
    • Service-to-service calls (服务调用)
    • Load balancing (负载均衡)
    • Circuit Breakers (熔断器)
    • Global locks (全局锁)
    • Leadership election and cluster state ( 选举与集群状态管理)
    • Distributed messaging (分布式消息传递平台)

三 Spring Cloud 架构

3.1 Spring Cloud 核心组件

3.2 Spring Cloud 体系结构(组件协同工作机制)

  • 消费方、提供方注册到注册中心。
  • API网关(gateway)负责转发所有外来的请求。
  • 配置中心提供了统一的配置信息管理服务,可以实时的通知各个服务获取最新的配置信息。

3.3 Spring Cloud 与 Dubbo 对比

  • Spring Cloud Netflix是基于HTTP的,所以效率上没有Dubbo高(TCP、UDP),但前者具有Sprign大家族背景,能提供一站式服务解决方案。

四 Spring Cloud核心组件

[[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-s3DUs4uK-1622710220364)(https://z3.ax1x.com/2021/06/03/21LAqU.png)]]

4.1 Eureka注册中心

1. 基础架构图

  • 微服务启动后,会周期性地向Eureka Server发送心跳(默认周期为30秒,默认Eureka Server 90S会将还没有续约的给剔除)以续约自己的信息。30S续约,90S滚蛋
  • Eureka通过心跳检测、健康检查和客户端缓存等机制,提高系统的灵活性、可伸缩性和高可用性
2.搭建注册中心
server:
  port: 9300
spring:
  application:
    name: lagou-cloud-eureka-server # 应用名称,会在Eureka中作为服务的id标识
eureka:
  instance:
    prefer-ip-address: true #自定义实例显示格式
    instance-id: ${spring.cloud.client.ipaddress}:${spring.application.name}:${server.port}:@project.version@
  client:
    serviceurl:
      defaultZone: http://127.0.0.1:9301/eureka #集群情况相互注册
    register-with-eureka: true # 注册服务
    fetch-registry: false #自己就是服务不需要从Eureka Server获取服务信息,默认为true
  • 启动类使用:
    • @EnableEurekaServer注解。声明当前项目为Eureka服务
3. 元数据定义
  • 使用eureka.instance.metadata-map配置,符合KEY/VALUE的存储格式。

  • 获取:

	List<ServiceInstance> instances = discoveryClient.getInstances("lagouservice-page");
instance.getMetadata().entrySet();//转为key value视图
4. 自我保护机制
  • 如果在15分钟内超过85%的客户端节点都没有正常的心跳,那么 Eureka就认为客户端与注册中心出现了网络故障,Eureka Server自动进入自我保护机制,此时会出现 以下几种情况:
    1. 不再移除过期服务。
    2. 仍可注册、查询,但不会同步。
    3. 网络恢复后,再同步信息到其余节点。

4.2 Ribbon负责均衡

  • 启动类添加:@EnableDiscoveryClient,声明当前是Eurake客户端。

  • 使用restTemplate调用时,直接在生成Bean接口上添加@LoadBalanced即可。

1. 负责均衡策略一览

2. 修改负载均衡策略
#针对的被调用方微服务名称,不加就是全局生效
lagou-service-goods:
  ribbon:
    ReadTimeout: 5000 # 超时时间
    MaxAutoRetries: 0 #对当前选中实例重试次数,不包括第一次调用
    MaxAutoRetriesNextServer: 0 #切换实例的重试次数
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #随机策略

4.3 Hystrix熔断器

  • 启动类:@EnableCircuitBreaker。
/**
* 注解简化写法
* @SpringCloudApplication =
@SpringBootApplication+@EnableDiscoveryClient+@EnableCircuitBreaker
*/
  • 一种容错机制
  • 服务雪崩效应:是一种因“服务提供者的不可用”(原因)导致“服务调用者不可用”(结果),并将不可用逐渐放大的现象。
1. 熔断+服务降级
  • 所有熔断方法使用一个Hystrix线程池(10个线程),那么这样的话会导致因线程机制导致服务不可用。
  • 解决办法:为每个方法创建一线程池,取代默认的所有方法维护一个线程池。
@HystrixCommand(
	// 线程池标识,要保持唯一,不唯一的话就共用了
	threadPoolKey = "getProductServerPort3TimeoutFallback",
	// 线程池细节属性配置
	threadPoolProperties = {
	@HystrixProperty(name = "coreSize", value = "2"), // 线程数
	@HystrixProperty(name = "maxQueueSize", value = "100") // 等待队列长度
   	@HystrixProperty(name = "queueSizeRejectionThreshold", value = "80") // 队列最大阈值
	},
	commandProperties = {
        //超时时间
		@HystrixProperty(name ="execution.isolation.thread.timeoutInMilliseconds", value = "2000"),
		fallbackMethod = "myFallBack" // 回退方法
)
@RequestMapping("/getPort3")
public String getProductServerPort3() {
	String url = "http://lagou-service-product/server/query";
	return restTemplate.getForObject(url, String.class);
}

/**
* 定义回退方法,返回预设默认值
* 注意:该方法形参和返回值与原始方法保持一致
*/
public String myFallBack() {
	return "-1"; // 兜底数据
}
2. 高级应用+自我修复
  1. 出现问题,开启时间窗(10S)。

  2. 10S内是否达到最新请求数?

    • 没达到,回到1。

    • 达到:失败占比是否达到阈值?

      • 未达到,回到1

      • 达到:熔断

  3. 熔断后,开启活动窗口(默认5s)。每隔5s,Hystrix会让一个请求通过,到达那个问题服务,看是否调用成功,如果成功,重置断路器回到第1步,如果失败,回到第3步

/**
* 8秒钟内,请求次数达到2个,并且失败率在50%以上,就跳闸
* 跳闸后活动窗口设置为3s(3S通过一个请求,检测是否可用)
*/
@HystrixCommand(
	commandProperties = {
	//统计窗口时间的设置
	@HystrixProperty(name ="metrics.rollingStats.timeInMilliseconds",value = "8000"),
	//统计窗口内的最小请求数
	@HystrixProperty(name ="circuitBreaker.requestVolumeThreshold",value = "2"),
	//统计窗口内错误请求阈值的设置 50%
	@HystrixProperty(name ="circuitBreaker.errorThresholdPercentage",value = "50"),
	//自我修复的活动窗口时间
	@HystrixProperty(name ="circuitBreaker.sleepWindowInMilliseconds",value = "3000")
}
)
3.提取到配置文件
# 配置熔断策略:
hystrix:
	command:
		default:
			circuitBreaker:	
				forceOpen: false # 关闭强制开启熔断器
				# 触发熔断错误比例阈值,默认值50%
				errorThresholdPercentage: 50
				# 熔断后休眠时长,默认值5秒
				sleepWindowInMilliseconds: 3000
				# 熔断触发最小请求次数,默认值是20
				requestVolumeThreshold: 2
			execution:
				isolation:
					thread:
					# 熔断超时设置,默认为1秒
					timeoutInMilliseconds: 2000

4. 服务暴露健康检测等端口
# springboot中暴露健康检查等断点接口
management:
	endpoints:
		web:
			exposure:
				include: "*"
  • 访问健康检查接口:http://localhost:9100/actuator/health
5. 最大请求数优化
  • 之前关于hystrix线程池配置了队列最大等待长度:maxQueueSize。
  • 但Hystrix还有一 个queueSizeRejectionThreshold属性,这个属性是控制队列最大阈值的,两个属性必须同时设置。
  • 正确配置:
# 将核心线程数调低,最大队列数和队列拒绝阈值的值都设置大一点:
hystrix:
	threadpool:
		default:
			coreSize: 10
			maxQueueSize: 1500
			queueSizeRejectionThreshold: 1000

4.4 Feign远程调用组件

  • Feign是Netflix开发的一个轻量级RESTful的HTTP服务客户端(用它来发起请求,远程调用)

  • Feign = RestTemplate+Ribbon+Hystrix

  • 启动类:添加@EnableFeignClients、消除@EnableCircuitBreaker。(前者自动引入)

1. 创建Feign接口
@FeignClient(name="lagou-service-product",fallback = ProductFeignFallBack.class)
public interface ProductFeign {
    /**
     * 获得端口号
     * @return
     */
    @RequestMapping("/server/query")
    public String findServerPort();
}
2. 创建降级返回类
  • 实现Feign接口
@Component
public class ProductFeignFallBack implements ProductFeign {
    @Override
    public String findServerPort() {
        return "这是Feign的降级返回数据";
    }
}
3. 远程调用
    /**
     * Feign远程调用
     * 负载均衡+服务熔断降级
     * 有无休眠+有无降级返回数据
     */
    @GetMapping("/getServicePortByFeign")
    public String getProductByFeign(){
        return  productFeign.findServerPort();
    }
    
  • name与服务提供方名称相同。
  • 对于负载均衡,Feign本身完成了自动配置,在ribbon直接配置即可。
4.熔断策略
  • 开启熔断
# 开启Feign的熔断功能
feign:
	hystrix:
		enabled: true
  • Feign的超时时长设置那其实就上面Ribbon的超时时长。
  • 针对超时这一点,当前有两个超时时间设置(Feign/hystrix),熔断的时候是根据这两个时间的最小值来进行的,即处理时长超过最短的那个超时时间了就熔断进入回退降级逻辑。
5.Feign对请求压缩和响应压缩的支持
  • Feign 支持对请求和响应进行GZIP压缩,以减少通信过程中的性能损耗。通过下面的参数 即可开启请求与响应的压缩功能
feign:
  #开启请求和响应压缩
  compression:
    request:
      enabled: true #默认不开启
      mime-types: text/html,application/xml,application/json # 设置压缩的数据类型,处也是默认值
      min-request-size: 2048 # 设置触发压缩的大小下限,此处也是默认值
    response:
      enabled: true #默认不开启

4.5 GateWay

  • Spring Cloud GateWay不仅提供统一的路由方式(反向代理)并且基于 Filter(定义过滤器对请求过 滤,完成一些功能) 链的方式提供了网关基本的功能,例如:鉴权、流量控制、熔断、路径重写、日志监控等。
1. 配置文件
spring:
  application:
    name: lagou-cloud-gateway
  #配置网关
  cloud:
    gateway:
      routes:
        - id: lagou-service-product
          # 动态路由(负载均衡) lb代表从注册中心获取服务
          uri: lb://lagou-service-product
          # 断言匹配成功,转发给相应的微服务
          predicates:
            - Path=/product/**
          filters:
            - StripPrefix=1  #去掉uri中的第一部分(匹配断言字段)
  • 发送接口:
http://127.0.0.1:9501/product/product/query/1
  • 断言规则有许多,时间、cookie、Header、Method、Path、QueryParam、RemoteAddr等。
2. GateWay过滤器
  • pre:调用路由之前。
  • post路由后执行。

4.6 配置中心

  • 对配置文件进行集中式管理。

  • Spring Cloud Config + Spring Cloud Bus 实现自动刷新,一次通知处处生效。
1. 配置中心服务器
  1. 在Github上上传配置文件,如lagou-service-page-dev.yml。项目+环境。
  2. 引入Config依赖
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<!--消息总线支持-->
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>

  1. 启动类添加:@EnableConfigServer // 开启配置服务器功能;并注册到注册中心。
  2. 配置文件:
spring:
  application:
    name: lagou-service-config # 应用名称,会在Eureka中作为服务的id标识
  cloud:
    config:
      server:
        git:
          uri: https://github.com/用户名/项目名.git #git地址
          username: 用户名
          password: 密码
          search-paths:
            - lagou-config #项目名
      label: master #分支
  rabbitmq:
    host: IP
    port: 5672
    username: 用户名
    password: 密码

# springboot中暴露所以端口
management:
  endpoints:
    web:
      exposure:
        include: "*"
2. 客户端读取配置
  • 添加依赖
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-config-client</artifactId>
</dependency>
  • 配置文件:bootstrap.yml
spring:
 cloud:
    config:
      name: application #配置文件名称
      profile: dev #后缀名称
      label: master #分支名称
      uri: http://localhost:9400 #ConfigServer配置中心地址
  rabbitmq:
    host: IP
    port: 5672
    username: 用户名
    password: 密码
  • 测试类
@RestController
@RefreshScope //手动刷新
public class ConfigController {
    @Value("${person.name}")
    private String name;
    @RequestMapping("getConfig")
    public String getConfig(){
       return name;
    }
}


分支名称
      uri: http://localhost:9400 #ConfigServer配置中心地址
  rabbitmq:
    host: IP
    port: 5672
    username: 用户名
    password: 密码
  • 测试类
@RestController
@RefreshScope //手动刷新
public class ConfigController {
    @Value("${person.name}")
    private String name;
    @RequestMapping("getConfig")
    public String getConfig(){
       return name;
    }
}
  • 向配置中心服务端发送post请求,各个客户端配置即可自动刷新

  • http://127.0.0.1:9400/actuator/bus-refresh

  • 定向更新:http://localhost:9006/actuator/bus-refresh/lagou-service-page:9100

Spring Cloud是一个用于构建分布式系统的开发工具集合。它提供了一些常用的组件和框架,包括服务注册和发现、负载均衡、断路器、分布式配置等等。在使用Spring Cloud时,有一些常见的错误和注意事项需要注意。 首先,关于Spring Boot和Spring Cloud版本对应错误。在使用Spring Cloud时,需要确保Spring Boot和Spring Cloud的版本兼容。不同版本之间可能存在依赖冲突或不兼容的情况,因此需要根据官方文档或者相关文档来选择合适的版本。 另外,Spring Cloud Config是一个用于集中管理和动态获取配置的工具。它支持从Git、SVN或本地文件系统中获取配置文件,并提供了服务器和客户端支持。你可以通过官方使用说明文档了解更多关于Spring Cloud Config的详细信息。 此外,关于选择使用Nacos还是Eureka作为服务注册和发现组件的问题。Nacos是一个功能更强大的服务注册和发现组件,它整合了Spring Cloud Eureka、Spring Cloud Config和Spring Cloud Bus的功能。使用Nacos可以实现配置的中心动态刷新,而不需要为配置中心新增集群或使用消息队列。另一方面,Eureka是Spring Cloud原生全家桶的一部分,相对来说更加稳定一些。选择使用哪个组件需要根据具体的需求和项目特点来决定。 综上所述,Spring Cloud是一个用于构建分布式系统的开发工具集合,它提供了一些常用的组件和框架。在使用Spring Cloud时,需要注意Spring Boot和Spring Cloud版本的兼容性,并可以使用Spring Cloud Config来动态获取配置。同时,可以选择使用Nacos或Eureka作为服务注册和发现组件,具体选择需要根据项目需求来决定。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值