想要了解微服务开发的框架,首先就得知道是什么是微服务架构?
微服务架构:
而微服务架构是一种特殊的分布式架构;
所谓分布式架构:
现如今市面上的大部分分布式架构都是用spring提供的sprng-cloud框架提供的;
spring-cloud是一个微服务架构的工具集,上面提供了大量的微服务所用的工具;
伞形项目,由多个子项目组成,主要的子项目:
- spring-cloud-netflix 最早开源
-
- eureka 服务发现
- ribbon 负载均衡
- hyxtrix 服务容错
- archlius 配置管理
- zuul 服务网关
- ...
- spring-cloud-alibaba 国产
-
- nacos 服务发现 配置管理
- dubbo 服务调用
- sentinel 服务容错
- seata 分布式事务
- ...
- spring-cloud 官方
-
- gateway 服务网关
- loadbalancer 负载均衡
- openfeign 服务调用
而本文主要介绍为个人理解的最终选型:
- nacos 服务发现 配置管理
- sentinel 服务容错
- seata 分布式事务
- gateway 服务网关
- openfeign 服务调用
- ribbon 负载均衡
Nacos 服务发现 配置管理:
简单原理:服务端在启动时向服务注册表(Service Registry)上报本机的ip及端口号,服务调用端去服务注册表中拉去服务列表中服务端的信息,服务注册表随时 ‘健康检测’服务端的健康状态,如果服务端有变更的ip及端口,或服务端出现异常情况,服务注册表就会向服务调用端发送变更通知,服务调用端在收到变更通知后会重新拉取服务列表的信息。
例:
而nacos 就做了这么一个简单使用的服务发现的功能,并且还集成了 配置管理的功能;
Ribbon 负载均衡:
服务端或者服务调用端往往不止有一个实例,这时候在服务调用的时候,如果不能好好的分配调用的话,就会堆积在一个实例上,这就是负载均衡所解决的问题;
负载均衡可以针对不同的情况选择不同的策略,ribbon的默认策略是轮询;
策略名 |
策略声明 |
策略描述 |
实现说明 |
BestAvailableRule 最小并发数 |
public class BestAvailableRule extends ClientConfigEnabledRoundRobinRule |
选择一个最小的并发请求的server |
逐个考察Server,如果Server被tripped了,则忽略,在选择其中ActiveRequestsCount最小的server |
AvailabilityFilteringRule |
public class AvailabilityFilteringRule extends PredicateBasedRule |
过滤掉那些因为一直连接失败的被标记为circuit tripped的后端server,并过滤掉那些高并发的的后端server(active connections 超过配置的阈值) |
使用一个AvailabilityPredicate来包含过滤server的逻辑,其实就就是检查status里记录的各个server的运行状态 |
WeightedResponseTimeRule 响应时间加权 |
public class WeightedResponseTimeRule extends RoundRobinRule |
根据响应时间分配一个weight,响应时间越长,weight越小,被选中的可能性越低。 |
一个后台线程定期的从status里面读取评价响应时间,为每个server计算一个weight。Weight的计算也比较简单responsetime 减去每个server自己平均的responsetime是server的权重。当刚开始运行,没有形成statas时,使用roubine策略选择server。 |
RetryRule |
public class RetryRule extends AbstractLoadBalancerRule |
对选定的负载均衡策略机上重试机制。 |
在一个配置时间段内当选择server不成功,则一直尝试使用subRule的方式选择一个可用的server |
RoundRobinRule 轮询 |
public class RoundRobinRule extends AbstractLoadBalancerRule |
roundRobin方式轮询选择server |
轮询index,选择index对应位置的server |
RandomRule 随机 |
public class RandomRule extends AbstractLoadBalancerRule |
随机选择一个server |
在index上随机,选择index对应位置的server |
ZoneAvoidanceRule |
public class ZoneAvoidanceRule extends PredicateBasedRule |
复合判断server所在区域的性能和server的可用性选择server |
使用ZoneAvoidancePredicate和AvailabilityPredicate来判断是否选择某个server,前一个判断判定一个zone的运行性能是否可用,剔除不可用的zone(的所有server),AvailabilityPredicate用于过滤掉连接数过多的Server。 |
Openfeign 服务调用
服务调用就是由一个实例调用另一个实例的方法;
其实不仅openfeign可以实现服务调用,okhttp和RestTemplate也可以实现;
但是相对来说openfeign不仅简便而且它还是声明式服务调用组件;
openfeign的实现原理:
- spring-aop 创建实现类(代理类)
- 底层使用的动态代理(jdk动态代理)
- 反射
Seata 分布式事务:
微服务架构下,一个业务操作必须经过多个服务,每个服务有自己独立的数据库,造成一个业务操作必然在多个数据库实例中执行,必须达到多个数据库实例同时成功或者失败的效果,才能实现这个业务操作,必须对数据库进行协调。
分布式事务的基本概念:
- 全局事务:分布式事务本身,由参与的所有分支事务组成
- 分支事务:单个服务内部的事务
- 事务协调者:TC Transaction Coodinator 协调各个分支事务,同时提交,同时回滚
- 事务发起者:TM Transaction Manager 事务管理者 发起全局事务
- 事务参与者:RM Resource Manager 资源管理者 参与全局事务,维护分支事务
分布式解决方案seata 提供的AT模式
阶段一:预备阶段
- 1.执行业务
- 2. 获取并持久化回滚数据
- (1)seata代理数据源(javax.sql.DataSource),拦截所有的数据库操作(SQL)
- (2)获取到操作执行前后的数据镜像,生成insert SQL,插入到undo_log表
- (3)加入到当前事务,提交
阶段二:提交阶段
- 正常提交:删除undo_log表中的记录
- 异常回滚:
- seata提取对应的undo_log表中的记录,计算生成回滚用sql
- 执行回滚SQL,提交事务
Gateway 服务网关
服务网关是整个分布式系统的唯一入口,几乎所有的请求都要经过服务网关才能调用服务;
服务网关解决了请求可以随意调用的问题。
服务网关提供了大量的通用公共功能:
- ip黑名单,封禁ip
- ip白名单,允许哪些ip通过
- 认证、授权,进行权限控制
- 动态路由,根据请求路径,转发给相应的服务
- api.xxx.com/v2/xxx/xxx
- 日志记录,原始数据
- 性能统计
- 协议转换, http -> dubbo/grpc/thrift
- 限流
- ...
Sentinel 服务容错
服务容错解决在服务调用的时候出现不可控的问题;
早在1994年,Peter Deutsch就提出了分布式计算的七大谬论,后来被James Gosling(Java之父)等人完善为八大谬论。
●网络是可靠的。(The network is reliable.)
●网络是没有延迟的。(Latency is zero.)
●带宽是无限的。(Bandwidth is infinite.)
●网络是安全的。(The network is secure.)
●网络拓扑不会改变。(Topology doesn't change.)
●肯定至少有一个(在值班的)管理员。(There is one administrator.)
●传输开销为零。(Transport cost is zero.)
●网络是同质的。(The network is homogeneous.
典型场景:服务雪崩
单个实例故障时,处理请求缓慢或者没有响应,导致上层调用它的服务实例也变慢,请求堆积,负载拉高。进一步导致更广泛的服务实例故障。
最后整个分布式系统大面积出现服务实例故障,形同异常雪崩,突然全线崩溃。这种由单个服务实例引发的级联故障称为服务雪崩。
造成雪崩原因可以归结为以下三个:
1,服务提供者不可用(硬件故障,程序bug,缓存击穿,用户大量请求)
2,重试加大流量(用户重试,代码逻辑重试)
3,服务调用者不可用(同步等待造成的资源耗尽)
出错的概率
在复杂的分布式架构的应用程序有很多的依赖,都会不可避免地在某些时候失败。高并发的依赖失败时如果没有隔离措施,当前应用服务就有被拖垮的风险。
1. 例如:一个依赖30个SOA服务的系统,每个服务99.99%可用。
2. 99.99%的30次方 ≈ 99.7%
3. 0.3% 意味着一亿次请求 会有 3,000,00次失败
4. 换算成时间大约每月有2个小时服务不稳定.
5. 随着服务依赖数量的变多,服务不稳定的概率会成指数性提高.
服务容错框架Sentinel的简单原理及特点:
本文仅为个人理解,如有不对,请踊跃提出 ,作者会及时纠正,谢谢。