微服务

100 阅读8分钟

微服务

​ 以前所有的代码都放在同一个工程中,部署在同一个服务器上,同一项目的不同模块不同功能互相抢占资源, 微服务就是将工程根据不同的业务规则拆分成微服务,部署在不同的服务器上,服务之间相互调用

Spring Cloud组件有哪些?

Eureka: 注册中心

Ribbon: 负责均衡

Feign: 远程调用

Hysterix: 服务熔断

Zuul/Getway: 网关

服务注册和发现是什么意思?Spring Cloud如何实现服务注册发现?

服务注册: 服务提供者需要把自己的信息注册到eureka, 由eureka来保存这些信息,比如服务名称,ip,端口等

服务发现: 消费者向eureka拉取服务列表信息,如果服务提供者有集群, 则消费者会利用负责均衡算法,选择一个发起调用

服务监控: 服务提供者会每隔30秒向eureka发送心跳,报告健康状态,如果eureka服务90秒没收到心跳,则该服务会从eureka中剔除

nacos和Eureka的区别

共同点: 都支持服务注册和服务拉取; 都支持服务提供者心跳方式做健康检测

区别:

  • Nacos支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时实例采用主动检测模式
  • 临时实例心跳不正常会被剔除,非临时实例则不会被剔除
  • Nacos支持服务列表变更的消息推送模式,服务列表更新及时
  • Nacos集群默认采用AP方式,当集群中存在非临时实例时,采用CP模式; Eureke采用AP
  • Nacos还支持了配置中心,eureka则只有注册中心,也是选择使用nacos的一个重要原因

image.png

项目的负载均衡如果实现的呢?

微服务的负载均衡主要是使用了组件Ribbon,比如:我在在使用feign远程调用的过程中,底层的负载均衡就是使用了Ribbon

Ribbon负载均衡策略有哪些?

  • RoundRobinRule:简单轮询服务列表来选择服务器
  • WeightedResponseTimeRule:按照权重来选择服务器,响应时间越长,权重越小
  • RandomRule:随机选择一个可用的服务器
  • ZoneAvoidanceRule: 区域敏感策略,以区域可用的服务器为基础进行服务器的选择. 使用Zone对服务器进行分类,这个Zone可以理解为一个机房,机架等.然后再对Zone内的多个服务做轮询(默认)

如果想自定义负载均衡策略如何实现?

提供了两种方式:

  • 创建类实现IRule接口,可以指定负载均衡策略(全局)
  • 在客户端的配置文件中, 可以配置某一个服务调用的负载均衡策略(局部)

什么是服务雪崩, 怎么解决这个问题?

服务雪崩: 一个服务失败,导致整条链路的服务都失败的情形

解决:

服务降级: 服务自我保护的一种方式,或者保护下游服务的一种方式,用于确保服务不会受请求突增影响变得不可用,确保服务不会崩溃,一般在实际开发中与feign接口整合,编写降级逻辑

服务熔断: 默认关闭,需手动打开, 如果检测到10秒内请求的失败率超过50%,就触发熔断机制. 之后每隔5秒重新尝试请求微服务,如果微服务不能响应,继续走熔断机制. 如果微服务可达,则关闭熔断机制,恢复正常请求

微服务是怎么监控的?

可以采用skywalking进行监控

  • skywalking主要可以监控接口,服务,物理实例的一些状态,特别是在压测的时候可以看到众多服务中那些服务接口比较慢,我们可以针对性的优化和分析
  • skywalking还可以设置告警规则,特别是项目上线之后,如果报错,可以分别设置给相关负责人发短信和邮件,第一时间知道项目的bug情况,第一时间修复

其他监控方式: spring boot admin prometheus+Grafana zipkin

你们项目中有没有做过限流?怎么做的?

限流就是对请求的速率进行限制,避免瞬时的大量请求击垮软件系统

为什么限流?

  • 并发量大(突发流量)
  • 防止用户恶意刷接口

比如到假期就会抢购车票, QPS最高可达2000, 平时都是100-500之间,突然来了大量的请求,这时就需要做限流

nginx限流

控制速率,使用漏桶算法来实现过滤,首先请求先进入到漏桶里,漏桶以固定的速度出水(也就是处理请求),当水流入的速率过大会直接溢出(访问频率超过接口响应速率),然后就会拒绝请求 或者限制并发连接数

image.png

网关限流

spring cloud getway中支持局部过滤器RequestRatelimiter来做限流,使用的是令牌桶算法, 令牌桶算法是以固定速率往桶里放入令牌,如果请求需要被处理,则需要先从桶里获取一个令牌,当桶里没有令牌可取时,多余的请求将被阻塞或丢弃

image.png

解释一下CAP和BASE

CAP定理(一致性, 可用性, 分区容错性)

  1. 分布式系统节点通过网络连接,一定会出现问题分区(P)
  2. 当分区出现时,系统的一致性(C)和可用性(A)就无法同时满足

BASE理论

  • 基本可用 2. 软状态 3.最终一致
  • 解决分布式事务的思想和模型

1.最终一致思想: 各分支事务分别执行提交,如果有不一致的情况,再想办法恢复数据(AP)

2.强一致思想:各分支事务执行完业务不要提交,等待彼此结果,而后统一提交或回滚(CP)

分布式事务的解决方案

只要是发生了多个服务之间的写操作, 都需要进行分布式事务控制

  • seata的XA模式: CP,需要互相等待各个分支事务提交,可以保证一致性,性能差
  • seata的AT模式: AP,底层使用undo log 实现,性能好
  • seata的TCC模式: AP,性能较好,不过需要人工编码实现
  • MQ模式实现分布式事务,在A服务写数据的时候,需要在同一个事务内发送消息到另外一个事务,异步,性能最好

分布式服务的接口幂等性如何设计?

幂等:多次调用方法或者接口不会改变业务状态,可以保证重复调用的结果和单次调用的结果一致

需要幂等场景:

  • 用户重复点击,或网络波动多次请求
  • MQ重复消费
  • 应用使用失败或超时重试机制

怎么保证接口幂等性:

  • insert前先select

    在新增数据的接口中,在insert前,先根据id等唯一字段查询一下数据, 如果该数据已经存在,则直接返回,不存在则进行insert操作

  • 可以使用数据库的唯一索引, 如果重复插入数据就会抛出异常, 然后需要对异常进行捕获,并返回

  • 分布式锁,性能较低

  • 使用token+redis来实现,性能较好

  1. 第一次请求,生成一个唯一token存入redis,返回给前端
  2. 第二次请求, 业务处理,携带之前的token,到redis进行验证,如果存在,可以执行业务,删除token;如果不存在,则直接返回,不处理业务

image.png

项目中使用了什么分布式任务调度?

首先,还是要描述当时是什么场景用了任务调度

xxl-job解决的问题

  • 解决集群任务的重复执行问题
  • cron表达式定义灵活
  • 定时任务失败了,重试和统计
  • 任务量大,分片执行

xxl-job路由策略有哪些?

xxl-job提供了很多的路由策略,我们平时用的较多就是:轮询、故障转移、分片广播…

xxl-job任务执行失败怎么解决?

  • 路由策略选择故障转移,使用健康的实例来执行任务
  • 设置重试次数
  • 查看日志+邮件告警来通知相关负责人解决

如果有大数据量的任务同时都需要执行,怎么解决?

  • 让多个实例一块去执行(部署集群),路由策略分片广播
  • 在任务执行的代码中可以获取分片总数和当前分片,按照取模的方式分摊到各个实例执行