自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

苏雨丶

个人 博客

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

原创 【源码系列】MyBatis原理源码

Mybatis的核心是Jdk的动态代理和各个组件,整个运行可以分为两大步骤:1. 准备阶段1. 解析配置文件获取全局Configuration对象,该过程中为每个Mapper接口创建MapperProxyFactory对象,2. 有了Configuration对象以后通过构建者模式构建SqlSessionFactory3. 通过SqlSessionFactory创建SqlSession对象,SqlSession包含了Executor(Sql的执行器),如果有插件,Executor会织入插件逻辑(通

2022-03-24 17:34:24 4583 6

原创 项目中使用缓存报Redisson is shutdown排查

上周运维将项目的测试环境从k8s中迁出来后,测试发现储能网关一直在上报数据,但是并没有映射到对应的设备上,排查时发现MQ在正常消费,并没有消息挤压,而且日志也没有报错信息,当时就很纳闷,觉得不可思议,通过过滤日志,发现消费了网关的上报的消息,并没有将消息发到设备对应的Topic中,于是启动本地代码连测试环境,发现我本地并不报错,又只能去测试服务区排查,后面通过arthas拦截处理消息的方法,才看到异常信息,发现是,有了异常信息我们就好排查啦。

2023-03-27 16:25:44 7184

原创 【源码系列】MyBatis与Spring整合原理源码

本文是对之前的MyBatis原理源码一文的补充,工作中都是Mybatis不会单独使用而是整合Spring一起使用,整合以后我们都感觉不到和SqlSession的存在,需要用到哪个Mapper时,直接使用@Autowired注入就行,而且SqlSession默认的实现是线程不安全的,别问我怎么知道的,的类注释告诉我的到这里大家肯定有几个问题想问Spring是如何解决SqlSession的线程安全问题?Mapper接口是怎么注入到Spring容器的?.........

2022-08-17 20:20:33 758 2

原创 【源码系列】Spring事务执行原理源码

其实事务的源码还是比较好理解的,首先要知道它是基于AOP来实现的,明白事务传播特性,搞清楚各个特性的作用,执行流程主要分为三大步事务准备:通过TransactionManager(事务管理器)、TransactionAttribute(事务注解属性的包装)、TransactionStatus(包含了连接对象、被挂起的事务等)来实例化TransacationInfo对象,事务执行:事务代码执行,成功提交(如果当前事务不是一个全新的事务那么会做空提交,需要第一个创建事务的才提交)、失败回滚(如果当前事务有

2022-08-15 15:14:23 1209 1

原创 记录MySQL数据迁移时使用的存储过程、游标以及存储过程中文乱码异常解决

记录MySQL数据迁移时使用的存储过程、游标以及存储过程中文乱码异常解决。

2022-07-26 10:01:29 291

原创 RocketMQ 事务消息源码分析 (RocketMQ系列八)

之前已经讲过了普通消息的发送流程,事务消息只是在普通消息的基础上做了一些操作,消息在Producer端发送以后(这里叫半消息),Broker收到消息以后,会判断是否是事务消息,如果是事务消息会替换掉消息的Topic为事务的消息主题,将原本的消息主题和队列信息封装到消息中,等客户端执行完本地事务代码后,告诉Broker半消息是提交还是回滚。提交就是将事务半消息移到目标Topic的队列中,然后客户端就能消费到该消息。回滚的话就是将消息移到系统的另一个操作队列中,标记消息为删除,Consumer永远也消费不到该消

2022-07-11 15:43:53 577

原创 记录一下工作中遇到的生产bug以及整个解决过程

今天测试过来问assert服务是不是崩了,所有设计到该服务的接口前端请求都直接超时了,在服务器上通过观察日志发现服务在批量更新站点公式后,才不正常的,一开始以为是更新公式比较耗资源,导致服务器的负载和cpu过高,导致的系统卡死。呆着这样的猜测去验证自己的猜想。于是使用命令来观察服务内存和cpu的占用情况,发现负载和cpu都是正常于是通过命令查看服务的堆栈信息,查看几乎所有线程都处于WAITING状态为了方便观察,于是对其中一个节点进行堆转储,将文件到导到本地的jvisualvm上查看,通过观察线程的

2022-06-14 19:49:14 281

原创 Nacos配置中心配置变更,自己编码实现自动刷新的功能

Nacos本身已经支持了@NacosValue的属性刷新功能,必须要在配置文件中打开自动刷新,还必须设置@NacosValue的属性autoRefreshed = true 默认为false,但是我们项目中使用的最多的是@Value来做占位符操作,Nacos并没有支持@Value的属性工作,工作上有个需求,需求内容如下配置中心内容变更,@Value修饰的属性也需要支持刷新值操作。如果有只需要解决问题,不需要知道原理的同学,可以直接把该项目拿过去用,项目中也包含了测试代码,有用的话麻烦Stat一下,该项目我

2022-06-09 18:39:55 5430 4

原创 【源码系列】Nacos客户端服务发现原理源码

文章目录客户端服务发现原理源码客户端服务发现服务订阅并获取服务本地内存获取服务端服务订阅处理客户端故障转移客户端服务发现原理源码客户端服务发现上一篇Nacos服务注册原理源码文章中,在Nacos提供的注册中心测试单元中代码,我们只讲到了服务的注册,注册完后,服务获取方法没有往下展开分析,今天我们主要就是讲解这个方法。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mn0ipN0z-1649754204345)( https://java-imgs.oss-cn-hon

2022-04-12 17:09:38 456 1

原创 【源码系列】Nacos服务注册原理源码

Nacos服务注册原理源码客户端服务注册测试单元Nacos自动装配服务注册服务端服务注册集群同步Nacos服务注册原理源码客户端服务注册测试单元我们先看一下Nacos客户端给出的服务注册的测试单元代码测试单元中主要做的事情:构建服务Instance对象通过工厂创建NamingService对象Instance向NamingService(注册中心)注册通过serviceName向注册中心(NamingService)获取实例列表信息测试单元中我们知道客户端根据服务的ip、

2022-04-06 20:11:36 759

原创 【源码系列】SpringBoot启动过程原理源码

文章目录SpringBoot启动过程原理源码1.Spring的SPI2.SpringApplication实例化3.run方法执行流程1. 获取事件发布器2. 创建环境对象3. 创建上下文对象4.上下文刷新前5.上下文刷新自动装配具体实现Tomcat启动6.上下文刷新后7. 应用生命周期函数SpringBoot启动过程原理源码1.Spring的SPI文章中会多次提到SPI这个东西,我们简单的介绍一下,SPI全称为Service Provider Interface 这个东西你可以理解为 它就是一个

2022-03-31 17:08:09 1405

原创 Java获得两个日期之间的所有年、月份、日

/** * 获取两个时间段的时间段值 * @param startTime 开始时间 * @param endTime 结束时间 * @param typeEnum 时间类型枚举 * @return */ protected static List<String> getTimePeriodFromTwoTime(Long startTime, Long endTime, TimeTypeEnum typeEnum) { .

2022-03-21 19:20:45 2812 5

原创 RocketMQ pull方式消费消息,无需手动维护offset、集群负载

前言平常我们在使用RocketMQ消息队列消费时,基本使用的都是push模式,有些时候我们也需要通过pull方式来实现我们的功能。我们都知道RocketMQ的push模式底层就是使用的pull模式来实现的,所以我们其实可以自己来实现一些push的功能。别的不说,比较忙。直接上代码。亮点1.实现了push模式的offset、如果不实现这个功能,我们需要自己手动去维护这个offset、我想要一个一劳永逸的办法,不想自己去维护,我们知道push模式就是RocketMQ自己帮我们维护了,我通过源码,调用了pu

2021-04-20 19:11:44 1429

原创 Spring中FactoryBean原理解析

FactoryBean创建流程1.判断当前bean是否是FactoryBean,如果是进入FactoryBean的创建流程,不是走普通的Bean创建流程2.给BeanName加上&修饰前缀开始getBean3.在doGetBean时,移除&前缀,去容器缓存中获取,第一次创建基本不没有,没有就将该Bean添加到已经创建的缓存中,要走开始创建流程4.FactoryBean到了创建时(CreateBean)和普通Bean创建流程就一样了5.FactroyBean实例化成功后走getObj

2021-03-18 10:52:24 602

原创 go语言小白入门资料整理

Go语言介绍Go语言是Google内部公司大佬开发的,主要起因于Google公司有大量的C程序项目,但是开发起来效率太低,维护成本高,于是就开发了Go语言来提高效率,而且性能只是差一点。(Go是2007年开始研发,2009推出发布)Go语言目前的主要应用场景Go非常适用需要高性能高并发的网络编程,这里的网络编程是指不需要界面,底层只是用Socket相互传输数据的系统,类似于Java中Netty的用途。一些云计算容器,比如Docker,K8s,底层就是Go语言开发的,也可以用做底层自研运维项目的开发

2021-02-07 16:00:59 393

原创 GoLang基本数据类型之间的相互转换

数据类型之间的转换//demo06fmt.Println("<--------int转浮点---------------->")n1 := 100f2 :=float32(n1)fmt.Println("int类型的100转为float32,结果:",f2)fmt.Println("<--------浮点转int---------------->")f3 := 3.14var n2 = int(f3)fmt.Println("3.14转为int,结果:",

2021-02-06 19:35:42 464

原创 RocketMQ Consumer的Push模式启动过程 (RocketMQ系列七)

Consumer启动流程前言上一篇讲了RocketMQ在消息发送的流程,这一篇开始讲Consumer的启动流程,看下Consumer在启动的过程中做了哪些事情。Consumer端消费代码下面是consumer并发消费时的代码,主要分为了Consumer的初始化,以及注册消息并发消费的监听器,最后就是启动consumerDefaultMQPushConsumer consumer = new DefaultMQPushConsumer(CONSUMER_GROUP);consumer.setN

2021-01-31 18:55:30 801

原创 RocketMQ消息发送流程 (RocketMQ系列六)

前言上一篇我们讲了Broker的启动流程,我们对Broker在启动阶段做的一些事情有了充分的了解,这一篇我们开始讲Producer的初始化和启动过程以及消息发送过程以及Broker接受到消息请求的处理过程。Producer端发送流程下面是producer发送一条简单消息的代码,我们一句句来分析,看下具体做了哪些事情//初始化发送消息的线程池DefaultMQProducer producer = new DefaultMQProducer("test-group"); //1producer.s

2021-01-24 16:57:36 645

原创 Java服务,CPU100%问题如何快速定位?

JVM线上问题排查前言项目运行中,难免会遇到一些问题,有时候cpu占用特别高,有时候内存特别高,出现这样的问题,我们该如何怎么解决,现在我们就从下面示例代码来演示,如何定位到是哪个线程造成的,造成的原因是啥。示例代码public class Deadlock { public static void main(String[] args) throws InterruptedException { Object o = new Object(); new

2021-01-18 10:16:28 300 1

原创 RocketMQ Broker启动流程(RocketMQ系列五)

Broker启动流程前言今天我们讲Broker的启动流程,讲完这篇以后,大家对Broker启动做的事情有一个清晰的认识,这个源码是我自己一点一点啃得,有点硬,后面再整理代码注释的时候,参考了一些博客,我尽可能的说的清楚一些,我表达和总结能力比较弱,有些地方说的可能不清楚,大家可以给我留言,我看到了都会回复的。源码Idea启动Broker找到Broker的启动类,BrokerStartup,然后编辑main方法,修改启动参数,如下图所示环境目录会在下图所示的包中具体配置:ROCKETMQ_

2021-01-16 20:42:51 1796

原创 线程创建的五种方法

创建线程的方法继承Thread类public class MyThread extends Thread { @Override public void run() { System.out.println("MyThread"); } public static void main(String[] args) { new MyThread().start(); }}实现Runable接口public cla

2021-01-15 13:29:39 202

原创 RocketMQ消费者的负载均衡策略详解(RocketMQ系列四)

RocketMQ消费负载策略Consumer在拉取消息之前需要对TopicMessage进行负载操作,负载操作由一个定时器来完成单位,定时间隔默认20s简单来说就是将Topic下的MessageQueue分配给这些Consumer,至于怎么分,就是通过这些负载策略定义的算法规则来划分。AllocateMessageQueueAveragely平均负载策略,RocketMQ默认使用的就是这种方式,如果某个Consumer集群,订阅了某个Topic,Topic下面的这些MessageQueue会被平均分

2021-01-08 18:33:52 8503 4

原创 RocketMQ整合SpringBoot(RocketMQ系列三)

前言上一篇我们讲了消息的发送和消息消费的一些知识,本篇我们开始讲RocketMQ整合SpringBoot。RocketMQ整合SpringBoot我会讲两种整合SpringBoot的方式,一种使用SpringBoot的starter来整合,另外一种我们自己整合,相对来说,Starter整合方式更加单,不过技多不压身嘛,两种都学习一下。Starter方式整合pom.xml文件<!-- web --><dependency> <groupId>org.spr

2021-01-05 14:00:38 361

原创 RocketMQ消息发送和消费相关知识(RocketMQ系列二)

前言上一篇讲了RocketMQ的安装和简单测试了系统自带的测试,本篇将开始讲RocketMQ的api使用、消息发送方式、消费模式,消息的类型。消息//消息Topicprivate String topic;//消息标记 0表示非事务消息private int flag;//一些额外属性,消息tag,key等private Map<String, String> properties;//消息体private byte[] body;//事务消息传递到消息idprivate

2021-01-01 20:05:30 672

原创 RocketMQ的安装、角色介绍(RocketMQ系列一)

前言最近一直在学RocketMQ的东西,为了加深对它的印象,决定写一个关于RocketMQ的主题博客,博客会涉及RocketMQ从安装、到使用、集群、以及各种原理源码。笔者水平有限,说的不对的地方,还希望各位老哥能够指出来,毕竟误人子弟不是我的初衷,我也是希望对读者们有一些帮助。简介RocketMQ是一个分布式消息中间件,最初是由阿里团队开发的,经过一系列的迭代升级,经历了淘宝双十一的大流量考验,很多小伙伴可能比较好奇市面上已经有了很多成熟的消息中间件、ActiveMQ、Kafka、RabbitMQ等

2020-12-30 16:22:19 240

原创 Linux服务器RocketMQ和可视化界面外网安装

下载RocketMQ的安装包我们这里安装的版本是4.7.1,我们下载安装包就行,源码包需要编译,编译完还是得到安装包点击下面链接下载https://rocketmq.apache.org/release_notes/release-notes-4.7.1/

2020-10-30 11:25:55 700

原创 Java项目本地访问resource目录文件运行正常,打包成jar后提示没有那个文件目录

本地获取方法代码入下://这种方式得到的路径,打包成jar后会访问不到这个路径this.getClass().getClassLoader().getResource(FONT_PATH).getPath()/usr/local/api/fxq-contract-0.0.1.jar!/BOOT-INF/classes!/fonts/SIMSUN.TTF (没有那个文件或目录) //正常的获取方法,只能获取文件流 然后再做操作 InputStream inputStream =this.get

2020-08-05 11:17:59 1027

原创 ELK日志分析系统搭建以及springboot日志发送到ELK中

前言安装之前服务器必须装了Java环境,我们这里安装的是7.7.0版本,而且7.7.0版本还必须要求jdk11以上。安装elasticsearch#下载elasticsearch安装包wget https://mirrors.huaweicloud.com/elasticsearch/7.7.0/elasticsearch-7.7.0-linux-x86_64.tar.gz#解压tar -xvf elasticsearch-7.7.0-linux-x86_64.tar.gz 为elastic

2020-08-01 16:38:53 1002

原创 Redis主从 + 哨兵 高可用搭建

Redis主从+哨兵集群搭建前言先准备一台或多台Linux服务器,当然也可以只用一台来搭建一个伪集群,其实会在一台上搭建集群,多台服务器搭建是一样的安装Redis首先在服务器上建一个文件夹,我这里直接建在根目录,名字叫softmkdir soft 官网下载reids的源码文件包,我们通过wget来下载,如果没安装weget的先安装这个#我们搭建时使用的是5.0.5版本的cd soft#安装wgetyum install wget#下载源码包wget http://downl

2020-07-22 11:14:04 258

原创 JVM调优常用参数

最重要的一个参数-XX:+PrintFlagsFinal 可以列出所有的调优参数# 假如我们要查G1相关参数只需要执行下面这个命令java -XX:+PrintFlagsFinal | grep G1通用参数-Xmn:设置年轻代大小(eg:-Xmn2G)-Xms:最小堆大小(eg: -Xms4G)-Xmx:最大堆大小(最大堆和最小堆建议设置一样)-Xss:栈大小(eg:-Xss1024K)-XX:+UseTLAB:设置开启线程本地分配,默认是开启的 不建议动-XX:+Pri

2020-07-16 17:27:14 240

原创 MySql行转列 以及列转行

行转列sql脚本CREATE TABLE `score` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(40) COLLATE utf8mb4_bin DEFAULT NULL, `subject` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL, `score` int(255) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=Inno

2020-07-14 16:39:06 435

原创 JVM面试题附带答案

1.JVM运行时结构,各个区存放的数据按线程可见性来分可以分为下面这两类线程共享堆区:堆用来存放数组和对象,内部又分为了新生代和老年代,他们的比例默认为1:2,新生代又分为了一个Eden和两个Survivor,默认比例为8:1:1方法区:用来存放类的方法、属性、字符串常量池、静态变量等。在1.7的时侯,字符串常量和静态变量都放在永久代,在1.8的时候移除了永久代,永久代在启动之前必须制定初始大小,FGC还不会对它进行垃圾回收,新加入了元空间(MetaSpace),将原本存放在永久代的数据全部移

2020-07-09 21:32:20 4698

原创 JVM运行时数据区、类加载机制、双亲委派

JVM运行时数据区、类加载机制、双亲委派前言我们先讲一下Java运行时的数据区,类加载机制,双亲委派,然后再开始讲各个垃圾回收器,每个回收器使用的垃圾回收算法,回收的过程,以及JVM的性能调优Java运行时数据区为了方便大家理解JVM的结构,我画了这个图,方便大家理解JVM运行时的数据区线程共享堆区堆区又分为了老年代和新生代,新生代和老年代的内存空间默认比例为1:2,新生代又分为了一个Eden和两个Survivor区(这两个幸存区有些地方叫From和To,还有的资料叫S0和S1)Eden

2020-07-08 22:07:57 149

原创 垃圾回收基础理论

垃圾没有任何引用指向的对象都是垃圾找垃圾的方法引用计数法:一个对象创建时会分配一个计数器,有引用指向这个对象时,计数器+1,当引用失效,计数器-1,当计数器为0时,就可以判断为一个垃圾对象(这种方法解决不了循环引用的问题)根可达算法:以GC Roots为根展开引用链路搜索,如果一个对象没有任何链路跟GC Roots关联,那么就可以判断为一个垃圾对象GC Roots的对象:线程栈变量,静态变量,常量池,JNI指针(本地方法对象)垃圾清除的算法标记清除算法:优点:标记处垃圾对象后清

2020-07-03 09:47:42 281

原创 i++和 ++i的区别

前言我们平常工作中对某个数进行累加的时候,一般都是用i++,但是我看HashMap和其他一些jdk里面的代码,用到自增基本上用的都是++i,这两个有啥区别呢?我们都知道一个是i++先赋值再自增, 另一个是先自增再赋值。我们只知其然,不知其所以然。今天我尝试给大家解释一下,希望我能表达清楚吧。测试代码首先列出我们的测试代码,你可以想一下这个i会打印几。i++ public static void main(String[] args) { int i = 8;

2020-07-02 18:42:48 1405 3

原创 Spring的扩展点后置处理器,Spring bean的生命周期

这个是腾讯课堂鲁班学院讲解Spring源码老师做的笔记后置处理器Bean工厂的初始化过程Bean的生命周期

2020-06-16 16:13:01 285

原创 加强对Aop的理解,自己实现一个简单版的Aop

手写AOP实现思路我们先看下我们平常是如何使用spring的Aop,下面代码是一个比较简单的aop的前置通知的使用。@Component@Aspectpublic class BeforeAspect { @Before("execution(public * com.test.controller..*.*(..))") public void before(JoinPoint joinPoint) { }}首先我们看类注解,@Component、@Aspect

2020-06-08 18:59:16 460

原创 spring结合数据库实现策略模式 彻底干掉if

前言我们公司是做电子合同系统的,电子合同里面最重要的就是CA证书,其中颁发机构有浙江CA,湖北CA、天威诚信 、 沃通CA、CFCA 不同的行业客户对证书的要求都不一样,普通的客户一般用天威诚信或者湖北CA就好,有一些金融客户,可能会要求必须使用某个CA机构的比如必须要求沃通,为了满足这个需求,想到了设计模式中的策略模式,不同的客户在调用的时候使用不同的策略就行了。策略模式策略模式是将多个类似的业务公共的部分抽离出来成一个接口类,然后具体的业务由各自的策略类去实现这个接口,在使用的时候由一个上下文

2020-06-04 15:31:25 431

原创 Java对象深拷贝和浅拷贝

前言拷贝功能,在电脑上我们经常用到,也许换个名字更容易理解,那就是复制功能。我们平常复制以后就是两个独立的文件,修改其中一个文件的内容并不会影响另一个文件的内容。我们平常在写代码的时候,也经常会有这样的场景,把一个对象完完全全的复制一份出来,那么我们Java里面的对象拷贝是啥样的呢?拷贝方式浅拷贝我们先不说什么事浅拷贝,我们先举个栗子????1: 同类型对象直接将值赋给另一个对象 Son son = new Son() .setName("小明");

2020-06-03 15:04:32 249

原创 Pdf文件定位关键词坐标

Pdf定位关键词坐标之前就做过关键词获取坐标的demo,但是有时候会发现有些关键字,文档上面明明存在的,但是通过demo中的代码来获取,就是获取不大,后面查资料,发现大家都有这个情况,后面在一篇博客中看到个比较好的解决方案,因为itext 5.x 获取文本的代码textRenderInfo.getText();这个只能获取到单个字符的坐标,比如,甲方,如果你去匹配甲这个关键词,是能定位到坐标的,但是如果你同时去获取甲方这个关键词就会获取不到,后面在这个博客上面看到既然能获取到单个字,于是我有了下面

2020-06-01 16:26:42 3905 1

itext-pdf-replace.zip

pdf使用itext实现关键字替换 使用 # 等关键字 替换成任意的字符,单个替换 批量替换

2020-04-09

空空如也

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

TA关注的人

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