<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[小小少年的博客]]></title><description><![CDATA[]]></description><link>https://blog.youkuaiyun.com/CPLASF_</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; CPLASF_]]></copyright><item><title><![CDATA[ConcurrentHashMap原理]]></title><link>https://blog.youkuaiyun.com/CPLASF_/article/details/129375563</link><guid>https://blog.youkuaiyun.com/CPLASF_/article/details/129375563</guid><author>CPLASF_</author><pubDate>Thu, 16 Mar 2023 09:28:09 +0800</pubDate><description><![CDATA[所以，总结来看，concurrentHashMap线程安全的原因有以下几点会通过cas，对tab[i]位置进行赋值在插入元素的时候，会通过synchronized来加锁在统计hashmap中元素个数的时候，通过volatile修饰的变量，以及cas操作来完成+1。]]></description><category></category></item><item><title><![CDATA[nacos源码入门]]></title><link>https://blog.youkuaiyun.com/CPLASF_/article/details/129369378</link><guid>https://blog.youkuaiyun.com/CPLASF_/article/details/129369378</guid><author>CPLASF_</author><pubDate>Tue, 07 Mar 2023 18:42:52 +0800</pubDate><description><![CDATA[这个bean是监听了WebServerInitializedEvent事件，在监听到这个事件之后，会进行一些列的逻辑，我们来看下主要关注这里的register()方法对于nacos注册中心，业务应用是如何注册的，再总结下在应用启动之前，我们需要引入springcloud-nacos相关的jar包。]]></description><category></category></item><item><title><![CDATA[sentinel源码入门]]></title><link>https://blog.youkuaiyun.com/CPLASF_/article/details/129354396</link><guid>https://blog.youkuaiyun.com/CPLASF_/article/details/129354396</guid><author>CPLASF_</author><pubDate>Tue, 07 Mar 2023 08:20:58 +0800</pubDate><description><![CDATA[总结来看，sentinel的源码逻辑是比较清晰的通过springboot的自动注入，注入了一个切面在切面中，通过环绕通知，分别执行slot的entry()和exit()方法在调用entry()方法之前，会通过spi机制，获取到所有的slot，并构建成一个执行链在所有的slot被调用完毕之后，会开始调用业务的方法在最后的finally方法中，会调用exit()，执行各个slot的exit()方法。]]></description><category></category></item><item><title><![CDATA[seata源码-全局事务提交 服务端源码]]></title><link>https://blog.youkuaiyun.com/CPLASF_/article/details/129037257</link><guid>https://blog.youkuaiyun.com/CPLASF_/article/details/129037257</guid><author>CPLASF_</author><pubDate>Sun, 19 Feb 2023 10:23:10 +0800</pubDate><description><![CDATA[以上，就是全局事务提交的逻辑，整体看下来，我们可以发现，对于全局事务提交的时候，分支事务在处理的时候，是异步来处理的，这是和回滚逻辑有很大的区别，因为上篇博客中，我们有看到，全局事务回滚时，分支事务在第二阶段，是同步处理的，在接收到请求之后，会根据undoLog生成回滚sql，并执行，然后删除undoLog数据，但是对于全局事务提交的第二阶段，会发现，接收到请求之后，直接塞到了队列中，通过异步的请求，没1000ms执行一次提交的逻辑。]]></description><category></category></item><item><title><![CDATA[seata源码-全局事务回滚服务端源码]]></title><link>https://blog.youkuaiyun.com/CPLASF_/article/details/128917361</link><guid>https://blog.youkuaiyun.com/CPLASF_/article/details/128917361</guid><author>CPLASF_</author><pubDate>Sun, 12 Feb 2023 10:13:41 +0800</pubDate><description><![CDATA[对于分布式事务，进行全局回滚的逻辑，还是比较简单的在事务管理者这边发起全局事务回滚的请求seata服务端，也就是事务协调者接收到请求之后，会向所有的rm，发起netty请求，进行分支事务的处理各个分支事务，会根据undoLog日志，生成回滚的sql，然后执行seata服务端在等分支事务返回状态之后，会先删除分支事务，在删除分支事务之前，会将分支事务加的锁给删除（这里的锁，如果是mysql的话，其实就是写入到mysql中的一条记录）]]></description><category></category></item><item><title><![CDATA[openFeign源码学习]]></title><link>https://blog.youkuaiyun.com/CPLASF_/article/details/128964015</link><guid>https://blog.youkuaiyun.com/CPLASF_/article/details/128964015</guid><author>CPLASF_</author><pubDate>Sat, 11 Feb 2023 10:37:04 +0800</pubDate><description><![CDATA[所以，openFeign其实底层，就是通过代理对象的方式，帮我们去发起远程调用，在代理对象中，会分别区分使用微服务名进行负载均衡的逻辑和程序员直接指定ip、端口的方式，本质上没太大的区别，只是一个集成了ribbon，一个直接发起调用。]]></description><category></category></item><item><title><![CDATA[seata源码-开启全局事务服务端源码]]></title><link>https://blog.youkuaiyun.com/CPLASF_/article/details/128908267</link><guid>https://blog.youkuaiyun.com/CPLASF_/article/details/128908267</guid><author>CPLASF_</author><pubDate>Tue, 07 Feb 2023 08:32:48 +0800</pubDate><description><![CDATA[通过上面服务端的代码来看，其实在开启全局事务的时候，服务端的逻辑是比较简单明了的根据事务id + ip + port生成全局事务id根据全局事务id,写入到globalTable表中一条记录这里写到数据库中的记录，就是全局事务的信息，在后面分支事务提交和回滚的时候，都会相应的操作这条记录。]]></description><category></category></item><item><title><![CDATA[seata源码-入门]]></title><link>https://blog.youkuaiyun.com/CPLASF_/article/details/128861017</link><guid>https://blog.youkuaiyun.com/CPLASF_/article/details/128861017</guid><author>CPLASF_</author><pubDate>Sun, 05 Feb 2023 13:52:26 +0800</pubDate><description><![CDATA[这篇博客，主要是站在client端的角度，去看了一些源码，大致的逻辑，再总结下当业务应用启动的时候，会通过seata的bean对象，给需要处理全局事务的service，生成代理对象在service的方法被执行的时候，会被interceptor拦截到在被拦截之后，会先开启全局事务，接着执行目标方法，如果没有异常，就进行全局事务提交，如果有异常，就进行全局事务回滚。]]></description><category></category></item><item><title><![CDATA[rocketmq源码-consumer负载均衡逻辑]]></title><link>https://blog.youkuaiyun.com/CPLASF_/article/details/128324580</link><guid>https://blog.youkuaiyun.com/CPLASF_/article/details/128324580</guid><author>CPLASF_</author><pubDate>Sat, 04 Feb 2023 12:59:04 +0800</pubDate><description><![CDATA[这篇笔记主要记录consumer在启动过程中，负载均衡的逻辑，多个消费者组成一个消费者组，对于集群模式，同一个消费者组中的多个消费者共同消费一个topic下的所有消息，所以每个consumer可能会处理N个messageQueue，至于哪个consumer消费哪个messageQueue，是由负载均衡策略决定的。]]></description><category></category></item><item><title><![CDATA[rocketmq源码-consumerQueue和indexFile文件写入]]></title><link>https://blog.youkuaiyun.com/CPLASF_/article/details/128328881</link><guid>https://blog.youkuaiyun.com/CPLASF_/article/details/128328881</guid><author>CPLASF_</author><pubDate>Sat, 04 Feb 2023 12:58:01 +0800</pubDate><description><![CDATA[在rocketmq的文件中，除了commitLog文件，还有两个重要的文件，分别是indexFile文件和consumerQueue文件，这篇笔记主要记录这两个文件的数据是怎么写进去的consumeQueue文件中对应topic下的一个queue，在consumeQueue文件中，存放了三部分数据：分别是当前消息在commitLog中的offset、以及消息的大小、tagCode信息。]]></description><category></category></item><item><title><![CDATA[rocketmq源码-consumer已消费offset更新逻辑]]></title><link>https://blog.youkuaiyun.com/CPLASF_/article/details/128376539</link><guid>https://blog.youkuaiyun.com/CPLASF_/article/details/128376539</guid><author>CPLASF_</author><pubDate>Tue, 20 Dec 2022 13:48:45 +0800</pubDate><description><![CDATA[这篇博客，主要记录consumer已经消费的offset是如何更新的对于集群模式，offset是维护在broker中的；而广播模式，offset是存储在本地文件中（暂时没有验证具体存储的位置，是根据源码推测的）不管是pull模式，还是push模式，都需要维护consumer当前已经消费的offset更新offset的逻辑，大致是这样的：1.client从broker拉取消息2.然后client回调业务系统的消费者所注册的messageListener，对消息进行处理。]]></description><category></category></item><item><title><![CDATA[rocketmq源码-关于消费者push模式和pull模式的对比]]></title><link>https://blog.youkuaiyun.com/CPLASF_/article/details/128333070</link><guid>https://blog.youkuaiyun.com/CPLASF_/article/details/128333070</guid><author>CPLASF_</author><pubDate>Fri, 16 Dec 2022 08:34:36 +0800</pubDate><description><![CDATA[按照网上大部分的说法，对于push模式是broker自己推送消息给consumer，如果这个推断成立，那broker设计我认为是有问题的，因为对于broker而言，我只是去存储消息的，我不关心你是push还是pull，我只需要提供接口，让client来查询消息就可以了，如果broker还需要关心consumer的模式，那系统就太耦合了；对于pull模式，是通过netty请求去broker拉取消息，拉取到消息之后，将消息存入到了内存中的一个队列中，存入到队里中之后，立即发起下次请求；]]></description><category></category></item><item><title><![CDATA[rocketmq源码-broker处理consumer拉取消息请求]]></title><link>https://blog.youkuaiyun.com/CPLASF_/article/details/128332407</link><guid>https://blog.youkuaiyun.com/CPLASF_/article/details/128332407</guid><author>CPLASF_</author><pubDate>Thu, 15 Dec 2022 18:49:59 +0800</pubDate><description><![CDATA[在前面consumer拉取消息的博客中，有说过，对于consumer，在拉取消息的时候，是需要指定code码的，在consumer去broker拉取消息的时候，指定的code码是：PULL_MESSAGE，所以这篇博客，我们简单看下broker在接收到netty请求之后，是如何处理的这里看起来，是比较简单明了的，就是根据当前请求中的offset和size，从commitLog中拉取消息数据，然后返回就可以了；]]></description><category></category></item><item><title><![CDATA[rocketmq源码-pull模式拉取消息、同步拉取消息]]></title><link>https://blog.youkuaiyun.com/CPLASF_/article/details/128313720</link><guid>https://blog.youkuaiyun.com/CPLASF_/article/details/128313720</guid><author>CPLASF_</author><pubDate>Thu, 15 Dec 2022 18:47:07 +0800</pubDate><description><![CDATA[上一篇博客，记录的是push模式，异步发送netty请求拉取消息的代码，这篇博客主要记录consumer发送同步netty请求，去拉取消息的逻辑，但是对于同步发送请求，需要结合LitePullConsumer来看在Lite PullConsumer中有两种方式，分别是：subscribe和assign模式，这两种模式的区别，我的理解是：前者是mq帮我们进行负载均衡，后者我们可以按照自己的需求去进行负载均衡，给当前消费者分配messageQueue。]]></description><category></category></item><item><title><![CDATA[rocketmq源码-consumer拉取消息（push模式）]]></title><link>https://blog.youkuaiyun.com/CPLASF_/article/details/128311025</link><guid>https://blog.youkuaiyun.com/CPLASF_/article/details/128311025</guid><author>CPLASF_</author><pubDate>Thu, 15 Dec 2022 09:10:13 +0800</pubDate><description><![CDATA[在前面consumer启动的博客中，有说过，在启动过程中，有两个比较重要的逻辑，分别是负载均衡和拉取消息的service，这篇博客，主要记录拉取消息的service，因为前面的demo和这篇笔记中的demo，都是基于push模式来学习的，所以前面的笔记都是基于push模式的，但是最近看了下pull模式，和push模式的代码还是有点区别的，所以后面单独起一篇博客，记录pull模式的逻辑对于消费者有两种模式：pull和push但是在push模式中，又分为了顺序消费和并行消费。]]></description><category></category></item><item><title><![CDATA[rocketmq源码-consumer启动]]></title><link>https://blog.youkuaiyun.com/CPLASF_/article/details/128306843</link><guid>https://blog.youkuaiyun.com/CPLASF_/article/details/128306843</guid><author>CPLASF_</author><pubDate>Thu, 15 Dec 2022 08:50:53 +0800</pubDate><description><![CDATA[这篇笔记记录consumer启动的逻辑consumer主要是负责去broker中拉取消息，然后将拉取到的消息，交给消费者去处理consumer本质上也是一个netty客户端，所以，在启动的时候，和producer有很多相似的点，但是有1个区别点：1、producer的负载均衡是在真正去发送消息的时候，通过轮询的方式，选择其中的一个messageQueue；]]></description><category></category></item><item><title><![CDATA[rocketmq源码-broker接收消息]]></title><link>https://blog.youkuaiyun.com/CPLASF_/article/details/128300731</link><guid>https://blog.youkuaiyun.com/CPLASF_/article/details/128300731</guid><author>CPLASF_</author><pubDate>Thu, 15 Dec 2022 08:46:29 +0800</pubDate><description><![CDATA[这篇笔记，主要记录producer在通过netty发送了请求之后，在broker这边是如何处理的消息的这里是broker的nettyServer端接收客户端发送消息的入口，不解释为什么会是这个类了。]]></description><category></category></item><item><title><![CDATA[rocketmq源码-producer发送消息]]></title><link>https://blog.youkuaiyun.com/CPLASF_/article/details/128296240</link><guid>https://blog.youkuaiyun.com/CPLASF_/article/details/128296240</guid><author>CPLASF_</author><pubDate>Wed, 14 Dec 2022 08:47:07 +0800</pubDate><description><![CDATA[这篇笔记，记录producer发送消息的相关源码我们以最简单的demo为例i < 3;i ++) {try {}我们要看的是：producer.send()这个方法校验消息的合法性根据消息中的topic，找到对应的路由信息根据路由信息 以及轮询策略，找到要发送的messageQueue构建netty请求，发送到broker。]]></description><category></category></item><item><title><![CDATA[rocketmq源码-producer启动流程]]></title><link>https://blog.youkuaiyun.com/CPLASF_/article/details/128292440</link><guid>https://blog.youkuaiyun.com/CPLASF_/article/details/128292440</guid><author>CPLASF_</author><pubDate>Tue, 13 Dec 2022 19:05:23 +0800</pubDate><description><![CDATA[创建、启动producer的逻辑，是写在业务系统中的，根据rocketmq源码中的demo，只需要这几行代码，就可以启动producer这几行代码的逻辑，也比较简单，就是创建一个producer对象，创建对象时，需要指定producerGroup’然后设置nameSrv地址；最后调用其start()方法即可所以，启动producer最为核心的代码，是在start()方法中在start()方法中，最重要的是mqClientFactory.start()方法。]]></description><category></category></item><item><title><![CDATA[rocketmq源码学习-broker启动]]></title><link>https://blog.youkuaiyun.com/CPLASF_/article/details/128286130</link><guid>https://blog.youkuaiyun.com/CPLASF_/article/details/128286130</guid><author>CPLASF_</author><pubDate>Tue, 13 Dec 2022 09:49:13 +0800</pubDate><description><![CDATA[这篇笔记记录broker启动的源码学习broker主要完成一下几件事情：1.接收producer的发送请求，并对消息进行持久化、同步其他节点2.接收consumer读取消息星球3.定时向nameSrv注册心跳信息，保持连接在启动的时候，也是分了两个方法1、创建brokerController2、启动brokerController总结来看，broker在启动的时候启动nettyServer和nettyClient。]]></description><category></category></item></channel></rss>