- 博客(90)
- 收藏
- 关注
原创 Netty-初探
扩展:同样是Kafka的Broker,Consumer订阅消息时,Broker把消息的数据从磁盘发送到网卡的发送缓冲区这个过程就使用了sendfile技术。已经停止开发了,其底层的AIO模型,参考了NIO的epoll模型,性能并没有提高很多,而且还会带来很多的异步回调问题。同步非阻塞:获取资源不存在,线程阻塞了,线程去做其他事,线程会频繁的查询资源是否存在,消耗很多CPU。Mina几乎不更新了。6、社区活跃,版本迭代周期短,发现的BUG可以被及时修复,同时,更多的新功能会加入;比较适合存简单对象扁平化。
2024-01-15 12:57:17
894
原创 ShardingSphere-JDBC学习笔记
Sharding-JDBC是2015年开源的,早期的定位就是一个分布式数据库的中间件,而在它之前有一个MyCat的产品。使用其实不难的,关键是要找对方法,网上文章千千万,版本也是千奇百怪,初学者看的配置越多可能越不理解,ShardingSphere每个大版本的配置项都有很多改进,所以笔者建议理解每种策略存在的意义,解决问题的思想才是更有价值的。主要是用在压测的场景,比如说你的业务开发完了,需要测试性能,这个时候最好的情况是压测环境和生产的环境是一样的,影子库就是和生产环境的库是一样的,但是数据不同。
2024-01-07 09:20:07
1135
原创 ShardingSphere-JDBC初探
接下来本篇文章的学习重点就是ShardingSphere,早期的时候是叫ShardingJdbc,实际上ShardingJdbc是ShardingSphere内部提供的一个服务,ShardingSphere的目标是要做一个生态,而不是一个简单的JDBC分库分表工具,从官网文档可以看出,ShardingSphere是想把一些周边的组件(MySQL、zk、Oracle等)作为其生态的一个支撑(目标很宏大),具体的看官网详细介绍。分析:当前有两个库,每个库有两个分片,也就是一共4个分片。所以取模4均分数据;
2024-01-05 12:53:19
990
原创 后台管理项目的多数据源方案
空闲连接时间过长,数据库就会自动把连接关闭,Druid为了防止从连接池中拿到被数据库关闭的连接,设置了这个参数,超过时间强行关闭连接。注意:如果设置的太小,当客户端连接多的情况下,就需要新创建数据库连接,是一个比较耗时的操作,可能导致客户端连接超时。设置太大会占用系统资源。4、saveW和saveR方法后面的业务发生异常,事务管理器回滚saveW的更新,saveR已提交,数据不一致。3、saveW和saveR方法中间的业务发生异常,事务管理器回滚saveW的更新,saveR未提交,数据一致。
2024-01-03 23:11:31
1067
原创 Java原生网络BIO
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口,一般由操作系统提供。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议处理和通信缓存管理等等都隐藏在Socket接口后面,对用户来说,使用一组简单的接口就能进行网络应用编程,让Socket去组织数据,以符合指定的协议。主机 A 的应用程序要能和主机 B 的应用程序通信,必须通过 Socket 建立连接。
2023-12-28 11:41:05
404
原创 Zookeeper-一致性协议ZAB
ZAB 协议全称:Zookeeper Atomic Broadcast(Zookeeper 原子广播协议)。Zookeeper 是一个为分布式应用提供高效且可靠的分布式协调服务。在解决分布式一致性方面,Zookeeper 并没有使用 Paxos ,而是采用了 ZAB 协议,ZAB是Paxos算法的一种简化实现。。(当 Leader 服务可以正常使用,就进入消息广播模式,当 Leader 不可用时,则进入崩溃恢复模式。基于该协议,Zookeeper 实现了一种。
2023-12-26 11:07:59
948
原创 Zookeeper-源码启动
3、将conf文件夹里的log4j.properties文件复制一份到zookeeper-server项目的 \target\classes 目录下,这样项目启动时才会打印日志。2、启动之前需要先将zookeeper-server项目里pom.xml文件里依赖的包(除了jline)的scope为provided这一行全部注释掉。1、将conf文件夹里的zoo_sample.cfg文件复制一份改名为zoo.cfg,将zoo.cfg文件位置配置到启动参数里。所以上传到云服务器后执行编译命令。
2023-12-24 12:23:09
713
原创 Zookeeper-应用实战
Curator还为ZooKeeper客户端框架提供了一些比较普遍的、开箱即用的、分布式开发用的解决方案,例如Recipe、共享锁服务、Master选举机制和分布式计算器等,帮助开发者避免了“重复造轮子”的无效开发工作。deletingChildrenIfNeeded:指定了该函数后,系统在删除该数据节点的时候会以递归的方式直接删除其子节点,以及子节点的子节点。ZooKeeper官方的客户端API提供了基本的操作:创建会话、创建节点、读取节点、更新数据、删除节点和检查节点是否存在等。
2023-12-22 11:07:12
1670
原创 Zookeeper-集群架构
集群模式下配置一个文件 myid,这个文件在 dataDir 目录下,这个文件里面有一个数据 就是 A 的值,Zookeeper 启动时读取此文件,拿到里面的数据与 zoo.cfg 里面的配置信息比较从而判断到底是哪个server。2、epoch表示ZooKeeper服务器的逻辑时期(logical epoch),它是一个相对时间的概念,用于区分不同的Leader选举周期。全局可线性化(Linearizable )写入:先到达leader的写请求会被先处理,leader决定写请求的执行顺序。
2023-12-21 10:56:49
1438
原创 Zookeeper-快速开始
和持久节点的区别是 ZK 服务端启动后,会有一个单独的线程去扫描,所有的容器节点,当发现容器节点的子节点数量为 0 时,会自动删除该节点。持久顺序节点(PERSISTENT_SEQUENTIAL): znode除了具备持久性znode的特点之外,znode的名字具备顺序性。临时顺序节点(EPHEMERAL_SEQUENTIAL): znode除了具备临时性znode的特点之外,zorde的名字具备顺序性。ZooKeeper的层次模型称作Data Tree,Data Tree的每个节点叫作Znode。
2023-12-19 11:05:48
1329
原创 Kafka-生产调优
另外,EFAK需要依赖的环境主要是Java和数据库。其中,数据库支持本地化的SQLLite以及集中式的MySQL。在搭建EFAK之前,需要准备好对应的服务器以及MySQL数据库。而Kafka-eagle就是一个可以监控Kafka集群整体运行情况的框架,在生产环境经常会用到。配置完成后,先启动Zookeeper和Kafka服务,然后调用EFAK的bin目录下的ke.sh脚本启动服务。在官网的DownLoad页面可以下载EFAK的运行包,efak-web-3.0.2-bin.tar.gz。
2023-12-17 12:07:37
564
原创 Kafka-日志索引
在搭建Kafka服务时,在server.properties配置文件中通过log.dir属性指定了Kafka的日志存储目录。实际上,Kafka的所有消息就全都存储在这个目录下。这些核心数据文件中,.log结尾的就是实际存储消息的日志文件。大小固定为1G(由参数 log.segment.bytes参数指定),写满后就会新增一个新的文件。一个文件也成为一个segment文件名表示当前日志文件记录的第一条消息的偏移量。.index和.timeindex是日志文件对应的索引文件。
2023-12-16 11:33:46
1277
原创 Kafka-集群架构设计
Kafka将状态信息保存在Zookeeper中,这些状态信息记录了每个Kafka的Broker服务与另外的Broker服务 有什么不同。通过这些差异化的功能,共同体现出集群化的业务能力。这些数据,需要在集群中各个Broker 之间达成共识,因此,需要存储在一个所有集群都能共同访问的第三方存储中。Kafka的整体集群结构:Kafka的集群中,最为主要的状态信息有两个:在多个Broker中,需要选举出一个Broker,担任 Controller角色。
2023-12-14 12:19:06
1144
原创 Kafka-客户端使用
然后,Sender对读取出来的消息,会以Broker为key,缓存到一个对应的队列当中。但是如果消费者没有提交Offset,Broker就会认为这个消息还没有被处理过,就会重新往对应的消费者组进行推送,不过这次,一般会尽量推送给同一个消费者组当中的其他消费者实例。例如如果在部署消费者时,如果我们的服务器配置不一样,就可以通过定制消费者分区器,让性能更好的服务器上的消费者消费较多的消息,而其他服务器上的消费者消费较少的消息,这样就能更合理的运用上消费者端的服务器性能,提升消费者的整体消费速度。
2023-12-12 12:17:08
2052
原创 Kafka-快速实战
Kafka是面向海量消息设计的,一个Topic下的消息会非常多,单机服务很难存得下来。一个典型的MQ系统,会将消息消息由生产者发送到MQ进行排队,然后根据一定的顺序交由消息的消费者进行处理。最后:Kafka集群中的这些Broker信息,包括Partition的选举信息,都会保存在额外部署的Zookeeper集群当中,这样,kafka集群就不会因为某一些Broker服务崩溃而中断。Kafka的基础工作机制:消息发送者将消息发送到kafka上指定的topic,消息消费者从指定的topic上消费消息。
2023-12-10 11:19:34
1229
原创 RocketMQ-生产环境常见问题分析总结
生产者使用事务消息机制。Broker配置同步刷盘+Dledger主从架构消费者不要使用异步消费。整个MQ挂了之后准备降级方案。
2023-12-08 10:33:13
957
原创 RocketMQ-源码架构二
消费者进行消息消费时,通过ConsumeQueue文件就足够完成消息检索了,但是如果消费者指定时间戳进行消费,或者要按照MessageId或者MessageKey来检索文件,比如RocketMQ管理控制台的消息轨迹功能,ConsumeQueue文件就不够用了。但是可以看到,RocketMQ并不可能真正来一条消息就进行一次刷盘,这样在海量数据下,操作系统是承受不了的。而磁盘IO操作通常是一个很耗性能,很慢的操作,所以,对消息持久化机制的设计,是一个MQ产品提升性能的关键,甚至可以说是最为重要的核心也不为过。
2023-12-06 11:22:28
1766
原创 RocketMQ-源码架构
在RocketMQ中,NameServer主要是RPC的服务端RemotingServer,Broker对于客户端来说,是RPC的服务端RemotingServer,而对于NameServer来说,又是RPC的客户端。所以在RocketMQ中,整个消费者的业务逻辑是非常复杂的,甚至某种程度上来说,比服务端更复杂,所以,在这里重点关注用得最多的推模式的消费者。start方法中,相当于对很多消费者的服务进行初始化,包括指定一些服务的实现类,以及启动一些定时的任务线程,比如清理过期的请求缓存等。
2023-12-05 11:37:38
1828
原创 RocketMQ-整合SpringBoot
只要注入并启动了这个DefaultLitePullConsumer实例后,后续就可以通过template实例的receive方法,来调用DefaultLitePullConsumer的poll方法,主动去Pull获取消息。为了保证消息至少被消费一次,消息队列 RocketMQ 的服务端将在网络恢复后再次尝试投递之前已被处理过的消息,消费者后续会收到两条内容相同并且 Message ID 也相同的消息。通常,一条消息进入了死信队列,意味着消息在消费处理的过程中出现了比较严重的错误,并且无法自行恢复。
2023-12-04 12:19:13
1149
原创 RocketMQ-核心编程模型
如果需要重试的这些消息还是放在原来的MessageQueue中,就会对当前MessageQueue产生阻塞,让其他正常的消息无法处理。这样,这些重试的消息有了自己单独的队列,就不会影响到Topic下的其他消息了。但是,这里还是会造成一种分裂,消息最终是由Consumer来处理,但是消息却是由Broker推送过来的,也就是说,Consumer无法确定自己将要处理的是哪些消息。但是,如果消费者一直处理失败,超过最大重试次数,那么RocketMQ就会跳过这一条消息,处理后面的消息,这会造成消息乱序。
2023-12-02 11:16:27
1053
原创 RocketMQ-集群搭建
在RocketMQ的这种主从架构的集群下,客户端发送的消息会分散保存到broker-a和broker-b两个服务上,然后每个服务都配有slave服务,可以备份对应master服务上的消息,这样就可以防止单点故障造成的消息丢失问题。与第一组broker-a服务的配置方式类似,在worker3上配置broker-b的MASTER服务。了的,slave服务虽然拥有全部的数据,但是它没办法升级成为master服务去响应客户端的请求,依然只是傻傻等待master服务重启后,继续做它的数据备份工作。
2023-12-01 11:59:26
1587
原创 RocketMQ-快速实战
比如在具体功能方面,在4.x版本中,对于定时消息,只能设定几个固定的延迟级别,而5.0版本中,已经可以指定具体的发送时间了。在服务端架构方面,4.x版本只支持固定角色的普通集群和可以动态切换角色的Dledger集群,而在5.0版本中,增加了Dledger Controller混合集群模式,即可以混合使用Dledger的集群机制以及 Broker 本地的文件管理机制。注:在2020年下半年,RocketMQ新推出了5.0的大版本,这对于RocketMQ来说,是一个里程碑式的大版本。
2023-11-30 11:58:40
1162
原创 Redis-性能优化
bigkey也就意味着每次获取要产生的网络流量较大,假[[设一个bigkey为1MB,客户端每秒访问量为1000,那么每秒产生1000MB的流量,对于普通的千兆网卡(按照字节算是128MB/s)的服务器来说简直是灭顶之灾,而且一般服务器会采用单机多实例的方式来部署,也就是说一个bigkey可能会对其他实例也造成影响,其后果不堪设想。1、对于并发几率很小的数据(如个人维度的订单数据、用户数据等),这种几乎不用考虑这个问题,很少会发生缓存不一致,可以给缓存数据加上过期时间,每隔一段时间触发读的主动更新即可。
2023-11-27 11:35:32
1320
原创 Redis-缓存设计
比如服务降级,我们可以针对不同的数据采取不同的处理方式。由于缓存层承载着大量请求, 有效地保护了存储层, 但是如果缓存层由于某些原因不能提供服务(比如超大并发过来,缓存层支撑不住,或者由于缓存设计不好,类似大量请求访问bigkey,导致缓存能支撑的并发急剧下降), 于是大量请求都会打到存储层, 存储层的调用量会暴增, 造成存储层也会级联宕机的情况。对于恶意攻击,向服务器请求大量不存在的数据造成的缓存穿透,还可以用布隆过滤器先做一次过滤,对于不存在的数据布隆过滤器一般都能够过滤掉,不让请求再往后端发送。
2023-11-26 11:05:17
1162
原创 Redis-缓存高可用集群
当客户端向一个错误的节点发出了指令,该节点会发现指令的 key 所在的槽位并不归自己管理,这时它会向客户端发送一个特殊的跳转指令携带目标操作的节点地址,告诉客户端去连这个节点去获取数据。奇数个master节点可以在满足选举该条件的基础上节省一个节点,比如三个master节点和四个master节点的集群相比,大家如果都挂了一个master节点都能选举新master节点,如果都挂了两个master节点都没法选举新master节点了,所以奇数的master节点更多的是。Rank越小代表已复制的数据越新。
2023-11-24 23:44:22
2374
1
原创 Redis-主从与哨兵架构
哨兵架构下client端第一次从哨兵找出redis的主节点,后续就直接访问redis的主节点,不会每次都通过sentinel代理访问redis的主节点,当redis的主节点发生变化,哨兵会第一时间感知到,并且将新的redis主节点通知给client端(这里面redis的client端一般都实现了订阅功能,订阅sentinel发布的节点变动消息)如果哨兵节点已经启动了,然后再复制一份修改为其他的哨兵节点,这种情况如果没有删除已经生成的myid,就会导致哨兵节点之间不想感应不到,因为它们的myid是相同的。
2023-11-24 01:17:41
2124
3
原创 Redis-持久化
master会在其内存中创建一个复制数据用的缓存队列,缓存最近一段时间的数据,master和它所有的slave都维护了复制的数据下标offset和master的进程id,因此,当网络连接断开后,slave会请求master继续进行未完成的复制,从所记录的数据下标开始。AOF修改内存数据的命令存在一起,都写入新的AOF文件,新的文件一开始不叫appendonly.aof,等到重写完新的AOF文件才会进行改名,覆盖原有的AOF文件,完成新旧两个AOF文件的替换。的,可以共享主线程的所有内存数据。
2023-11-22 23:20:25
605
原创 Redis-五种数据类型
来统一存储多台应用服务器的会话信息。当应用服务器不再存储用户的会话信息,也就不再具有状态,一个用户可以请求任意一个应用服务器,从而更容易实现高可用性以及可伸缩性。h) 社交类需求 Set 可以实现交集,从而实现共同好友等功能,Set通过求差集,可以进行好友推荐,文章推荐。d) 键值对中的值类型可以是string,hash,list,set,sorted set 等。Set 为无序的,自动去重的集合数据类型,Set 数据结构底层实现为一个。c) 键值对中键的类型可以是字符串,整型,浮点型等,且键是唯一的。
2023-11-22 00:32:42
179
原创 Redis-核心数据结构
1、数据容量受到物理内存的限制,不能用作海量数据的高性能读写 2、Redis不具备自动容错和恢复功能,主机如果宕机会导致前端部分读写请求失败,需要等待机器重启或手动切换前端访问的IP才能恢复;Redis的操作都是基于内存的,非常快速,数据存在内存中,类似于HashMap、其查找和操作的时间复杂度都是O(1),而且结构简单,读数据操作也很简单,其次还采用单线程,避免了不必要的上下文切换和竞争关系,也不存在多线程切换消耗的CPU性能,且不用考虑各种锁的开销,除此外,其使用多路复用IO,非阻塞IO。
2023-11-21 00:34:24
264
原创 Spring-事务
开启Spring事务本质上就是增加了一个Advisor,在使用@EnableTransactionManagement注解来开启Spring事务时,该注解代理的功能就是向Spring容器中添加了两个Bean。当某个类中存在@Transactional注解,就会产生一个代理对象作为Bean,在执行代理对象的某个方法时会进入到TransactionInterceptor的invoke()方法中。(再次判断是考虑到一个类中可能有多个方法,有的方法有@Transactional注解,有的没有)
2023-11-14 11:52:00
205
1
原创 Spring-ProxyFactory
当某个Bean初始化后,会调用wrapIfNecessary()方法进行AOP:AbstractAdvisorAutoProxyCreator会找到所有的Advisor,然后判断当前这个Bean是否存在某个Advisor与之匹配(根据Pointcut),如果匹配就表示当前这个Bean有对应的切面逻辑,需要进行AOP,需要产生一个代理对象。先执行MethodInvocation的proceed(),会执行下一个Interceptor,如果没有下一个Interceptor了,会执行target对应的方法。
2023-11-13 00:55:39
251
原创 Spring-SpringAOP的实现
Spring是依赖了AspectJ的,Spring觉得AspectJ中的@Before、@Around等注解比较好用,所以把这些注解直接拿过来用,但是注解底层的解析是由Spring自己做的。,表示在一个特定连接点上所采取的动作。翻译:AOP中的这些概念不是Spring特有的,不幸的是,AOP中的概念不是特别直观的,但是,如果Spring重新定义自己的那可能会导致更加混乱。,表示一个程序在执行过程中的一个点,比如一个方法的执行,比如一个异常的处理,在Spring AOP中,一个连接点通常表示一个方法的执行。
2023-11-12 01:59:34
350
原创 Spring-动态代理
通过BeanNameAutoProxyCreator可以对批量的Bean进行AOP,并且指定了代理逻辑,指定了一个InterceptorName,也就是一个Advise,前提条件是这个Advise也得是一个Bean,这样Spring才能找到的,但是BeanNameAutoProxyCreator的缺点很明显,它只能根据beanName来指定想要代理的Bean。,被代理类是父类,代理类是子类,代理对象就是代理类的实例对象,代理类是由cglib创建的。表示创建代理对象的一个工厂,使用起来更加方便。
2023-11-10 23:50:33
396
原创 Spring-推断构造方法
后续在根据BeanDefinition创建Bean时,会根据isFactoryMethodUnique来操作,如果为 true,那就表示当前BeanDefinition只对应了一个方法,那也就是只能用这个方法来创建Bean了, 但是如果isFactoryMethodUnique为false,那就表示当前BeanDefition对应了多个方法,需要和推 断构造方法的逻辑一样,去选择用哪个方法来创建Bean。标签,表示构造方法参数,可以根据这个确定想要使用的构造方法的参数个数,从而确定想要使用的构造方法。
2023-11-09 23:43:37
362
原创 Spring-循环依赖简述
/ A依赖了Bclass Apublic B b;// B依赖了Aclass Bpublic A a;// 循环依赖a.b = b;b.a = a;对象之间的相互依赖很正常,但是在Spring中由于对象创建要经过Bean的生命周期,所以就有了循环依赖问题1、:缓存经过了完整生命周期的bean2、:缓存未经过完整生命周期的bean,如果某个bean出现了循环依赖,就会提前。
2023-11-08 23:52:50
363
原创 Spring-依赖注入findAutowireCandidates源码实现
5、判断当前type是不是泛型,如果是泛型是会把容器中所有的beanName找出来的,如果是这种情况,那么在这一步中就要获取到泛型的真正类型,然后进行匹配,如果当前beanName和当前泛型对应的真实类型匹配,那么则继续判断。1、找出BeanFactory中类型为type的所有的Bean的名字,根据BeanDefinition就能判断和当前type是不是匹配,不用生成Bean对象。6、根据第4、5步,可以知道o对应的具体就是OrderService,s对应的具体类型就是StockService。
2023-11-08 11:08:44
181
原创 Spring-依赖注入补充
9、最后将currElements集合封装成一个InjectionMetadata对象,作为当前Bean对应的注入点集合对象并缓存。2、字段上存在@Autowired、@Value、@Inject中的任意一个,就认为该字段是一个注入点。static修饰的字段和方法是属于类的,在多例Bean的情况下很可能发生覆盖,相互影响导致错误发生。,进行依赖查找,找到当前方法参数所匹配的Bean对象。,进行依赖查找,找到当前字段所匹配的Bean对象。方法中,会遍历所找到的注入点依次进行注入。
2023-11-06 23:29:17
167
原创 Spring-依赖注入
普通的byType是根据set方法中的参数类型去找bean,找到多个会报错,而constructor就是通过构造方法中的参数类型去找bean,如果找到多个会根据参数名确定。方法参数个数为0个,并且(方法名字以"get"开头或者方法名字以"is"开头并且方法的返回类型为boolean)方法参数个数为1个,并且(方法名字以"set"开头并且方法返回类型为void)1、获取到set方法中的唯一参数的类型,并且根据该类型去容器中获取bean。在创建Bean的过程-填充属性时,Spring会去解析当前类,把。
2023-11-06 11:18:42
132
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人