- 博客(164)
- 收藏
- 关注
原创 RabbitMQ详解
基于Raft一致性协议实现的一种新型的分布式消息队列,他实现了持久化,多备份的FIFO队列。Durability有两个选项,Durable和Transient,前者表示队列会将消息保存到硬盘,这样消息的安全性更高。务处理后自动进行应答,而如果消费者的业务逻辑抛出异常,RabbitMQ会将消息进行重试,这样是不会丢。会尽可能早的将消息内容保持到硬盘中,并且只有在用户请求的时候,才临时从硬盘加载到RAM内存中。这时,可以尽量多的申请机器,部署消费端应用,争取在最短的时间内消费掉积压的消息。
2025-05-19 00:33:32
731
原创 RabbitMQ概念详解
消息发送到RabbitMQ中后,会首先进入一个交换机,然后由交换机负责将数据转发到不同的队列中。RabbitMQ中有多种不同类型的交换机来支持不同的路由策略。也可以理解为是客户端与RabbitMQ实际进行数据交互的通道,我们后续的大多数的数据操作都是在信道 Channel 这个层面展开的。Exchange与Queue之间会建立一种绑定的关系,通过绑定关系,Exchange交换机里发送的消息就可以分发到不同的Queue上。从官网的封面就能看到,现在RabbitMQ主推的是Quorum队列。
2025-05-11 14:46:23
575
原创 JVM对象创建内存分配
大量的对象被分配在eden区,满了后触发minor gc;垃圾回收后,剩余少量存活的被挪到survivor区,下一次eden区满了后,再次触发minor gc, 把eden区和survivor区垃圾对象回收,把剩余存活的对象一次性挪到另一块空的survivor区。运行8秒,即可占满eden区,即每8秒有100M到老年代,触发Full Gc;修改:将年轻代调大翻倍,此时运行第16秒后,移动到survivor区,下次minor gc,少量的移动到老年代;假设分配为3G的,年轻代和老年代为1G和2G;
2025-05-10 16:55:57
354
原创 spring Ai---向量知识库(二)
可按页进行分割,使用嵌入模型将文本转为向量表示;存储到数据库中(redis、es);用户提出问题,生成问题对应的向量;调用api的向量检索,找到相关文档;RAG:检索增强,结合了检索和生成两种技术;用于提升生成模型的效果。在此类问题中,需要先处理的是进行文档PDF的存入向量中;通过垂直场景,通过实时更新知识库,无需重新训练模型;即可实现通过文档,输入垂直问题获得向量对应的答案。后续直接调用spring ai的接口。第一步:配置RAG Advisor。保存到本地磁盘中demo。
2025-04-21 00:23:08
154
原创 spring Ai---向量知识库(一)
在一些垂直领域以及公司内部信息相关或者实时性相关的大模型应用,就无法直接使用chatGPT。向量模型定义:将文档向量化,保证内容越相似的文本,在向量空间中距离越近;以上就实现了一个简单的自带存储PDF,然后进行向量接口搜索的demo。我们需要先将文档转为Document,存入向量库。通过坐标向量最接近的即为匹配相关答案。存储文档的可以用redis, es等;测试输入一段文本,被存储在里面的坐标。对于API调用层,都是如下的调用方法。这个时候,向量知识库就进入了。最后通过调用接口搜索。
2025-04-19 22:53:51
780
原创 springAi---智能客服
在需求分析阶段,把功能属于传统Java处理的和ai的功能进行分离。spring Ai 大模型应用相关开发demo,智能客服系统;首先被取代的是客服类,智能客服机器人都能够高效地完成任务。在ChatClient中,配置defaultTools。函数定义好后,交给spring ai由他们处理即可。业务代码等逻辑,通过CourseTool 实现即可。在大模型中,通过Function定义来实现。第二步:定义Tool,即Function。以上就完成了简单的智能客服。第三步,配置Tool。
2025-04-19 15:11:22
268
原创 SpringAi 会话记忆功能
即会话id,每次会话的时候,通过前端区分这个会话id。属于比较粗暴的方式,把之前的内容与新的提示词一起再次发给大模型。让我们看到他们有记忆功能。在使用chatGPT,豆包等产品后,就会发现他们的会话有“记忆”功能。下面介绍deepseek通过spring ai接入的时候实现记忆功能。以上是springAi中通过内存的实现方式实现如下接口。那么我们用API接口的话,这个是怎么实现的呢?二:配置会话记忆Advisor。上述方式即实现了会话记忆方案。一:定义会话存储方式。
2025-04-13 23:54:41
494
原创 springAi接入本地部署deepseek
上一篇本地简单的部署了deepseek后,通过spring推出的spring ai进行代码实现一个快速入门。2.2注入ollamaChatModel。2.3简单的通过rest接口进行输出文本。勾选一下web spring AI。构建一个新的spring ai项目。2.4通过流试方式输出文本。
2025-04-13 10:13:54
286
1
原创 本地部署大模型(ollama模式)
下载完成ollama后,进行运行deepseek模型。案例以deepseek-r1 为模型。在ollama会给出运行模型的命令。分享记录一下本地部署大模型步骤。至此,就可以本地模型进行聊天了。进入官网,下载ollama。
2025-04-12 23:15:15
328
原创 微服务API网关---APISIX
为客户端与服务系统之间的交互提供统一的接口,也是管理请求和响应的中心点,选择一个合适的API网关,可以有效地简化开发并提高系统的运维与管理效率。API网关作为一个系统访问的切面,对外提供统一的入口访问,隐藏系统架构实现的细节,让微服务使用更为友好;并集成了通用特性,鉴权,限流,熔断,避免每个微服务单独开发,提升效率,使系统更加标准化,单独注重业务。随着业务发展,API的数量也在剧增,使用网关对API统一管理也将面临挑战,选择一个更强大的API网关,可以有效的增强系统的监控、容灾、鉴权和限流等能力。
2024-02-28 15:19:46
1019
1
原创 ConcurrentHashMap源码解析(二)之------put()方法。
当sizeCtl < 0 ,大概率为-1,其他线程正在进行创建table的过程,当前线程没有竞争到初始化table的锁。p是红黑树,如果与你插入节点的key有冲突点的话,则putTreeVal()方法会返回冲突节点的引用。再次判断table为null,防止其他线程已经初始化完毕,然后当前线程再次初始化,导致数据丢失。强制设置binCount为2,因为binCount
2023-01-15 11:55:31
1050
原创 ConcurrentHashMap源码解析(一)之------基础属性
HashMap在单线程中非常好用,也不会出现什么问题。但是在多线程中,HashTable的效率太低。后面提供了ConcurrentHashMap解决多线程的问题,后续都以1.8的为对象进行研究。在1.8中,ConcurrentHashMap的设计与HashMap保持一致,使用了链表和红黑树的组合,当一个链表上的节点数超过8,且总个数超过64,就会触发转为红黑树。
2023-01-08 14:06:00
485
原创 线程池的设计与原理解析(五)之---getTask()方法
1.rs >= SHUTDOWN 成立: 当前的状态最低也是STOP状态,一定要返回 null了。4.线程池中的线程数超过 corePoolSize 时,会有一部分线程可能返回null。getTask()是工作线程在while死循环中获取任务队列中的任务对象的方法;2.前置条件 状态是 SHUTDOWN, workQueue.isEmpty()3.线程池中的线程数量,超过最大限制时,会有一部分线程返回null。1.表示当前线程获取任务是否超时;什么情况下getTask()返回null?
2022-12-17 14:40:47
941
1
原创 线程池的设计与原理解析(四)之---runWorker()方法
2.如果task为空,则通过getTask()再去取任务,并赋值给task,如果取到的Runnable不为空,则执行该任务;在调用start()方法,调用的就是worker的run方法,实际上调用的是runWorker()方法。4.如果getTask()取到的任务依然是空,那么整个runWorker()方法执行完毕;3.执行完毕后,通过while循环继续getTask()取任务。1.如果task不为空,则开始执行task方法。1.将初始执行task赋值给task。简单的梳理runWorker的流程。
2022-12-17 14:09:47
986
1
原创 spring bean生命周期四---Initialization阶段
使用场景:实现SmartInitializingSingleton的接口后,当所有单例 bean 都初始化完成以后, Spring的IOC容器会回调该接口的 afterSingletonsInstantiated()方法。主要是回调:SmartInitializingSingleton#afterSingletonsInstantiated。Spring Bean 初始化完成阶段。Spring Bean 初始化后阶段。属性填充后,就是初始化值。
2022-11-20 22:38:31
206
原创 spring bean生命周期三---PopulateBean阶段
postProcessAfterInstantiation()方法,可以决定是否进行属性填充,只要有一个返回了false,都会终止属性填充的过程。自动装配:autowiring自动装配,根据ByName或者ByType。提取依赖的bean,并统一存入到 propertyValues 中。filterPropertyDescriptorsForDependencyCheck()方法。@Autowired 和 @Resource 的注入工作主要是通过。实例化Bean之后,就是对Bean的属性进行注入的过程。
2022-11-20 22:00:10
259
原创 Spring之Bean生命周期之二--- Instantiation阶段
Spring Bean 实例化前阶段、Spring Bean 实例化阶段、Spring Bean 实例化后阶段等阶段。第二次调用后置处理器determineCandidateConstructors获取最优构造方法实例化对象。有参创建 :推断处理的 构造器方法不为null或者开启自动装配或者 使用指定入参的构造方法。第四次调用后置处理器getEarlyBeanReference解决循环依赖的问题。在BeanFactory中,主要的流程就是创建Bean的过程,实例化Bean在源码中。
2022-11-20 21:40:50
567
1
原创 FutureTask详解
FutureTask 表示一个异步运算的任务。FutureTask 里面可以传入一个 Callable 的具体实现类,可以对这个异步运算的任务的结果进行等待获取、判断是否已经完成、取消任务等操作。在学习多线程的时候,了解了FutureTask。FutureTask的构造函数。
2022-11-19 15:26:30
398
原创 Spring之Bean生命周期之一----BeanDefinition生成阶段
三个条件表达的意思是: mbd 中如果nonPublicAccessAllowed字段的值为true,表示class是非公开类型的,也可以创建实列。在Spring源码中,从AbstractAutowireCapableBeanFactory类的 createBean()方法开始。在doCreateBean()方法中,有一个createBeanInstantce方法,该方法即为将bean实例化;在该方法中,具体创建Bean的是doCreateBean()方法。条件3: 说明配置了 构造参数信息。
2022-11-13 21:41:49
539
原创 Order By 多条件排序【MySQL】
mysql 多字段排序,原来是需要逗号隔开,进行描写条件。之前都以为是作为一个,直接逗号一起就行;根据两个条件进行排序查询,开始以为很简单的写了SQL。以为结束了,仔细才发现,后续的没有根据id 进行排序。碰到一个SQL的排序问题,先排序后分页。最终将SQL修改为如下: 完成了该功能。开始就很简单的写了根据多条件的排序。记录一下这个小知识点。
2022-10-29 12:53:36
2160
原创 使用RabbitMQ常见问题
基于MQ的事件驱动机制,给庞大的互联网应用带来了不一样的方向。MQ的异步、解耦、削峰三大功能特点在很多业务场景下都能带来极大的性能提升,在日常工作过程中,应该尝试总结这些设计的思想。
2022-10-23 23:51:02
1179
原创 RabbitMQ入门
MQ:MessageQueue,消息队列;MQ的作用主要有以下三个方面:异步: 能提供系统的响应速度,吞吐量。解耦:服务之间进行解耦,才可以减少服务之间的影响。削峰:以稳定的系统资源应对突发的流量冲击。常用的MQ有:RabbitMQ,RocketMQ,Kafka等;接下来主要学习RabbitMQ;
2022-10-23 14:20:52
774
原创 Nacos源码学习(一)
onPut(key, value):其中的value就算Instances,要更新的服务信息。基于线程池的方式,异步的将service信息写入注册表中。key:是nameSpace的id,起到隔离环境的作用。Nacos提供了服务注册的API接口,客户端只需要向该接口发送请求,即可实现服务注册。2)然后将更新后的数据封装到Instances对象中,后面更新到注册表使用。3)调用put方法完成Nacos集群的数据同步,保证集群一致性。该方法对修改服务列表的动作加了sync,确保线程安全。
2022-09-04 22:00:37
848
原创 微服务组件Feign
是Netflix开发的声明试、模板化的HTTP客户端,更加便捷、优雅的调用HTTP的API;内部集成了Ribbon,与之不同的是,feign只需要定义服务绑定接口且声明的方法,实现服务的调用。通过 Options 可以配置连接超时时间和读取超时时间,Options 的第一个参数是连接的超时时间(ms), 默认值是 2s;spring Cloud 在Feign的基础上实现了OpenFeign支持了Spring mvc的注解。Feign的底层用的是Ribbon,但超时时间以Feign配置为准。
2022-09-03 18:45:42
311
原创 Idea同时切换多个项目的分支
再开发过程中,切换分支的时候,就希望每个项目也能跟随一起切换,同时提交代码的时候能够一起push。然后通过右侧的添加按钮,把我们需要一起切换分支的项目引入,并选择Git。再项目开发中,我们可能会把多个依赖性比较高的项目通过idea同步打开。1.通过Setting 搜索 到 version control。再Version control中的Git 栏下。当我们引入完多个项目之后,需要进行如下设置。进行勾选此按钮即可。...
2022-08-29 10:06:41
3049
原创 ElasticSearch基础入门
在Elastic Stack生态圈中Elasticsearch作为数据存储和搜索,是生态圈的基石,Kibana在0上层提供用户一个可视化及操作的界面,Logstash和Beat可以对数据进行收集。一个索引由一个名字来标识(必须全部是小写字母的),并且当我们要对应于这个索引中的文档进行索引、索引、更新和删除的时候,都要使用到这个名字。比如: 可以有一个客户数据的索引,另一个产品目录的索引,还有一个订单数据的索引。是一个分布式,Restful风格的搜索和数据分析引擎,是用Java开发,稳定,可靠,快速。...
2022-08-27 19:52:37
470
原创 @Async注解的使用方法
第二个问题:在spring boot中,如果没有自定义线程池实例,那么Spring boot会使用默认的线程池,这个默认线程池是SimpleAsyncTaskExecutor,这种线程池是会为每个任务创建一个线程去执行,可能会引起资源问题。第一个问题: 注解里面的线程池是无界队列LinkedBlockingQueue,这导致最大线程数的配置是无效的,且如果异步线程很多执行时间很长,会导致任务一直堆在队列中,任务延迟很大。2.开启后,如果两个方法再同一个类里面,也是不会执行的。...
2022-08-06 13:09:31
4615
原创 ReentrantLock学习之---释放锁过程
当s==null表示当前节点是tail节点,>0说明当前节点的后继节点是取消状态,说明后继节点是取消状态,需要进行的操作是唤醒一个合适的节点。也可以理解为,释放锁操作在tryRelease()方法中处理,处理完成后,如果不是最后一个节点还会继续唤醒后一个节点的操作。回到release()中,当前的head节点已经被初始化,且后继节点有值,才会进行唤醒后一个节点的操作。在release()方法中,获取成功进入释放锁时,需要的操作是唤醒后继节点的操作.先看tryRelease()方法。...
2022-07-24 17:20:05
726
原创 ReentrantLock学习之---基础方法
针对tryAcquire,接下来看下里面的逻辑。本次主要是进入的公平锁的该方法的实现。该方法主要是将线程放入到队列中,再队列中是进行双向绑定,也及为双向链表的结构队列。这里就需要用到上篇博客中的state,获取当前线程的状态进而处理;使用双向链表新加入队列和删除锁的时候双向链表再时间和空间上更节约。另一个逻辑.即为重入锁逻辑,进行更新state的值,每次+1.用了自旋入队的方式,只有当前封装的node成功了才会跳出循环。很明显,加入队列的具体逻辑在enq()方法中。整个线程第一个入队的有一个逻辑....
2022-07-23 21:53:56
375
原创 ReentrantLock学习之---基本属性
通过简易的模仿公平锁后,对ReentrantLock的源码进行了学习。waitStatus主要是通过状态判断节点。先对节点Node的属性进行了解。
2022-07-17 11:50:58
147
原创 ReentrantLock学习之公平锁过程
ReentrantLock支持公平锁和非公平锁,默认使用非公平锁。Node封装节点,里面包含有前置节点和引用节点和线程信息。在源码中,加公平锁的时候,主要是进行该段代码逻辑获取加锁。在ReentrantLock实现类里面,有几个变量。在公平锁加锁的过程中,还有一段逻辑是获取锁的过程。模拟ReentrantLock的加锁过程。通过源码可以发现公平锁的加锁方法。自定义一个Lock进行实现。主要记录公平锁里面的实现。...
2022-07-16 20:05:10
550
原创 Synchronized理论
Synchronized是Java中解决并发问题的一种最常用的方法,也是最简单的一种方法。偏向锁:撤销偏向锁为什么需要在安全点执行?线程获取锁的第一步就是向线程栈的锁记录空间中push一条锁记录信息。并且每次重入,都会插入一条心的锁记录,用于表示重入次数。锁记录空间原则上只允许本线程操作,所以一定是线程安全的。当偏向锁线程依然持有偏向锁时,说明偏向锁线程锁记录空间中一定存在该lock的LockRecord记录。偏向锁撤销,就需要将偏向锁升级为“轻量级锁”。轻量级锁:场景:A和B两个线程,运行过程中获取
2022-07-12 10:24:25
333
原创 Netty学习之---Selector
在入门学习netty的时候,我们就写过一个简单client连接service的代码;1:client代码 public static void main(String[] args) throws Exception{ SocketChannel sc = SocketChannel.open(); sc.connect(new InetSocketAddress("localhost",8080)); System.out.println("waitin
2022-05-29 13:15:23
472
原创 Netty之三----java NIO基础
Netty 是基于Java NIO 封装的网络通讯框架,只有充分理解了 Java NIO 才能理解好Netty的底层设计。Java NIO 由三个核心组件组件:BufferChannelSelector一.Channel是一个通道,它就像自来水管一样,网络数据通过 Channel 这根水管读取和写入。传统的 IO 是基于流进行操作的.常见的channel实现类有:1.FileChannel: 读写文本数据 public static void main(String[] args) t
2022-05-14 15:38:39
185
原创 学习Netty之---Hello Netty
Not faster than NIO (epoll) on unix systems (which is true)There is no daragram suppportUnnecessary threading model (too much abstraction without usage)以上就是Netty目前还是使用NIO的方式的原因;BootStrap: 是Netty框架的启动类和主入口类,分为客户端BootStrap和服务器类ServerBootStrap两种。Channel:
2022-05-04 17:33:37
741
原创 深入理解网络通信
今天温习了下之前的网络通信,以及TCP/IP相关的知识。计算机网络的标准定义利用通信线路将地理上分散的、具有独立功能的计算机系统和通信设备按不同的形式连接起来,以功能完善的网络软件及协议实现资源共享和信息传递的系统。OSI七层模型物理层: 网线物理层数据链路层:提供介质访问和链路管理网络层:IP及路由选址传输层:建立和管理端到端的连接会话层:建立会话表示层:数据格式转换、数据加密应用层:为应用程序提供服务TCP/IP 五层模型TCP:一种可靠的数据传输,面向连接。UDP:不可靠
2022-04-27 09:35:27
1507
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人