高级编程
文章平均质量分 88
无心六神通
金融科技系统架构师
展开
-
Netty中ChannelHandler的生命周期
首先我们先分析小网络连接的生命周期,连接建立 ---> 数据交互 ---> 连接断开,在数据交互阶段,包括从连接中读取数据和向连接中写入数据。知道了连接的生命周期,就可以按图索骥的在各个阶段进行想要的操作。而在Netty中,网络连接的不同生命周期都可以通过回调的方式来绑定相应的逻辑,这个回调接口就是。在使用Netty进行网络编程的时候,通常需要在网络连接的不同阶段进行相应的操作,比如在连接建立时,客户端向服务端发起认证,在接收到数据时对数据内容进行解析等等。那么,连接的不同阶段在netty中如何表示呢?原创 2024-07-21 11:06:11 · 444 阅读 · 0 评论 -
TransitiveThreadLocal线程间可传递的ThreadLocal实现
TransitiveThreadLocal可传递的ThreadLocal实现1. 通过一个全局ThreadLocal视图来缓存jvm所有线程的ThreadLocal2. 通过组合模式复用jdk底层能力,内部成员包含java.lang.InheritableThreadLocal可继承ThreadLocal对象,实现父子线程数据传递原创 2024-07-20 22:58:03 · 313 阅读 · 0 评论 -
SLF4J warning or error messages and their meanings
注意,诸如库或框架之类的嵌入式组件不应该声明对任何SLF4J提供程序的依赖,而应该只依赖SLF4J -api。以及slf4j-reload4j、slf4j-jdk14、slf4j-simple 2.0.0或更高版本之一。将slf4j-nop.jar、slf4j-simple.jar、slf4j-reload4j.jar、slf4j-jdk14.jar或logback-classic.jar等许多可用的提供程序中的一个(且只有一个)放在类路径上将解决这个问题。当在类路径上找不到SLF4J提供程序时报告。原创 2024-07-19 09:15:03 · 1022 阅读 · 0 评论 -
ByteBuf.release() was not called before it‘s garbage-collected
本文讨论了什么是引用技术对象,已经在netty中的应用和内存泄漏发生场景、检测、排除修复等技术手段原创 2024-07-14 12:30:47 · 672 阅读 · 0 评论 -
netty系列之:netty实现http2中的流控制
HTTP2相对于http1.1来说一个重要的提升就是流控制flowcontrol。为什么会有流控制呢?这是因为不管是哪种协议,客户端和服务器端在接收数据的时候都有一个缓冲区来临时存储暂时处理不了的数据,但是缓冲区的大小是有限制的,所以有可能会出现缓冲区溢出的情况,比如客户端向服务器端上传一个大的图片,就有可能导致服务器端的缓冲区溢出,从而导致一些额外的数据包丢失。为了避免缓冲区溢出,各个HTTP协议都提供了一定的解决办法。原创 2024-07-12 21:59:56 · 723 阅读 · 0 评论 -
Dubbo3源码研读-消费者关键执行链路-IO接收-HTTP/2流的二进制帧
二进制帧累积缓冲区HEADERS 帧DATA 帧END 帧原创 2024-07-11 21:31:39 · 374 阅读 · 0 评论 -
半小时搞懂 HTTP、HTTPS和HTTP2
HTTP 超文本传输协议是位于 TCP/IP 体系结构中的应用层协议,它是万维网的数据通信的基础。当我们访问一个网站时,需要通过统一资源定位符 URL 来定位服务器并获取资源。代码语言:javascript复制<协议>://<域名>:<端口>/<路径>一个 URL 的一般形式通常如上所示(),现在最常用的协议就是 HTTP,HTTP 的默认端口是 80,通常可以省略。在这里插入图片描述。原创 2024-07-08 08:52:50 · 1177 阅读 · 1 评论 -
Dubbo-消费端线程池模型优化
这样,相比于老的线程池模型,由业务线程自己负责监测并解析返回结果,免去了额外的消费端线程池开销。改进后的消费端线程池模型,通过复用业务端被阻塞的线程,很好的解决了这个问题。原创 2024-07-07 23:20:55 · 305 阅读 · 0 评论 -
通过 HTTP/2 协议案例学习 Java & Netty 性能调优:工具、技巧与方法论
Dubbo3 Triple 协议是参考 gRPC、gRPC-Web、Dubbo2 等协议特点设计而来,它吸取各自协议特点,完全兼容 gRPC、Streaming 通信、且无缝支持 HTTP/1 和浏览器。当你在 Dubbo 框架中使用 Triple 协议,然后你就可以直接使用 Dubbo 客户端、gRPC 客户端、curl、浏览器等访问你发布的服务,不需要任何额外组件与配置。原创 2024-07-07 22:36:08 · 889 阅读 · 0 评论 -
Netty http2 多路复用
关键是该register方法会调用该channel的unsafe的register方法,DefaultHttp2StreamChannel由自己的unsafe,叫Http2ChannelUnsafe,下面我们看下该Http2ChannelUnsafe的register方法。一般rpc 框架要实现多路复用,都在发送的报文里携带请求唯一标示ID,netty http2在handler 层就已经隔离了不同stream之间的frame。通过上面的分析,总结下,在http2的协议下,netty实现多路复用,是。原创 2024-07-07 21:33:25 · 303 阅读 · 0 评论 -
Dubbo3源码研读-消费者关键执行链路-异步发送-写入缓冲队列
Dubbo3源码研读-消费者关键执行链路-异步写入队列原创 2024-07-07 14:13:48 · 258 阅读 · 0 评论 -
Dubbo中的InternalThreadLocal的简单分析
Dubbo中存在一些优化设计,这些设计具有一定的参考价值,这里调研下 InternalThreadLocal 的优化设计。原创 2024-07-07 09:39:29 · 966 阅读 · 0 评论 -
一个单例模式中volatile关键字引发的思考
对于JMM的happens-before规则,即对一个volatile修饰的变量的写操作,happens-before随后对这个变量的读操作。而如果我们使用一个基于句柄方式访问对象的编译器(如Symantec JIT),不加volatile关键字可能会导致重排序,返回一个未初始化完成的实例。,其中说到:如果使用Symantec JIT(一个基于句柄方式访问对象的编译器),它编译出来的代码就会发生上述的重排序。// 给客户端调用的,如果初始化未完成,应该返回false,如果完成,返回true。原创 2024-06-30 22:52:45 · 815 阅读 · 0 评论 -
什么是缓存一致性问题,CPU Cache 的读取和写入过程是如何执行的,MESI 缓存一致性协议又是什么?
CPU 缓存一致性(Cache Coherence)问题指 CPU Cache 与内存的不一致性问题。事实上, 在分析缓存一致性问题时,考虑 L1 / L2 / L3 的多级缓存没有意义,所以我们提出缓存一致性抽象模型,只考虑核心独占的缓存。CPU 三级缓存与抽象模型在单核 CPU 中,只需要考虑 Cache 与内存的一致性。但是在多核 CPU 中,由于每个核心都有一份独占的 Cache,就会存在一个核心修改数据后,两个核心 Cache 数据不一致的问题。在修改 Cache 数据后,如何同步回内存?原创 2024-05-21 13:48:29 · 628 阅读 · 0 评论 -
Netty - Native transports 本地传输
与基于NIO的传输相比,这些JNI传输添加了特定于平台的特性,生成的垃圾更少,并且通常提高了性能.原创 2024-06-23 18:04:41 · 873 阅读 · 0 评论 -
redission实践-踩坑-高并发(百万并发)-内存泄露-OOM
redission实践-踩坑-高并发-内存泄露-OOM-自旋等待原创 2024-06-22 14:33:56 · 475 阅读 · 0 评论 -
effective java —— 终结方法守卫者
effective java —— 终结方法守卫者原创 2024-06-20 23:23:26 · 640 阅读 · 0 评论 -
log4j2-RoutingAppender
RoutingAppender对LogEvents求值,然后将它们到一个从属Appender。可以是,可以通过其名称进行引用,也可以根据需要。RoutingAppender应该配置在它引用的appender之后,以允许它正确地关闭。你也可以用脚本配置RoutingAppender:你可以在appender启动时运行脚本,也可以在为日志事件选择路由时运行脚本。一个过滤器,用于。使用CompositeFilter可以使用多个过滤器。操作LogEvent的重写策略。包含一个或多个,以标识。truefalse。原创 2024-06-05 12:58:18 · 816 阅读 · 0 评论 -
Java-泛型-通配符-详解
泛型类型是固定的,某些场景下使用起来不太灵活,于是,通配符就来了!通配符可以允许类型参数变化,用来解决泛型无法协变的问题。无界通配符可以接收任何泛型类型数据,用于实现不依赖于具体类型参数的简单方法,可以捕获参数类型并交由泛型方法进行处理。List<?> 和 List 有区别吗?** 当然有!List<?> list 表示 list 是持有某种特定类型的 List,但是不知道具体是哪种类型。因此,我们添加元素进去的时候会报错。原创 2024-02-06 03:21:27 · 872 阅读 · 0 评论 -
Java-序列化-详解
如果我们需要持久化 Java 对象比如将 Java 对象保存在文件中,或者在网络传输 Java 对象,这些场景都需要用到序列化。序列化: 将数据结构或对象转换成二进制字节流的过程反序列化:将在序列化过程中所生成的二进制字节流转换成数据结构或者对象的过程对于 Java 这种面向对象编程语言来说,我们序列化的都是对象(Object)也就是实例化后的类(Class),但是在 C++这种半面向对象的语言中,struct(结构体)定义的是数据结构类型,而 class 对应的是对象类型。原创 2024-02-06 03:19:13 · 895 阅读 · 0 评论 -
Java-IO模型-详解
I/O 一直是很多小伙伴难以理解的一个知识点,这篇文章我会将我所理解的 I/O 讲给你听,希望可以对你有所帮助。原创 2024-02-06 03:14:50 · 1219 阅读 · 0 评论 -
Java-并发编程-常见面试题-总结
悲观锁总是假设最坏的情况,认为共享资源每次被访问的时候就会出现问题(比如共享数据被修改),所以每次在获取资源操作的时候都会上锁,这样其他线程想拿到这个资源就会阻塞直到锁被上一个持有者释放。也就是说,共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程。像 Java 中和等独占锁就是悲观锁思想的实现。悲观锁通常多用于写多比较多的情况下(多写场景),避免频繁失败和重试影响性能。原创 2024-01-30 11:09:28 · 1105 阅读 · 0 评论 -
Java-JMM-内存模型-详解
Java 是最早尝试提供内存模型的编程语言。由于早期内存模型存在一些缺陷(比如非常容易削弱编译器的优化能力),从 Java5 开始,Java 开始使用新的内存模型。一般来说,编程语言也可以直接复用操作系统层面的内存模型。不过,不同的操作系统内存模型不同。如果直接复用操作系统层面的内存模型,就可能会导致同样一套代码换了一个操作系统就无法执行了。Java 语言是跨平台的,它需要自己提供一套内存模型以屏蔽系统差异。这只是 JMM 存在的其中一个原因。原创 2024-02-06 03:04:21 · 815 阅读 · 0 评论 -
Java-线程池-最佳实践
一般建议是不同的业务使用不同的线程池,配置线程池的时候根据当前业务的情况对当前线程池进行配置,因为不同的业务的并发以及对资源的使用情况都不同,重心优化系统性能瓶颈相关的业务。原创 2024-02-06 03:02:26 · 872 阅读 · 0 评论 -
Java-常见并发容器-总结
在很多应用场景中,读操作可能会远远大于写操作。由于读操作根本不会修改原有的数据,因此对于每次读取都进行加锁其实是一种资源浪费。我们应该允许多个线程同时访问List的内部数据,毕竟读取操作是安全的。这和我们之前提到过的读写锁的思想非常类似,也就是读读共享、写写互斥、读写互斥、写读互斥。JDK 中提供了类比相比于在读写锁的思想又更进一步。为了将读取的性能发挥到极致,读取是完全不用加锁的,并且更厉害的是:写入也不会阻塞读取操作。只有写入和写入之间需要进行同步等待。这样一来,读操作的性能就会大幅度提升。原创 2024-02-06 03:01:17 · 954 阅读 · 0 评论 -
Java-Atomic-原子类-总结
Atomic 翻译成中文是原子的意思。在化学上,我们知道原子是构成一般物质的最小单位,在化学反应中是不可分割的。在我们这里 Atomic 是指一个操作是不可中断的。即使是在多个线程一起执行的时候,一个操作一旦开始,就不会被其他线程干扰。所以,所谓原子类说简单点就是具有原子/原子操作特征的类。并发包的原子类都存放在下,如下图所示。根据操作的数据类型,可以将 JUC 包中的原子类分为 4 类基本类型使用原子的方式更新基本类型:整型原子类AtomicLong:长整型原子类:布尔型原子类数组类型。原创 2024-02-06 03:00:01 · 1521 阅读 · 0 评论 -
Java-并发编程-CompletableFuture
同时实现了Future和接口。除了提供了更为好用和强大的Future特性之外,还提供了函数式编程的能力。Future:尝试取消执行任务。:判断任务是否被取消。: 判断任务是否已经被执行完成。get():等待任务执行完成并获取运算结果。:多了一个超时时间。接口描述了一个异步计算的阶段。很多计算可以分成多个阶段或步骤,此时可以通过它将所有步骤组合起来,形成异步计算的流水线。接口中的方法比较多,的函数式能力就是这个接口赋予的。从这个接口的方法参数你就可以发现其大量使用了 Java8 引入的函数式编程。原创 2024-02-03 19:59:52 · 1118 阅读 · 0 评论 -
Java-并发编程-ThreadLocal
对于,大家的第一反应可能是很简单呀,线程的变量副本,每个线程隔离。的 key 是弱引用,那么在的时候,发生GC之后,key 是否为null?中的数据结构?的Hash 算法?中Hash 冲突如何解决?的扩容机制?中过期 key 的清理机制?探测式清理和启发式清理流程?方法实现原理?方法实现原理?项目中使用情况?遇到的坑?......上述的一些问题你是否都已经掌握的很清楚了呢?本文将围绕这些问题使用图文方式来剖析的点点滴滴。原创 2024-02-03 19:56:30 · 968 阅读 · 0 评论 -
Java-并发编程-AQS
AQS 的全称为,翻译过来的意思就是抽象队列同步器。这个类在包下面。AQS 就是一个抽象类,主要用来构建锁和同步器。AQS 为构建锁和同步器提供了一些通用功能的是实现,因此,使用 AQS 能简单且高效地构造出应用广泛的大量的同步器,比如我们提到的Semaphore,其他的诸如等等皆是基于 AQS 的。使用者继承并重写指定的方法。将 AQS 组合在自定义同步组件的实现中,并调用其模板方法,而这些模板方法会调用使用者重写的方法。这和我们以往通过实现接口的方式有很大区别,这是模板方法模式很经典的一个运用。原创 2024-02-03 19:35:13 · 975 阅读 · 0 评论 -
Java-并发编程-线程池
顾名思义,线程池就是管理一系列线程的资源池,其提供了一种限制和管理线程资源的方式。每个线程池还维护一些基本统计信息,例如已完成任务的数量。降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。原创 2024-02-03 19:31:54 · 907 阅读 · 0 评论 -
Java-并发编程-乐观锁和悲观锁
悲观锁总是假设最坏的情况,认为共享资源每次被访问的时候就会出现问题(比如共享数据被修改),所以每次在获取资源操作的时候都会上锁,这样其他线程想拿到这个资源就会阻塞直到锁被上一个持有者释放。也就是说,共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程。像 Java 中和等独占锁就是悲观锁思想的实现。悲观锁通常多用于写比较多的情况下(多写场景),避免频繁失败和重试影响性能。原创 2024-02-03 19:24:33 · 803 阅读 · 0 评论 -
Java-IO-设计模式-总结
IO 流中的字符流和字节流的接口不同,它们之间可以协调工作就是基于适配器模式来做的,更准确点来说是对象适配器。更侧重于让接口不兼容而不能交互的类可以一起工作,当我们调用适配器对应的方法时,适配器内部会调用适配者类或者和适配类相关的类的方法,这个过程透明的。更侧重于动态地增强原始类的功能,装饰器类需要跟原始类继承相同的抽象类或者实现相同的接口。装饰器模式通过组合替代继承来扩展原始类的功能,在一些继承关系比较复杂的场景(IO 这一场景各种类的继承关系就比较复杂)更加实用。的子类比较少的话,这样做是没问题的。原创 2024-01-28 23:36:47 · 934 阅读 · 0 评论 -
Java-IO-基础知识-总结
IO 即,输入和输出。数据输入到计算机内存的过程即输入,反之输出到外部存储(比如数据库,文件,远程主机)的过程即输出。数据传输过程类似于水流,因此称为 IO 流。IO 流在 Java 中分为输入流和输出流,而根据数据的处理方式又分为字节流和字符流。Java IO 流的 40 多个类都是从如下 4 个抽象类基类中派生出来的。Reader: 所有的输入流的基类,前者是字节输入流,后者是字符输入流。Writer: 所有输出流的基类,前者是字节输出流,后者是字符输出流。原创 2024-01-28 23:32:45 · 921 阅读 · 0 评论 -
Java-源码-ConcurrentHashMap-底层-数据结构
Java7 中使用的分段锁,也就是每一个 Segment 上同时只有一个线程可以操作,每一个Segment都是一个类似HashMap数组的结构,它可以扩容,它的冲突会转化为链表。但是Segment的个数一但初始化就不能改变。Java8 中的使用的锁加 CAS 的机制。结构也由 Java7 中的 Segment数组 +HashEntry数组 + 链表进化成了Node 数组 + 链表 / 红黑树,Node 是类似于一个 HashEntry 的结构。原创 2024-01-28 23:31:21 · 862 阅读 · 0 评论 -
Java-源码-HashMap-底层数据结构
HashMap 主要用来存放键值对,它基于哈希表的 Map 接口实现,是常用的 Java 集合之一,是非线程安全的。HashMap可以存储 null 的 key 和 value,但 null 作为键只能有一个,null 作为值可以有多个JDK1.8 之前 HashMap 由 数组+链表 组成的,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的(“拉链法”解决冲突)。JDK1.8 以后的HashMap。原创 2024-01-28 23:29:51 · 874 阅读 · 0 评论 -
Java-源码-ArrayList-扩容机制
ArrayList的底层是数组队列,相当于动态数组。与 Java 中的数组相比,它的容量能动态增长。在添加大量元素前,应用程序可以使用操作来增加ArrayList实例的容量。这可以减少递增式再分配的数量。ArrayList继承于 AbstractList,实现了 List这些接口。是一个标志接口,表明实现这个接口的 List 集合是支持快速随机访问的。在ArrayList中,我们即可以通过元素的序号快速获取元素对象,这就是快速随机访问。ArrayList实现了 Cloneable接口,即覆盖了函数。原创 2024-01-28 23:28:29 · 867 阅读 · 0 评论 -
Java-集合-使用注意事项-总结
就是起一个模板的作用,指定了返回数组的类型,0 是为了节省空间,因为它只是为了说明返回的类型。方法的时间复杂度也是 O(1),不过,也有很多复杂度不是 O(1) 的,比如。方法,时间复杂度接近于 O(1)(没有出现哈希冲突的时候为 O(1))。方法是通过遍历所有元素的方法来做的,时间复杂度接近是 O(n)。的真正得到的参数就不是数组中的元素,而是数组对象本身!的唯一元素就是这个数组,这也就解释了上面的代码。的简易源码,我们可以看到这个类重写的方法有哪些。方法的可读性更好,并且时间复杂度为 O(1)。原创 2024-01-28 23:26:45 · 820 阅读 · 0 评论 -
Java-常见面试题-集合-总结
为了能让 HashMap 存取高效,尽量较少碰撞,也就是要尽量把数据分配均匀。我们上面也讲到了过了,Hash 值的范围值-2147483648 到 2147483647,前后加起来大概 40 亿的映射空间,只要哈希函数映射得比较均匀松散,一般应用是很难出现碰撞的。但问题是一个 40 亿长度的数组,内存是放不下的。所以这个散列值是不能直接拿来用的。用之前还要先做对数组的长度取模运算,得到的余数才能用来要存放的位置也就是对应的数组下标。这个数组下标的计算方法是“(n 代表数组长度)。原创 2024-01-28 23:25:17 · 831 阅读 · 0 评论 -
Java-重要知识点-语法塘详解
语法糖(Syntactic Sugar)也称糖衣语法,是英国计算机学家 Peter.J.Landin 发明的一个术语,指在计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。简而言之,语法糖让程序更加简洁,有更高的可读性。有意思的是,在编程领域,除了语法糖,还有语法盐和语法糖精的说法,篇幅有限这里不做扩展了。我们所熟知的编程语言中几乎都有语法糖。作者认为,语法糖的多少是评判一个语言够不够牛逼的标准之一。原创 2024-01-28 23:23:05 · 797 阅读 · 0 评论 -
Java-重要知识点-SPI机制详解
其实不难发现,SPI 机制的具体实现本质上还是通过反射完成的。我们按照规定将要暴露对外使用的具体实现类在文件下声明。另外,SPI 机制在很多框架中都有应用:Spring 框架的基本原理也是类似的反射。还有 Dubbo 框架提供同样的 SPI 扩展机制,只不过 Dubbo 和 spring 框架中的 SPI 机制具体实现方式跟咱们今天学得这个有些细微的区别,不过整体的原理都是一致的,相信大家通过对 JDK 中 SPI 机制的学习,能够一通百通,加深对其他高深框的理解。原创 2024-01-28 23:21:48 · 1123 阅读 · 1 评论