- 博客(84)
- 收藏
- 关注
原创 Skywalking的DataCarrier
之前分析源码时经常会看到DataCarrier这个类,现在详细分析一下这个。简单来说就是维护了一个本地的轻量级消息队列模型,主要目的为了防止收集方生成数据速度大于往后端发送数据速度造成的数据积压和生成方阻塞。这里有几个关键类:DataCarrier 主要类型,针对内存消息队列的操作都是以这个类为入口的。 该类持有了Channels和IDriverChannels 数据通道集合,用于针对数据的存取操作。主要有以下属性:bufferChannels 数据的存取操作dataPartitioner
2021-10-18 16:37:14 974
原创 OAP处理GRPC消息
OAP处理GRPC消息启动时SPI注入的模块TraceModuleProvider,start方法中注入了两种协议的处理器(grpc和rest):@Overridepublic void start() { GRPCHandlerRegister grpcHandlerRegister = getManager().find(SharingServerModule.NAME) .
2021-10-15 16:19:40 608
原创 Skywalking的OAL分析(二)
前文提到Skywalking oal运行时解析core.oal语法生成AnalysisResult对象集合。Antlr4的解析过程做了些什么呢?从oal-rt工程中很容易找到OALListener,可以明确使用的是Antlr4的监听模式。里面的代码不是很复杂,就是在Antlr4遍历语法树的时候,将语法中每个词加入到当前AnalysisResult对象中。但是,光有这些词有什么用呢? 我们看一下AnalysisResult类,里面有很多属性,有些是对象类型,这些属性的赋值不是只是解析语法树就能填充的。
2021-10-14 11:33:59 692
原创 Skywalking的OAL分析(一)
oal-观测分析语言(Observability Analysis Language),Skywalking定义的一套高级语法,用于聚焦服务, 服务实例以及端点的度量指标。 语法分析使用的Antlr4框架,主要是要定义.g4文件用于描述词法分析和语法解析。Skywalking的oal,对应的.g4文件在oal-grammar工程中,主要是两个文件: OALLexer.g4 OALParser.g4 这里先不详细展开了。 可以理解成oal定义了一套高级查询语法,主要目的是对于a.
2021-10-14 10:42:25 1485
原创 RocketMQ十四、Broker处理Consumer请求
首先我们知道RocketMQ是将Producer发来的消息全部放入CommitLog里面,消费时是通过维护ConsumerQueue来帮助Consumer进行消费。当Broker收到Consumer的pull请求时,会先读取ConsumerQueue得到offset,然后再读取CommitLog得到消息内容。我们看一下broker启动时初始化的处理pull请求的处理器:this.remotingServer.registerProcessor(RequestCode.PULL_MESSAGE, thi.
2021-05-28 15:27:57 432
原创 RocketMQ十三、Broker的消息接收
先回过头来看一下broker启动时注册的消息处理器:public void registerProcessor() { /** * SendMessageProcessor */ SendMessageProcessor sendProcessor = new SendMessageProcessor(this); sendProcessor.registerSendMessageHook(sendMessageHookList); sendProces
2021-05-28 10:59:46 252
原创 RocketMQ十二、Broker启动
本篇开始介绍Broker部分的内容,主要包括Broker的启动、消息的接收、消息的处理。broker的启动主要分为两个过程,即initialize初始化和start启动BrokerStartup类的main方法:public static void main(String[] args) { start(createBrokerController(args));}其中createBrokerController方法初始化过程,start方法启动过程initializepublic
2021-05-28 10:21:22 871
原创 RocketMQ十一、消息存储(3)
本篇我们分析一下整体存储的流程。首先入口方法DefaultMessageStore的putMessage方法:@Overridepublic PutMessageResult putMessage(MessageExtBrokerInner msg) { // 状态检查 PutMessageStatus checkStoreStatus = this.checkStoreStatus(); if (checkStoreStatus != PutMessageStatus.PUT_
2021-05-27 16:17:49 131
原创 RocketMQ十、消息存储(2)
分析一下RocketMQ消息存储中的几个关键对象。MappedFileRocketMQ的文件操作是基于MappedByteBuffer操作的,MappedFile类是对MappedByteBuffer的包装,具有创建文件(使用非堆区内存), 写入, 提交, 读取, 释放, 关闭等功能, RocketMQ使用该类实现数据从内存到磁盘的持久化。其中:属性fileChannel: 该类对应的文件通道.mappedByteBuffer: 文件在内存中的映射. 如前文所述RocketMQ使用内存映射的方
2021-05-27 14:16:19 289
原创 RocketMQ九、消息存储(1)
前面提到RocketMQ是基于Topic模型的,这里先简单了解一下broker中是如何存储消息的。首先要知道的,RocketMQ的消息存储是基于文件系统的,主要包含三类文件:CommitLog、ConsumerQueue、IndexFile。其中:CommitLog 消息主体以及元数据的存储主体。 所有producer端写入的消息主体内容都会写入到CommitLog文件中。虽然消息内容的长度不是固定长度的,但是对于CommitLog,每个CommitLog文件是固定长度的,大小是1G(这么做的主要目
2021-05-27 11:13:26 173
原创 RocketMQ八、nameserver的请求处理
继续DefaultRequestProcessor的processRequest方法:@Overridepublic RemotingCommand processRequest(ChannelHandlerContext ctx, RemotingCommand request) throws RemotingCommandException { if (ctx != null) { log.debug("receive request, {} {} {}",
2021-05-14 16:41:12 207
原创 RocketMQ七、rocketMQ的网络通信模块
关于rocketMQ的netty消息处理,实际上都在一个rocketmq-remoting模块中。不管是nameserver还是broker,从netty的handler开始是统一的结构。我们先以nameserver部分的跟踪一下。前一篇看到过netty的启动,我们回过来再看一下:@Overridepublic void start() { ... prepareSharableHandlers(); ServerBootstrap childHandler =
2021-05-14 15:59:32 266
原创 RocketMQ六、NameServer的启动
首先我们先理解nameserver在做什么。简单来说就是一个注册中心,用于管理broker的地址信息和topic的信息,客户端可以通过nameserver获得topic信息,通过topic获取broker相关信息,以及每个broker上topic的queue信息等。也就是说nameserver维护了整个MQ集群的元数据信息,客户端可以通过链接nameserver得到这些信息,以明确将对应的消息发送到哪个broker上去。NameServer的启动NamesrvStartup类的main方法:pu
2021-05-14 15:35:18 397
原创 RocketMQ五、生产消费模型
简单介绍一下我对RocketMQ的topic的结构理解: 每个topic会有多个queue队列,每个queue会有多份分布在不同的broker上,如下图:consumer在消费一个topic时,选择某一个Queue进行消费,同ConsumerGroup下不同的consumer消费的是不同的queue,不同ConsumerGroup下的consumer可以消费同一个queue:...
2021-05-14 11:27:14 243
原创 RocketMQ四、Client的通信
Client -> Broker直接看DefaultMQProducerImpl的send方法:private SendResult sendDefaultImpl( Message msg, final CommunicationMode communicationMode, final SendCallback sendCallback, final long timeout) throws MQClientException, RemotingExcepti
2021-04-29 11:38:33 459
原创 RocketMQ三、Consumer的启动
我们先看一下RocketMQAutoConfiguration的定义:@Configuration@EnableConfigurationProperties(RocketMQProperties.class)@ConditionalOnClass({ MQAdmin.class, ObjectMapper.class })@ConditionalOnProperty(prefix = "rocketmq", value = "name-server")@Import({ JacksonFallb
2021-04-29 10:09:34 1312
原创 RocketMQ二、producer端启动
前面简单了解了一下RocketMQ的使用。本文分析一下producer端的启动流程。首先还是看一下RocketMQ的配置类:@Bean @ConditionalOnMissingBean(DefaultMQProducer.class) @ConditionalOnProperty(prefix = "rocketmq", value = {"name-server", "producer.group"}) public DefaultMQProducer defaultMQPr
2021-04-28 14:27:33 1087
原创 Spring和SpringBoot
前段时间面试的时候有人问到关于Spring和SpringBoot的区别,虽然当时巴拉巴拉说了一大堆,现在回想起来感觉思路不是很清晰。这里就做一下整理吧。由于本人了解的内容有限,可能有些偏差,还请各位大神见谅。Spring先说一下Spring吧,这里主要是指SpringFramework,也就是Spring的工作平台。如果把软件开发比作是盖房子,那么Spring的主要作用就是把这个过程中所需要的各种材料管理起来,砖头、水泥、钢筋。。。同时像和水泥这种工作,砂石、水这些配比组合。总结下来两点:材料仓库和组
2021-03-01 11:45:39 270 3
原创 RocketMQ一、使用RocketMQ
最近比较忙,好长时间没有更新了。正好最近在使用rocketMQ,先聊聊使用过程中的一些情况吧。引入springboot环境中引入rocketMQ很简单,加入相应的starter即可:<dependency> <groupId>org.apache.rocketmq</groupId> <artifactId>rocketmq-spring-boot-starter</artifactId></dependency>
2021-02-05 10:45:51 1260
原创 Nacos源码分析二十四、Raft选举过程(2)
MasterElection 投票前面我们看到了MasterElection用于选举的任务,我们再看一下run方法:@Overridepublic void run() { try { // ready状态 if (!peers.isReady()) { return; } //获取本地结点 RaftPeer local = peers.local(); // 任期-500
2021-01-12 16:33:36 491
原创 Nacos源码分析二十三、Raft选举过程(1)
关于raft的原理就不多介绍了,有兴趣的百度吧。这里提供一个小动画,蛮形象的,加深理解吧。我们知道raft节点的状态只有leader、follower、candidate三种。各状态流转如下:然后我们讲几个概念:majority 大多数term任期 – 任期是不断增加的election选举然后有两个超时时间election timeout – 选举超时时间heatbeat timeout – 心跳超时时间下面我们看一下nacos启动时做了什么吧。我们思考一下既然要看启动做了什么,
2021-01-12 11:41:56 897
原创 Nacos源码分析二十二、数据一致性同步-CP
然后是RaftConsistencyServiceImpl CP强制一致性实现。同样是put方法:@Overridepublic void put(String key, Record value) throws NacosException { try { raftCore.signalPublish(key, value); } catch (Exception e) { Loggers.RAFT.error("Raft put failed.",
2021-01-11 15:02:02 808
原创 Nacos源码分析二十一、数据一致性同步-AP
先讨论DistroConsistencyServiceImpl AP最终一致性的实现。我们知道当添加实例时会调用到put方法:@Overridepublic void put(String key, Record value) throws NacosException { onPut(key, value); // 一致性协议的同步数据。这里同步数据是异步任务执行的,也就是说先返回客户端put成功再同步,弱一致性。 AP模型 distroProtocol.sync(new D
2021-01-11 14:47:18 1224 1
原创 Nacos源码分析二十、数据一致性同步总览
之前在讨论服务端实例注册时已经看到了部分数据一致性同步的相关内容。 以下两篇把这个课题单独拿出来讨论一下。Nacos内部使用AP、CP两种一致性方案,如果实例是临时的,则是AP,如果是永久的,则是CP。一致性服务接口是ConsistencyService,我们看一下它的类图:其中左半部分是AP,右半部分是CP。中间的DelegateConsistencyServiceImpl是一个代理类,通过它来确定是使用AP还是CP:@DependsOn("ProtocolManager")@Service(
2021-01-11 14:31:04 511
原创 Nacos源码分析十九、服务端处理查询实例列表
前面分析客户端服务发现时,已经知道是调用NacosNamingService的getAllInstances方法查询实例列表,跟进去是NamingProxy的queryList方法:public String queryList(String serviceName, String clusters, int udpPort, boolean healthyOnly) throws NacosException { final Map<String, String&
2021-01-11 13:39:32 834
原创 Nacos源码分析十八、服务端的心跳处理
上篇在服务注册时我们注意到,每个Service实例化时会创建一个心跳检测任务ClientBeatCheckTask:@Overridepublic void run() { try { if (!getDistroMapper().responsible(service.getName())) { return; } if (!getSwitchDomain().isHealthCheckEnabled()
2021-01-11 13:28:16 527
原创 Nacos源码分析十七、服务端实例注册分析
本篇讨论nacos服务端对于实例注册的处理流程。先回想一下客户端如何发起注册请求的,代码在NacosNamingService的registerService方法:@Overridepublic void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException { if (instance.isEphemeral()) { BeatInfo
2021-01-11 11:29:12 708
原创 Nacos源码分析十六、服务端配置新增修改和删除
Nacos服务端对于配置的新增修改和删除这部分,相对比较简单。代码还是在ConfigController里,publishConfig方法提供新增和修改,deleteConfig方法提供删除操作publicConfig@PostMapping@Secured(action = ActionTypes.WRITE, parser = ConfigResourceParser.class)public Boolean publishConfig(HttpServletRequest request,
2021-01-08 15:45:00 1070
原创 Nacos源码分析十五、服务端处理配置监听
还记得NacosConfigService里的那个长轮询监听配置变更么?ClientWorker类里的LongPollingRunnable内部类。我们看一下它的run方法里的这句:List<String> changedGroupKeys = checkUpdateDataIds(cacheDatas, inInitializingCacheList);这个方法就是调用服务端的/v1/cs/configs/listener接口,以监听可能出现变更的配置数据。往里跟一下代码:List&l
2021-01-08 15:21:54 726
原创 Nacos源码分析十四、服务端处理获取配置请求
Nacos客户端的学习已经基本告一段落。从本篇开始我们把关注点放在服务端。我们知道nacos服务端主要功能就是提供配置中心的功能和命名服务。接下来我们还是按这两部分讨论。首先是配置中心。我们先看一下服务端如何处理客户端发起的获取配置的请求,相应接口是在com.alibaba.nacos.config.server.controller.ConfigController中定义,我们看一下getConfig方法:@GetMapping@Secured(action = ActionTypes.READ,
2021-01-08 11:52:11 514
原创 Nacos源码分析十三、客户端服务发现
前面分析了NacosNamingService的基本工作内容,下面我们结合dubbo看一下服务发现部分内容。先看一下dubbo中RegistryProtocol的refer方法:public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException { ... return doRefer(cluster, registry, type, url);}private <
2021-01-08 09:46:23 350
原创 Nacos源码分析十二、NacosNamingService
上篇说到Nacos对于服务注册和发现的支持是通过NamingService接口来实现的,对应的实现类是NacosNamingService,本篇详细介绍这个类。先上一个结构图简单看一下这个类的结构,有个大体的了解:看一下初始化代码:private void init(Properties properties) throws NacosException { ValidatorUtils.checkInitParam(properties); this.namespace = Ini
2021-01-07 17:39:53 1058
原创 Nacos源码分析十一、客户端服务注册
前面部分主要是分析了nacos作为配置中心时,客户端的相关逻辑,主要包括:configService的初始化,对数据的监听结合spring-cloud实现动态配置更新。关于nacos服务端的存储结构后面再统一分析。本篇分析nacos作为注册中心时客户端如何进行服务注册。我们以dubbo+nacos为例。首先添加依赖:<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId
2021-01-07 13:49:12 642
原创 Nacos源码分析十、配置动态刷新(3)
前文提到RefreshScope中维护了一个map缓存,缓存的内容是包装原bean的BeanLifecycleWrapper,这个包装类具备销毁能力。当新的配置更新通知来后,我们只要能找到RefreshScope去销毁了对应的bean,那么再次使用时cglib的proxy就会重新去获取target类实例,然后重新实例化。回到NacosContextRefresher类,看一下注册监听的代码:private void registerNacosListener(final String groupKey,
2021-01-07 09:26:58 1091 2
原创 Nacos源码分析九、配置动态刷新(2)
前文分析了@RefreshScope注解和RefreshScope类相关内容,我们了解到此时被@RefreshScope注解的类所对应的代理类类型已经换成了LockedScopedProxyFactoryBean,本篇主要分析这个类的作用。首先看一下这个类的类图:从这个图上可以看到FactoryBean。 这是一个工厂bean,也就是说容器中getBean得到的对象是通过它的getObject方法得到的。BeanFactoryAware。 beanFactory注入,需要关注一下setBeanF
2021-01-06 17:47:18 420
原创 Nacos源码分析八、配置动态刷新(1)
回顾一下前面分析的内容,NacosConfigAutoConfiguration定义了NacosContextRefresher监听器,监听ApplicationReadyEvent事件,当触发事件后会往nacos的configService中注册配置监听,Nacos在收到配置变更时会向applicationContext发布RefreshEvent事件。下面我们分析触发这个事件的后续操作。首先我们定义一下测试代码:@RestController@RequestMapping("/refreshCon
2021-01-06 16:56:41 856
原创 Nacos源码分析七、NacosConfigAutoConfiguration配置类
Nacos除了Bootstrap的自动配置类,同时也配置了SpringBoot的自动配置:org.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.alibaba.cloud.nacos.NacosConfigAutoConfiguration,\com.alibaba.cloud.nacos.endpoint.NacosConfigEndpointAutoConfigurationNacosConfigEndpoint
2021-01-06 08:55:10 1550
原创 Nacos源码分析六、NacosConfigBootstrapConfiguration配置类
前文在分析BootStrapApplicationListener时得到当引入nacos时,会加载NacosConfigBootstrapConfiguration配置类:@Configuration(proxyBeanMethods = false)@ConditionalOnProperty(name = "spring.cloud.nacos.config.enabled", matchIfMissing = true)public class NacosConfigBootstrapConfi
2021-01-05 17:23:57 4062
原创 Nacos源码分析五、BootstrapApplicationListener运行原理(2)
接着上篇,我们看BootstrapImportSelectorConfiguration配置类:@Configuration(proxyBeanMethods = false)@Import(BootstrapImportSelector.class)public class BootstrapImportSelectorConfiguration {}Import了一个Selector:@Overridepublic String[] selectImports(AnnotationMe
2021-01-05 16:33:58 601
原创 Nacos源码分析四、BootstrapApplicationListener运行原理(1)
要理解nacos的配置变更如何更新到应用的配置上,这部分的内容属于SpringCloud部分的,要全部串起来,需要了解spring-cloud-context和spring-cloud-alibaba-nacos-config相关的内容。一下学习过程spring-cloud-alibaba-nacos-config版本为2.2.1.RELEASE,对应spring-cloud-context版本为2.2.2.RELEASE我们先看BootStrapApplicationListener怎么来的吧首先sp
2021-01-05 15:39:27 827 2
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人