- 博客(143)
- 收藏
- 关注
原创 RocketMQ(五):揭秘高吞吐量并发消费原理
提交消费请求后,会根据每次消费批处理最大消息数量进行分批次构建消费请求并提交到线程池执行任务并发消费消息的特点是吞吐量大,使用线程池对拉取的消息进行消费,但是消费消息是无法预估执行顺序消费消息时会使用消费者的消费监听器进行消费消息并获取返回状态,根据状态进行后续的处理(集群模式下)如果状态为成功则删除ProcessQueue中的消息,并更新内存中记录Broker的消费偏移量,后续定时任务向Broker进行更新该消费者所有队列对应的消费偏移量。
2024-11-21 09:25:34
1096
原创 RocketMQ(四):消费前如何拉取消息?(长轮询机制)
消息中间件消费端获取消息的方式通常有推送、拉取、长轮询(推拉结合)三种Broker主动推送消息有很好的实时性,但消费端未做流控可能会压力大,导致吞吐量、性能下降,消息积压消费者主动拉取消息能根据自己的消费能力决定拉取数量,但无法预估拉取频率,太慢会导致实时性差长轮询是特殊的拉取方式,在拉取的基础上,如果未拉取到消息会进行等待,超时或消息到达后再进行拉取,弥补拉取方式实时性差的缺点,但大量长连接一直等待资源开销大。
2024-11-21 09:24:48
1039
原创 RocketMQ(三):面对高并发请求,如何高效持久化消息?
Broker为了持久化消息会写很多文件,其中主要为CommitLog、ConsumerQueue、IndexFile文件为了实现高性能的写入,写入文件通常都是使用mmap(内存映射)对应源码中的MappedFileCommitLog为消息顺序写入的文件,通过顺序写的方式提高写入性能,文件名以起始偏移量命名,固定1G,消息被消费后会删除。
2024-11-20 11:35:45
1055
原创 搭建环境麻烦?5分钟上手云主机快速开发
本文将详细介绍如何在云主机中使用IDE工具结合Redis开发测试秒杀抢购功能,帮助读者充分理解该强大的开发环境
2024-11-20 11:34:36
784
原创 入门Hadoop存储与计算:实现单词统计的分布式文件处理系统
本文主要讨论Hadoop下的HDFS存储与MapReduce计算HDFS存储架构主要由namenode、datanode来实现,其中存储分为不同机架rack,机架上的节点间通信需要交换机,节点上真正存储数据块block同时为了实现数据可用与可靠,会对数据块进行冗余,副本存储在不同机架上,机架上不均匀的存储可以减少写开销计算流程会先对输入进行切片,切片后一一进行映射map,然后对KV进行分区排序后,再进行reduce合并,最终将结果输出到文件存储到HDFS。
2024-11-19 09:51:04
679
原创 Spring AI 开发专属于你的AI聊天机器人
随着人工智能技术的飞速发展,聊天机器人在现代商业中的应用越来越广泛聊天机器人不仅提高了效率,还改善了用户体验,它们可以24/7不间断地为客户提供服务,解答常见问题本文将介绍如何设计并实现一个AI聊天机器人,该机器人能够理解用户的文本输入并给出相应的回答通过结合Spring Boot、Spring AI等技术,我们将构建一个AI聊天机器人,适用于各种对话场景本篇文章通过Spring Boot、Spring AI、Alibaba-AI等技术实现AI聊天机器人。
2024-11-19 09:50:26
1058
原创 从零开始:手摸手教你入门搭建Hadoop
通过引入Hadoop,业务团队能够有效地应对大规模数据的存储和处理挑战,提升了数据处理效率,降低存储成本,增强系统的稳定性和可靠性搭建Hadoop的过程可能涉及到不同的坑,但通过本文的详细指导,同学们可以顺利地进行搭建希望本篇实践能帮助你在项目中成功应搭建Hadoop,带来显著的业务价值。
2024-11-18 10:05:17
1316
1
原创 入门微服务架构设计:由下单场景实现服务注册、发现以及调用
本文使用 Java 和 Spring Boot 框架设计一个微服务架构,以扣减库存的流程来实现服务的注册、发现和调用,并通过Spring Cloud (Alibaba)进行服务治理虽然我们已经简化很多流程,但不难看出微服务架构下的开发要比单体架构下麻烦的多微服务架构虽然能够解决单体架构所带来的问题,但同时也会引入一系列的问题因此选择不同的架构时需要结合项目、场景等多方面因素进行选择本篇文章被收入专栏深入浅出微服务,感兴趣的同学可以持续关注喔本篇文章笔记以及案例被收入。
2024-11-18 09:58:45
987
原创 ReflectionUtils提高反射性能!
反射是需要检查访问权限的,比如说私有字段是否允许访问使用反射进行方法调用时通常是Object,因此会涉及到需要强制类型转换JIT即时编译器会将循环次数多的热点代码进行编译成本地码,而后续不再需要解释执行,从而进行优化反射需要运行时动态解析类的元数据并查找,动态解析导致可能无法使用JIT为了安全,反射调用本地方法查找方法、字段数组时,通常会将对象进行copy后返回新的实例。
2024-10-24 09:33:51
865
原创 丸辣!BigDecimal又踩坑了
小菜之前在国内的一家电商公司自研电商项目,在那个项目中是以人民币的分为最小单位使用Long来进行计算现在小菜在跨境电商公司也接到了类似的计算需求,在小菜火速完成提交代码后,却被技术leader给叫过去臭骂了一顿技术leader让小菜将类型改为BigDecimal,小菜苦思不得其解,于是下班后发奋图强,准备搞懂BigDecimal后再对代码进行修改在 Java 中,浮点类型在进行运算时可能会产生精度丢失的问题尤其是当它们表示非常大或非常小的数,或者需要进行高精度的金融计算时。
2024-10-24 09:32:57
911
原创 RocketMQ(二):揭秘发送消息核心原理(源码与设计思想解析)
先校验参数,避免参数出错再获取Topic路由信息,如果本地没有就从NameServer获取然后通过线性轮询法选择队列,如果开启后,同步失败新的重试会选择其他broker紧接着对消息进行封装,设置唯一ID、压缩消息、检查禁止发送钩子、发送前后钩子等最后使用Netty写请求进行rpc,期间也会有rpc的钩子,如果是同步则会等待在此期间会进行重试、超时检测。
2024-10-23 09:15:33
1024
原创 这样的SQL执行为什么不会报错?optimizer_trace深度历险
本篇文章被收入专栏MySQL进阶之路,感兴趣的同学可以持续关注喔本篇文章笔记以及案例被收入感兴趣的同学可以stat下持续关注喔~关注菜菜,分享更多干货,公众号:菜菜的后端私房菜。
2024-10-23 09:14:16
678
原创 咦!Spring容器里为什么没有我需要的Bean?
默认只扫描当前包下的组件,如果需要扫描其他包,需要配置的或value字段当配置过时,默认不会扫描当前包下的组件,注意把当前包也加入配置本篇文章被收入专栏深入浅出常用框架,感兴趣的同学可以持续关注喔本篇文章笔记以及案例被收入,除此之外还有更多Java进阶相关知识,感兴趣的同学可以starred持续关注喔~关注菜菜,分享更多技术干货,公众号:菜菜的后端私房菜。
2024-10-22 09:28:04
425
原创 RocketMQ(一):消息中间件缘起,一览整体架构及核心组件
消息中间件通常有削峰填谷、异步通信、架构解耦、高性能、高可用、集群扩展、负载均衡等相关特点,同时项目中引入消息中间件也会增加调用链路、系统复杂度RocketMQ由NameServer、Broker、Product、Consumer等集群组成其中Broker作为服务端,负责接收消息、对消息进行高效持久化、消费消息时高效查询定义Topic对消息进行分类,为了提升水平扩展写入能力,Topic下可以设置MessageQueue队列,消息作为数据载体存储在队列中,等待被消费。
2024-10-22 09:27:20
1292
原创 异步任务编排神器CompletableFuture
CompletableFuture提供串行、AND、OR、异常捕获、结果聚合等多种API,通过这些API能够更方便、快捷的实现异步任务的编排使用CompletableFuture时务必对任务进行异常处理,并且它会使用CompletionException或ExecutionException包装异常,再打印异常时记得使用工具类处理,避免打印到包装的异常CompletableFuture异步任务中如果指定线程池则直接使用指定的线程池。
2024-10-21 10:59:53
897
原创 JUC组件实战:实现RRPC(Java与硬件通过MQTT的同步通信)
RRPC指的是调用该接口向指定设备发送请求消息,并同步返回响应在物联网场景下,如果想要做到Java服务与硬件同步通信的效果,那么一般会依赖MQTT来实现通信比如Java服务向硬件发送请求,请求查询硬件相关信息在这个同步通信的过程中,Java服务发送完消息是需要等待直到ack响应的,那么这个过程在Java服务端该如何实现这种等待/唤醒的模式呢?本文就结合JUC组件来实现Java与硬件(通过MQTT)同步通信的组件(为了简化流程,我们代码中使用阻塞队列代替MQTT)整体流程可以想象成远程调用的流程,只不过消费端
2024-10-21 10:58:54
729
原创 以超卖为例✨各种场景下如何防止并发污染数据?
本篇文章以防止商品超卖为案例,从Java层面到中间件层面描述各种场景下用不同的方式来解决并发读写可能引起的数据不一致性问题确保服务一直为单节点时在并发量较少的场景,可以使用本地锁synchronized、Lock,Lock可以超时等待避免大量请求阻塞如果服务一直为单节点时在并发量较高的场景,可以把库存数据放到内存中操作,再异步同步数据库,宕机可能导致部分数据丢失服务目前为单节点,以后可能会增加节点的场景,可以使用MySQL新增版本号字段做乐观锁。
2024-07-26 09:09:57
475
原创 Tomcat中的WebSocket是如何实现的?
WebSocket是一种长期、双向、实时通信的协议,基于HTTP协议后升级为WebSocket协议Tomcat在处理WebSocket时与HTTP请求有所不同,处理网络通信依旧还是使用EndPoint当请求为HTTP时会使用Http11Processor接卸请求,经过适配器最终交给Container容器处理;当请求为WebSocket时使用UpgradeProcessorInternal,路由到WebSocketContainer容器中的ServerEndPoint处理类进行处理。
2024-07-26 09:09:12
560
原创 盘点Tomcat中常见的13种设计模式
单例模式全局维护单一对象,适合生命周期长(与应用生命周期相同)、全局访问的对象,避免创建/销毁开销,但为了全局唯一,创建对象时需要使用“同步”的机制;业务中全局共享、生命周期长的组件考虑设计为单例工厂模式根据入参构建对象,屏蔽内部实现细节,常用于构建/复用复杂对象;业务中根据不同参数创建/获取不同实现组件考虑使用工厂适配器模式将原本不兼容的接口转换为期望的接口,提高兼容性,但转换过程存在开销;业务中对两个不适配的组件兼容时考虑适配器。
2024-07-25 09:07:07
845
原创 Tomcat类加载器揭秘:“重塑”双亲委派模型
双亲委派模型优先将类交给父类加载,如果父类不能加载再由自己加载,当自己也无法加载时抛出ClassNotFoundException异常,能够保证核心类库不被破坏通过类加载器可以解决隔离的问题,判断类是否相同时要满足全限定类名和类加载器都相同Tomcat为了解决多Web应用间类的隔离,自定义WebAppClassLoader类加载器作为Context容器的Loader。
2024-07-25 09:06:35
640
原创 深入浅出Tomcat网络通信的高并发处理机制
NioEndPoint将处理网络通信分为接收连接、监听事件、处理请求三个步骤其中Acceptor负责接收连接,使用LimitLatch限制连接数量(若超过上限则等待),获取客户端连接NioChannel,包装为NioSocketWrapper,再封装为PollerEvent放入Poller的队列中。
2024-07-24 09:17:29
1049
原创 面对海量网络请求,Tomcat线程池如何进行扩展?
Tomcat面对IO密集型任务,对JUC线程池进行扩展为了避免启动时高并发请求访问,将创建核心线程的“懒加载”调整为提前创建为了防止队列已满才去创建非核心线程,扩展阻塞队列入队逻辑,当任务数量超过线程数量并且不到最大线程数时就去创建非核心线程为了进一步提升吞吐量,在触发拒绝策略后捕获拒绝异常再次尝试放入队列中本篇文章被收入专栏Tomcat全解析:架构设计与核心组件实现,感兴趣的同学可以持续关注喔本篇文章笔记以及案例被收入。
2024-07-24 09:16:58
1048
原创 21张图解析Tomcat运行原理与架构全貌
早年间,精通CRUD的小菜同学在Tomcat上通过继承HttpServlet进行CRUD后来,有了Spring MVC框架的DispatcherServlet,让小菜更容易的进行CRUD到现在,Spring Boot框架内嵌Web服务器,让小菜更轻松、更便捷的专注CRUD小菜保持专一的原则,一心只关注CRUD,从未对服务器、框架有过”非分之想“突然有一天,小菜不知道改动了哪里,程序跑不起来了小菜心想:程序跑不了,那我岂不是得跑了?不行,不行,大环境这么恶劣,我可不能跑啊。
2024-07-23 09:05:57
1797
原创 一文搞懂网络通信的基石✅IO模型与零拷贝
IO模型的提出是为了解决CPU在内存的速度与外部设备加载到内存速度的差异在操作系统中为了安全使用系统资源,IO时会涉及到用户态、内核态的切换IO阶段通常分为准备数据和拷贝数据,准备数据主要由DMA将外部设备数据拷贝到内核缓冲区,拷贝数据是将内核缓冲区拷贝到用户缓冲区同步阻塞IO模型(BIO)发起系统调用后会阻塞到数据拷贝完成,不适合处理高并发网络通信的场景同步非阻塞IO模型使用轮询的方式判断数据是否就绪,就绪再同步阻塞等待数据拷贝。
2024-07-23 09:05:07
947
原创 一文读懂HTTPS⭐揭秘加密传输背后的原理与Nginx配置攻略
对称加密模型只有一种密钥,加密/解密都使用这种密钥,高效但不安全非对称加密模型分为公钥与私钥,公钥可以暴露给外界,而私钥自己保存,加密/解密开销大,但只是相对安全,遇到恶意第三方结构伪造成服务端篡改数据/伪造公钥还是不安全的为了让客户端判断数据是否被篡改/公钥是否可信任,引入第三方权威可信机构申请证书时,CA根据hash对数据进行加密得到数据摘要,再使用密钥对数据摘要进行加密得到数字签名,数字签名与其他信息形成数字证书。
2024-07-22 16:19:56
1081
原创 Java并发设计的7条原则
对于共享可变数据,如果只读可以使用volatile保证可见性,如果需要写则要使用同步手段过度使用同步手段会导致开销大,尽量在同步区间少做操作并发包下的Executor框架将任务与执行分离,使用线程池管理线程,还有并行stream的fork join框架都优于单独使用线程并发包下的工具使用更简单,了解后尽量使用并发包下的工具对于可能被并发调用的类需要声明线程安全性文档:绝对线程安全、相对线程安全、线程不安全等。
2024-07-22 16:18:26
278
原创 关于Java异常处理的9条原则
只有针对异常情况才使用异常,不要使用异常来做程序的流程控制广泛的异常分为受检异常、运行时异常(非受检异常)和错误,通常只接触前两者,后者排查虚拟机错误时才接触对于运行恢复的情况抛出受检异常,程序错误或不确定是否允许恢复的情况抛出运行时异常受检异常必须进行处理,能够带来可靠,但太多会导致复杂,不catch处理受检异常时可以直接抛出优先复用已有的标准异常,不满足需求时再自定义设计抽象层次方法时,关注抽象层次异常,而不是具体实现异常,通过捕获具体实现异常再抛出抽象层次异常。
2024-04-18 09:03:06
846
原创 12条通用编程原则✨全面提升Java编码规范性、可读性及性能表现
最好让局部变量作用域最小化,在第一次使用时声明,作用域只在循环时优先使用for循环foreach是迭代器与for循环实现的语法糖,只展示元素屏蔽迭代器与索引,优先使用foreach优先使用JDK、第三方类库,不要自己造轮子精确计算不使用浮点型,可以转换为最小单位使用整形,如果必须要小数部分或计算量超出整形范围使用BigDecimal只有集合、反射时才用包装类,其他情况使用基本数据类型,使用包装类注意空指针和用equals比较字符串适合文本,其他类型合适避免使用字符串。
2024-04-17 13:59:02
1139
原创 掌握8条方法设计规则,设计优雅健壮的Java方法
方法中不检查入参会导致运行时异常或错误结果,考虑在方法中检查入参,增加代码健壮性依赖的可变对象逃逸被修改会导致错误结果,可使用不可变对象或保护性拷贝(入参、响应)解决设计方法时需要见名知意、避免参数过长、定义参数类型为接口而不是类、boolean类型考虑泛型,并且API中不要追求大量便利的方法,这种方法应该在工具类中重载编译时就能够确定,为了避免转换类型调用错重载方法,可以使用具体类型命名的方法代替重载,如果一定要使用重载可以让实现一致。
2024-04-17 09:03:44
1129
原创 Lambda与Stream✨让代码简洁高效的七大原则
函数接口只存在一个抽象方法,并用注解@FunctionalInterface标识,可以使用Lambda表达式实现简单易懂的函数接口使用Lambda实现简洁,优于匿名内部类方法引用比Lambda更简洁,但某些情况下太简介会降低可读性,哪种方式更易提示代码可读性选择哪种java.util.function提供标准函数接口,当设计组件时优先选择标准函数接口,不满足需求再自定义。
2024-04-16 16:08:51
519
原创 8条枚举与注解技巧,提升代码质量与设计美学
枚举类继承抽象类Enum,用于定义常量,可由多个字段组成,并提供name\ordinal字段、values遍历方法等,使用枚举代替常量提升类型安全、可读性、扩展性ordinal用于标识枚举类型顺序,位置变动会发生改变,如果要依赖顺序性,最好使用字段记录EnumSet 使用位运算,在少量的空间高效的记录存储在同一集合的枚举常量EnumMap 使用ordinal索引下标,能够更高效、空间紧凑线性的对枚举常量类型进行分组如果想像新增类一样扩展枚举,可以定义接口类型由新增枚举实现。
2024-04-16 08:06:54
760
原创 掌握8条泛型规则,打造优雅通用的Java代码
使用泛型能够指定对象类型,在编译期间进行类型擦除并强制转换为对应类型除了兼容历史版本、获取Class对象、使用interface三种情况只能使用原生态类型,其他情况下都建议使用泛型泛型能够带来安全、灵活的特点,当无法预估对象类型时可以使用或无限制通配符<?
2024-04-15 16:21:48
747
原创 关于类和接口设计的11个好习惯
当实现类实现接口后,被认为是该接口的类型在早期会使用常量接口,接口只定义常量,而没有抽象方法,这会违反接口的定义设计组件时尽量让访问权限最小化,封装组件能够隐藏内部实现,让外部直接使用(降低耦合、组件独立、提升可重用)设计时遵守:字段私有、常量最好是不可变对象、使用方法访问字段不可变对象简单易实现、线程安全、满足原子性、可充当哈希表key,但是性能不好,每个值都需要一个对象,可以使用享元,缓存常用对象设计不可变对象遵守:字段私有、final;类不被继承 final class;
2024-04-15 13:40:53
1012
原创 对于所有对象都通用的方法⭐良好习惯总结
Object是每个类的父类,它提供一些非final方法:equals、hashCode、clone、toString、finalize...这些方法在设计上是可以被子类重写的,但是重写前需要遵守相关的规定,否则在使用时就可能踩坑为了避免业务开发踩坑,本文基于Effective Java中第三章节汇总出对于所有对象都通用方法的好习惯(文末附案例地址)finalize方法上篇文章已经描述就不再讨论equals表示逻辑相等,当需要判断对象逻辑相等时重写equals方法。
2024-04-13 10:01:30
625
原创 关于创建、销毁对象⭐Java程序员需要掌握的8个编程好习惯
考虑使用静态工厂方法代替构造器,静态工厂方法能够见名知意、可以使用单例或享元模式返回对象、搭配泛型返回对象可以是原类型子类、返回的对象可以随着入参改变、返回的对象所在的类可以在编译期不存在在参数较多时可以考虑使用建造者模式,可以代码可读性更高、防止构造对象期间发生逃逸可以通过私有构造强化单例,但能够被反射、序列号破坏单例;使用枚举单元素强化单例则可以避免破坏(在反射实例化前判断为枚举则抛出异常)对象依赖的“工具”不是固定的时,可以采用依赖注入DI的方式进行改变,而不是直接写死;
2024-04-12 15:11:29
345
原创 MySQL是怎样存储数据的?
本篇文章自顶向下描述MySQL的Innodb如何进行存储数据在MySQL的data目录中会存储日志、系统库、用户库等数据,其中库以目录为单位,表文件存储在对应库中Innodb下表文件通常包括表结构文件(.frm存储表结构) 和表空间文件(.idb存储记录-用户数据)表空间分为共享表空间和独立表空间,共享表空间服务元数据存储回滚段等,独立表空间服务用户数据存储非叶子节点段、叶子节点段等段是逻辑上的概念方便于管理不同功能的空间,段由若干个区和零散页组成。
2024-04-12 08:59:27
1861
原创 深入浅出Redis(十三):SpringBoot整合Redis客户端
// 自己定义了一个 RedisTemplate@Bean// 我们为了自己开发方便,一般直接使用 <String, Object>// Json序列化配置//json解析任意对象变成一个json序列化//使用ObjectMapper转义// String 的序列化// key采用String的序列化方式// hash的key也采用String的序列化方式// value序列化方式采用jackson。
2024-04-11 16:34:21
817
原创 深入浅出Redis(十二):Redis的排序命令Sort
本篇文章围绕Sort命令,深入浅出的解析Sort命令原理以及使用Sort命令使用新的等长数组来对list、set、zset对象进行排序,其中数组中的节点RedisSortObject存储元素地址和权值,先使用节点记录要排序对象中元素的地址和权值,再使用快速排序根据权值进行排序然后返回默认情况下权值为浮点型,如果是对字符串类型排序,需要使用alpha选项;想要使用其他key作为权值排序时使用by选项;限制结果集返回使用limit;想要返回其他key的值时使用get选项;
2024-04-11 09:27:09
1174
原创 深入浅出Redis(十一):Redis四种高级数据结构:Geosptial、Hypeloglog、Bitmap、Bloom Filter布隆过滤器
本篇文章深入浅出的解析Redis中四种高级数据结构的使用、适用场景以及原理Geospatial 使用Geohash算法以及zset对象实现,适用于计算地理空间的场景Hypeloglog 使用少量固定空间以及基数统计算法,适用于大数据情况下能接收微小出错的统计场景Bitmap 使用sds实现的位数组,sds逆序存储位数组扩容时不用修改旧数据,适用于大数据情况下只有两个状态的统计场景Bloom Filter 使用位数组与多个哈希函数实现,适用于在大数据情况下且能接收微小出错的判断元素是否存在集合的场景。
2024-04-10 16:49:10
711
原创 深入浅出Redis(九):Redis的发布订阅模式
本文围绕Redis的发布订阅模型,深入浅出描述了发布订阅模型的使用、发布订阅模型实现的数据结构以及使用发布订阅模型的场景发布订阅是一种通信模式,哨兵通过发布订阅来与节点进行交流,发布订阅能够实现关注、订阅系统的实现发布订阅的两种方式订阅频道、模式是通过维护频道字典和模式链表实现的,其中发送消息会先遍历字典和链表找出匹配频道的订阅客户端进行发送,其他pubsub相关查看订阅信息命令都是从频道字典和模式链表中获取信息本篇文章笔记以及案例被收入感兴趣的同学可以stat下持续关注喔~
2024-04-10 16:27:10
439
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人