- 博客(50)
- 收藏
- 关注
原创 时间轮算法解析
这里最简单,就是每来一个任务,这边就定义一个线程,然后通过sleep来延迟执行任务,通过while循环来周期性的执行任务上面那种方式存在问题就是每个任务我都需要创建一个对应的线程,这个时候如果系统中有大量的定时任务,那么在调度切换的时候性能消耗会非常大,而且线程数多也会占用系统资源,不适合大规模场景下的定时任务。
2023-03-26 23:03:34
1088
1
原创 Dubbo源码解析-——服务引用
在之前我们讲过Spring和Dubbo的集成,我们在服务上标注了@Reference的注解,然后最终Dubbo会调用到ReferenceBean#get方法中来返回一个代理对象,本次我们就来剖析下服务引用的全流程。
2023-03-26 18:45:52
863
原创 JDK源码系列——线程池源码解析
这个是线程保持空闲的时间,可能很长一段时间都没有任务提交过来,那么线程池中的线程都处于空闲状态,但是他们还占用资源,所以当线程数量超过了核心线程数,并且有线程超过了keepAliveTime时间一直处于空闲状态,那么就会把他干掉,直到线程数减少到核心线程数。这里你可能想问为啥不再继续创建线程,反正还没到最大线程数,再创建线程当然可以,但是如果核心线程数处理的很快,可能过了很短的时间就能空闲出来继续处理任务,那么就可以避免掉线程频繁创建销毁的开销了。这里我们创建了一个线程池,并且批量往线程池中提交任务。
2023-03-05 23:31:36
1526
原创 Dubbo源码解析-——服务导出
首先获取到class的类名,例:ProviderConfig然后判断如果以指定后缀结尾的则去除掉,SUFFIXES = new String[]{“Config”, “Bean”},这里的ProviderConfig会变成Provider然后把Provider全转成小写的,也就是provider返回> cls) {break;return tag;这个方法就是判断类型是不是基本数据类型或者是基本数据的包装类型或者是Object类型> type) {
2023-03-05 18:30:54
733
原创 Zookeeper源码环境搭建
这里我们分别启动zoo-1,zoo-2,zoo-3,发现启动zoo-1的时候就报错了,类找不到,这是因为zookeeper-server模块的pom.xml文件部分依赖的scope是provided的,只有编译和测试环境中依赖才起作用,想在运行时也起作用,可以将provided改为compile,或者去掉scope,因为默认scope是compile,编译,运行,测试环境依赖都起作用。这里我们把zoo-2给kill掉,我们发现zoo-3重新选举成leader了,集群已经实现高可用。
2023-02-26 21:58:34
662
原创 Dubbo源码解析-——SPI机制
SPI 全称为 Service Provider Interface,是一种服务发现机制。SPI 的本质是将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实现类。这样可以在运行时,动态为接口替换实现类。正因此特性,我们可以很容易的通过 SPI 机制为我们的程序提供拓展功能。
2023-02-26 19:06:33
3440
1
原创 spring注解方式整合Dubbo源码解析
ConfigureBean的前置操作然后设置注册中心配置,监控中心配置,应用配置,模块配置等ConfigureBean的后置操作这里设置配置的逻辑一致,都是从@Reference注解中获取对应的配置名,然后从spring容器中找到对应的配置Bean,然后设置到属性中。
2023-02-19 20:53:55
2589
原创 Sentinel源码解析-ProcessorSlot具体
判断上一次请求重试的时间距离当前时间有没有过重试间隔这里首先把熔断器状态成OPEN变更HALF_OPEN如果请求发生异常,则会把状态再从HALF_OPEN变成OPEN状态注:这里我们只看到了断路器状态从HALF_OPEN变成OPEN,和从OPEN变成HALF_OPEN,那么从CLOSE状态变成OPEN状态和从HALF_OEPN状态变成CLOSE状态我们还没看到,我们后续看下方法。
2023-02-12 15:03:22
696
原创 Sentinel源码解析-请求入口
首先是这个Tree,这个Tree是由NodeSelectorSlot这个插槽来创建的,每创建一个树都有一个Root节点,这个Root节点就代表的是一个应用,一个应用只会创建一个Root节点。这里首先判断注解中有没有指定资源名,如果指定了资源名就用注解指定的,如果没有指定资源名,则通过解析方法,通过通过方法所在类+方法名+方法参数类名拼接出来一个资源名。这里看好像是环境的初始化操作,初始化需要的对应组件,不是主线逻辑,我们在Env中已经知道。:统计节点,是Node接口的实现类,用于完成数据统计。
2023-02-05 16:45:23
798
1
原创 Sentinel源码解析-源码环境搭建
本文会讲解如何搭建Sentinel源码调试环境,以方便更好的debug源码,如果对sentinel还不了解的话,可以先参考官方文档:Sentinel官方文档这里controller提供的两个api都会去调用TestService,我们的流控规则也定义在testService中这里方法都通过SentinelResource注解来标注成一个资源,并指定了资源名和callback方法和处理BlockException的handler。我们运行DemoApplication,启动这个demo服务。这里d
2022-12-03 17:57:25
894
原创 JDK源码系列——ReentrantReadWriteLock源码解析
> 1. ReentrantReadWriteLock提供了读写锁,适用于读多写少的场景,提高吞吐量> 2. 读写锁读读不互斥,读写互斥> 3. 当一个读线程获取锁的时候,不是一次性唤醒后续等待的所有读线程,而是接力一个接一个唤醒的,可能是为了防止同时过多的上下文切换> 4. 只有多个读锁都完全释放了才会唤醒下一个写线程,这种场景下可能会导致写线程饥荒,因为一直存在读线程。...
2022-07-10 22:36:50
480
原创 JDK源码系列——ReentrantLock源码解析
ReentrantLock是一个可重入锁,其底层是基于AQS来实现的,AQS(AbstractQueuedSynchronizer),它是java几乎所有锁和同步器底层的一个基石框架,AQS是基于FIFO的队列实现,内部维护了一个状态变量state,通过CAS更新这个状态变量来实现枷锁解锁等操作。...
2022-07-10 21:21:32
299
原创 springboot源码分析——启动流程分析
本文剖析SpringBoot启动时候做了哪些事情。2.1 、prepareRefresh:初始化前的预处理如果规则匹配,则会进入下面的 findPathMatchingResources 方法2.5.2、ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry2.5.2.2、ConfigurationClassParser#parse2.5.2.2.1、ConfigurationClassParser#proces
2022-07-10 18:41:04
1956
2
原创 JDK源码系列——PriorityQueue源码解析
优先级队列是包含0个或多个元素的集合,每个元素都一个权重值,每次出队弹出优先级最大或最小的元素,优先级队列是使用堆来实现了,所以大家看之间需要首先掌握堆结构。
2022-07-03 18:31:40
322
原创 spring源码学习——前置知识
本文主要讲解spring源码分析需要的一些前置知识,如果已经掌握可以进行跳过。4、BeanDefinition是如何生成的5、设计BeanDefition的意义10、BeanDefinitionRegistry1、BeanDefinitionRegistry概述
2022-07-02 20:58:37
788
原创 springboot源码分析——自动装配实现原理
从下图可以看出来他是一个组合注解,等价于同时标注`@Configuration`+`@EnableAutoConfiguration`+`@ComponentScan`注解。> 1. `@ComponentScan`作用:可以指定包扫描的跟路径,不指定路径默认扫描当前配置类所在包及其子包里的所有组件> 2. `@SpringBootApplication`作用:这个注解是被`@Configration`注解标注,说明他其实是用来标注配置类的,而且是标注主启动类的。> 3. `@EnableAutoC.
2022-06-26 21:56:43
668
1
原创 JDK源码系列——ConcurrentHashMap源码分析
由于HashMap不是线程安全的,在多线程环境下可能会发生错乱,死循环等问题,而HashTable虽然是线程安全的,但是是直接在方法上添加Synchronized来保证线程安全的,在高并发的情况下效率十分低下,因为读写也是互斥的。而ConcurrentHashMap是HashMap的线程安全版本,由于内部结构设计的优化,导致相比HashTable效率各方面都有极大的提高这里分段锁的实现很值得学习,通过分段的方式扩大并发度,从而提升读写效率,而且这里统计的时候也是没有直接加锁,而是采用了一种折中的方案,先进行
2022-06-26 16:22:07
521
原创 redis——基础数据结构
redis中每个键值对都是由对象组成,其中:优点:3.快速链表结构2. 跳表的随机层数3. 如果zset中的值的score值都一样,查找性能会退化成O(n)么?
2022-06-25 20:21:05
1210
原创 JDK源码系列-LinkedHashMap实现原理
为什么有了还需要,因为是通过的方式进行插入元素,所以迭代的时候并不是插入的顺序,有些场景下我们需要实现一个有序的,就比如缓存策略,这个时候就可以使用,它内部维护了一个双向链表,能根据元素的访问顺序遍历或根据元素的插入顺序遍历。这里发现的实现非常简单,都是通过中留下的钩子函数来实现扩展逻辑,不需要再重写put,方法了,所以在做代码的设计上一定要预留足够的扩展点,以方便后续的功能扩展。...
2022-06-25 16:07:27
364
原创 JDK源码系列-CopyOnWriteArrayList实现原理
CopyOnWrite是一种读写分离的思路,写入的时候会对原数组copy一份出来然后再做修改,适用于读多写少的场景,可以最大程度提升读效率。从上面方法的源码流程可以看出也是存在很多的弊端的,因为读写分离,其实我们读取的数据可能不是最新的一份数组,所以不保证实时一致性,只保证最终一致性,而且如果是读写均匀或者写多读少的情况下,那么就会造成存在多份副本数据,这个时候就会造成频繁的。...
2022-06-25 15:08:58
281
原创 nacos源码解析——集群间数据同步
之前分析过,是一个的注册中心,他的节点间数据同步是通过来进行的,而既是系统也是系统,临时节点的数据是存储在内存中,节点间的同步是通过方式,永久节点则是通过来实现数据的一致性的,是属于的。,然后交给线程执行,我们之前分析过,在处理的时候会调用方法,所以我们看下...
2022-06-19 18:26:34
4475
原创 nacos源码解析——服务发现
之前我们学习过,知道服务发现有推拉两种方式,也支持两种服务发现方式,一种是直接去服务端拉取某个服务的实例列表,另一种就是服务订阅的方式,就是订阅某个服务,然后这个服务下面的实例列表一旦发生变化,服务端会通过的方式通知到客户端。...
2022-06-19 16:29:51
1428
原创 nacos源码解析——服务下线
服务下线分为两种,一种是客户端主动调用服务的接口发起下线请求,第二种就是服务故障,然后过长时间没有向服务端发送心跳,然后服务端也会启动一个定时任务,来定时剔除这种故障服务1.5、ServiceManager#removeInstance这里就是讲解了两种下线方式的源码流程,重点是故障下线,实例会通过定时任务发送心跳来进行续约,然后服务端也会启动一个定时任务来定期检测长时间没有收到心跳的实例则会进行剔除。...
2022-06-12 19:17:15
6968
原创 nacos源码解析——服务注册
我们下载下来的的源码中,在他提供的测试类中有一个叫做,其中有服务注册的,我们就从这个例子来剖析服务注册的流程。1.2 、NacosNamingService构造方法1.2.1 、NacosNamingService#init1.3 NacosNamingService#registerInstance1.3.1、NamingClientProxyDelegate#registerService1.3.2、NamingHttpClientProxy#registerService
2022-06-12 17:58:25
1441
原创 Eureka源码解析——客户端初始化
Eureka Client实例化有以下几个重点步骤1. 全量拉取注册表信息,放入本地2. 创建服务续约,增量拉取注册表,实例变更重新注册等一系列的定时任务
2022-06-05 21:43:31
292
原创 Eureka源码解析——增量拉取注册表
注意这里首先加了一个写锁,之前讲解服务注册、续约、下线的时候都是使用读锁,这里使用读锁就是为了保证这一刻注册表的数据不发生变更。至于为什么这里查询加读锁而注册,下线等修改操作加读锁还是为了减少锁竞争。> 流程解析:> 1. 遍历`recentlyChangedQueue`队列(包含服务注册,下线等变更信息,这个队列只保存三分钟),将队列的实例信息添加到一个集合中> 2. 获取全量注册表实例信息,生成一个`hashcode`,这个`hashcode`会返回给客户端,这个`hashcode`是校准使用的.
2022-06-05 20:48:02
1113
原创 eureka源码解析——全量拉取注册表
在自动装配的时候会装配到容器中,在的标注了注解,所以在对象构造后会回调这个方法,在方法中会调用注册表的方法,在方法中会创建多级缓存并初始化
2022-06-05 18:33:41
573
原创 eureka源码解析——服务故障自动剔除
服务注册到`eurekaServer`上之后,会定时`30s`发送心跳请求来进行续约,如果服务宕机了或者其他情况导致没有主动向`EurekaServer`发送服务下线请求,那么`EurekaServer`在后台会启动一个定时后,默认`60s`扫描一次注册表,看看哪些服务实例规定时间没有发送续约请求,将这些故障实例从注册表剔除。...
2022-06-05 17:45:57
576
原创 eureka源码解析——服务主动下线
服务主动下线,客户端请求下线接口会调用到服务端的`InstanceResource#cancelLease`处理下线,这里直接调用注册表的`cancel`方法进行服务下线
2022-06-05 17:18:55
448
原创 eureka源码解析——服务续约
服务续约使用过心跳来实现了,客户端会开启一个定时任务,定时向eureka server发送续约请求,然后服务端收到续约信息然后更新租约的最后发送时间,在eureka server中也会开启一个定时任务,定时扫描注册表的实例租约信息,然后看最后续约时间距离现在是不是超过了存活时间(90s),如果超过了,就将这个实例从注册表中剔除...
2022-06-05 17:03:48
324
原创 eureka源码解析——服务注册流程
> 1. 更新注册表信息,这里注册表就是一个`map(key是appName,value是Lease(InstanceInfo)),`这个`lease`其实就是租约的相关信息,其中会包含实例信息,`ip,port`和最后一次续约的时间戳,租期等,这里如果判断之前在注册表中就存在的话,看有没有变更过,通过变更时间来判断,如果没有,则继续使用原有的`instance`信息。如果是第一次注册肯定注册表里没有实例信息,那么就会将`expectedNumberOfClientsSendingRenew+1`,这个表示
2022-06-05 16:43:31
417
原创 eureka源码解析——集成到springCloud
> 在引入`eureka`的依赖之后,配置`eureka server`的时候需要我们在`springBoot`的启动类上面加个`@EnbaleEurekaServer`的注解标识启动一个`eureka server`。
2022-06-04 23:23:57
228
原创 Apollo源码解析——集成到springboot
`ApolloApplicationContextInitializer`实现了两个接口`ApplicationContextInitializer`和`EnvironmentPostProcessor`,`Spring Boot`启动过程,会先调用`EnvironmentPostProcessor.postProcessEnvironment`方法,再调用`ApplicationContextInitializer.initialize`方法。也就是`Spring Boot`优先准备环境,再初始化容器。.
2022-06-03 15:51:57
1013
原创 Apollo源码解析——客户端通知配置变化(客户端长轮询请求接口)
文章目录一、概述二.代码流程一、概述在之前讲解配置发布的时候,NotificationControllerV2 得到配置发布的 AppId+Cluster+Namespace 后,会通知对应的客户端 ,实现在handleMessage方法中具体的实现流程是:客户端发起长轮询请求NotificationControllerV2不会立即返回结果,而是通过Spring Deferredresult把请求挂起。如果60s没有客户端关心的配置发布,那么就会返回403给客户端如果有客户端关心的配置,N
2022-05-29 22:47:32
631
原创 Apollo源码解析——ConfigService配置读取接口(客户端定时拉取接口)
文章目录一、概述二、代码流程一、概述上文讲了客户端定时轮询的接口,这里我们看下Config Service配置读取的接口的实现。二、代码流程1. ConfigController#queryConfig方法代码很长,但是大体流程就是根据客户端的参数从服务端查询出来最新的配置,然后根据clientSideReleaseKey和服务端的ReleaseKey进行比较,判断配置有没有更新,这里重点看下loadConfig方法,怎么加载最新的配置 @GetMapping(value = "/{
2022-05-29 21:46:26
1458
原创 Apollo源码解析——Client轮询拉取配置
文章目录一、概述二.代码流程一、概述Client的轮询包括两部分:RemoteConfigRepository,定时轮询Config Service的/configs/{appId}/{clusterName}/{namespace} 接口的配置读取RemoteConfigLongPollService 长轮询 Config Service的配置变更通知 /notification/v2接口二.代码流程1. AbstractConfigRepository#trySync方法客户
2022-05-29 21:14:28
518
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人