前言

文本已收录至我的GitHub仓库,欢送Star:https://github.com/bin3923282...
种一棵树最好的工夫是十年前,其次是当初

Tips

面试指南系列,很多状况下不会去深挖细节,是小六六以被面试者的角色去回顾常识的一种形式,所以我默认大部分的货色,作为面试官的你,必定是懂的。

https://www.processon.com/vie...

下面的是脑图地址

叨絮

分布式系统开发,微服务架构的一种支流实现形式,当然在面试中是必不可少的拉。

而后上面是后面的文章汇总

  • 2021-Java后端工程师面试指南-(引言)
  • 2021-Java后端工程师面试指南-(Java根底篇)
  • 2021-Java后端工程师面试指南-(并发-多线程)
  • 2021-Java后端工程师面试指南-(JVM)
  • 2021-Java后端工程师面试指南-(MySQL)
  • 2021-Java后端工程师面试指南-(Redis)
  • 2021-Java后端工程师面试指南-(Elasticsearch)
  • 2021-Java后端工程师面试指南-(音讯队列)
  • 2021-Java后端工程师面试指南-(SSM)

什么是SpringBoot呢

简而言之,从实质上来说,Spring Boot 就是 Spring,它做了那些没有它你本人也会去做的 Spring Bean 配置。基于约定大于配置的一个实践

说说SpringBoot的特点吧

  • 开发基于 Spring 的应用程序很容易。
  • Spring Boot 我的项目所需的开发或工程工夫显著缩小,通常会进步整体生产力。
  • Spring Boot 不须要编写大量样板代码、XML 配置和正文。
  • Spring 疏导应用程序能够很容易地与 Spring 生态系统集成,如 Spring JDBC、Spring ORM、Spring Data、Spring Security 等。
  • Spring Boot 遵循“回心转意的默认配置”,以缩小开发工作(默认配置能够批改)。
  • Spring Boot 应用程序提供嵌入式 HTTP 服务器,如 Tomcat 和 Jetty,能够轻松地开发和测试 web 应用程序。(这点很赞!一般运行 Java 程序的形式就能运行基于 Spring Boot web 我的项目,省事很多)

说说@SpringBootApplication 这个注解吧

能够看出大略能够把 @SpringBootApplication 看作是 @Configuration、@EnableAutoConfiguration、@ComponentScan 注解的汇合。依据 SpringBoot官网,这三个注解的作用别离是:

  • @EnableAutoConfiguration:启用 SpringBoot 的主动配置机制
  • @ComponentScan: 扫描被@Component (@Service,@Controller)注解的bean,注解默认会扫描该类所在的包下所有的类。
  • @Configuration:容许在上下文中注册额定的bean或导入其余配置类。

-所以说 @SpringBootApplication 就是几个重要的注解的组合,为什么要有它?当然是为了省事,防止了咱们每次开发 Spring Boot 我的项目都要写一些必备的注解。这一点在咱们平时开发中也 常常用到,比方咱们通常会提一个测试基类,这个基类蕴含了咱们写测试所须要的一些根本的注解和一些依赖。

晓得SpringBoot的钩子函数吗,如何对你我的项目的启动和死亡做监控。

  • 启动的时候,比方CommandLineRunner 重写它的run办法,就能在启动的时候做一个钩子函数,比方链接钉钉等
  • 意外宕机也是能够的, @PreDestroy 这个注解也能实现,在宕机之前回调这个办法,实现钉钉机器人等。

理解spring boot 中的spring factories 机制吗?

Spring Factories.这种机制实际上是仿照java中的SPI扩大机制实现的。

spring -core 包里定义了SpringFactoriesLoader 类,这个类实现了检索META-INF/spring.factories文件,并获取指定接口的配置的性能。 在这个类中定义了两个对外的办法:
-loadFactories 依据接口类获取其实现类的实例,这个办法返回的是对象列表

  • loadFactoryNames 依据接口获取其接口类的名称,这个办法返回的是类名的列表。

说说springBoot的主动配置原理吧

首先咱们晓得SpringBoot我的项目的启动注解@SpringBootApplication 中有一个@EnableAutoConfiguration,这个就是开启springBoot的主动注册机制
能够看到,在@EnableAutoConfiguration注解内应用到了@import注解来实现导入配置的性能,而EnableAutoConfigurationImportSelector外部则是应用了SpringFactoriesLoader.loadFactoryNames办法进行扫描具备META-INF/spring.factories文件的jar包

最初再加上咱们的EnableAutoConfiguration 读取咱们在配置文件中的文件就能够实现主动配置了,就比方咱们的springboot Admin,咱们的client只有配置下配置文件就能胜利了,起因就是这个

下面这些都是Spring Boot中的主动配置相干类;在启动过程中会解析对应类配置信息。每个Configuation类都定义了相干bean的实例化配置。都阐明了哪些bean能够被主动配置,什么条件下能够主动配置,并把这些bean实例化进去。如果咱们自定义了一个starter的话,也要在该starter的jar包中提供 spring.factories文件,并且为其配置org.springframework.boot.autoconfigure.EnableAutoConfiguration对应的配置类。所有框架的主动配置流程根本都是一样的,判断是否引入框架,获取配置参数,依据配置参数初始化框架相应组件

说说SpringBoot的启动流程吧

其实这块很大一部分和spring的启动流程有重叠的,然而,咱们还是从头到尾来过一遍,当温习了。

SpringBoot的启动次要是通过实例化SpringApplication来启动的,启动过程次要做了以下几件事件:配置属性、获取监听器,公布利用开始启动事件初、始化输出参数、配置环境,输入banner、创立上下文、预处理上下文、刷新上下文(加载tomcat容器)、再刷新上下文、公布利用曾经启动事件、公布利用启动实现事件。

实例化SpringApplication时做了什么
  • 推断WebApplicationType,次要思维就是在以后的classpath下搜寻特定的类
  • 搜寻META-INF\spring.factories文件配置的ApplicationContextInitializer的实现类
  • 搜寻META-INF\spring.factories文件配置的ApplicationListenerr的实现类
  • 推断MainApplication的Class
SpringApplication的run办法做了什么?
  • 创立一个StopWatch并执行start办法,这个类次要记录工作的执行工夫
  • 配置Headless属性,Headless模式是在短少显示屏、键盘或者鼠标时候的系统配置
  • 在文件META-INF\spring.factories中获取SpringApplicationRunListener接口的实现类EventPublishingRunListener,次要公布SpringApplicationEvent
  • 把输出参数转成DefaultApplicationArguments类
  • 创立Environment并设置比方环境信息,零碎相熟,输出参数和profile信息
  • 打印Banner信息
  • 创立Application的上下文,依据WebApplicationTyp来创立Context类,如果非web我的项目则创立AnnotationConfigApplicationContext,在构造方法中初始化AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner
  • 在文件META-INF\spring.factories中获取SpringBootExceptionReporter接口的实现类FailureAnalyzers
  • 筹备application的上下文
  • 初始化ApplicationContextInitializer
  • 执行Initializer的contextPrepared办法,公布ApplicationContextInitializedEvent事件
  • 如果提早加载,在上下文增加处理器LazyInitializationBeanFactoryPostProcessor
  • 执行加载办法,BeanDefinitionLoader.load办法,次要初始化了AnnotatedGenericBeanDefinition
  • 执行Initializer的contextLoaded办法,公布ApplicationContextInitializedEvent事件
  • 刷新上下文(后文会独自剖析refresh办法),在这里真正加载bean到容器中。如果是web容器,会在onRefresh办法中创立一个Server并启动。
refresh办法 和spring的有点不同
srping中的onrefesh办法是空的,这个外面是须要去加载web容器的如tomcat jetty等,具体的办法还是一样的,这边就不说了,能够去看ssm那篇

说说SpringCloud容器和SpringBoot容器的关系呗

首先说一点就是 如果是SpringBoot呢?他是能够独自应用的,而SpringCloud是不能独自应用的,它必须依赖SpringBoot。

在咱们SpringCloud的我的项目中呢,整个我的项目的容器分为三层

  • BootStrap Spring 容器:由SpringCloud 监听器创立,用来初始化 SpringCloud 上下文
  • SpringBoot Spring 容器:由SpringBoot创立,也是我的项目中罕用的Spring容器。
  • 微服务 Spring相干容器:Feign和Ribbon配置类对应的上下文,由配置容器形象工厂 NamedContextFactory 创立,用于容器隔离。
次要流程

首先 SpringBoot 我的项目启动,触发监听器,如果引入了SpringCloud 中的BootstrapApplicationListener,则开始初始化 SpringCloud 相干的上下文:Bootstrap ApplicationContext,将其设置为先人容器,而后持续创立其子容器:SpringBoot Application。

说说分布式系统开发的痛点,业界是怎么设计的这些解决方案

首先分布式系统开发,目前支流的架构就是微服务架构,如果说你做微服务架构的话,无论你怎么去选型,怎么去设计,首先你总归要碰到以下的几个问题

  • 这么多的服务,客户端如何去拜访,你就好比说咱们几百个服务,难道前端要在代码中调用几百个地址,而况服务地址多了,咱们也不好去治理这些ip和端口,
  • 服务与服务之间,如何去通信,那是不是得解决咱们服务外部之间的调用形式,
  • 服务挂了怎么办,你不能因为一个服务挂了,导致整个我的项目呈现问题,导致服务雪崩吧
  • 服务与服务是如何做到服务的发现与注册的,你不能说那个服务挂了,我是如何去告诉其余服务的。也就是服务的治理

说说你们公司的SpringCloud的组件吧

  • Spring Cloud 外围组件:Eureka 服务发现和注册核心
  • Spring Cloud 外围组件:Feign 服务与服务间接的调用
  • Spring Cloud 外围组件:Ribbon 负载平衡
  • Spring Cloud 外围组件:Hystrix 熔断 降级
  • Spring Cloud 外围组件:Zuul SpringCloudGateway 服务网关

聊聊Eureka吧

首先什么是Eureka

首先,eureka在springcloud中充当服务注册性能,相当于dubbo+zk外面得zk,然而比zk要简略得多,zk能够做得货色太多了,包含分布式锁,分布式队列都是基于zk外面得四种节点加watch机制通过长连贯来实现得,然而eureka不一样,eureka是基于HTTprest来实现的,就是把服务的信息放到一个ConcurrentHashMap中,而后服务启动的时候去读取这个map,来把所有服务关联起来,而后服务器之间调用的时候通过信息,进行http调用。eureka包含两局部,一部分就是服务提供者(对于eureka来说就是客户端),一部分是服务端,客户端须要每个读取每个服务的信息,而后注册到服务端,很显著了,这个服务端就是承受客户端提供的本身的一些信息。 目前eureka是ap的 然而呢 zk是cp的,至于分布式实践下次有空再聊哈。

聊聊eureka中一些重要的概念呗

在Eureka的服务治理中,会波及到上面一些概念:

  • 服务注册:Eureka Client会通过发送REST申请的形式向Eureka Server注册本人的服务,提供本身的元数据,比方ip地址、端口、运行状况指标的url、主页地址等信息。Eureka Server接管到注册申请后,就会把这些元数据信息存储在一个双层的Map中。
  • 服务续约:在服务注册后,Eureka Client会保护一个心跳来继续告诉Eureka Server,阐明服务始终处于可用状态,避免被剔除。Eureka Client在默认的状况下会每隔30秒发送一次心跳来进行服务续约。
  • 服务同步:Eureka Server之间会相互进行注册,构建Eureka Server集群,不同Eureka Server之间会进行服务同步,用来保障服务信息的一致性。
  • 获取服务:服务消费者(Eureka Client)在启动的时候,会发送一个REST申请给Eureka Server,获取下面注册的服务清单,并且缓存在Eureka Client本地,默认缓存30秒。同时,为了性能思考,Eureka Server也会保护一份只读的服务清单缓存,该缓存每隔30秒更新一次。
  • 服务调用:服务消费者在获取到服务清单后,就能够依据清单中的服务列表信息,查找到其余服务的地址,从而进行近程调用。Eureka有Region和Zone的概念,一个Region能够蕴含多个Zone,在进行服务调用时,优先拜访处于同一个Zone中的服务提供者。
  • 服务下线:当Eureka Client须要敞开或重启时,就不心愿在这个时间段内再有申请进来,所以,就须要提前先发送REST申请给Eureka Server,通知Eureka Server本人要下线了,Eureka Server在收到申请后,就会把该服务状态置为下线(DOWN),并把该下线事件流传进来。
  • 服务剔除:有时候,服务实例可能会因为网络故障等起因导致不能提供服务,而此时该实例也没有发送申请给Eureka Server来进行服务下线,所以,还须要有服务剔除的机制。Eureka Server在启动的时候会创立一个定时工作,每隔一段时间(默认60秒),从以后服务清单中把超时没有续约(默认90秒)的服务剔除。
  • 自我爱护:既然Eureka Server会定时剔除超时没有续约的服务,那就有可能呈现一种场景,网络一段时间内产生了异样,所有的服务都没可能进行续约,Eureka Server就把所有的服务都剔除了,这样显然不太正当。所以,就有了自我爱护机制,当短时间内,统计续约失败的比例,如果达到肯定阈值,则会触发自我爱护的机制,在该机制下,Eureka Server不会剔除任何的微服务,等到失常后,再退出自我爱护机制。

从这些概念中,就能够晓得大体的流程,Eureka Client向Eureka Server注册,并且保护心跳来进行续约,如果长时间不续约,就会被剔除。Eureka Server之间进行数据同步来造成集群,Eureka Client从Eureka Server获取服务列表,用来进行服务调用,Eureka Client服务重启前调用Eureka Server的接口进行下线操作。

说说Eureka的一些原理和服务流程

服务提供者

1、启动后,向注册核心发动register申请,注册服务

2、在运行过程中,定时向注册核心发送renew心跳,证实“我还活着”。

3、进行服务提供者,向注册核心发动cancel申请,清空以后服务注册信息。

服务消费者

1、启动后,从注册核心拉取服务注册信息

2、在运行过程中,定时更新服务注册信息。

3、服务消费者发动近程调用:

注册核心

1、启动后,从其余节点拉取服务注册信息(节点之间的数据同步)。

2、运行过程中,定时运行evict工作,剔除没有按时renew的服务(包含非正常进行和网络故障的服务)。

3、运行过程中,接管到的register、renew、cancel申请,都会同步至其余注册核心节点。

聊聊Eureka的存储机制

既然是服务注册核心,必然要存储服务的信息,咱们晓得ZK是将服务信息保留在树形节点上。而上面是Eureka的数据存储构造:

Eureka的数据存储分了两层:数据存储层和缓存层。Eureka Client在拉取服务信息时,先从缓存层获取(相当于Redis),如果获取不到,先把数据存储层的数据加载到缓存中(相当于Mysql),再从缓存中获取。值得注意的是,数据存储层的数据结构是服务信息,而缓存中保留的是通过解决加工过的、能够间接传输到Eureka Client的数据结构。

Eureka实现了二级缓存来保留行将要对外传输的服务信息,数据结构完全相同。

一级缓存:ConcurrentHashMap<Key,Value> readOnlyCacheMap,实质上是HashMap,无过期工夫,保留服务信息的对外输入数据结构。

二级缓存:Loading<Key,Value> readWriteCacheMap,实质上是guava的缓存,蕴含生效机制,保留服务信息的对外输入数据结构。

Eureka的服务续约机制

服务注册后,要定时(默认30S,可本人配置)向注册核心发送续约申请,通知注册核心“我还活着”。

注册核心收到续约申请后:

1、更新服务对象的最近续约工夫,即Lease对象的lastUpdateTimestamp;

2、同步服务信息,将此事件同步至其余的Eureka Server节点。

Eureka服务登记机制

服务失常进行之前会向注册核心发送登记申请,通知注册核心“我要下线了”。

注册核心服务接管到cancel申请后:

1、删除服务信息,将服务信息从registry中删除;

2、更新队列,将此事件增加到更新队列中,供Eureka Client增量同步服务信息应用。

3、清空二级缓存,即readWriteCacheMap,用于保证数据的一致性。

4、更新阈值,供剔除服务应用。

5、同步服务信息,将此事件同步至其余的Eureka Server节点。

Eureka自我爱护

Eureka自我爱护机制是为了避免误杀服务而提供的一个机制。Eureka的自我爱护机制“虚心”的认为如果大量服务都续约失败,则认为是本人出问题了(如本人断网了),也就不剔除了;反之,则是Eureka Client的问题,须要进行剔除。而自我爱护阈值是辨别Eureka Client还是Eureka Server出问题的临界值:如果超出阈值就示意大量服务可用,大量服务不可用,则断定是Eureka Client出了问题。如果未超出阈值就示意大量服务不可用,则断定是Eureka Server出了问题。

聊聊feign是啥

Feign是一种申明式、模板化的HTTP客户端(仅在Application Client中应用)。申明式调用是指,就像调用本地办法一样调用近程办法,无需感知操作近程http申请。 Spring Cloud的申明式调用, 能够做到应用 HTTP申请近程服务时能就像调用本地办法一样的体验,开发者齐全感知不到这是近程办法,更感知不到这是个HTTP申请。Feign的利用,让Spring Cloud微服务调用像Dubbo一样,Application Client间接通过接口办法调用Application Service,而不须要通过惯例的RestTemplate结构申请再解析返回数据。它解决了让开发者调用近程接口就跟调用本地办法一样,无需关注与近程的交互细节,更无需关注分布式环境开发。

聊聊Feign的原理呗

咱们来想想平时咱们应用feign的时候,会是一个怎么样的流程

  • 增加了 Spring Cloud OpenFeign 的依赖
  • 在 SpringBoot 启动类上增加了注解 @EnableFeignCleints
  • 依照 Feign 的规定定义接口 DemoService, 增加@FeignClient 注解
  • 在须要应用 Feign 接口 DemoService 的中央, 间接利用@Autowire 进行注入
  • 应用接口实现对服务端的调用

那咱们基于这些步骤来剖析剖析,本文并不会说十分深刻去看每一行的源码

  • SpringBoot 利用启动时, 由针对 @EnableFeignClient 这一注解的解决逻辑触发程序扫描 classPath中所有被@FeignClient 注解的类, 这里以 XiaoLiuLiuService 为例, 将这些类解析为 BeanDefinition 注册到 Spring 容器中
  • Sping 容器在为某些用的 Feign 接口的 Bean 注入 XiaoLiuLiuService 时, Spring 会尝试从容器中查找 XiaoLiuLiuService 的实现类
  • 因为咱们素来没有编写过 XiaoLiuLiuService 的实现类, 下面步骤获取到的 XiaoLiuLiuService 的实现类必然是 feign 框架通过扩大 spring 的 Bean 解决逻辑, 为 XiaoLiuLiuService 创立一个动静接口代理对象, 这里咱们将其称为 XiaoLiuLiuServiceProxy 注册到spring 容器中。
  • Spring 最终在应用到 XiaoLiuLiuService 的 Bean 中注入了 XiaoLiuLiuServiceProxy 这一实例。
  • 当业务申请实在产生时, 对于 XiaoLiuLiuService 的调用被对立转发到了由 Feign 框架实现的 InvocationHandler 中, InvocationHandler 负责将接口中的入参转换为 HTTP 的模式, 发到服务端, 最初再解析 HTTP 响应, 将后果转换为 Java 对象, 予以返回。

其实就是基于aop代理和面向切面编程,把那些反复的货色,帮咱们封装了起来,而后再联合一起其余的组件如负载平衡Ribbon等。

Hystrix是什么

在分布式系统中,每个服务都可能会调用很多其余服务,被调用的那些服务就是依赖服务,有的时候某些依赖服务呈现故障也是很失常的。
Hystrix 能够让咱们在分布式系统中对服务间的调用进行管制,退出一些调用提早或者依赖故障的容错机制。
Hystrix 通过将依赖服务进行资源隔离,进而阻止某个依赖服务呈现故障时在整个零碎所有的依赖服务调用中进行蔓延;同时Hystrix 还提供故障时的 fallback 降级机制。

总而言之,Hystrix 通过这些办法帮忙咱们晋升分布式系统的可用性和稳定性。

hystrix实现原理

hystrix语义为“豪猪”,具备自我爱护的能力。hystrix的呈现即为解决雪崩效应,它通过四个方面的机制来解决这个问题

  • 隔离(线程池隔离和信号量隔离):限度调用分布式服务的资源应用,某一个调用的服务呈现问题不会影响其余服务调用。
  • 优雅的降级机制:超时降级、资源有余时(线程或信号量)降级,降级后能够配合降级接口返回托底数据。
  • 融断:当失败率达到阀值主动触发降级(如因网络故障/超时造成的失败率高),熔断器触发的疾速失败会进行疾速复原。
  • 缓存:提供了申请缓存、申请合并实现。
  • 反对实时监控、报警、管制(批改配置)

聊聊hystrix的隔离机制

  • 线程池隔离模式:应用一个线程池来存储以后的申请,线程池对申请作解决,设置工作返回解决超时工夫,沉积的申请沉积入线程池队列。这种形式须要为每个依赖的服务申请线程池,有肯定的资源耗费,益处是能够应答突发流量(流量洪峰来长期,解决不完可将数据存储到线程池队里缓缓解决)
  • 信号量隔离模式:应用一个原子计数器(或信号量)来记录以后有多少个线程在运行,申请来先判断计数器的数值,若超过设置的最大线程个数则抛弃改类型的新申请,若不超过则执行计数操作申请来计数器+1,申请返回计数器-1。这种形式是严格的控制线程且立刻返回模式,无奈应答突发流量(流量洪峰来长期,解决的线程超过数量,其余的申请会间接返回,不持续去申请依赖的服务)

聊聊hystrix的融断机制 和降级

熔断器模式定义了熔断器开关互相转换的逻辑。

  • 服务的健康状况 = 申请失败数 / 申请总数。熔断器开关由敞开到关上的状态转换是通过以后服务健康状况和设定阈值比拟决定的。
  • 当熔断器开关敞开时,申请被容许通过熔断器。 如果以后健康状况高于设定阈值,开关持续放弃敞开。如果以后健康状况低于设定阈值,开关则切换为关上状态。当熔断器开关关上时,申请被禁止通过。当熔断器开关处于关上状态,通过一段时间后,熔断器会主动进入半开状态,这时熔断器只容许一个申请通过。当该申请调用胜利时,熔断器复原到敞开状态。若该申请失败,熔断器持续放弃关上状态,接下来的申请被禁止通过。
  • 熔断器的开关能保障服务调用者在调用异样服务时,疾速返回后果,防止大量的同步期待,并且熔断器能在一段时间后持续侦测申请执行后果,提供复原服务调用的可能。

降级须要对上层依赖的业务分级,把产生故障的丢了,换一个轻量级的计划,是一种退而求其次的办法,说白了就是咱们代码中常常用到的fallback,比如说间接返回一个动态的常量之类的。

什么是网关

 网关是整个微服务API申请的入口,负责拦挡所有申请,散发到服务下来。能够实现日志拦挡、权限管制、解决跨域问题、限流、熔断、负载平衡,暗藏服务端的ip,黑名单与白名单拦挡、受权等,罕用的网关有zuul(netflix的,然而曾经停更了)和spring cloud gateway (springcloudalibaba)。这里次要讲springcloud gateway,springcloud gateway是一个全新的我的项目,其基于spring5.0 以及springboot2.0和我的项目Reactor等技术开发的网关,其次要的目标是为微服务架构提供一种简略无效的API路由治理形式.

综上:个别状况下,网关个别都会提供申请转发、平安认证(身份/权限认证)、流量管制、负载平衡、容灾、日志、监控这些性能。

聊聊Spring Cloud Gateway的大抵流程

  • 路由的配置转换为routeDefinition
  • 获取申请对应的路由规定, 将RouteDefinition转换为Route
  • 执行Predicate判断是否合乎路由, 以及执行相干的过滤(全局过滤器以及路由过滤器)
  • 负载平衡过滤器负责将申请中的serviceId转换为具体的服务实例Ip

其实网关其实还有很多说的,因为网关企业级的网关分类比拟多,比方咱们的对外网关 对内网关,对合作伙伴的网关等

网关的设计方案

  • 基于Nginx+Lua+ OpenResty的计划,能够看到Kong,orange都是基于这个计划
  • 基于Netty、非阻塞IO模型。 通过网上搜寻能够看到国内的宜人贷等一些公司是基于这种计划,是一种成熟的计划。
  • 基于Node.js的计划。 这种计划是利用了Node.js天生的非阻塞的个性。
  • 基于java Servlet的计划。 zuul基于的就是这种计划,这种计划的效率不高,这也是zuul总是被诟病的起因。

最初问一个问题,mysql分库分表下的数据迁徙问题

问题场景:就是比如说咱们一开始设计架构的时候,咱们并不知道这个我的项目能火,然而忽然老板拿到了融资,而后数据量起来,原来的架构抗不住了,这个时候须要分库分表了,你怎么去迁徙,怎么保障迁徙之后的数据一致性

停机部署法

大抵思路就是,挂一个布告,中午停机降级,而后中午把服务停了,跑数据迁徙程序,进行数据迁徙。 步骤如下:

  • 出一个布告,比方“今晚00:00~6:00进行停机保护,暂停服务”
  • 写一个迁徙程序,读db-old数据库,通过中间件写入新库
  • 而后测试一下数据的一致性

大家不要感觉这种办法low,我其实始终感觉这种办法可靠性很强。而且我置信大部分公司肯定不是什么很牛逼的互联网公司,如果你们的产品凌晨1点的用户沉闷数还有超过1000的,你们握个爪!毕竟不是所有人都在什么电商公司的,大部分产品中午都没啥流量。所以此计划,并非没有可取之处。
然而此计划有一个毛病,累!不止身材累,心也累!你想想看,原本定六点完结,你五点把数据库迁徙好,然而不知怎么滴,程序切新库就是有点问题。于是,眼瞅着天就要亮了,连忙把数据库切回老库。第二个早晨持续这么干,几乎是身心俱疲。 ps:这里教大家一些技巧啊,如果你真的没做过分库分表,又想吹一波,涨一下工资,倡议答这个计划。因为这个计划比拟low,low到没什么货色能够深挖的,所以答这个计划,比拟靠谱。

双写部署法
  • 首先咱们用canal去监听咱们须要分库分表的那个表,就是上线之后的那些事务操作,而后把它放到队列外面,存起来,先不生产。
  • 启动一个程序把旧数据同步到分库分表的数据库,这里有一个问题怎么辨别新旧数据,就是当这个我的项目启动的时候,算出最大的id,这个之前的就是老数据了,或者是按更新工夫排序,再这个工夫之前的就是老数据,之后的就是新数据了。
  • 最初把迁徙数据下线,再去生产队列,实现数据的迁徙
  • 测试验证数据是否失常

完结

上面咱们来看看分布式的实践和Zk,对于分布式系统开发还是须要明确的。

日常求赞

好了各位,以上就是这篇文章的全部内容了,能看到这里的人呀,都是真粉

创作不易,各位的反对和认可,就是我创作的最大能源,咱们下篇文章见

微信 搜 "六脉神剑的程序人生" 回复888 有我找的许多的材料送给大家