一、微服务是什么
1、基本概念
微服务是一种架构风格(区别于单体架构、垂直架构、分布式架构、SOA架构),应用程序被划分为更小的、流程驱动的服务。
2、微服务的特征
- 轻量化:将复杂的系统或者服务进行纵向拆分,每个微服务专注于解决专项问题。
- 低耦合:拆分后的各个服务在代码、资源、环境上相互独立,可以独立地进行开发、测试、部署与维护,有利于系统的稳定性(发生问题时影响面降低)和扩展(扩展资源时资源评估更方便、风险更低 )。
- 跨平台:不同的微服务可以使用不同的开发语言,亦可以运行在不同的环境。
二、SpringCloud是什么
1、基本概念:
Spring Cloud是一个微服务框架,它提供了一系列分布式系统解决方案。通过组件化的方式提供微服务的开发部署、服务注册发现、服务治理与服务运维等能力。
2、常用组件:
1)Spring Cloud Netflix:
Eureka:注册中心
Ribbon:负载均衡
Feign :远程调用
Hystrix :服务熔断
Zuul/Gateway:网关
2)Spring Cloud Config:集中化的配置管理工具,应用配置的外部化存储,可用于Spring或非Spring的应用。
3)Spring Cloud Bus:事件、消息总线,用于传播集群中的状态变化或配置更改事件。
4)Spring Cloud Consul:服务发现与配置工具,与Docker容器无缝集成。
5)Spring Cloud Security:安全工具包,提供对应用安全和身份验证支持。
6)Spring Cloud Sleuth:分布式调用链跟踪,与Zipkin、HTrace和ELK跟踪兼容。
7)Spring Cloud Cluster:领导选举,通过对Zookeeper、Redis、Consul抽象实现。
8)Spring Cloud Data Flow:微服务编排,可以通过拖拽式界面或REST API简易使用。
9)Spring Cloud Stream:轻量级事件驱动微服务框架,快速构建连接外部系统的应用。
10) Spring Cloud Task:短期的微服务框架,快速构建完成批量数据处理任务的应用。
三、SpringCloud组件的使用步骤
springcloud教程 -- 3.微服务熔断机制,断路器hystrix的使用详解_java 熔断怎么配置-CSDN博客
springcloud教程 -- 4.网关zuul的使用详解_zuul使用教程-CSDN博客
1、Hystrix(熔断、降级、限流)
1)有什么作用?
在分布式系统中,如果某个服务节点发生故障或者网络发生异常,都有可能导致调用方被阻塞等待,如果超时时间设置很长,调用方资源很可能被耗尽。这又导致了调用方的上游系统发生资源耗尽的情况,最终导致系统雪崩。熔断可以有效防止服务雪崩。
如果遇到突增流量,一般的做法是对非核心业务功能采用服务降级的措施来保护核心业务功能正常服务,而对于核心功能服务,则需要采用限流的措施。
2)发生在客户端还是服务端?
服务熔断:一般是发生在服务端的(目的是让调用方快速失败),当某个服务超时或者异常时,就引起熔断,类似于现实生活中的保险丝。(有时也可以配置在客户端,当发现调用某个服务异常时让自己快速失败);
服务降级:一般是发生在客户端的,从整体网站请求负载考虑,当某个服务熔断或者关闭后,服务将不再调用;(有时也可以配置在服务端,当系统出现突发流量时对非核心功能进行降级保护核心功能);
限流:一般发生在服务端;
3)如何使用
-
熔断:
@EnableCircuitBreaker :application上开启熔断器
@HistrixCommand(fallbackMethod="xxxFallback",commandProperties = {
}) :熔断的注解是在降级的注解上增加,commandProperties = {} 里填熔断条件,具体熔断条件可点击HystrixPropertiesManager类查看。
@HystrixCommand(fallbackMethod = "xxxFallback",commandProperties = {//20秒内出现3个请求,失败率为30%,就会触发熔断,30秒内不再发送调用// 条件一: 请求数量达到3个@HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_REQUEST_VOLUME_THRESHOLD, value = "3"),// 条件二: 每20秒一个判断单位@HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_THREAD_INTERRUPT_ON_TIMEOUT,value = "20000"),// 条件三: 失败率30%@HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_ERROR_THRESHOLD_PERCENTAGE, value = "30"),// 结果: 熔断后, 30秒内不再请求远程服务@HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_SLEEP_WINDOW_IN_MILLISECONDS, value = "30000")})
-
降级:
新建xxxFallbackFactory类实现FallbackFactory并重写create方法,create里面定义降级方法。
@FeignCliend(fallbackFactory=xxxFallbackFactory.class):Histrix集成到了Feign里面
或者直接在方法上指定降级方法: @HistrixCommand(fallbackMethod="xxxFallback")
-
限流:
1、限流策略:
1)、信号量限流
信号量用来控制可同时并发的线程数。通过构造方法指定内部虚拟许可的数量。
如果采用信号量隔离技术,每接收一个请求,都是服务自身线程去直接调用依赖服务,信号量就相当于一道关卡,每个线程通过关卡后,信号量数量减1,当为0时不再允许线程通过,而是直接执行fallback逻辑并返回,说白了仅仅做了一个限流。
信号量可以理解为一个计数器,计数器统计当前正在处理的请求数量,当计数器的值达到设定值,则不接受后续请求(或降级),需要等待,直到计数器值小于设定值,后续请求才能进入处理。
@HystrixCommand(commandProperties= {@HystrixProperty(name="execution.isolation.strategy", value="SEMAPHORE"),@HystrixProperty(name="execution.isolation.semaphore.maxConcurrentRequests", value="20")},fallbackMethod = "errMethod"
)
2)、线程池限流
@HystrixCommand(commandProperties = {@HystrixProperty(name = "execution.isolation.strategy", value = "THREAD")},threadPoolKey = "createOrderThreadPool",threadPoolProperties = {@HystrixProperty(name = "coreSize", value = "20"),@HystrixProperty(name = "maxQueueSize", value = "100"),@HystrixProperty(name = "maximumSize", value = "30"),@HystrixProperty(name = "queueSizeRejectionThreshold", value = "120")},fallbackMethod = "errMethod"
)
这里要注意:在java
的线程池中,如果线程数量超过coreSize
,创建线程请求会优先进入队列,如果队列满了,就会继续创建线程直到线程数量达到maximumSize
,之后走拒绝策略。但在hystrix配置的线程池中多了一个参数queueSizeRejectionThreshold
,如果queueSizeRejectionThreshold < maxQueueSize
,队列数量达到queueSizeRejectionThreshold
就会走拒绝策略了,因此maximumSize
失效了。如果queueSizeRejectionThreshold > maxQueueSize
,队列数量达到maxQueueSize
时,maximumSize
是有效的,系统会继续创建线程直到数量达到maximumSize
。
2、信号量限流和线程池限流区别:
1)、性能层面:信号量使用原来的线程,性能消耗小;
2)、系统稳定层面:线程池隔离,自己出问题不会影响其他线程池;
3)、同步异步:因为信号量是使用的原有线程,所以是同步的,且是阻塞的。
3、限流策略使用场景:
当请求量非常密集,导致线程隔离的开销比较高的时候,建议使用信号量的方式降低负荷,这种情况通常用来应对非网络请求(不需要调用外部服务)。其他场景均建议使用线程池方式。
4)三者区别?
限流仅仅只是限流,只要不超过流量限制,服务仍然可用(区别于熔断),也不一定非要降级(也可以抛出超出流量限制异常给到调用方自行处理)。所以下面仅仅说一下熔断和降级的区别:
- 概念不同
熔断是服务整体不可用(侧重的是自我保护),降级是退而求其次(侧重的是兜底),限流是流量不能超过多少。
- 触发机制不同
默认情况 hystrix 如果检测到 10 秒内请求的失败率超过 50%,就触发熔断机制。之后每隔 5 秒重新尝试请求微服务,如果微服务不能响应,继续走熔断机制。如果微服务可达,则关闭熔断机制,恢复正常请求。
默认情况下,hystrix 在以下 4 种条件下都会触发降级机制:
- 方法抛出 HystrixBadRequestException
- 方法调用超时
- 熔断器开启拦截调用
- 线程池或队列或信号量已满
- 归属关系不同
熔断时可能会调用降级机制,而降级时通常不会调用熔断机制。因为熔断是从全局出发,为了保证系统稳定性而停用服务,而降级是退而求其次,提供一种保底的解决方案,所以它们的归属关系是不同(熔断 > 降级)。
2、Feign和RestTemplate
链接内容概要:
- 添加starter依赖;
- 添加注解:@EnableFeignClients;
- 创建Feign接口:
@FeignClient(name="eureka-HA",fallbackFactory=DeptClientServiceFallbackFactory.class)
springcloud教程 -- 1.快速搭建入门级demo,看这一篇就够了_叶巨岩-GitCode 开源社区废话不多讲,跟紧我,开启你的SpringCloud初体验首先回顾微服务的基本组成:[图片 here]生产者:提供服务消费者:消费服务服务注册/发现中心:服务注册,发现,监控所以,首先明白springcloud微服务的架构基础:生产者(client),消费者(client),服务注册/发现中心(server) 叶巨岩 GitCode 开源社区https://gitcode.csdn.net/65e840841a836825ed78b9d0.html?dp_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MzI1MTQ3NiwiZXhwIjoxNzIxMTM0MjcwLCJpYXQiOjE3MjA1Mjk0NzAsInVzZXJuYW1lIjoicXFfMTk5NTIwMjkifQ.7co5oRDfDrxtdqIsV-9AjJacdbURh-cikj5Rtxt7Z1c
3、Zuul的使用
参考:
SpringBoot项目架构实战之“网关zuul搭建“-CSDN博客
4、注册中心Eureka的使用
参考:
SpringBoot项目架构实战之“父项目搭建与注册中心搭建”_java搭建springboot父工程启动-CSDN博客
四、SpringCloud工作原理
1、Eureka工作原理:
-
服务注册:服务提供者在启动时,会向Eureka服务端发送注册请求,包括服务的IP地址、端口号、服务名等信息。Eureka服务端接收到注册请求后,会将服务信息保存到内存中,并对外提供服务注册信息查询功能。
-
服务发现:服务消费者在需要调用其他服务时,会向Eureka服务端发送服务发现请求,获取所需服务的实例列表。Eureka服务端接收到请求后,会返回对应服务的实例列表,包括服务的IP地址、端口号等信息。服务消费者根据返回的实例列表,选择其中一个服务实例进行调用(负载均衡)。
-
心跳健康检查:服务提供者会定期向Eureka服务端发送心跳包,以证明自身服务处于正常运行状态。如果Eureka服务端在一段时间内未接收到某个服务实例的心跳包,则认为该服务实例已经宕机,会将其从服务列表中移除。
五、SpringCloud底层源码
1、网关Zuul源码
SpringBoot项目架构实战之“网关zuul搭建“-CSDN博客文章浏览阅读227次。第三章网关zuul搭建前言:1、主要功能 zuul主要提供动态路由(内置ribbon实现)和过滤(可以做统一鉴权过滤器、灰度发布过滤器、黑白名单IP过滤器、服务限流过滤器(可以配合Sentinel实现))功能;2、和spring cloud GateWay的区别 属于两个不同开源组织提供的网关解决方案。spring cloud GateWay使用非阻塞API,内置限流过滤器,支持长连接(比如websockets),在高并发和后端服务响应慢的场景下比Zuul...https://blog.csdn.net/qq_19952029/article/details/124285479
2、注册中心Eureka源码
3、断路器Histrix源码
4、配置中心Config源码
5、负载均衡Ribbon源码
6、微服务调用Feign源码
六、SpringCloud如何实现分布式事务
Seata TCC模式实战(下)-阿里云开发者社区Seata TCC模式实战(下)https://developer.aliyun.com/article/1053737?spm=5176.26934562.main.1.799c6a03T45SJ9上面博文未解决悬挂问题,可以通过不同状态标识来进行判断。
https://www.cnblogs.com/lilpig/p/16613226.htmlhttps://www.cnblogs.com/lilpig/p/16613226.html
1、TCC模式角色
TM:事务管理器,随着@GlobalTransaction注解生成。
TC:协调者
RM:参与者
整个的流程就是:
TM代理你的全局事务,并在开始执行前向TC注册
TM开始执行全局事务中的每个分支事务,RM向TC注册报告分支事务以及执行状态
分支事务执行完成,TM向TC发起提交或回滚全局事务的请求
2、TCC资源预留、提交、回滚的含义。
预留表示将数据库资源锁定并更新为中间状态,待确认后进行二阶段提交时再改为生效状态。所以预留阶段和提交回滚阶段都涉及操作数据库,所以也可能存在confirm和rollback失败的情况,需要人工处理,可以通过记录日志、补偿重试等进行解决
3、TCC的优缺点
TCC模式优点:
- 一阶段直接提交,无DB锁,无其它锁,性能好
- 预留和恢复逻辑由自己编写,不依赖数据库,可以用在非事务型数据库
TCC模式缺点:
- 编码复杂
- 弱一致
- 因为
Confirm
和Cancel
也可能失败,需要处理这个过程 - 有些业务并不适合TCC模式,比如下单操作是一个新增行的过程,没法也没必要使用TCC
4、XA模式
强一致性,通过协调各参与者的本地事务何时提交和回滚。
XA模式的优点:
- 容易实现,因为大部分数据库都已经支持了XA事务,Seata只需要做简单的包装即可
- 强一致性
XA模式的缺点:
- 每个事务都需要等待所有事务处理完成,占用数据库锁,性能较差,可用性较低
- 如果数据库不支持XA事务就无法使用
5、AT模式
弱一致性