欢迎来到皮皮网官网

【csr8635源码】【xp 源码】【executeBatch源码】dubbo计算公式源码_dubbo实战与源码分析

时间:2024-11-15 06:11:34 来源:youget 源码

1.HashMap底层实现原理及Dubbo
2.《深潜Dubbo》· HashedWheelTimer定时轮算法

dubbo计算公式源码_dubbo实战与源码分析

HashMap底层实现原理及Dubbo

       一、算公式源实战学习内容

       1. Java中HashMap的源码底层实现原理

       1) HashMap的数据结构

       JDK1.8以前 HashMap 的实现是 数组加链表

       JDK1.8开始 HashMap 的实现是 数组加链表加红黑树

       HashMap中有两个常量:

       当链表中节点数量大于等于TREEIFY_THRESHOLD时,链表会转成红黑树。分析

       当链表中节点数量小于等于UNTREEIFY_THRESHOLD时,算公式源实战红黑树会转成链表。源码

       2) HashMap的分析csr8635源码三个构造函数

       HashMap():构造一个具有默认初始容量 () 和默认加载因子 (0.) 的空 HashMap。

       HashMap(int initialCapacity):构造一个带指定初始容量和默认加载因子 (0.) 的算公式源实战空 HashMap。

       HashMap(int initialCapacity,源码 float loadFactor):构造一个带指定初始容量和加载因子的空 HashMap。

       关于构造器中的分析参数:

       initialCapacity:初始容量,初始容量数值没有存起来,算公式源实战而且使用它计算阀值threshold。源码计算方法就是分析返回大于initialCapacity且最接近initialCapacity的一个2的正数幂的数字作为初始阀值。

       capacity:容量。算公式源实战capacity就是源码指HashMap中桶的数量。默认值为。分析一般第一次扩容时会扩容到,之后都是以2的幂数增加。

       loadFactor:装载因子,用来衡量HashMap满的程度,加载因子越大,填满的元素越多,空间利用率越高。loadFactor的默认值为0.f。计算HashMap的实时装载因子的方法为size/capacity。

       threshold:阀值,xp 源码满足公式threshold=loadFactor*capacity。当HashMap的size大于threshold时会执行扩容(resize)操作。

       3) HashMap的工作原理

       HashMap基于hashing原理,我们通过put()和get()方法储存和获取对象。当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算hashcode,让后找到bucket位置来储存值对象。当获取对象时,通过键对象的equals()方法找到正确的键值对,然后返回值对象。HashMap使用链表来解决碰撞问题,当发生碰撞了,对象将会储存在链表的下一个节点中。 HashMap在每个链表节点中储存键值对对象。

       当两个不同的键对象的hashcode相同时它们会储存在同一个bucket位置的链表中。键对象的equals()方法用来找到键值对。

       2. 学习框架dubbo

       1) zookeeper的安装以及配置

       安装教程: my.oschina.net/langwang...

       2) 几种架构:

       单一应用架构:

       背景:网站流量很小,只需一个应用将所有功能部署在一起,减少部署节点和成本。

       此时,用于简化增删改查工作量的数据访问框架(ORM)是关键

       垂直应用架构:

       背景:访问量逐渐增大,通过将应用拆分成互不相干的executeBatch源码几个应用以提升效率。

       此时,用于加速前端页面开发的Web框架(MVC)是关键

       分布式服务架构:

       背景:垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来作为独立的 服务,成为稳定的服务中心,使得前端应用能更快速地响应多变的市场需求。

       此时,用于提高业务复用及整合的分布式服务框架(RPC)是关键

       流动计算架构:

       背景:服务越来越多,显现出小服务资源的浪费等问题,需要增加一个调度中心基 于访问压力实时管理集群容量,提高集群利用率

       此时,用于提高机器利用率的资源调度和治理中心(SOA)是关键

       3) 什么是dubbo?它做些什么

       Dubbo :Dubbo是阿里旗下的一个弹性的分布式服务框架,致力于提供高性能和 透明化的RPC远程服务调用方案,以及SOA服务治理方案。

       作为RPC:支持各种传输协议

       作为SOA:具有服务治理功能,提供服务的注册和发现!用zookeeper实现注册中 心!

       4) 描述一个服务从发布到被消费的详细过程:

       一个服务的发布暴露过程:

       首先设置一个项目的别名,然后是定义注册中心和设定传输协议,之后定义服务名, 服务接口以jar形式导入到provider。一个服务发布暴露首先由spring的kubeapiserver源码spacehander 把相关的xml或者注解全部转化为springBean,之后通过ServiceConfig.exerp()方法 把bean传化为传输所需的url和参数注册到注册中心,发布后provder端的 ref(helloImpl)通过protocl(传输协议,如dubboprotocl,hessionprotocl)转化为Invoker 对象,即调用信息,包括类,方法,参数等等,再通过proxy操作(代理)如jdkproxy 代理转为为Exporter对象,以上就是整个的服务暴露过程。

       消费过程:

       一个Renfence类,通过RenfenceConfig的init 调用proxy的refer方法生产一个 invoker,invoker再通过proctol转化成具体的ref(hello),进行消费

       首先 ReferenceConfig 类的 init 方法调用 Protocol 的 refer 方法生成 Invoker 实 例(如上图中的红色部分),这是服务消费的关键。接下来把 Invoker 转换为客户端 需要的接口(如:HelloWorld)

       5) dubbo调用流程

       首先介绍dubbo中的几个角色:

       服务提供者(Provider)、服务消费者(Consumer)、注册中心( Registry)、监控中 心(Monitor)

       具体的调用流程:

       0. 服务容器负责启动、加载,运行Provider。

       1. Provider在启动时,向Registry注册自己提供的服务,Registry缓存服务列表,并建立长连接心跳检测。

       2. Consumer在启动时,sdio源码向Registry订阅自己所需的服务,并建立长连接心跳检测。

       3. Registry返回服务提供者地址列表给Consumer并缓存,如果服务有变更,Registry将基于长连接推送变更数据给Consumer并更新。

       4. Consumer在使用服务时,基于软负载均衡算法,从提供者地址列表中,选一台Provider进行调用,如果调用失败,则切换到另一台调用。

       5. Consumer和Provider,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到Monitor。

       6) 创建一个dubbo demo,并且成功运行

       代码结构:

       3. 其他内容

       重新配置电脑开发环境

       二、存在的问题

       1. 问题解决记录

       1) 安装zookeeper报错:JAVA_HOME is not set

       主要原因:zookeeper在启动服务端的时候回基于Java环境启动,所以在启动的时候会检测jdk是否安装,在zkservice启动的时候会找%JAVA_HOME%\bin\java.jar 进行java基础环境的启动。在zkEvn文件里有JAVA_HOME的验证,本身我已经设置了JAVA_HOME这个变量,但是在验证的时候没有获取到,所以解决的办法就是手动设置,在zkEvn.cmd文件中添加下面的语句

       详细解决办法: cnblogs.com/china-baizh...

       2. 未解决问题

       对dubbo一个服务的发布暴露过程以及消费过程的细节部分不理解

       三、明天学习计划

       1. 开始算法部分的学习(算法设计中的五大常用算法)

       2. 对前面近五天的内容进行回顾和总结,设计数据库

《深潜Dubbo》· HashedWheelTimer定时轮算法

       HashedWheelTimer定时轮算法被广泛应用,包括netty、dubbo乃至操作系统Linux,主要用于管理及维护大量Timer调度算法。

       HashedWheelTimer呈环形结构,类似时钟,分为众多槽位,每个槽位代表一个时间间隔,存储定时任务的双向链表。指针周期性跳动,到达某个槽位即执行该槽位定时任务。

       定时轮实现中,根据职责不同,分为时钟引擎、时钟槽、定时任务三个主要角色,深入理解其实现,本文将略去具体实现语言的特性。

       定时任务——HashedWheelTimeout在具体实现中扮演双重角色,既是双向链表的节点,也是实际调度任务TimerTask的容器。引擎在滴答运行起始时刻使用&取hash装入对应的时钟槽。

       关键属性包括:next和prev(当前定时任务在链表中的前驱和后继引用)、task(实际被调度的任务)、deadline(时间单位为纳秒,由currentTime + delay - startTime计算得出)、state(定时任务当前所处状态,如INIT、CANCELLED、EXPIRED)。

       HashedWheelTimeout支持的操作有限,如时钟槽——HashedWheelBucket,它是一个用于缓存和管理定时任务的双向链表容器,每个节点即一个定时任务。持有链表的首尾两个节点,可以完成相关操作。

       时钟引擎——HashedWheelTimer有节律地周期性运作,根据当前时钟滴答选定对应时钟槽,从链表头部开始迭代,对每个任务计算是否属于当前时钟周期,属于则执行,否则执行减一操作。

       时钟引擎维持两个缓存定时任务的阻塞队列,一个用于接收外界提交的任务,另一个用于缓存主动取消的任务。引擎需要在滴答开始期间将它们装入对应的时钟槽或从中移除。

       关键属性包括:timeouts和cancelledTimeouts(队列,用于缓存外界提交或取消的任务)、workerState(定时轮当前所处状态,如init、started、shutdown)、startTime(当前定时轮正式开始调度任务的时间)、ticks(滴答,步长为1的单调递增计数)、ticksDuration(滴答时长)、pendingTimeouts(当前定时轮实时任务剩余数)、n(时钟轮槽数)、mask(掩码)。

       引擎内核——Worker,时钟引擎分为对外接口和调度运行两部分,可以想象内核是引擎的心脏起搏器,驱动定时轮运行,完成任务调度。实现上对应一个工作线程。

       内核状态包括:状态机是关键组成部分,因此状态值控制对其至关重要。内核状态由定时轮维护管理,对外提供的接口都要借助它实现。初始时为init状态,当引擎被设计为不可复活时,不存在init/started/shutdown → init这样的迁移过程。

       外部接口包括:start(用于定时轮开启引擎)、stop(完成定时轮引擎的关闭过程,返回未被处理的定时任务)、Timeout newTimeout(用于向引擎提交任务)。

       调度运行:简单而言,就是周期性地执行滴答操作,包括相邻两个滴答周期的开始时间理论上等距,但结束时间会随该周期所需处理任务的数目及时长变化。因此,引擎剩下的休眠时间需要使用特定公式获得。

       定时轮在dubbo中的应用:实际上,定时轮算法并不直接用于等周期性地执行某些提交任务,向其提交的任务只会到期执行一次。但具体应用中,会利用每次任务的执行,调用newTimeout()提交Timer所引用的当前任务,使其在若干单位时间后重新继续执行。

       Dubbo中对定时轮的应用主要体现在以下几个方面:定时轮用单一的线程去管理触发Task的运行,Task执行期间,不能直接抛异常,否则会导致整个定时轮引擎崩溃而使得提交的后续任务无法执行。

       周期任务:在dubbo中,每个连接被表征为一个Channel通道,dubbo节点间建立连接相互通信,单个节点需要维护和多个连入节点的连接。基本的步骤如下:

       失败重试:网络情况的复杂多变性使得一件原本在单机上很轻易的事情,在分布式应用中,为确保某类型的操作能发生可能需要重试多次。

copyright © 2016 powered by 皮皮网   sitemap