分布式/微服务概念
分布式系统是一组部署在同一网络下的多个通过网络来通信和协调的组件,对于外部而言表现得如同一个系统。通过将系统的功能分散到多个离散的服务中,使得系统各自独立,降低系统耦合性,用以应对用户量、数据量急剧增长的复杂业务场景当中。
分布式系统一方面可以指不同的部件在网络上相互协作,比如电商网站;也可以指一个组件的多个副本构成的集群,比如防止数据不丢失才去的服务备份冗余。
本人学习所用框架为Spring-Cloud,Spring-Cloud是一个为开发人员提供的构建微服务架构的一个工具集,以快速构建分布式系统中的一些常见模式 (例如配置管理、服务发现等)。
以如下几点所涉技术浅谈拙见,不足之处诸君海涵。
服务发现
服务之间需要通信,实际上是服务调用service call
服务发现的流程如下:
1.消费者客户端(A)在启动时上报本机的ip和端口,发送到服务注册表(C)当中去。
2.生产者客户端(B)在服务注册表中拉取服务列表。
3.服务注册表不断给消费者客户端发送心跳检测,检测其是否正常。
4.若发现异常,则给生产者发送变更通知。
5.生产者重新去服务注册表中拉取服务列表。
简单总结:A注册到C,B在C中拉取服务列表,C不断检测A,若有变化C通知B,B重新在C中拉取服务列表。
负载均衡
实际场景当中,部署项目的主机性能和所处网络环境不同,对于不同请求的响应情况也各自不同。针对高并发、大数据量的访问时,尽可能得把流量均匀地分布到多个服务中去,以达到系统整体的响应速度和可用性。
Ribbon
一种实现负载均衡的工具。
内置的负载均衡策略有:
1.最小并发数(BestAvaliableRule):选择一个最小的并发请求的server。
2.响应时间加权(WeightedResponseTimeRule):根据响应时间的长短分布一个weight,响应时间越长,weight越小,越不容易被选中。
3.轮询(RoundRobinRule):挨个选server。
4.随机(RandomRule):随机选择一个server
声明式服务调用组件
Spring Cloud Openfeign
Spring Cloud Openfeign是 Spring 官方推出的一种声明式服务调用与负载均衡组件,它在 RestTemplate 的基础上做了进一步的封装,我们只需要通过声明一个接口并用注解进行配置即可实现负载均衡和服务调用功能,相当便捷。
其实现原理是spring-aop 创建client实现类,通过反射获取client上的注解,进一步获取请求相关信息(请求方式、参数类型、参数名等),然后根据请求信息生成服务调用的代码。
服务划分
服务只能从上往下调,不可从下往上反向调用,若有需要,可用mq异步通信。
服务分层:
1.聚合服务层:面向用户,每一个客户端提供一个服务。(比如:用户个人中心、订单中心……)
2.源子服务层:负责某个特定的领域(比如:用户中心里的登录、注册、修改密码、激活等具体操作)
分布式事务
在微服务架构当中,一个业务有可能经过多个服务,每个服务都有自己的数据库。如果在不进行分布式事务处理的情况下,执行一个业务功能时,调用不同的下游服务就会执行不同的数据库操作,若其中一个下游服务的数据库操作出错,在此前的数据库操作已然生效,而整体的业务流程却没能成功,就会导致业务中的部分数据库错误操作。
我们需要达到多个数据库同时成功,同时失败,才能保证一个完整的业务流程操作。
分布式事务的基本概念
1.全局事务:分布式事务本身,由所有参与的分支事务组成。
2.分支事务:一个业务流程中所涉及的单个服务的事务。
3.事务协调者:Transaction Coodinator(TC)协调分支事务,同时提交,同时回滚。
4.事务发起者:Transaction Manager(TM)事务管理者,发起全局事务。
5.事务参与者:Resource Manager(RM)资源管理者,参与全局事务,维护分支事务。
常见解决方案
1.XA协议
数据库层面解决:多个数据库同步打开事务,不提交,等待事务协调者协调,确认完成后提交(commit)。
缺点:资源锁定时间长,性能消耗大。
2.TCC(Try-Confirm-Cancel)
Try 尝试操作 Confirm 确认操作(try全部成功执行) Cancel 取消操作(try没有全部成功执行)
优点:与XA相比,独立提交事务,不用事务等待,资源消耗较少。
缺点:编码复杂,需要拆分成TCC3个接口
3.SAGAS
适用于长事务流程,事务流程中每个参与者都提交本地事务,当出现某一参与者失败时,则补偿前面已经执行成功的参与者。
比如:A调用B调用C调用D, 在C执行失败时,反向补偿 C、B、A
4.AT模式
seata提供的分布式解决方案
1.(1)执行业务。(2)seata代理数据源,拦截数据库操作,生成执行前后的数据镜像,插入到一张表中(undo_log)。并加入到当前事务一起提交。
2.当执行成功时,删除undo_log表中的记录;执行失败时,通过undo_log表中的数据反向生成回滚用的sql并执行sql进行回滚。
优点:性能消耗、资源消耗低
缺点:需要额外建表
服务网关
整个分布式系统的唯一入口。
分布式服务项目加入服务网关后,从外部调用业务流程必须经过网关进行转发,所有的外部请求都会先经过网关这一层。业务实现方面可以更多地考虑逻辑实现方面,而安全和监控等方面可以交给网关来进行完成。
学习用到的组件是spring-cloud-gateway
服务网关提供的一些功能
1.ip黑名单和白名单,允许哪些ip通过或者封禁哪些ip。
2.认证、授权、权限控制。
3.动态路由,根据请求路径,转发给相应的服务。
4.日志记录。
5.性能统计。
6.限流
……
过滤器
gateway的两种过滤器
1.网关过滤器(GatewayFilter)针对某一个route做请求的处理。
2.全局过滤器(GlobalFilter)针对所有route。执行需按照顺序执行,在NettyRoutingFilter进行路由转发。
服务容错
在分布式服务当中,因为网络的不可靠性或者主机自身的性能原因,服务并不能保证100%成功,在一个服务出现问题的时候,调用这个服务出现错误,而在高并发和大数据量的应用场景下,会造成线程阻塞的问题。
服务雪崩
因为微服务架构的服务和服务之间的依赖关系,在一个服务响应缓慢或者没有响应的时候,调用他的上层服务也会出现问题,一个服务的故障可能会引起多个服务的故障,最后使得整个分布式服务大面积出现鼓掌,就是“服务雪崩”。
造成服务雪崩的原因如下:
1.服务提供者不可用(程序bug、硬件故障、用户大量请求)
2.重试加大流量(用户重试,代码重试)
3.服务调用者不可用(同步等待造成的资源耗尽)
服务容错框架Sentinel
限流
流控模式:
1.直接:直接处理(对于超过每秒查询数的访问请求进行限流)
2.关联:A关联B时,当B的请求超过流量配置,会对A进行限流。
流控的效果:
1.快速失败:限流后的访问请求直接失败。
2.warm up 冷启动:一个系统平常的流量较小,在突然的大量请求涌入时,逐渐提高qps上限(每秒查询数)
3.排队等待:qps=x时,每秒通过x个请求,计算间隔时间,匀速地通过这x个请求。
熔断器
自动断开故障实例,自动修复
当一个请求频繁失败到一定阈值时,会打开熔断器,熔断器自身有个时间窗,在时间窗内,访问的同个请求会被直接拦截,直到时间窗结束过后,发送探测请求。
若是熔断器时间窗结束过后发送的探测请求仍然失败,会直接再次打开熔断器,再次在一个时间窗的作用范围内拦截同个请求(熔断器时间窗结束过后的第一个请求失败的时候,再次进入一次熔断器时间窗)。如此往复,直到探测请求成功过后关闭熔断器。