我把Spring Cloud的超详细资料介绍给你,面试官不会生气吧?geigei

在Eureka Server首页看到这段提示,说明Eureka进入保护模式。

导致原因

  1. 为什么会产生Eureka自我保护机制?

为了防止EurekaClient可以正常运行,但是与EurekaServer网络不通的情况下,EurekaServer不会立刻将EurekaClient服务剔除

  1. 什么是自我保护模式?

默认情况下,如果EurekaServer在一定时间内没有接收到某个微服务实例的心跳,EurekaServer将会注销该实例(默认90秒)。但是当网络分区故障发生(延时、卡顿、拥挤)时,微服务与EurekaServer之间无法正常通信,以上行为就变得很危险–因为微服务本身是健康的,此时不应该注销这个微服务。Eureka通过"自我保护模式"来解决这个问题–当EurekaServer节点在短时间内丢失过多客户端时(可能发生了网络分区故障),那么这个节点就会进入自我保护模式。

在自我保护模式中,Eureka Server会保护注册表中的信息,不在注销任何服务实例。设计的哲学就是宁可保留错误的服务注册信息,也不盲目注销任何健康的服务实例。自我保护模式是一种应对网络异常的安全保护措施。使用自我保护模式,可以让Eureka集群更加的健壮、稳定。

#关闭自我保护机制,保证不可用服务被及时踢除 enable-self-preservation: false

EurekaServer服务注册中心:在主启动类加@EnableEurekaServer ​ EurekaClient端:在主启动类加@EnableEurekaClient

Ribbon 负载均衡服务调用

白嫖资料

  1. 概述

Ribbon是Netfix发布的开源项目,主要功能是提供客户端的软件负载均衡算法和服务调用。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简单的说,就是在配置文件中列出Load Balancer(简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器。

  1. LB(负载均衡)

集中式LB

- 即在服务的消费方和提供方之间使用独立的LB设施(可以是硬件,如F5,也可以是软件,如Nginx),有该设施负责把访问请求通过某种策略转发至服务的提供方。

进程内LB

-将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的服务器。Ribbon就属于进程内LB,它只是一个类库,集成于消费方进程,消费方通过它来获取到服务提供方的地址。

  1. Ribbon架构说明

Ribbon在工作时分为两步:

先选择EurekaServer,它优先选择在同一个区域内负载较少的server。

再根据用户指定的策略,在从server取到的服务注册列表中获取一个地址。

Ribbon提供了多种策略:比如轮询、随机和根据响应时间加权。

Ribbon = 负载均衡 + RestTemplate调用

  1. RestTemplate方法

返回对象为响应体中数据转化成的对象,可以理解为JSON

restTemplate.getForObject();

返回对象为ResponseEntity对象,包含了响应中的一些重要信息,比如响应头、响应状态码、响应体等

restTemplate.getForEntity)();

  1. 核心组件IRule

根据特定算法中从服务列表选取一个要访问的服务

com.netflix.loadbalancer.RoundRobinRule ---- 轮询

com.netflix.loadbalancer.RandomRule ---- 随机

com.netflix.loadbalancer.RetryRule ----

先按照RoundRobinRule的策略获取服务,如果获取服务失败则在指定时间内会进行重试,获取可用的服务

WeightedResponseTimeRule ----

对RoundRobinRule的扩展,响应速度越快的实例选择权重越大,越容易被选择 BestAvailableRule ----

会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务 AvailabilityFilteringRule

---- 先过滤掉故障实例,再选择并发较小的实例 ZoneAvoidanceRule ---- 默认规则,复合判断server所在区域的性能和server的可用性选择服务器

需要更换特定算法: 主启动类添加@RibbonClient

@RibbonClient(name = “服务名”,configuration=自定义的Ribbon配置类)

  1. 负载均衡算法

rest接口第几次请求数 % 服务器集群总数量 = 实际调用服务器位置下标 ,每次服务重启动后rest接口计数从1开始。

OpenFeign服务接口调用

  1. 概述

Feign是一个声明式WebService客户端,让编写Web服务客户端变得非常容易,只需创建一个接口并在接口上添加注解即可。

  1. Feign的功能

1. 使编写Java Http客户端变得更容易

2. 在使用Ribbon+RestTemplate时,利用RestTemplate对http请求的封装处理,形成了一套模版化的调用方法。但是在实际开发中,由于对服务依赖的调用可能不止一处,往往一个接口会被多处调用,所以通常都会针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用。所以,Feign在此基础上做了进一步封装,由他来帮助我们定义和实现依赖服务接口的定义。在Feign的实现下,我们只需创建一个接口并使用注解的方式来配置它(以前是Dao接口上面标注Mapper注解,现在是一个微服务接口上面标注一个Feign注解即可),即可完成对服务提供方的接口绑定,简化了使用Spring cloud Ribbon时,自动封装服务调用客户端的开发量

3. Feign集成了Ribbon,利用Ribbon维护了Payment的服务列表信息,并且通过轮询实现了客户端的负载均衡。而与Ribbon不同的是,通过feign只需要定义服务绑定接口且以声明式的方法,优雅而简单的实现了服务调用。

  1. Feign和OpenFeign的区别

在这里插入图片描述

Feign自带负载均衡配置项

  1. 使用方式

接口 + 注解 (微服务调用接口+@FeignClient)

在主启动类上加@EnableFeignClients,在业务类上加@FeignClient

  1. OpenFeign超时控制

默认Feign客户端只等待一秒钟,但是服务器处理需要超过一秒钟,导致Feign客户端不想等待了,直接返回报错。为了避免这样的情况,需要设置Feign客户端的超时控制。

#设置feign客户端超时时间(OpenFeign默认支持ribbon)

ribbon:

#指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间

ReadTimeout: 5000

#指的是建立连接后从服务器读取到可用资源所用的时间

ConnectTimeout: 5000

  1. OpenFeign日志打印功能

1.概述

Feign提供了日志打印功能,我们可以通过配置来调整日志级别,对Feign接口的调用情况进行监控和输出。

2.日志级别

NONE:默认的,不显示任何日志;

BASIC:仅记录请求方法,URL、响应状态码及执行时间;

HEADERS:除了BASIC中定义的信息之外,还有请求和响应的头信息;

FULL:除了HEADRS中定义的信息之外,还有请求和响应的正文及元数据。

3. Yaml需要开启日志的Feign

logging: level:

# feign日志以什么级别监控哪个接口

com.atguigu.springcloud.service.PaymentFeignService: debug

Hystrix断路器

分布式系统面临的问题

复制分布式体系结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免地失败。

服务雪崩

多个微服务之间调用的时候,假设微服务A调用微服务B和微服务C,微服务B和微服务C又调用其它的微服务,这就是所谓的“扇出”。如果扇出的链路上某个微服务的调用响应时间过长或者不可用,对微服务A的调用就会占用越来越多的系统资源,进而引起系统崩溃,所谓的“雪崩效应”.

对于高流量的应用来说,单一的后端依赖可能会导致所有服务器上的所有资源都在几秒钟内饱和。比失败更糟糕的是,这些应用程序还可能导致服务之间的延迟增加,备份队列,线程和其他系统资源紧张,导致整个系统发生更多的级联故障。这些都表示需要对故障和延迟进行隔离和管理,以便单个依赖关系的失败,不能取消整个应用程序或系统。 所以, 通常当你发现一个模块下的某个实例失败后,这时候这个模块依然还会接收流量,然后这个有问题的模块还调用了其他的模块,这样就会发生级联故障,或者叫雪崩。

白嫖资料

  1. Hystrix概述

Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,Hystrix能够保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。“断路器”本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个符合预期的、可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要地占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。

  1. Hystrix重要概念

1.服务降级

服务器忙,请稍后再试,不让客户端等待并立刻返回一个友好提示,fallback

哪些情况会发生降级?

1.程序运行异常

2.超时

3.服务熔断触发服务降级

4.线程池/信号量打满

降级配置:@HystrixCommand

2.服务熔断

熔断机制概述 熔断机制是应对雪崩效应的一种微服务链路保护机制。当扇出链路的某个微服务出错不可用或者响应时间太长时, 会进行服务的降级,进而熔断该节点微服务的调用,快速返回错误的响应信息。当检测到该节点微服务调用响应正常后,恢复调用链路。在Spring Cloud框架里,熔断机制通过Hystrix实现。Hystrix会监控微服务间调用的状况,当失败的调用到一定阈值,缺省是5秒内20次调用失败,就会启动熔断机制。熔断机制的注解是@HystrixCommand。

类比保险丝达到最大服务访问后,直接拒绝访问,拉闸限电,然后调用服务降级的方法并返回友好提示

服务的降级->进而熔断->恢复调用链路

在主方法添加:@EnableCircuitBreaker #对hystrix熔断机制的支持

1.熔断打开

请求不再进行调用当前服务,内部设置时钟一般为MTTR(平均故障处理时间),当打开时长达到所设时钟则进入半熔断状态

2.熔断关闭

熔断关闭不会对服务进行熔断

3.熔断半开

部分请求根据规则调用当前服务,如果请求成功且符合规则则认为当前服务恢复正常,关闭熔断

在这里插入图片描述

涉及到断路器的三个重要参数:快照时间窗、请求总数阀值、错误百分比阀值。

1:快照时间窗:断路器确定是否打开需要统计一些请求和错误数据,而统计的时间范围就是快照时间窗,默认为最近的10秒。

2:请求总数阀值:在快照时间窗内,必须满足请求总数阀值才有资格熔断。默认为20,意味着在10秒内,如果该hystrix命令的调用次数不足20次,即使所有的请求都超时或其他原因失败,断路器都不会打开。

3:错误百分比阀值:当请求总数在快照时间窗内超过了阀值,比如发生了30次调用,如果在这30次调用中,有15次发生了超时异常,也就是超过50%的错误百分比,在默认设定50%阀值情况下,这时候就会将断路器打开。

断路器开启或者关闭的条件

1.当满足一定的阀值的时候(默认10秒内超过20个请求次数)

2.当失败率达到一定的时候(默认10秒内超过50%的请求失败)

3.到达以上阀值,断路器将会开启

4.当开启的时候,所有请求都不会进行转发

5.一段时间之后(默认是5秒),这个时候断路器是半开状态,会让其中一个请求进行转发。如果成功,断路器会关闭,若失败,继续开启。重复4和5

断路器打开之后

1:再有请求调用的时候,将不会调用主逻辑,而是直接调用降级fallback。通过断路器,实现了自动地发现错误并将降级逻辑切换为主逻辑,减少响应延迟的效果。

2:原来的主逻辑要如何恢复呢?

对于这一问题,hystrix也为我们实现了自动恢复功能。

当断路器打开,对主逻辑进行熔断之后,hystrix会启动一个休眠时间窗,在这个时间窗内,降级逻辑是临时的成为主逻辑,

当休眠时间窗到期,断路器将进入半开状态,释放一次请求到原来的主逻辑上,如果此次请求正常返回,那么断路器将继续闭合,

主逻辑恢复,如果这次请求依然有问题,断路器继续进入打开状态,休眠时间窗重新计时。

白嫖资料

ALL配置

@HystrixCommand(fallbackMethod = “str_fallbackMethod”,

groupKey = “strGroupCommand”,

commandKey = “strCommand”,

threadPoolKey = “strThreadPool”,

commandProperties = {

// 设置隔离策略,THREAD 表示线程池 SEMAPHORE:信号池隔离

@HystrixProperty(name = “execution.isolation.strategy”, value = “THREAD”),

// 当隔离策略选择信号池隔离的时候,用来设置信号池的大小(最大并发数)

@HystrixProperty(name = “execution.isolation.semaphore.maxConcurrentRequests”, value = “10”),

// 配置命令执行的超时时间

@HystrixProperty(name = “execution.isolation.thread.timeoutinMilliseconds”, value = “10”),

// 是否启用超时时间

@HystrixProperty(name = “execution.timeout.enabled”, value = “true”),

// 执行超时的时候是否中断

@HystrixProperty(name = “execution.isolation.thread.interruptOnTimeout”, value = “true”),

// 执行被取消的时候是否中断

@HystrixProperty(name = “execution.isolation.thread.interruptOnCancel”, value = “true”),

// 允许回调方法执行的最大并发数

@HystrixProperty(name = “fallback.isolation.semaphore.maxConcurrentRequests”, value = “10”),

// 服务降级是否启用,是否执行回调函数

@HystrixProperty(name = “fallback.enabled”, value = “true”),

// 是否启用断路器

@HystrixProperty(name = “circuitBreaker.enabled”, value = “true”),

// 该属性用来设置在滚动时间窗中,断路器熔断的最小请求数。例如,默认该值为 20 的时候,

// 如果滚动时间窗(默认10秒)内仅收到了19个请求, 即使这19个请求都失败了,断路器也不会打开。

@HystrixProperty(name = “circuitBreaker.requestVolumeThreshold”, value = “20”),

// 该属性用来设置在滚动时间窗中,表示在滚动时间窗中,在请求数量超过

// circuitBreaker.requestVolumeThreshold 的情况下,如果错误请求数的百分比超过50,

// 就把断路器设置为 “打开” 状态,否则就设置为 “关闭” 状态。

@HystrixProperty(name = “circuitBreaker.errorThresholdPercentage”, value = “50”),

// 该属性用来设置当断路器打开之后的休眠时间窗。 休眠时间窗结束之后,

// 会将断路器置为 “半开” 状态,尝试熔断的请求命令,如果依然失败就将断路器继续设置为 “打开” 状态,

// 如果成功就设置为 “关闭” 状态。

@HystrixProperty(name = “circuitBreaker.sleepWindowinMilliseconds”, value = “5000”),

// 断路器强制打开

@HystrixProperty(name = “circuitBreaker.forceOpen”, value = “false”),

// 断路器强制关闭

@HystrixProperty(name = “circuitBreaker.forceClosed”, value = “false”),

// 滚动时间窗设置,该时间用于断路器判断健康度时需要收集信息的持续时间

@HystrixProperty(name = “metrics.rollingStats.timeinMilliseconds”, value = “10000”),

// 该属性用来设置滚动时间窗统计指标信息时划分"桶"的数量,断路器在收集指标信息的时候会根据

// 设置的时间窗长度拆分成多个 “桶” 来累计各度量值,每个"桶"记录了一段时间内的采集指标。

// 比如 10 秒内拆分成 10 个"桶"收集这样,所以 timeinMilliseconds 必须能被 numBuckets 整除。否则会抛异常

@HystrixProperty(name = “metrics.rollingStats.numBuckets”, value = “10”),

// 该属性用来设置对命令执行的延迟是否使用百分位数来跟踪和计算。如果设置为 false, 那么所有的概要统计都将返回 -1。

@HystrixProperty(name = “metrics.rollingPercentile.enabled”, value = “false”),

// 该属性用来设置百分位统计的滚动窗口的持续时间,单位为毫秒。

@HystrixProperty(name = “metrics.rollingPercentile.timeInMilliseconds”, value = “60000”),

// 该属性用来设置百分位统计滚动窗口中使用 “ 桶 ”的数量。

@HystrixProperty(name = “metrics.rollingPercentile.numBuckets”, value = “60000”),

// 该属性用来设置在执行过程中每个 “桶” 中保留的最大执行次数。如果在滚动时间窗内发生超过该设定值的执行次数,

// 就从最初的位置开始重写。例如,将该值设置为100, 滚动窗口为10秒,若在10秒内一个 “桶 ”中发生了500次执行,

// 那么该 “桶” 中只保留 最后的100次执行的统计。另外,增加该值的大小将会增加内存量的消耗,并增加排序百分位数所需的计算时间。

@HystrixProperty(name = “metrics.rollingPercentile.bucketSize”, value = “100”),

// 该属性用来设置采集影响断路器状态的健康快照(请求的成功、 错误百分比)的间隔等待时间。

@HystrixProperty(name = “metrics.healthSnapshot.intervalinMilliseconds”, value = “500”),

// 是否开启请求缓存

@HystrixProperty(name = “requestCache.enabled”, value = “true”),

// HystrixCommand的执行和事件是否打印日志到 HystrixRequestLog 中

@HystrixProperty(name = “requestLog.enabled”, value = “true”),

},

threadPoolProperties = {

// 该参数用来设置执行命令线程池的核心线程数,该值也就是命令执行的最大并发量

@HystrixProperty(name = “coreSize”, value = “10”),

// 该参数用来设置线程池的最大队列大小。当设置为 -1 时,线程池将使用 SynchronousQueue 实现的队列,

// 否则将使用 LinkedBlockingQueue 实现的队列。

@HystrixProperty(name = “maxQueueSize”, value = “-1”),

// 该参数用来为队列设置拒绝阈值。 通过该参数, 即使队列没有达到最大值也能拒绝请求。

// 该参数主要是对 LinkedBlockingQueue 队列的补充,因为 LinkedBlockingQueue

// 队列不能动态修改它的对象大小,而通过该属性就可以调整拒绝请求的队列大小了。

@HystrixProperty(name = “queueSizeRejectionThreshold”, value = “5”),

}

)

3.服务限流

秒杀高并发等操作,严禁一窝蜂的过来拥挤,大家排队,一秒钟N个,有序进行

3.工作流程

在这里插入图片描述

白嫖资料

1 创建 HystrixCommand(用在依赖的服务返回单个操作结果的时候) 或

HystrixObserableCommand(用在依赖的服务返回多个操作结果的时候) 对象。 2 命令执行。其中

HystrixComand 实现了下面前两种执行方式;而 HystrixObservableCommand

实现了后两种执行方式:execute():同步执行,从依赖的服务返回一个单一的结果对象,

或是在发生错误的时候抛出异常。queue():异步执行, 直接返回 一个Future对象,

其中包含了服务执行结束时要返回的单一结果对象。observe():返回 Observable 对象,它代表了操作的多个结果,它是一个 Hot

Obserable(不论 “事件源” 是否有 “订阅者”,都会在创建后对事件进行发布,所以对于 Hot Observable 的每一个

“订阅者” 都有可能是从 “事件源” 的中途开始的,并可能只是看到了整个操作的局部过程)。toObservable(): 同样会返回

Observable 对象,也代表了操作的多个结果,但它返回的是一个Cold Observable(没有 “订阅者”

的时候并不会发布事件,而是进行等待,直到有 “订阅者” 之后才发布事件,所以对于 Cold Observable

的订阅者,它可以保证从一开始看到整个操作的全部过程)。 3 若当前命令的请求缓存功能是被启用的, 并且该命令缓存命中,

那么缓存的结果会立即以 Observable 对象的形式 返回。 4

检查断路器是否为打开状态。如果断路器是打开的,那么Hystrix不会执行命令,而是转接到 fallback 处理逻辑(第 8

步);如果断路器是关闭的,检查是否有可用资源来执行命令(第 5 步)。 5

线程池/请求队列/信号量是否占满。如果命令依赖服务的专有线程池和请求队列,或者信号量(不使用线程池的时候)已经被占满, 那么 Hystrix

也不会执行命令, 而是转接到 fallback 处理逻辑(第8步)。 6 Hystrix

会根据我们编写的方法来决定采取什么样的方式去请求依赖服务。HystrixCommand.run()

:返回一个单一的结果,或者抛出异常。HystrixObservableCommand.construct(): 返回一个Observable

对象来发射多个结果,或通过 onError 发送错误通知。 7 Hystrix会将 “成功”、“失败”、“拒绝”、“超时”

等信息报告给断路器, 而断路器会维护一组计数器来统计这些数据。断路器会使用这些统计数据来决定是否要将断路器打开,来对某个依赖服务的请求进行

“熔断/短路”。 8 当命令执行失败的时候, Hystrix 会进入 fallback 尝试回退处理, 我们通常也称该操作为

“服务降级”。而能够引起服务降级处理的情况有下面几种:第4步: 当前命令处于"熔断/短路"状态,断路器是打开的时候。第5步:

当前命令的线程池、 请求队列或 者信号量被占满的时候。第6步:HystrixObservableCommand.construct() 或

HystrixCommand.run() 抛出异常的时候。 9 当Hystrix命令执行成功之后,

它会将处理结果直接返回或是以Observable 的形式返回。 tips:如果我们没有为命令实现降级逻辑或者在降级处理逻辑中抛出了异常,

Hystrix 依然会返回一个 Observable 对象, 但是它不会发射任何结果数据, 而是通过 onError

方法通知命令立即中断请求,并通过onError()方法将引起命令失败的异常发送给调用者。

4.服务监控hystrixDashboard

  1. 概述

除了隔离依赖服务的调用以外,Hystrix还提供了准实时的调用监控(Hystrix Dashboard),Hystrix会持续地记录所有通过Hystrix发起的请求的执行信息,并以统计报表和图形的形式展示给用户,包括每秒执行多少请求多少成功,多少失败等。Netflix通过hystrix-metrics-event-stream项目实现了对以上指标的监控。Spring Cloud也提供了Hystrix Dashboard的整合,对监控内容转化成可视化界面。

  1. Hystrix监控界面

在这里插入图片描述

zuul路由网关

  1. 概述

Zuul是一种提供动态路由、监视、弹性、安全性等功能的边缘服务。 Zuul是Netflix出品的一个基于JVM路由和服务端的负载均衡器。

API网关为微服务架构中的服务提供了统一的访问入口,客户端通过API网关访问相关服务。API网关的定义类似于设计模式中的门面模式,它相当于整个微服务架构中的门面,所有客户端的访问都通过它来进行路由及过滤。它实现了请求路由、负载均衡、校验过滤、服务容错、服务聚合等功能。

Zuul包含了最主要的功能:代理 + 路由 + 过滤

  1. 负载均衡

网关为入口,由网关与微服务进行交互,所以网关必须要实现负载均衡的功能; 网关会获取微服务注册中心里面的服务连接地址,再配合一些算法选择其中一个服务地址,进行处理业务。 这个属于客户端侧的负载均衡,由调用方去实现负载均衡逻辑。

  1. 灰度发布

在灰度发布开始后,先启动一个新版本应用,但是并不直接将流量切过来,而是测试人员对新版本进行线上测试,启动的这个新版本应用,就是我们的金丝雀。如果没有问题,那么可以将少量的用户流量导入到新版本上,然后再对新版本做运行状态观察,收集各种运行时数据,如果此时对新旧版本做各种数据对比,就是所谓的A/B测试。新版本没什么问题,那么逐步扩大范围、流量,把所有用户都迁移到新版本上面来。

  1. Zuul配置

在主启动类上加:@EnableZuulProxy

启用路由:zuul映射配置+注册中心注册后对外暴露的服务名称+rest调用地址

如果不想使用默认的路由规则,可以添加以下配置来忽略默认路由配置

zuul:

ignored-services: cloud-provider-payment

开启查看路由的端点

management:

endpoints:

web:

exposure:

include: ‘routes’

  1. 过滤器

过滤功能负责对请求过程进行额外的处理,是请求校验过滤及服务聚合的基础。

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
img

《MySql面试专题》

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

《MySql性能优化的21个最佳实践》

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

《MySQL高级知识笔记》

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

文中展示的资料包括:**《MySql思维导图》《MySql核心笔记》《MySql调优笔记》《MySql面试专题》《MySql性能优化的21个最佳实践》《MySq高级知识笔记》**如下图

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

关注我,点赞本文给更多有需要的人

转存中…(img-akdflC7K-1711036278385)]

[外链图片转存中…(img-UsOfjkW0-1711036278385)]

《MySQL高级知识笔记》

[外链图片转存中…(img-3wKk9D9g-1711036278386)]

[外链图片转存中…(img-a7vzrm25-1711036278386)]

[外链图片转存中…(img-plk0Zqeq-1711036278386)]

[外链图片转存中…(img-ZmfzzD4s-1711036278387)]

[外链图片转存中…(img-HEJ0XOgX-1711036278387)]

[外链图片转存中…(img-E1cQR4GE-1711036278387)]

[外链图片转存中…(img-DmmpzIk7-1711036278388)]

[外链图片转存中…(img-XNE8KU9x-1711036278388)]

[外链图片转存中…(img-5hmXuv8Q-1711036278388)]

[外链图片转存中…(img-QWSBNFes-1711036278389)]

文中展示的资料包括:**《MySql思维导图》《MySql核心笔记》《MySql调优笔记》《MySql面试专题》《MySql性能优化的21个最佳实践》《MySq高级知识笔记》**如下图

[外链图片转存中…(img-eLaDfcnE-1711036278389)]

关注我,点赞本文给更多有需要的人

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

  • 15
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值