自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

Night Field' Blog

每天进步一点点

  • 博客(63)
  • 收藏
  • 关注

原创 Apache HttpClient 模拟 SSO 登陆丢失 cookie 问题解决

背景需要用 Java 访问一个被 SSO 保护的特殊接口获取信息。方案设计假如我们用浏览器来实现这个功能,步骤简单如下:输入目标 API 地址(浏览器自动重定向到 SSO 登陆页面)输入用户名密码登陆(浏览器重定向回到 API 地址,并附带认证信息)获取目标 API 的资源信息其中需要用户操作的是步骤 1 和步骤 3。但要求是用 Java 来实现上述功能,关键点在于如何获取认证信息。有了认证信息,我们便能直接 call 目标 API。所以我们需要模拟浏览器的登陆行为,此时的初步想法

2022-04-16 22:06:39 1803

原创 Mybatis 批量插入 Oracle 记录

基本环境语言:Java 8数据库:OracleORM 框架:MyBatis 3.4.5需求批量插入数据,数据需要有自增 id。每次插入有一个唯一的 sessionId 来标记这些记录,插入完成之后返回这个 sessionId。方案循环插入单条记录,伪代码:int sessionId = dao.querySessionId();for (Record record : recordList) { dao.insertRecord(record, sessionId);}re

2022-01-06 14:25:12 763

原创 Big Key 导致 Redis 频繁重连的问题排查

背景监控是系统的重要模块,我们给产线的 Redis 机器配置了全方位的监控,包括机器性能指标测试以及 Redis 服务测试等等。今天收到了 PagerDuty 告警,报告说 Redis 服务间歇性异常。问题描述Redis 是一个集群,三主三从,每个节点各配置了一个监控,监控的测试逻辑大致是,用 INFO,CLUSTER SLOTS,CLUSTER NODES 等命令查看节点以及集群的基本信息是否正常,然后给主节点(master) set 一个 dummy key,看是否在规定时间内能同步到从节点(sl

2021-11-30 16:25:59 1433

原创 博客搬家日记--搭建基于Docker的LNMP环境

背景由于云主机马上就要到期了,所以最近对比了几家云服务器提供商。最终决定尝试一下 UCloud。于是不得不把原博客(typecho)迁移过来。下面是流水账式地记录一下过程。过程记录本想尝试按照以前的笔记重新搭建一套环境,然后再把数据导过来,但是一想到这一长串的步骤,以及可能碰到的问题就头疼,于是决定构建一个基于容器的 LNMP 环境,一劳永逸,也方便日后继续做博客迁移。当然如果有同学也想搭建基于 LNMP 的博客如 Typecho,则可以参考我的模板:-)(文末有 Github 链接)。注:以下命令

2021-11-21 15:44:27 2391

原创 如何用 ThreadGroup 记录线程创建链路

背景我们维护一个监控平台,平台跑着各种各样的插件来测试不同的场景。平台捕获插件的标准输出来得到日志,获取退出码来知道运行结果。Java 插件就是一个可执行的 .jar 文件,它会被加载到平台的 JVM 中,运行在一个线程池里面。针对 Java 插件,我们提供了一个 SDK 给客户以降低开发难度,主要包括一些工具方法,定义标准执行流程,异常捕获等功能。难点在 Java SDK 中,我们希望提供一个工具方法,来统一打印标准输出。在 Java 插件中,只需要调用类似 PluginLogger.print(

2021-11-21 15:42:48 231

原创 用 maven dependency plugin 优化 maven 依赖

layout: posttitle: 优化 maven 依赖实践date: 2020-06-28categories:Handbooktags:Maven背景Maven 是非常优秀的项目管理工具,我们可以方便地在 pom 文件里配置 Java 工程的依赖。但是随着项目的迭代和时间推移,pom 文件在新老需求的不断增删改之下变得越来越臃肿,到后来连自己都不知道哪些是有效依赖。下面将简单介绍如何用 Maven 插件 maven dependency plugin 来解决这个问题。ma.

2021-07-06 16:23:51 907

原创 浅谈分布式

前言互联网时代,分布式是一个绕不过去的话题。本文将简单谈谈个人对分布式的理解。何为分布式维基百科上对分布式系统(Distributed System)的定义如下:A distributed system is a system whose components are located on different networked computers, which communicate and coordinate their actions by passing messages to one

2021-04-02 10:19:28 216 1

原创 漫谈zookeeper watcher单次触发特性

架构师 Hooya 正带领着他的团队着手开发一款高性能分布式协调工具,暂名 zookeeper。Hooya开场白:同学们,作为一个分布式协调软件,通知功能是必不可少的。今天我们来 brainstorm 一下如何设计咱 zookeeper 的通知机制吧。攻城狮小A抢先道:这简单呀,不就是实现一个大号的观察者模式嘛,Client 注册 watcher,Server 在数据改动的时候通知 Client,目测不会太复杂。Hooya:再简单也要从头开始,我们先定义一下通知的事件吧。小A一拍脑门:zookeep

2021-04-01 14:54:24 198 1

原创 zookeeper的watcher是一次性的吗?!

zookeeperzookeeper 是流行的高性能分布式协调工具,它提供了分布式环境中需要的命名服务,配置管理,分布式锁,注册中心,Leader 选举等等功能,应用十分广泛。zookeeper 的 watcherClient 可以在 zookeeper 的节点(znode)上设置监听器(watcher),当节点被修改时,zookeeper 会向客户端发送一个相应的通知。可以通过 getData(),getChildren() 和 exists() 三个方法来设置 watcher。以 getData

2021-03-31 17:54:28 925

原创 Connection Timeout 问题排查

背景我们组开发维护了一个 Agent 工程,帮客户采集一些客户有用的网络数据。客户需要下载一个 MSI,然后安装并注册。问题描述某个客户下载安装 Agent 之后,提示注册失败。其实 Agent 注册就是一个用户登陆验证服务,然后创建一个 Machine ID 的过程。所谓 Machine ID,就跟用户帐号一样,是 Agent 的一个唯一标识。注册的流程大致如下:注册的主要目的是为 Agent 创建一个 Machine ID,为此需要获取一个 token,而这个 token 可以通过用户登陆来获

2021-03-01 16:54:36 12560 7

原创 MyBatis内置DataSource的连接池实现原理

前言MyBatis是一个流行的ORM框架,它简单易用,支持自定义SQL、存储过程以及高级映射。MyBatis免除了几乎所有的JDBC代码以及设置参数和获取结果集的工作。作为一款优秀的持久层框架,连接池是必不可少的。本文将分析MyBatis内置的数据源是如何实现连接池功能的(源码基于MyBatis3.4.5)。JDBC对数据库的操作回忆一下,我们用原生的JDBC来操作数据库的一般流程:public class JDBCExample { // JDBC driver name and dat

2020-12-12 14:29:19 956

原创 Hotspot早期的垃圾收集器简介

前言很多人的博文里面会提到JVM三种垃圾收集器:串行,并行和并发。这么分类也不能说错,但事实上也没有这么简单。本文简要介绍Hotspot早期的垃圾收集器(Garbage Collector)。名词解释年轻代和老年代:JVM中不同的对象,生命周期是不同的。比如线程中的临时变量,在方法结束之后便会被销毁;而静态变量,则会一直存在直到其所对应的类被销毁为止。基于这样的事实,才有了分代收集的概念:将JVM堆分为年轻代和老年代。年轻代存放刚被创建的对象,老年代存放经过多次GC之后依然存活的对象。一般年轻代空间

2020-12-10 17:38:36 93

原创 Redis的键过期策略及内存淘汰策略简介

RedisRedis是高性能的基于内存的NoSQL数据库。因为内存是比较宝贵的资源,无法无限制使用,所以Redis提供了:键过期策略来防止内存饱和。内存淘汰策略来使得内存饱和之后继续对外提供服务。内存过期策略expire命令Redis提供了expire命令来给一个键(key)设置过期时间:redis> SET foo "bar""OK"redis> EXPIRE foo 10(integer) 1redis> TTL foo(integer) 10类似set

2020-11-08 17:47:20 188

原创 Netty的ChannelPool导致内存泄漏的排查经历

背景接到了线上机器的报警,登上服务器,发现是Java进程挂了,看日志报了OOM:java.lang.OutOfMemoryError: Java heap space问题描述内存溢出,那当然是看dump文件了。这里推荐大家在产线机器上都加上JVM参数-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath={path}/{to}/{dump},这样,JVM在OOM的时候,会自动做一个内存dump,相当于保存现场。拿到dump文件,放到MAT里面分析,以下是

2020-08-31 10:07:56 1329

原创 自定义Classloader导致ClassCastException:不要轻易破坏双亲委派模型

背景java.lang.ClassCastException: cn.com.nightfield.Plugin cannot be cast to cn.com.nightfield.Plugin相同的class,竟然不能cast?这是什么鬼?问题描述自定义类加载器(Classloader)是很常见的,它可以让我们从自定义的文件系统目录,网络甚至是数据库的各种文件类型(jar, war, zip等)中加载class文件。我们项目中使用了一个开源的类管理工具PF4J,来加载指定目录下的class

2020-08-15 16:19:05 1015

原创 深入理解Linux, NIO和Netty中的零拷贝(Zero-Copy)

背景零拷贝(Zero Copy)是一个耳熟能详的术语,众多高性能的网络框架如Netty,Kafka,Rocket MQ都将零拷贝标榜为其特性。那么究竟什么是零拷贝?零拷贝Wikipedia上对零拷贝的解释如下:“Zero-copy” describes computer operations in which the CPU does not perform the task of copying data from one memory area to another. This is freq

2020-06-10 10:04:25 1839

原创 Quartz Task在Tomcat中重复运行问题解决

问题描述Spring Quartz是很常用的定时任务框架。把一个Quartz的工程部署到Tomcat中启动,意外地发现,每个Task都在同一时间跑了两次,而本地在开发的过程中却没有问题。问题排查为了防止多线程问题,有部分Task上是加了锁的,类似如下方式:@Componentpublic class ExampleTask{ private ReentrantLock lock = new ReentrantLock(); protected void executeInternal()

2020-06-09 16:12:15 325

原创 设计模式总结

经过了两个多月的时间,终于,将常见的设计模式结合例子过了一遍,在此做一个简单的小结。设计模式小结不难发现,应用各种设计模式所带来的好处,都会提到解耦二字。开闭原则要求我们的系统对扩展开放,对修改关闭。高内聚,低耦合的系统,有更高的稳定性与灵活性,也更易于维护。如何来解耦模块之间的关系呢?如果只用一句话来概括的话,那就是:将变与不变分离。细看下来,设计模式通常通过增加一个中间抽象层的方式,来封装会变的部分。创建型模式中,将对象的创建模块抽离出来,使客户端不需要关心对象如何创建;几乎所有的结构模式和行为模式

2020-06-06 17:04:34 129

原创 设计模式,行为模式之责任链模式

1 概述责任链模式(Chain of Responsibility Pattern)是常见的行为模式,它将处理器封装成一条处理链,让请求可以在链上传递。链上的处理器自行决定是否对请求进行处理。2 责任链模式一个典型的责任链模式的使用场景是,当一个事件或请求需要被多个处理器处理时。应用责任链模式,将所有的处理器串在一起,然后把请求从链的头部开始传送。各个处理器可以对请求进行判断,选择执行相关逻辑,或者将它传递给下一个处理器。如此一来,解耦了请求者和接收者(所有的处理器)。一般情况下,链上的处理器需要持

2020-06-06 16:01:09 168

原创 设计模式,行为模式之备忘录模式

1 概述备忘录模式(Memento Pattern),又叫Token模式,它提供了一种方式,来捕捉对象某一时刻的内部状态,并将其保存成备忘录(Memento),如此一来,对象可以根据此备忘录恢复到之前的状态。2 备忘录模式几乎所有的编辑器都支持撤销功能,这其实就是备忘录模式的例子,撤销操作,使得文本得以恢复到之前的状态。面向对象设计中,备忘录模式的实现一般需要三个角色:发起人(Originator):主对象,提供将内容保存成备忘录,或者从备忘录恢复状态的功能。备忘录(Memento):备忘录对象

2020-06-04 11:39:54 129

原创 设计模式,行为模式之命令模式

1 概述命令模式(Command Pattern),是将请求封装成一系列命令对象,以解耦请求发起者和请求接收者的一种行为模式。2 命令模式正常情况下,请求发送者和请求接收者是相互耦合的,发送者直接调用接收者相关的方法,直接交互。用命令模式进行改造,将两者交互的媒介----命令单独抽离出来,使得发送者和接收者相互独立,只依赖于命令对象,提高了扩展性和可维护性。同时,通过命令模式,我们还能完成一些高级操作,如撤销命令,方法参数化,命令入队,批量命令等等。3 案例通过一个简单的例子加深对命令模式的理解

2020-06-03 13:10:06 152

原创 设计模式,行为模式之访问者模式

1 概述访问者模式(Visitor Pattern)是一种行为模式,不常用。它可以将作用在对象上的算法逻辑,与对象本身分离开来。2 访问者模式当需要对一组相似类型的对象执行操作时,我们可以将操作逻辑分别维护在每个对象内部,但这违背了单一职责原则。访问者模式就是来应对这种情况的:将所有的算法逻辑移动到一个新的类----访问者(Visitor)中,统一维护,如果其中的逻辑发生了变化,那么我们只需要在访问者实现中进行更改,而不用影响到原对象。同时,在访问者模式中,扩展变得很容易,增加新的对象以及操作逻辑,

2020-05-31 13:56:07 169

原创 设计模式,行为模式之模板方法模式

1 概述模板方法模式(Template Method Pattern)是一种很常见的行为模式。在超类/抽象类中创建一个模板方法,方法中定义一个算法步骤或框架,让子类在不修改主结构的情况下,重写其中的子步骤。2 模板方法模式假如存在一系列对象的方法,他们的步骤是大体一致的,区别只是其中的一个子步骤。这种情况会导致大量重复冗余的代码,当公共部分需要改变时,不得不修改所有相关的对象。如果用模版方法模式改造,可以简化逻辑:将其中不变的部分抽离出来,作为一个模板方法,然后让子类只实现差异化的部分代码。比如,前

2020-05-31 08:17:59 223

原创 设计模式,行为模式之中介者模式

1 概述中介者模式(Mediator Pattern)是一种行为模式,通过定义一个中介对象,来管理一系列对象之间的依赖,从而解耦原有对象之间的关系。2 中介者模式大量的对象相互依赖,会大大增加系统复杂度,提高维护成本。中介者模式(Mediator Pattern)是迪米特原则的一个很好体现,它通过将对象的依赖关系维护在一个中介者中,使原本耦合在一起的对象变得相互独立。交通信号灯是一个很常见的例子,如果没有信号灯,十字路口的车子必须知道互相之间要去的方向,来决定什么时候踩油门,什么时候踩刹车,如此一来

2020-05-30 12:25:58 390

原创 设计模式,行为模式之状态模式

1 概述状态模式(state Pattern)是行为模式之一,一般用在对象的行为依赖于内部状态的场景。2 状态模式考虑一个场景:对象有状态,而且根据状态不同,对象的行为也会不同。对于该情况,最简单的方式是,对状态做if-else或者swith-case判断,根据状态调用相应的行为。但是这种做法,把对象和状态耦合在了一起,难于扩展和维护。更好的做法是,用状态模式将状态抽离出来形成一个接口,而目标对象依赖该状态接口,来完成对应的行为,由此达到解耦的目的。状态模式跟策略模式非常相像,可视为策略模式的扩展。

2020-05-28 17:12:47 160

原创 设计模式,行为模式之策略模式

1 概述策略模式(Strategy Pattern)是行为模式的一种,复杂度并不高,当完成某项任务的方式有多种时,可以考虑使用策略模式。2 策略模式在策略模式中,我们需要定义一族算法,并将算法放入独立的类中,每种算法代表完成任务的一种方法。如计算器,我们可以定义基本的加,减,乘,除四种策略,对于任意输入的两个数字,调用不同的策略,将得到不同的结果;又如网上购物结算,我们可以定义一系列支付策略,支付宝支付,微信支付,信用卡支付,储值卡支付…顾客可以根据自己的喜好选择相应的支付方式。策略模式解耦了算法的

2020-05-24 16:12:56 272

原创 设计模式,行为模式之观察者模式

layout: posttitle: 行为模式之观察者模式date: 2020-05-04categories:HandbookDesign Patternstags:JavaDesign Patterns1 概述观察者模式(observer Pattern),也叫发布-订阅模式,是一种很重要的行为模式,它被广泛运用在异步编程之中,可以说是异步编程的基础。2 观察者模式当我们需要关注某个对象的状态时,可以不断地轮询,查看状态是否变化,这也就是我们熟知的同步方式。然而这样的方式.

2020-05-10 15:52:08 191 2

原创 设计模式,行为模式之迭代器

1 概述迭代器模式(iterator Pattern)是最常见的设计模式之一,一般使用过Java集合的人,都接触过这种模式。2 迭代器模式集合(Collection)是编程中常用的一种类型,它们是存储元素的容器。集合有多种类型,如列表(List),集合(Set),栈(Stack),树(Tree)等等,对于使用者来说,需要有一种统一的方式来遍历集合中的元素。除此之外,使用者有时还需要不同的元素...

2020-05-04 12:27:11 88

原创 设计模式,结构模式之享元模式

1 概述享元模式(flyweight Pattern)是通过重用元素来降低内存开销的一种设计模式。2 享元模式所谓享元,意思是共享元素。当程序需要创建大量元素,或创建一些占用大量内存的元素时,对服务器的内存资源是很大的挑战。这时可以应用享元模式,将元素拆分成变量与不变量两部分。其中不变量,是所有的元素共通的部分,可以共享;变量,可以做为不同的元素的区分。比如要渲染一片森林,我们不需要为每一颗...

2020-04-25 14:22:40 144

原创 设计模式,结构模式之装饰模式

1 概述装饰模式(Decorator Pattern),意在不改变原有对象的情况下,改变/增强它的方法。2 装饰模式在不违反开闭原则的前提下,要改变某个对象的行为,可以使用继承。然而继承不适用于类/方法被final修饰的情况,而且一般需要了解类内部的情况,违反了迪米特法则。装饰模式体现了组合优先于继承的思想,通过组合的方式,“装饰”对象的功能,也能达到改变对象行为的目的。装饰模式的实现模式...

2020-04-19 11:15:35 139

原创 设计模式,结构模式之代理模式

1 概述代理模式(Proxy Pattern)是Javaer们最熟悉的设计模式之一,大名鼎鼎的AOP就是通过代理模式来实现的。2 代理模式现实中,如果要邀请某个明星参加活动,我们不是跟这个明星直接沟通,而是找他的经纪人。因为明星只需要负责表演就可以了,其他的事情由经纪人来安排。代理模式就是类似思想的体现:构造一个代理对象作为中间层,当我们需要调用某个功能时,不是直接调用功能本身,而是通过代理...

2020-04-16 22:58:29 126

原创 设计模式,结构模式之组合模式

1 概述组合模式(Composite Pattern),是指把一类有共同抽象的对象组合在一起,形成树状结构,来表示部分-整体的关系。2 组合模式我们经常会遇到一些对象有相同的行为,同时对象之间又有层级结构。像这种情况,使用组合模式可以使系统高内聚,低耦合。通过把类组合成树形结构,调用者能够以统一的方式对待单个对象和整体结构,忽略个体和整体之间的差异。实现组合模式一般需要:定义一个接口/抽...

2020-04-05 21:49:58 120

原创 设计模式,结构模式之适配器模式

1 概述适配器模式(adapter pattern),从名字就可以看出,工作模式类似于适配器:将原本不兼容的两样事物连接,以协同工作。2 适配器模式充电器(电源适配器)是日常生活中常见的例子。大多手机要求输入电压是5V,而家用交流电的电压都是220V,充电器作为适配器,将220V的电压转为目标电器需要的电压。适配器模式也类似,通过适配器,将类的接口转换为目标所期望的另一个接口。适配器模式是...

2020-04-04 14:53:59 149

原创 设计模式,结构模式之桥接模式

1 概述上一篇文章介绍了外观模式,接下来介绍桥接模式。桥接模式有时也被称为桥梁模式,也是一种常见结构模式,它主要体现了面向对象设计中的两个思想:面向接口编程。合成复用原则,即组合优先于继承。2 桥接模式桥接模式的目的是将抽象与实现分离,使二者能独立变化。说白了,其实就是:给对象定义接口,来充当桥梁的作用。调用者要依赖于目标对象的抽象(接口)而不是具体实现,更不是继承目标对象。...

2020-03-30 20:49:00 166

原创 设计模式,结构模式之外观模式

layout: posttitle: 结构模式之外观模式date: 2020-03-29categories:HandbookDesign Patternstags:JavaDesign Patterns1 概述外观模式,也叫门面模式,是一种常见结构模式,它是面向对象设计封装思想的体现。2 外观模式所谓外观,其实是一个额外的类,它包含了复杂多变的子系统,并只对外提供...

2020-03-29 14:32:43 219

原创 设计模式,创建型模式之单例模式

1 概述单例模式应该是最简单,同时又是最复杂的一种创建型模式。因为大家都知道这个模式:无非就是保证某个对象在系统中只存在一个实例。然而想要真正实现一个完美的单例模式,却不简单。2 单例模式一般单例模式的实现,都需要包含两个步骤:将类的构造函数私有化。提供一个public的方法,以供外界获取唯一的实例。下面将一一介绍单例模式的各种实现方式。3 案例3.1 注册表式提供一个注册表...

2020-03-28 22:19:47 93

原创 设计模式,创建型模式之原型模式

1 概述原型模式比较好理解,即以某个对象为原型,创建该对象的副本。我们可以不用知道对象内部的属性以及内部的状态,是迪米特法则的很好体现。2 原型模式原型模式一般用在较为复杂对象的创建,并且希望保留对象所持有的状态。Java对这种对象的创建方式也是提供了原生的支持——Object.clone()方法。public class Object { protected native Obj...

2020-03-26 21:17:19 133

原创 设计模式,创建型模式之建造者模式

1 概述前面我们说了工厂模式和抽象工厂模式,下面来说说建造者模式。建造者模式也是一种极为常见的创建型模式,前面提到的两类工厂模式隐藏了类的属性与构造细节,而建造者模式通过Builder类,适当地暴露了类的属性,使得类的创建更具有灵活性和可读性。2 建造者模式当一个类的构造函数包含很多参数,或者参数之间有很多种组合(如肯德基的套餐),调用构造函数来创建类将会变得不方便,可读性也很差。对于多种...

2020-03-22 14:09:00 125

原创 设计模式,创建型模式之抽象工厂模式

1 概述上一篇文章讲到了工厂方法模式,它提供了一种在不指定具体实现的情况下,创建类实例的解决方案。那为什么还需要抽象工厂模式呢?2 抽象工厂模式抽象工厂模式本质上,也是定义一个工厂,用来作为类创建的入口,拥有工厂方法模式的优点:如隐藏类的构造细节,降低类的使用复杂度,与调用者解耦等等。而它与工厂方法模式最大的区别在于,抽象工厂模式更强调创建一族的元素。比如对于不同的浏览器,有不同的按钮,选...

2020-03-21 13:25:45 105

原创 设计模式,创建型模式之工厂模式

1 概述创建型模式,提供了一种创建对象的最佳实践。工厂方法模式的核心思想,是通过统一的工厂类来获取对象,而不需要调用类的构造方法。2 优点可以将类的实例化过程延缓到子类。调用者无需知道接口/抽象类的具体实现是什么,利用工厂方法即可获取类的实例,降低与调用者的耦合度。隐藏类的构造细节,降低类创建的复杂度,提高程序可读性。可以根据不同环境/参数,从工厂构造不同的方法。3 案例有一个饭...

2020-03-20 22:31:40 90

空空如也

空空如也

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

TA关注的人

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