自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(52)
  • 收藏
  • 关注

原创 lucene学习-FST源码分析

第三步插入do/17,do和deep有公共字符d可以将字符p和字符e写入FST,这里字符p的flags和上面字符t的flags相同为15,表明arc对应字符是term最后一个字符,arc是当前节点最后一条边,arc连接的两个节点是临近节点不需要记录target,arc的目标节点是一个终止节点,字符e的flags和上面的字符a的flags相同,表明arc是当前节点最后一条边而且arc连接的两个节点是临近节点。将父节点指向冻结后的节点,冻结后的节点就是compileNode,该方法就是将节点转变为冻结节点。

2024-08-10 14:11:54 239

原创 elasticsearch源码分析-08Serch查询流程

这里可以看到首先会执行lucene的查询,然后对查询结果进行打分、执行聚合逻辑,然后生成SearchPhaseResult返回。和Get查询一样,请求会经过转发dispatchRequest,查询路由对应的handler处理类,然后执行处理。数据节点查询数据后返回协调节点,我们继续回到executePhaseOnShard方法执行回调。search操作会发送请求到索引下的所有分片,相同分片只会发送到主分片或副本分片。这里收集本集群和跨集群及其他集群需要查询的索引,这里我们主要是分析本集群搜索。

2024-08-03 15:11:46 334

原创 elasticsearch源码分析-07GET查询流程

而TransportGetAction继承了TransportSingleShardAction最终调用它的doExecute方法。ES的读取分为Get和search两种,get是根据id从索引中获取内容,而search是根据关键词从倒排索引中获取内容。就是将请求转发到其他节点执行,处理逻辑和上面的逻辑一致,其他节点执行后会把数据返回,然后节点把数据返回给用户请求。获取线程池然后执行,最终都会调用processMessageReceived方法。get请求的处理在actionModule中进行注册。

2024-07-27 14:52:27 270

原创 elasticsearch源码分析-06索引恢复

索引恢复allocation阶段最后会向集群发布一个新的集群状态,状态发布后会进入IndicesClusterStateService的applyClusterState应用集群状态@Overridepublic synchronized void applyClusterState(final ClusterChangedEvent event) { if (!lifecycle.started()) { return; } final ClusterSta

2024-07-20 23:27:11 960

原创 elasticsearch源码分析-05分片分配

副本分片分配也需要获取一次shard信息,但是之前主分片分配已经获取了一次数据,副本分片分配可以直接使用上次执行获取分片的结果,如果没有node可以分配则查看是否延迟分配,然后执行initialize方法。主分分配器primaryShardAllocator和replicaShardAllocator都继承了BaseGatewayShardAllocator方法,在执行allocateUnassigned时主分片分配和副本分片分配会执行相同的方法,只是会执行不同的决策。

2024-07-13 14:05:10 581

原创 elasticsearch源码分析-04集群状态发布

es使用二阶段提交来实现状态发布,第一步是push及先将状态数据发送到node节点,但不应用,如果得到超过半数的节点的返回确认,则执行第二步commit及发送提交请求,二阶段提交不能保证节点收到commit请求后可以正确应用,也就是它只能保证发了commit请求,但是无法保证单个节点上的状态应用是成功还是失败的。回到MasterService的runTasks方法中新的集群状态已经生成并返回,然后判断集群状态和之前的集群状态是否相同,如果发生变化则将进入集群状态发布阶段,将最新的集群状态广播到所有节点。

2024-07-06 14:32:45 992

原创 elasticsearch源码分析-03选举集群状态

首先判断只有主节点可以执行状态选举,然后判断是否已经在执行了状态恢复任务了,如果是则直接返回;遍历所有节点选择返回的索引元数据版本最高的节点作为索引级元数据,然后将索引级元数据添加到metadataBuilder中。从磁盘读取构建索引级元数据和集群级元数据,用于构建集群状态对象ClusterState。开始通过版本号选择集群层元数据,比较版本号,选择版本号最大的集群状态。构造集群状态,删除索引信息,下面会选择索引级元数据。我们继续回到每个节点发送请求的返回处理。构造恢复后的集群级元数据和索引级元数据。

2024-06-29 12:05:36 682

原创 elasticsearch源码分析-02选举主节点

NodesFaultDetection运行在master节点,master也是定时发送心跳ping请求给非master节点,如果发送失败则先重试,重试达到一定次数调用notifyNodeFailure,如果返回连接错误则调用handleTransportDisconnect(node)如果选择的master节点是本节点加入的节点则设置选举结束。首先会比较两个候选节点的集群状态版本信息,如果版本信息比较新则排在前面,如果版本号相同则需要比较两个节点的节点id,然后选择排在最前面的一个节点为master。

2024-06-23 09:45:10 874

原创 elasticsearch源码分析-01服务启动

1.服务启动服务启动入口类为Elasticsearch/*** Main entry point for starting elasticsearch*/public static void main(final String[] args) throws Exception { LogConfigurator.registerErrorListener(); final Elasticsearch elasticsearch = new Elasticsearch();

2024-06-15 14:36:17 841

原创 sentinel源码分析-09流量整形控制器

这里首先计算两个请求之间的间隔时间costTime,通过costTime计算下次请求可以通过的时间expectedTime,如果expectedTime <= currentTime说明当前时间已经到达expectedTime ,则请求可以正常通过,否则说明当前时间请求需要等待,计算等待时间waitTime,如果waitTime比设置的最大等待时间大则直接不允许通过,如果没有达到最大排队时间则等待waitTime后通过。关注控制每秒传入请求的计数,类似于令牌桶算法。

2023-08-26 17:35:51 80

原创 sentinel源码分析-08流量数据统计

这里就是将时间按照窗口数量化分成相同大小的环形桶,当前请求过来时,根据请求的时间查看落在那个时间窗口内,这里我们以成功通过后的数据统计为入口。我们可以看到统计节点主要是保存三种实时统计指标,每秒统计信息、每分钟的统计信息、并发线程数。ArrayMetric底层又是通过LeapArray来完成数据的统计,其中几个重要的属性。这里通过当前时间获取有效结果的时间窗集合,然后遍历所有时间窗集合然后或的成功的请求总数。这里array可以理解就是一个环形的桶,首先计算当前时间落在那个桶中,及计算索引值。

2023-08-26 17:01:25 127

原创 sentinel源码分析-07GatewayFlowSlot网关限流

如果没有设置pattern则直接返回取值结果,如果设置pattern则可能是针对某类参数生效,支持3种模式精确匹配、子串匹配和正则匹配,如果匹配成功则返回参数值否则返回默认值$NM,它会匹配热点参数规则的参数例外项,但是例外项的阈值是100万,等同于直接放行。解析设置的参数放入参数数组,如果有没有参数的规则,则将参数数组的最后一位设置成默认参数$D,为了进行资源的所有无参数例外项的热点规则流控校验。这里设置了两个分组,并设置了对应匹配分组的规则。将无参网关流控规则,转换为热点参数规则。

2023-08-19 17:55:02 203

原创 sentinel源码分析-06热点参数限流

这里是一个简单的令牌桶,每次执行逻辑查看是否需要限流时,计算上次添加令牌的时间距离当前时间差,如果时间大于一个周期,则重置令牌桶令牌数量,然后立即使用acquireCount个令牌,如果已经存在令牌桶则计算上次添加时间到当前时间差可以放入的令牌数和剩余令牌数之和是否能够支持acquireCount个令牌,如果达不到则需要限流。热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。这里获取热点数据流控规则,通过配置规则中的设置的索引获取对应需要限流的热点参数。

2023-08-19 16:27:21 69

原创 sentinel源码分析-05核心链路调用

这里可能是为了高并发考虑,使用copyOnWrite操作,clusterNodeMap是使用static volatile修饰的,如果直接put其他线程无法感知到map内容的变化,通过copyOnWrite操作重新赋值,会使clusterNodeMap地址发生改变,其他线程会感知到变化,保证数据一致性,同时起到读写分离的效果,提高读写并发,同时创建的临时map进行了初始容量的赋值,不会因为扩容导致性能波动。资源调用会创建一个CtEntry,然后开始执行上面创建的执行链。

2023-08-19 16:24:12 65

原创 sentinel源码分析-04核心概念介绍

sentinel中的资源类,可以通过注解SentinelResource指定资源,具体的资源类是ResourceWrapper,包装了name和entryType属性,用户可以为需要保护的对象创建一个资源类,然后再配置相对于的规则就可以实现对资源的保护,同时资源和规则是解耦的,而且规则可以在运行时进行修改。

2023-08-12 18:22:19 107

原创 sentinel源码分析-03构建执行链

这里又是通过SPI机制获取所有SlotChainBuilder的实现类,查看META-INF.services下的com.alibaba.csp.sentinel.slotchain.SlotChainBuilder文件。上文中我们分析了核心逻辑入口是SphU.entry(target, EntryType.IN),我们只分析了一些初始化逻辑下面,我们分析一下核心限流处理逻辑。首先查看之前线程有没有创建了context,如果已经有了就直接获取,如果没有则创建默认的context。这里主要完成以下几个事情。

2023-08-12 17:50:07 48

原创 sentinel源码分析-02客户端处理服务端下发请求

这里代码比较长,其实主要逻辑就是将字符串请求解析为CommandRequest请求,根据请求获取对应的处理器,如果没有找到返回错误请求,如果有对象请求处理器,则执行命令处理然后返回请求结果。到这里我们分析完了服务端下发命令到客户端后客户端是如何处理请求和保存数据的,我们发现这些数据都保存在内存中,组件重启就会丢失,所以需要外部持久化存储规则数据。sentinel客户端中会存储一些限流规则而这些限流规则是我们通过页面配置后由服务端下发下来的,下面让我们来看看客户端是如何接收服务端下发的命令的。

2023-08-06 14:26:55 81

原创 sentinel源码分析-01客户端启动和注册

w.func.init()方法会执行每个InitFunc实现类的init()方法,根据InitOrder注解对初始化实现类进行排序,值越小优先级越高,会先执行CommandCenterInitFunc和HeartbeatSenderInitFunc的init方法。这里通过SPI机制会去加载META-INF/services/下的com.alibaba.csp.sentinel.init.InitFunc文件获取InitFunc接口的实现类。查看CommonFilter.doFilter方法。

2023-08-06 14:23:23 151

原创 netty源码浅析-池化内存PoolThreadCache分配

其实PoolArena中的中的数组,如tinySubpagePools中的元素其实也是双向链表,他会把我们第一次申请的元素连接到数组中的head下,这样我们如果在下次需要申请和之前申请的长度相同时,就可以快速找到相同大小的已经分配的poolChunk,然后就可以直接通过这个page已经切分后的subpage进行分配了。这里我们看下分配后的大小分类说明。上面我们已经分析了没有命中缓存的分配方式,会分配一段连续的内存来分配,现在我们来分析一下名字缓存的分配方式,这个实现就在PoolThreadCache中。

2023-07-30 15:39:50 60

原创 netty源码浅析-PooledByteBuf扩容操作

在AbstractByteBuf中会有很多调用ensureWritable0的操作,判断需不需要扩容,我们跟踪到这个方法中,如果需要写入的空间比可写内存小则直接返回,不需要扩容,如果不是则重新计算需要扩容的长度。这里会先判断需要扩容的大小不能超过最大值,如果大小超过了4M,则每次向上取整获取扩容的大小,如果小于4M,则以64开始每次翻一倍,获取大于minNewCapacity的扩容值。我们上面分析了分配操作和回收操作,部分代码我们在上面已经分析过了,现在我们看下扩容操作。

2023-07-30 15:38:46 79

原创 netty源码浅析-池化内存回收

这里根据bitmapIdx计算在位图数组中的位置,然后将bit为重新设置为0,也就是没有被占用状态,然后设置下一个可用位置就是当前释放的位置,如果可用大小和最大可分配内容不相同则直接返回,说明这个poolSubpage还在被占用,如果相等,查看是不是就一个head节点,如果是也直接返回,如果不是可能是别的poolSubpage加入了pool,则将释放的subpage移除。直接内存通过两种方式释放堆外内存,一种是使用cleaner执行clean方法释放内存,一种是执行unsafe方法释放内存。

2023-07-30 15:38:13 166

原创 netty源码浅析-池化内存直接申请

这里会赋值当前的poolSubpage是属于那个chunk,然后赋值内存分配管理数组下标位置,在这个chunk中的内存起始位置,赋值page的大小,然后创建一个长度为8的位图。比如这里我们是一颗树高度为2,就是[0,0,1,1,2,2,2,2],我们将下标找到这个最左侧的节点,也就是第一个2的位置将其变为了12,然后向上循环修改后的数组为[0,1,2,1,12,2,2,2],这样也就是说明跟节点能分配的大小为8M,他的左子节点能分配的大小为2M,右子节点可以分配4M大小。我们再次回到上面的申请方法。

2023-07-30 15:36:22 114

原创 设计模式-23职责链模式

职责链模式,又叫责任链模式,为请求创建一个接收对象的链,这种模式对请求发送者和接收者进行解耦职责链模式通常每个接受者都包含对另一个接收者的引用,如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依次类推职责链模式属于行为模式设计模式是编程中有意或者无意使用到的,并且同一种设计模式也不是100%的一样,设计模式主要是提高程序的扩展性、可读性、可维护性、规范性设计模式是可以结合使用,源码中可能部分使用到了A模式,也有可能部分使用到了B模式。

2023-07-30 15:17:08 44

原创 设计模式-22策略模式

策略模式中,定义算法族,分别封装起来,让他们之间可以相互替换,此模式算法的变化独立于使用算法的用户策略模式体现了几个设计原则:第一、把变化的代码从不变得代码中分离出来;第二、针对接口编程而不是具体类(定义了策略接口);第三、多用组合或聚合少用继承(客户使用组合方式使用策略)

2023-07-30 15:02:12 33

原创 设计模式-21状态模式

状态模式主要用来解决对象在多种状态转换时,需要对外输出不同的行为问题,状态和行为是一一对应的,状态之间可以相互转换当一个对象的内在状态改变时,允许改变其行为,这个对象看起来像是改变了其类。

2023-07-30 14:58:43 35

原创 设计模式-20解释器模式

在编译原理中,一个算数表达式通过词法分析器形成词法单元,而后这些词法单元再通过语法分析器构建分析树,最终形成一颗抽象的语法分析树,这里的词法分析器和语法分析器都可以看做是解释器解释器模式:是指给定一个语言,定义它的文法的一种表示,并定义一个解释器,使用该解释器来解释语言中的句子(表达式)应用场景:1。应该可以将一个需要解释执行的语言中的句子表示为一个抽象语法树2.一些重复出现的问题可以用一种简单的语言来表达3.一个简单语法需要解释的场景。

2023-07-29 16:32:33 37

原创 设计模式-19备忘录模式

备忘录模式在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可将该对象恢复到原先保存的状态可以这样理解备忘录模式:现实生活中的备忘录是用来记录某些要去做的事情,或者是记录已经达成的共同遇见的事情,以防忘记。而在软件层面,备忘录模式有着相同的意义,备忘录对象主要用来记录一个对象的某种状态,或者某些数据,当要做回退时,可以从备忘录对象里获取原来的数据进行恢复操作备忘录模式属于行为型模式。

2023-07-29 16:31:07 53

原创 设计模式-18中介者模式

中介者模式,用一个中介对象来封装一系列的对象交互,中介者使各个对象不需要显示地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的关系中介者模式属于行为型模式,使代码更易于维护比如MVC模式,controller使Model和View的中介者,在前后端交互时起到了中间人的作用。

2023-07-29 16:29:42 41

原创 设计模式-17观察者模式

观察者模式:对象之间多对一的一种设计方案,被依赖的对象为subject,依赖的对象为observer,subject通知Observer变化,比如这里的奶站是subject,是1的一方,用户是Observer,是多的一方。observer:接收输入,主要是update()方法。实现一个不同网站请求天气网站,获取天气不断变化的功能。subject:等级、移除、通知。观察者模式类似于定牛奶业务。

2023-07-29 16:27:55 34

原创 设计模式-16迭代器模式

迭代器模式属于行为型模式如果我们的集合元素是用不同的实现的,有数组,还有java的集合类,或者还有其他方式,当客户端要遍历这些集合元素的时候就要使用多种的遍历方式,而且还会暴露元素的内部结构,可以考虑使用迭代器模式迭代器模式,提供一种遍历集合元素的统一接口,用一直的方法遍历集合元素,不需要知道集合对象的底层表示,即:不暴露内部结构。

2023-07-29 16:26:23 31

原创 设计模式-15访问者模式

访问者模式,封着了一些作用于某些数据结构的各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的操作主要将数据结构和数据操作分离,解决数据结构和操作耦合性问题访问者模式的基本工作原理是:在被访问的类里面加一个对外提供接待访问者的接口访问者模式主要应用场景是:需要对一个对象结构中的对象进行很多不同的操作(这些操作彼此没有关联),同时需要避免让这些操作“污染”这些对象的类,可以选用访问者模式解决。

2023-07-29 16:23:30 50

原创 设计模式-14命令模式

命令模式:在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需要在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式进行设计命令模式使得请求的发送者和接收者消除彼此之间的耦合,让对象之间的调用关系更加灵活,实现解耦在命令模式中,会将一个请求封装成一个对象,以便使用不同参数来表示不同的请求,同时命令模式也支持撤销的操作。

2023-07-29 16:21:17 34

原创 设计模式-13模板模式

模板方法模式,在一个抽象的类公开定义执行它的方法的模板,它的子类可以按需要重写方法实现,但调用将以抽象类中的定义执行简单说,模板方法模式定义了一个操作中的算法的骨架,而将一些步骤延迟到了子类中,使得子类可以不改变一个算法的结构,就可以重定义改算法的某些特定步骤模板模式属于行为型设计模式。

2023-07-29 16:19:27 31

原创 设计模式-11享元模式

享元模式也叫蝇量模式,运用共享技术有效的支持大量细粒度的对象常用于系统底层开发,解决系统的性能问题,像数据库连接池,里面都是创建好的对象,在这些连接对象中有我们需要的则直接拿来用,避免重新创建,如果没有我们需要的,则重新创建一个享元模式能够解决重复对象的内存浪费的问题,当系统中有大量相似对象,需要缓冲池时,不需总是创建新对象,可以从缓存池里拿,这样可以降低系统内存,同时提高效率。

2023-07-29 16:16:47 32

原创 设计模式-12代理模式

代理模式为对象提供一个替身,以控制对这个对象的访问,即通过代理对象访问目标对象,这样做的好处是,可以在目标对象实现的基础上,增强额外的功能和操作,即扩展了目标对象的功能被代理的对象可以是远程对象、创建开销大的对象或者需要安全控制的对象代理模式又不同形式,主要可以分为三种:1)静态代理2)动态代理,也可以成为JDK代理,接口代理3)Cglib代理,可以在内存中动态的创建对象,而不需要实现接口,他是属于动态代理的范畴。

2023-07-29 16:11:58 31

原创 设计模式-10外观模式

外观模式,也叫过程模式,外观模式为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。外观模式通过定义一个一致的接口,用以屏蔽内部子系统的细节,使得调用端只跟这个接口发生调用,而无需关心这个子系统的内部细节。

2023-07-23 16:38:24 37

原创 设计模式-09组合模式

组合模式又叫部分-整体模式,他创建对象组的树形结构,将对象组合成树状结构以表示,**“整体-部分”**的层次关系。组合模式依据树形结构来组合对象,用来表示部分以及整体的层次。组合模式使得用户对单个对象和组合对象的访问具有一致性,即:组合能让客户以一种的方式处理个别对象以及组合对象。

2023-07-23 16:36:43 32

原创 设计模式-08装饰者模式

装饰者模式实现,使单个产品组合和方便,扩展性更好,当新增咖啡类型和调料的时候只需要继承coffee和Decorator就可以实现扩展,特别方便。装饰者模式:动态的将新功能附加到对象上,在对象功能扩展方面,他比继承更有弹性,装饰者模式也体现了开闭原则(OCP)。2、动态的为一个对象增加功能,而且还能动态撤销。(继承不能做到这一点,继承的功能是静态的,不能动态增删。源码案例:java的IO结构,FilterInputStream就是一个装饰者。缺点:产生过多相似的对象,不易排错!1、需要扩展一个类的功能;

2023-07-23 16:35:16 50

原创 设计模式-07桥接模式

桥接模式基于类的最小设计原则,通过使用封装、聚合、继承等行为让不同的类承担不同的职责,他的主要特点就是把抽象与行为实现分离开来,从而可以保持各部分的独立性以及应对他们功能的扩展。源码使用:jdbc的driver接口,driver就是一个接口,下面可以有MySQL的Driver和oracle的Driver,这些可以看做是实现接口。介绍:将实现与抽象放在两个不同的类层次中,是两个层次可以独立改变。案例:打印小米、vivo品牌,折叠和翻盖手机的组合。

2023-07-23 16:33:58 26

原创 设计模式-06适配器模式

基本介绍:adapter类,通过继承src类,实现dst类接口,完成src-》dst的适配。

2023-07-23 16:32:09 34

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除