SpringCloud学习

文章介绍了微服务架构的概念,以及SpringCloud在构建微服务中的作用。重点讲解了Eureka服务注册中心的工作原理,包括心跳检测和自我保护机制。接着讨论了Zuul网关的功能和与Nginx的区别。Ribbon作为客户端负载均衡器,与Nginx的服务器端负载均衡对比。此外,文章还阐述了Hystrix熔断器在防止服务雪崩中的重要性及其工作方式。
摘要由CSDN通过智能技术生成

概述

什么是微服务架构

微服务架构就是将单体的应用程序分成多个应用程序,这多个应用程序就成为微服务,每个微服务运行在自己的进程中,并使用轻量级的机制通信。这些服务围绕业务能力来划分,并通过自动化部署机制来独立部署。这些服务可以使用不同的编程语言,不同数据库,以保证最低限度的集中式管理

Spring Cloud 是什么

Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、智能路由、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。

在这里插入图片描述

Eureka服务注册中心

作用

解耦服务提供者和服务调用者

  1. 实现动态扩缩容。将程序之间对于IP+端口号的依赖转化为服务名的依赖,服务名可以根据业务功能等进行命名
  2. 对服务的状态进行管理,当程序状态发生改变,可以第一时间通知程序的调用者

原理

在这里插入图片描述

Eureka

Eureka通过⼼跳检测、健康检查和客户端缓存等机制,提⾼系统的灵活性、可伸缩性和可⽤性。
在这里插入图片描述

流程

客户端发起服务注册
服务端保存注册信息到注册表
客户端定时发生心跳检测
服务端服务剔除及自我保护
客户端发起服务下线
客户端或者服务端注册信息到本地内存
客户端整合服务发现

心跳检测

微服务启动后,会周期性地向Eureka发送⼼跳(默认周期为30秒)以续约⾃⼰的信息
Eureka在⼀定时间内(默认90秒)没有接收到某个微服务节点的⼼跳,Eureka将会注销该微服务节点

注册信息维护

Eureka为了提⾼响应速度,在内部做了优化,加⼊了两层的缓存结构。提⾼ Eureka Server 的响应速度,缺点是缓存会导致 Client获取不到最新的服务实例信息,然后导致⽆法快速发现新的服务和已下线的服务
在这里插入图片描述

第⼀层缓存是readOnlyCacheMap,采⽤ConcurrentHashMap来存储数据的,主要负责定时与readWriteCacheMap进⾏数据同步,默认同步时间为 30 秒⼀次。

第⼆层缓存是readWriteCacheMap,采⽤Guava来实现缓存。缓存过期时间默认为180秒,当服务下线、过期、注册、状态变更等操作都会清除此缓存中的数据。

如果两级缓存都无法查询,会触发缓存的加载,从存储层拉取数据到缓存中,然后再返回给 Client。

更新问题

我们可以缩短读缓存的更新时间让服务发现变得更加及时,或者直接将只读缓存关闭,同时可以缩短客户端如ribbon服务的定时刷新间隔,多级缓存也导致C层⾯(数据⼀致性)很薄弱。
Eureka Server 中会有定时任务去检测失效的服务,将服务实例信息从注册表中移除,也可以将这个失效检测的时间缩短,这样服务下线后就能够及时从注册表中清除。

自我保护

如果 Eureka 服务器检测到超过预期数量的注册客户端终止了连接,并且同时正在等待被驱逐,那么将进入自我保护模式。这样做是为了确保灾难性网络事件不会擦除eureka注册表数据。

Zuul网关

什么是网关

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

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

什么是Zuul

在这里插入图片描述

Zuul与Nginx有什么区别?

Zuul是java语言实现的,主要为java服务提供网关服务,尤其在微服务架构中可以更加灵活的对网关进行操作。Nginx是使用C语言实现,性能高于Zuul,但是实现自定义操作需要熟悉lua语言,对程序员要求较高,可以使用Nginx做Zuul集群。

Ribbon负载均衡

Nginx与Ribbon的区别

Nginx是反向代理服务端负载均衡,Ribbon是客户端负载均衡

自定义负载均衡使用场景

  1. 灰度发布
    灰度发布是能够平滑过渡的一种发布方式,在发布过程中,先发布一部分应用,让指定的用户使用刚发布的应用,等到测试没有问题后,再将其他的全部应用发布。如果新发布的有问题,只需要将这部分恢复即可,不用恢复所有的应用。

  2. 多版本隔离
    多版本隔离跟灰度发布类似,为了兼容或者过度,某些应用会有多个版本,这个时候如何保证 1.0 版本的客户端不会调用到 1.1 版本的服务,就是我们需要考虑的问题。

  3. 故障隔离
    当线上某个实例发生故障后,为了不影响用户,我们一般都会先留存证据,比如:线程信息、JVM 信息等,然后将这个实例重启或直接停止。然后线下根据一些信息分析故障原因,如果我能做到故障隔离,就可以直接将出问题的实例隔离,不让正常的用户请求访问到这个出问题的实例,只让指定的用户访问,这样就可以单独用特定的用户来对这个出问题的实例进行测试、故障分析等。

Hystrix熔断器

网络异常策略

超时重试:时间设置需要合理,太短,可能有些服务调用还没有来得及执行完,就被丢弃;太长,可能导致服务消费者被拖垮
双发:不等第一次结果,直接访问两次。避免无脑两倍访问,服务消费者发起一次服务调用后,在给定时间内,若没返回请求结果,则Consumer就立刻发起另一次服务调用。

什么是服务雪崩

微服务化后,一次用户调用可能会被拆分成多系统间的服务调用,任何一次服务调用若发生问题都可能导致用户请求最终是失败的。一个系统异常会影响所有依赖该系统所提供服务的服务消费者,浪费其线程资源,可能导致服务雪崩。

熔断

当失败率达到阈值自动触发降级,通俗理解为:熔断就是具有特定条件的降级,当出现熔断时在设定的时间内不在请求。熔断有自动恢复机制,如:当熔断器启动后,每隔5秒,尝试将新的请求发送给service,如果服务可正常执行并返回结果,则关闭熔断器,恢复服务。如果仍调用失败,则继续返回fallback,熔断器持续开启。

Hystrix实现

Hystrix就包含三种状态:关闭、打开、半打开。Hystrix会把每次服务调用都用HystrixCommand封装,实时记录每次服务调用的状态,包括成功、失败、超时还是被线程拒绝。
在这里插入图片描述

滑动窗口算法

在这里插入图片描述
默认情况下,滑动窗口包含10个桶,每个桶时间宽度为1s,每个桶内记录这1s内所有服务调用中成功的、失败的、超时的以及被线程拒绝的次数。当新的1s到来时,滑动窗口就会往前滑动,丢弃掉最旧的1个桶,把最新1个桶包进来。任意时刻,Hystrix都会取滑动窗口内所有服务调用的失败率作为断路器开关状态的判断依据,这10个桶内记录:滑动窗口内所有服务的调用失败率 =(失败的+超时的+被线程拒绝的调用次数)/总调用次数

Hystrix的作用

  • 封装请求会将用户的操作进行统一封装,统一封装的目的在于进行统一控制。
  • 资源隔离限流会将对应的资源按照指定的类型进行隔离,比如线程池和信号量。
    • 计数器限流,例如5秒内技术1000请求,超数后限流,未超数重新计数
    • 滑动窗口限流,解决计数器不够精确的问题,把一个窗口拆分多滚动窗口
    • 令牌桶限流,类似景区售票,售票的速度是固定的,拿到令牌才能去处理请求
    • 漏桶限流,生产者消费者模型,实现了恒定速度处理请求,能够绝对防止突发流量
  • 失败回退其实是一个备用的方案,就是说当请求失败后,有没有备用方案来满足这个请求的需求。
  • 断路器这个是最核心的,,如果断路器处于打开的状态,那么所有请求都将失败,执行回退逻辑。如果断路器处于关闭状态,那么请求将会被正常执行。有些场景我们需要手动打开断路器强制降级。
  • 指标监控会对请求的生命周期进行监控,请求成功、失败、超时、拒绝等状态,都会被监控起来。

Feign

作用

feign是声明式的web service客户端,基于接口的注解,更加易用
整合了ribbon,具有负载均衡的能力
整合了Hystrix,具有熔断的能力

原理

启动时,程序会进行包扫描,扫描所有包下所有@FeignClient注解的类,并将这些类注入到spring的IOC容器中。当定义的Feign中的接口被调用时,通过JDK的动态代理来生成RequestTemplate。
RequestTemplate中包含请求的所有信息,如请求参数,请求URL等。
RequestTemplate声场Request,然后将Request交给client处理,这个client默认是JDK的HTTPUrlConnection,也可以是OKhttp、Apache的HTTPClient等。
最后client封装成LoadBaLanceClient,结合ribbon负载均衡地发起调用。

Feign的使用

SpringbootApplication启动类加上@FeignClient注解,以及@EnableDiscoveryClient。

@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class ProductApplication {

    public static void main(String[] args) {
        SpringApplication.run(ProductApplication.class, args);
    }
}
@FeignClient(value = "optimization-user", fallback = UserRemoteClientFallback.class)
public interface UserRemoteClient {
	
	@GetMapping("/user/get")
	public User getUser(@RequestParam("id")int id);
	
}

容错

fallback

定义容错的处理类,也就是回退逻辑,fallback的类必须实现Feign Client的接口,无法知道熔断的异常信息。

fallback定义

@Component
public class UserRemoteClientFallback implements UserRemoteClient {
	@Override
	public User getUser(int id) {
		return new User(0, "默认fallback");
	}
	
}
fallbackFactory

也是容错的处理,可以知道熔断的异常信息。

fallbackFactory定义

@Component
public class UserRemoteClientFallbackFactory implements FallbackFactory<UserRemoteClient> {
	private Logger logger = LoggerFactory.getLogger(UserRemoteClientFallbackFactory.class);
	
	@Override
	public UserRemoteClient create(Throwable cause) {
		return new UserRemoteClient() {
			@Override
			public User getUser(int id) {
				logger.error("UserRemoteClient.getUser异常", cause);
				return new User(0, "默认");
			}
		};
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值