自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

程序员小潘

专注于Java后端技术分享!

  • 博客(352)
  • 资源 (1)
  • 收藏
  • 关注

原创 Java Timer定时任务源码分析

Java 提供的类可以用来执行延时任务,任务可以只执行一次,也可以周期性的按照固定的速率或延时来执行。

2025-03-20 21:00:25 609

原创 Spring线程池优雅关闭

线程池大家一定不陌生,常被用来异步执行一些耗时的任务。但是线程池如何优雅的关闭,却少有人关注。当 JVM 进程关闭时,你提交到线程池的任务会被如何处理?如何保证任务不丢?

2025-01-03 17:16:49 1024

原创 Dubbo分布式日志跟踪实现

随着越来越多的应用逐渐微服务化后,分布式服务之间的RPC调用使得异常排查的难度骤增,最明显的一个问题,就是整个调用链路的日志不在一台机器上,往往定位问题就要花费大量时间。如何在一个分布式网络中把单次请求的整个调用日志给串起来,变得刻不容缓。

2024-11-11 20:08:17 1287

原创 Dubbo Telnet服务追踪源码分析

Dubbo 的 Telnet 特性允许开发者通过 Telnet 客户端直接连接到 Dubbo 服务提供者,执行一系列命令以获取服务状态、调试信息和进行服务管理。这种特性在开发和运维过程中非常有用,尤其是在需要快速定位问题或查看服务状态时。本文介绍 Telnet 中最为常用的 trace 命令,它可以追踪服务提供者的某个服务的某个方法,把服务调用的入参出参以及执行耗时输出到 Telnet 客户端。

2024-11-04 19:29:24 459

原创 基于Flink MySQL CDC技术实现交易告警

CDC 的全称是 Change Data Capture,是一种用于捕获数据库变更数据的技术。例如 MySQL 对数据的所有变更都会写入到 binlog,CDC 就可以通过监听 binlog 文件来实现对 MySQL 数据变更的捕获,然后做进一步的处理。Flink CDC 将CDC技术和 Flink 流计算整合到一起,把CDC捕获到的数据变更作为 Flink数据源,以实现对数据变更的流式处理。

2024-10-15 16:45:58 1409 2

原创 Flink状态一致性保证

一个Flink作业由一系列算子构成,每个算子可以有多个并行实例,这些实例被称为 subTask,每个subTask运行在不同的进程或物理机上,以实现作业的并行处理。在这个复杂的分布式场景中,任何一个节点故障都有可能导致 Flink 作业宕机,Flink 状态本地化虽然可以实现极致的访问速度,但是节点故障后的状态恢复问题也是Flink必须要解决的。

2024-10-15 16:45:12 1291

原创 Flink算子状态为何只能用ListState?

Flink 将状态是否要按照 key 进行分类,将状态分为键值状态(Keyed State)和算子状态(Operator State)两种,两者除了状态本身的作用域不同外,其中算子状态的状态类型更是被 Flink 限制为 ListState,这是为什么呢?

2024-10-15 16:44:33 1357

原创 Flink有状态计算

状态是什么?状态就是数据,准确点说,状态是指 Flink 作业计算时依赖的历史数据或中间数据。如果一个 Flink 作业计算依赖状态,那它就是有状态计算的作业,反之就是无状态计算的作业。举个例子,服务端应用为了方便扩缩容,一般会设计成无状态的,但是对外服务的接口又是有状态的,这是因为服务端应用本身不存储数据,数据存储在关系型或非关系型数据库中,此时的“状态”就从服务端迁移到数据库中了。Flink 同理,一个稍微复杂一点的作业,基本都会使用到状态。

2024-10-15 16:44:01 1376

原创 Flink双流时间窗口联接

Flink 除了可以在一条数据流上使用各种时间窗口算法来处理数据,还支持两条数据流上的一段时间窗口内的数据进行联接操作,类似于SQL中的 join 操作。

2024-10-15 16:43:27 917

原创 Flink移除器Evictor

实现接口即可自定义 Evictor,泛型要注意,第一个是元素类型,第二个是窗口类型。举个例子,我们定义一个 Evictor,它在 ProcessFunction 计算前把窗口内所有的奇数全部移除掉,只保留偶数。@Override= 0) {@Override编写一个简单的 Flink 作业验证一下我们自定义的 Evictor,数据源手动指定为数字1到6,统一分配到 GlobalWindow 窗口,Trigger 元素等于6个就出发计算,最终输出窗口内的元素@Override});

2024-10-15 16:42:44 801

原创 Flink触发器Trigger

通过子类继承 Trigger 重写相应的方法,即可自定义我们自己的触发器。举个例子,我们自定义一个和时间不相关的 Trigger,我们等窗口积攒到一定数量的元素再出发计算。@Override// 通过Flink state来保存窗口内积攒的元素数量@Override@Override@Override接下来验证一下我们的Trigger是否生效。

2024-10-15 16:41:33 1300

原创 Flink窗口分配器WindowAssigner

窗口对象被 Flink 统一封装为抽象类TimeWindow 基于时间范围的窗口,包含开始时间戳和结束时间戳GlobalWindow 全局窗口,与时间无关的窗口如果内置的这两种窗口无法满足你的需求,你也可以自定义窗口。需要注意的是,窗口本身是要在算子间传输的,所以你在自定义窗口的同时,还必须提供一个窗口序列化器,以便于 Flink 可以将你的窗口对象序列化传输。如下示例,我们定义了一个基于数字范围的 NumberWindow,可以将一个数字划分到对应的数字范围窗口内。return min;

2024-10-15 16:41:02 1075

原创 Flink时间窗口程序骨架结构

Flink 作业的基本骨架结构包含三部分:创建执行环境、定义数据处理逻辑、提交并执行Flink作业。日常大部分 Flink 作业是基于时间窗口计算模型的,同样的,开发一个Flink时间窗口作业也有一套基本的骨架结构,了解这套结构有助于我们更快地上手时间窗口作业开发。

2024-10-15 16:40:32 1659

原创 Flink事件时间和Watermark

内置 WatermarkGenerator 不满足需求时,也可以自定义Watermark生成策略。如果数据本身携带 Watermark 标志,那么可以重写 onEvent() 来发送 Watermark。@Override// 假设数据格式中 字符串W开头是Watermark,其中f1是时间戳@Override// NOOP如果数据本身没有Watermark标志,我们也可以直接根据系统时钟,周期性的发送 Watermark。

2024-10-15 16:39:59 1369

原创 Flink时间语义和时间窗口

在实际的流计算业务场景中,我们会发现,数据和数据的计算往往都和时间具有相关性。归纳总结可以发现,这些和时间相关的数据计算可以统一用一个计算模型来描述:每隔一段时间,计算过去一段时间内的数据,并输出结果。这个计算模型,就是时间窗口。

2024-10-15 16:39:19 1750

原创 Flink作业骨架结构

Flink是大数据流计算引擎,本质上是对大数据的计算处理,那么首先要解决的问题是:数据从哪儿来?解决这个问题,就是给Flink作业定义数据源,数据源被抽象成了 SourceFunction 接口,实现该接口重写 run 方法即可接收数据。有了数据,接下来就是声明要对这些数据做哪些处理?对数据的处理被抽象成了 ProcessFunction 接口,实现该接口重写 processElement 方法即可处理一条条数据。常见的数据处理操作有:过滤、转换、聚合等。

2024-10-15 16:38:35 1399

原创 初识Flink

伴随现代信息技术的持续发展,我们能清晰地察觉到,信息生产的规模不断扩张,信息更新的速率持续攀升。以电商系统为例,用户从搜索商品到下单支付,整个链路可能短短几秒就可以完成,倘若能在这条链路里更迅速地分析与挖掘出价值更高的信息,便能取得优势地位。在这种需求推动的宏大背景下,各类批处理、流处理引擎得以快速发展,其中 Apache Flink 更是成为后来居上的佼佼者。

2024-10-15 16:37:50 902

原创 Elasticsearch查询类型

搜索是Elasticsearch最核心的功能之一,它能够在海量数据中精准、快速地召回我们期望的文档。Elasticsearch支持各种复杂的条件搜索,查询类型之多,往往让新手一头雾水。甚至同一个搜索需求,可以用不同的查询类型来实现,但是效率却天差地别,理解Elasticsearch提供的各种查询类型,可以帮助我们更好的搜索我们的数据。

2024-10-15 16:36:25 1500

原创 Elasticsearch文档操作

Elasticsearch索引是一组相关文档的集合,文档在Elasticsearch中用JSON来表示,每个文档都有一个唯一的”_id“字段来标识。每个文档又是一组字段的集合,字段可以有自己的数据类型,可以是数字、字符串、日期、布尔类型等,Elasticsearch可以索引文档,并对索引的文档做检索和数据分析。

2024-10-15 16:35:40 1197

原创 Elasticsearch Ingest Pipelines

在将第三方数据源的数据导入到Elasticsearch中时,原始数据长什么样,索引后的文档就是什么样。文档数据结构不统一,导致后续数据分析时变得麻烦,以往需要额外写一个中间程序来读取原始数据,转换加工后再写入到Elasticsearch,比较麻烦,于是官方推出了Ingest pipeline。Ingest pipeline 允许文档在被索引之前对数据进行预处理,将数据加工处理成我们需要的格式,例如删除或增加一些字段等。

2024-10-15 16:34:34 1485

原创 Elasticsearch文本分析器

Elasticsearch规定,任何分析器都由0个或多个字符过滤器、1个分词器、0个或多个分词过滤器组成,官方内置了大量的基础组件,同时又基于这些基础组件定义了一堆内置的分析器。如果这些内置分析器不能够满足我们的需求,我们也可以任意搭配组合定制化一个分析器。假设,我们现在创建一个questions索引,用来索引问题,然后可以根据关键词搜索问题。question字段使用text类型,同时使用我们自定义的文本分析器my_analyzer。自动过滤掉文本中的标点符号简单点,针对“/"符号来做分词吧。

2024-10-15 16:23:46 1083

原创 Elasticsearch字段数据类型

ES文档的每个字段都至少有一个数据类型,此类型决定了字段值如何被存储以及检索。例如,字符串类型可以定义为text或者keyword,前者用于全文检索,会经过分词后索引;后者用于精准匹配,值会保持原样被索引。ES字段类型按族分组,同一族中的类型具有完全相同的搜索行为,但可能具有不同的空间使用或性能特征。

2024-10-15 16:22:55 2504

原创 Elasticsearch索引映射定义

索引是文档的集合,文档是字段的集合,每个字段都有自己的数据类型。在映射数据时,需要创建一个映射定义,其中包含与文档相关的字段列表。映射定义还包括元数据字段,如_source字段,它自定义如何处理文档的关联元数据。

2024-07-16 08:55:15 1252

原创 Java线程池execute和submit的区别

ThreadPoolExecutor提供了两种方法来执行异步任务,分别是execute和submit,也是日常开发中经常使用的方法,那么它俩有什么区别呢?

2024-06-04 16:44:25 1705 1

原创 Elasticsearch索引定义

在索引文档前,首先需要定义索引。包括:索引名称、索引设置、索引映射、别名、分析器等。如下示例,我们创建了一个名称为“student”的索引,它拥有1个分片数和1个副本数;在索引映射里我们定义了三个字段分别是:学号 student_id、姓名 name、性别 gender,字段类型都是keyword,用于精准匹配;同时该索引还有一个别名:student_alias。

2024-04-30 16:23:18 2036 2

原创 Elasticsearch快速上手

索引是文档的容器,就像关系数据库中,要存储行记录必须先创建数据库和表一样。ES6 及之前的版本还存在”类型“的概念,一个索引下可以存储多个类型的文档,但是不同类型下的文档却不是相互独立的,这些文档同属于一个 Lucene 索引,仅通过_type字段做逻辑区分,导致不同类型下的相同字段名无法实现不同的数据类型而出现问题,于是 ES7 废弃了类型的概念,ES8 彻底移除了类型。文档是可以被索引的最小信息单元,相当于关系数据库中的行记录。文档由若干个字段(Field)组成,每个字段是一个键值对。

2024-04-07 18:18:01 1252

原创 Spring事件监听机制

Spring 的事件监听机制,采用了观察者的设计模式。一套完整的事件监听流程是这样的,首先定义事件类,即ApplicationEvent的子类,它包含事件发生的时间戳timestamp和产生事件的来源source,以及自定义的其它事件属性;然后实现事件监听器 ApplicationListener 并注册到容器,订阅感兴趣的事件,Spring 会在事件发生时触发监听器;最后通过事件发布器 ApplicationEventPublisher 发布自定义事件。

2024-03-04 19:41:11 1299 1

原创 基于Redis商品库存扣减方案

电商业务场景下,对于库存的处理是比较重要的,表面上看只是对商品库存数做一个扣减操作,但是要做到不超卖、不少卖,同时还要保证高性能,却是一件非常困难的事。

2024-02-22 17:10:23 2103

原创 Spring Bean的生命周期

Spring Bean 是 Spring IOC 容器负责实例化、组装和管理的对象,它和普通的 Java 对象并没有什么区别,唯一的区别就是它不是由开发人员自己 new 出来的,而是由容器负责创建的。IOC 容器除了实例化对象,还会负责管理对象之间的依赖关系,自动注入依赖和属性,甚至创建代理对象来对原始对象进行增强。生命周期是一个对象从创建到被销毁经历的整个过程,普通Java对象的生命周期是JVM分配内存,调用构造函数实例化对象,当该对象没有被引用后再由GC负责销毁并释放内存。

2024-02-18 20:33:50 2493 1

原创 Redis分布式可重入锁实现方案

在单进程环境下,要保证一个代码块的同步执行,直接用关键字或即可。在分布式环境下,要保证多个节点的线程对代码块的同步访问,就必须要用到分布式锁方案。分布式锁实现方案有很多,有基于关系型数据库行锁实现的;有基于ZooKeeper临时顺序节点实现的;还有基于 Redis setnx 命令实现的。本文介绍一下基于 Redis 实现的分布式锁方案。

2024-02-18 15:03:32 2400

原创 ThreadLocalMap为什么用线性探测解决哈希冲突

ThreadLocal 本身不存储值,访问的是当前线程 ThreadLocalMap 里存储的数据副本,实现了线程间的数据隔离。只有当前线程能访问,也就不存在并发访问时的安全问题了。ThreadLocal 的核心是 ThreadLocalMap,它和 HashMap 不同的是:面对哈希冲突时,后者用的是链表法,而前者用的是线性探测法,为什么呢???

2024-01-19 11:33:26 1108 1

原创 自定义Dubbo RPC通信协议

然后是定义grpc的 Service 和消息格式DispatcherService.proto 请求分发服务的定义RequestData.proto 请求消息的定义,主要是对 Invocation 的描述ResponseData.proto 响应消息的定义,主要是对 AppResponse 的描述使用插件把 proto 文件生成对应的 Java 类。

2024-01-18 08:42:07 1510

原创 Dubbo分层设计之Protocol层

Dubbo 框架采用分层设计,自上而下共分为十层。最底下的 Serialize 层关心的是如何序列化对象、往上的 Transporte 层关心的是如何把数据传输到远程、再往上的 Exchange 层关心的则是如何实现 请求-应答 消息交换模式、再往上就是 Protocol 层,它关心的是如何封装 RPC 调用,屏蔽底层细节。

2024-01-18 08:41:16 1294

原创 Dubbo分层设计之Exchange层

Dubbo Exchanger 也可以基于 SPI 一键替换,我们实现一个自定义的 Exchanger,加深理解。首先,我们新建一个模块,并引入依赖:

2024-01-17 19:44:42 1060

原创 基于JavaSocket重写Dubbo网络传输层

新建一个模块用来封装我们自己的传输层实现。因为要写的是 Dubbo 传输层的一个实现策略,所以要依赖

2024-01-17 19:44:03 1062

原创 Dubbo分层设计之Transport层

Dubbo 框架采用分层设计,最底下的 Serialize 层负责把对象序列化为字节序列,再经过 Transport 层网络传输到对端。一次 RPC 调用,在 Dubbo 看来其实就是一段请求报文和一段响应报文的传输过程。

2024-01-15 11:14:26 1155

原创 Dubbo分层设计之Serialize层

Serialization 被设计成 SPI 接口,所以它可以很轻松的被替换。接下来,我们就基于 Fastjson2 写一个序列化模块,替换掉默认的 hessian2,让你对整个序列化过程理解的更加清楚。首先,我们新建一个模块。因为我们要依赖 Dubbo 提供的接口去实现一套新的序列化组件,所以自然要引入模块。又因为我们是基于 fastjson2 实现的,所以也得引入 fastjson2 的依赖。

2024-01-15 11:12:22 1186

原创 Spring Boot Starter设计实现

Starter 是 Spring Boot 非常重要的一个硬核功能。通过 Starter 我们可以快速的引入一个功能或模块,而无须关心模块依赖的其它组件。关于配置,Spring Boot 采用“约定大于配置”的设计理念,Starter 一般都会提供默认配置,只有当我们有特殊需求的时候,才需要在里进行单独配置以覆盖掉默认配置。例如,我们开发一个 Web 应用,需要用到 Spring MVC、Tomcat 等组件,我们只需要依赖。

2024-01-11 16:52:27 752

原创 Spring Boot自动装配

跟自动装配相对立的就是手动装配,早期我们通过 xml 手动往容器里注册 bean 的方式就是手动装配。

2024-01-11 16:51:50 603

原创 SpringBoot内嵌Tomcat启动流程

Spring MVC 让开发者不用了解 Servlet 细节,专注于 Controller 编写 API 接口。Spring Boot 更是采用约定大于配置的设计思想,通过内嵌 Tomcat 的方式让开发者可以快速构建并部署一个 Web 应用。怎么做到的呢?

2024-01-11 16:51:12 1125

HashMap.java

JDK7的HashMap源码阅读,几乎给每个方法和属性都加上了中文注释。 可以帮助大家更好的阅读源码,可能有理解不对的地方,望指正。

2019-12-27

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除