服务性能优化总结

简介: 服务性能优化总结

一、数据库连接池耗时优化


1.1 问题排查


在链路工具上查看偶尔会有性能抖动,排查后发现是dbcp耗时过长

网络异常,图片无法展示
|


1.1.1 线上dbcp配置情况


线上dbcp数据库连接池配置,如下:


<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">

<property name="driverClassName" value="${db.jdbc.driverClassName}"/>

<property name="url" value="${db.jdbc.url}"/>

<property name="username" value="${db.jdbc.username}"/>

<property name="password" value="${db.jdbc.password}"/>

<property name="maxActive" value="20"/>

<property name="maxIdle" value="3"/>

<property name="maxWait" value="15000"/>

<property name="timeBetweenEvictionRunsMillis" value="60000"/>

<property name="minEvictableIdleTimeMillis" value="180000"/>

</bean>


当前使用的版本是dbcp 1.4 版本


<dependency>

<groupId>commons-dbcp</groupId>

<artifactId>commons-dbcp</artifactId>

<version>1.4</version>

</dependency>


1.1.2 dbcp配置项含义

参数

默认值

说明

username

\

传递给JDBC驱动的用于建立连接的用户名

password

\

传递给JDBC驱动的用于建立连接的密码

url

\

传递给JDBC驱动的用于建立连接的URL

driverClassName

\

使用的JDBC驱动的完整有效的Java 类名

initialSize

0

初始化连接:连接池启动时创建的初始化连接数量,1.2版本后支持

maxActive

8

最大活动连接:连接池在同一时间能够分配的最大活动连接的数量, 如果设置为非正数则表示不限制

maxIdle

8

最大空闲连接:连接池中容许保持空闲状态的最大连接数量,超过的空闲连接将被释放,如果设置为负数表示不限制

minIdle

0

最小空闲连接:连接池中容许保持空闲状态的最小连接数量,低于这个数量将创建新的连接,如果设置为0则不创建

maxWait

无限

最大等待时间:当没有可用连接时,连接池等待连接被归还的最大时间(以毫秒计数)超过时间则抛出异常,如果设置为-1表示无限等待

testOnReturn

false

是否在归还到池中前进行检验

testWhileIdle

false

连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,

则连接将被从池中去除.设置为true后如果要生效,validationQuery参数必须设置为非空字符串

minEvictableIdleTimeMillis

1000 60 30

连接在池中保持空闲而不被空闲连接回收器线程(如果有)回收的最小时间值,单位毫秒

numTestsPerEvictionRun

3

在每次空闲连接回收器线程(如果有)运行时检查的连接数量

timeBetweenEvictionRunsMillis

-1

在空闲连接回收器线程运行期间休眠的时间值,以毫秒为单位. 如果设置为非正数,则不运行空闲连接回收器线程

validationQuery

null

SQL查询,用来验证从连接池取出的连接,在将连接返回给调用者之前.如果指定,则查询必须是一个SQL SELECT并且必须返回至少一行记录

testOnBorrow

TRUE

是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个.


。validationQuery(测试连接的sql语句) : validationQuery= “SELECT 1”


。testWhileIdle (连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,则连接将被从池中去除) : testWhileIdle = “true”


。testOnBorrow = “false” 借出连接时不要测试,否则很影响性能,性能会下降7-10倍


。timeBetweenEvictionRunsMillis (每30秒运行一次空闲连接回收器(独立线程)。并每次检查3个连接,


如果连接空闲时间超过30分钟就销毁。销毁连接后,连接数量就少了,如果小于minIdle数量,就新建连接,维护数量不少于minIdle)


。timeBetweenEvictionRunsMillis = “30000”


。minEvictableIdleTimeMillis(池中的连接空闲x毫秒后被回收,默认30分钟):minEvictableIdleTimeMillis = “1800000”


。numTestsPerEvictionRun(在每次空闲连接回收器线程(如果有)运行时检查的连接数量,默认值就是3.) : numTestsPerEvictionRun =“3”


1.1.3 dbcp现有配置分析


我们的应用对有效参数只配置了


<property name="maxActive" value="20"/>

<property name="maxIdle" value="3"/>

<property name="maxWait" value="15000"/>


<property name="timeBetweenEvictionRunsMillis" value="60000"/>

<property name="minEvictableIdleTimeMillis" value="180000"/>


因此,当前数据库连接池配置的含义转换下,就是:


初始化连接数initialSize是0,


最小空闲连接数minIdle是0,


最大连接数maxActive是20,


最大空闲数maxIdle是3,


最大排队等待时间maxWait是15秒,


检查空闲连接线程的时间timeBetweenEvictionRunsMillis是60秒,


空闲线程保持时间多久会被回收minEvictableIdleTimeMillis是30分钟。


1.1.4 线上数据库情况分析


网络异常,图片无法展示
|

按照user维度查询,当前连接数是120个,实例是60台,平均每个实例保持2个连接数,由于当前没有配置minIdle,也就是minIdle默认是0,当空闲数大于休眠时间是可以被回收的,


因此,当一个应用运行连接数达到≥2时刻会产生连接数扩容,小于maxIdle=3后会回收,这里是可能产生性能问题的地方。

网络异常,图片无法展示
|

再按照连接数维度查询,目前是2个物理分库6个逻辑分库,即A物理分库有1-3逻辑库,B物理分库有4-6逻辑库,单个物理分库保持在360个已连接数(如图)总连接数大概为360*2=720个,实例是60个,每个实例平均12个连接数,每个应用都会对接6个逻辑库,因此每个应用日常使用的单个逻辑库数据库连接平均也是2个,与user维度分析是一致的。


1.2 原因分析


出现耗时一般是创建连接池创建连接。在当前配置下,可能个别应用出现空闲连接较长被回收,但是minIdle未配置最小空闲保持数量,导致回收后又扩容连接数的问题从而影响性能。关于数据库连接池的配置之前没有太多考究和分析,应该是其他项目直接粘贴过来的,以后关于核心配置项都要充分思考和实践得出可行性结论。


1.3 解决过程


1.3.1 数据库连接数规划


dba反馈,数据库连接数的限制,物理机一般为3000最大,虚拟机一般为1500最大,不可以扩容连接数,要根据情况调整数据库连接池、应用机器数量。


基于当前系统架构,2个物理分库,6个逻辑分库,A物理分库(1、2、3逻辑库)B物理分库(4、5、6逻辑库),目前应用实例为30台,单机单实例配置。


根据逻辑拆分后,对现有连接数做资源规划,由于主库查询主要是学校信息,查询量较小,分配最大150连接数,其余分库分表均为学生信息,每个逻辑分库分配最大450连接数。


根据当前数据库能力,评估下最大负载能力,评估下数据库连接数的可用性

场景

tp999

理论连接数分析

理论最大支持qps

最大负载

10ms

30台实例,每个实例的每个逻辑分库的最大连接数被限制为15个,3015(1000ms/10ms)=45000qps,即单个逻辑库可支持45000qps,由于拥有6个逻辑分库,理想情况下水平散列分摊到6个库上,即45000qps*6=27Wqps,由于目前拆分两个物理库,所以物理单库负载为27Wqps/2=13.5Wqps

27Wqps,物理单库13.5Wqps

最大负载

20ms

30台实例,每个实例的每个逻辑分库的最大连接数被限制为15个,3015(1000ms/20ms)=22500qps,即单个逻辑库可支持22500qps,由于拥有6个逻辑分库,理想情况下水平散列分摊到6个库上,即22500qps*6=13.5Wqps,由于目前拆分两个物理库,所以物理单库负载为13.5Wqps/2=6.75Wqps

13.5Wqps,物理单库6.75Wqps

最大负载

30ms

30台实例,每个实例的每个逻辑分库的最大连接数被限制为15个,3015(1000ms/30ms)≈15000qps,即单个逻辑库可支持15000qps,由于拥有6个逻辑分库,理想情况下水平散列分摊到6个库上,即15000qps*6=9Wqps,由于目前拆分两个物理库,所以物理单库负载为9Wqps/2=4.5Wqps

9Wqps,物理单库4.5Wqps


综上分析:以上均是理论值,实际上数据库机器配置承载不了,随着qps上升数据库CPU、内存的可用性均会线性下降,性能也会线性下降。仅分析在没有慢SQL,没有超巨大流量撞库的情况下,数据库连接数是充足的,在一般情况下是用不满的


1.3.2 连接池参数调优


日常调用评估


日常调用MANAGE的核心接口tp999保持在10ms-30ms之间,日常qps在1200-1500左右

场景

qps

tp999

理论连接数分析

逻辑分库连接数(60实例)

理论分析结论

日常

1200

10ms

1200qps/(单个连接数每秒吞吐量 1000ms/10ms)= 12,即1200qps在性能10ms情况下需要12个连接数负载, 由于逻辑分库为6个, 理想情况下水平散列分摊到6个库上,即12/6=2,即每个逻辑库负载2个连接数; 极端情况下聚集单库上,即每个逻辑库负载12个连接数

理想 2 / 60 = 至少1 极端 12 / 60 = 至少1

1200qps,10ms,单个应用需要1个连接数配置

日常

1200

20ms

1200qps/(单个连接数每秒吞吐量 1000ms/20ms)= 24,即1200qps在性能20ms情况下需要24个连接数负载, 由于逻辑分库为6个, 理想情况下水平散列分摊到6个库上,即24/6=4,即每个逻辑库负载4个连接数 极端情况下聚集单库上,即每个逻辑库负载24个连接数

理想 4 / 60 = 至少1 极端 24 / 60 = 至少1

1200qps,20ms,单个应用需要1个连接数配置

日常

1200

30ms

1200qps/(单个连接数每秒吞吐量 1000ms/30ms)≈36,即1200qps在性能30ms情况下需要36个连接数负载, 由于逻辑分库为6个, 理想情况下水平散列分摊到6个库上,即36/6=6,即每个逻辑库负载6个连接数 极端情况下聚集单库上,即每个逻辑库负载36个连接数

理想 6 / 60 = 至少1 极端 36 / 60 = 至少1

1200qps,30ms,单个应用需要1~2个连接数配置

日常

1500

10ms

1500qps/(单个连接数每秒吞吐量 1000ms/10ms)= 15,即1500qps在性能10ms情况下需要15个连接数负载, 由于逻辑分库为6个, 理想情况下水平散列分摊到6个库上,即15/6=2.5,即每个逻辑库负载2.5个连接数 极端情况下聚集单库上,即每个逻辑库负载15个连接数

2.5向上取整3 理想 3 / 60 = 至少1 极端 15 / 60 = 至少1

1500qps,10ms,单个应用需要1个连接数配置

日常

1500

20ms

1500qps/(单个连接数每秒吞吐量 1000ms/20ms)= 30,即1500qps在性能20ms情况下需要30个连接数负载, 由于逻辑分库为6个, 理想情况下水平散列分摊到6个库上,即30/6=5,即每个逻辑库负载5个连接数 极端情况下聚集单库上,即每个逻辑库负载30个连接数

理想 5 / 60 = 至少1 极端 30/ 60 = 至少1

1500qps,20ms,单个应用需要1个连接数配置

日常

1500

30ms

1500qps/(单个连接数每秒吞吐量 1000ms/30ms)≈ 45,即1500qps在性能30ms情况下需要45个连接数负载, 由于逻辑分库为6个, 理想情况下水平散列分摊到6个库上,即45/6=7.5,即每个逻辑库负载7.5个连接数 极端情况下聚集单库上,即每个逻辑库负载45个连接数

7.5向上取整8 理想 8 / 60 = 至少1 极端 45/ 60 = 至少1

1500qps,30ms,单个应用需要1个连接数配置


综上分析:日常调用量,由于调用量小,考虑散列极端情况,60个实例情况下,单个应用的数据库连接数需要1个,该情况能够覆盖日常场景对数据库连接池的要求


大促调用评估


大促峰值BIZ调用约为1W,由于缓存拦截撞库小于1W

场景

qps

tp999

理论连接数分析

逻辑分库连接数(60实例)

理论分析结论

大促

10000

10ms

10000qps/(单个连接数每秒吞吐量 1000ms/10ms)= 100,即10000qps在性能10ms情况下需要100个连接数负载, 由于逻辑分库为6个, 理想情况下水平散列分摊到6个库上,即100/6≈16.6,即每个逻辑库负载16.6个连接数

16.6向上取整 17 / 60 = 至少1

10000qps,10ms,单个应用需要1个连接数配置

大促

10000

20ms

10000qps/(单个连接数每秒吞吐量 1000ms/20ms)= 200,即10000qps在性能20ms情况下需要200个连接数负载, 由于逻辑分库为6个, 理想情况下水平散列分摊到6个库上,即200/6≈33.3,即每个逻辑库负载33.3个连接数

33.3向上取整 34 / 60 = 至少1

10000qps,20ms,单个应用需要1个连接数配置

大促

10000

30ms

10000qps/(单个连接数每秒吞吐量 1000ms/30ms)≈ 303,即10000qps在性能30ms情况下需要303个连接数负载, 由于逻辑分库为6个, 理想情况下水平散列分摊到6个库上,即303/6=50.5,即每个逻辑库负载50.5个连接数

50.5向上取整 51 / 60 = 至少1

10000qps,30ms,单个应用需要1个连接数配置

大促

10000

50ms

10000qps/(单个连接数每秒吞吐量 1000ms/50ms)≈ 500,即10000qps在性能50ms情况下需要500个连接数负载, 由于逻辑分库为6个, 理想情况下水平散列分摊到6个库上,即500/6≈83.3,即每个逻辑库负载83.3个连接数

83.3向上取整 84 / 60 = 至少2

10000qps,50ms,单个应用需要2个连接数配置


综上分析:峰值调用量,由于调用量大,不考虑散列极端情况,单个应用的数据库连接数需要在1~2个之间浮动,该情况能够覆盖压测对数据库连接池的要求


压测调用评估


按照大促峰值5倍压测,极端情况5W全部穿透缓存进行撞库,分析如下

场景

qps

tp999

理论连接数分析

逻辑分库连接数(60实例)

理论分析结论

压测

50000

10ms

50000qps/(单个连接数每秒吞吐量 1000ms/10ms)= 500,即50000qps在性能10ms情况下需要500个连接数负载, 由于逻辑分库为6个, 理想情况下水平散列分摊到6个库上,即500/6≈83.3,即每个逻辑库负载83.3个连接数

83.3向上取整 84 / 60 = 至少2

50000qps,10ms,单个应用需要2个连接数配置

压测

50000

20ms

50000qps/(单个连接数每秒吞吐量 1000ms/20ms)= 1000,即50000qps在性能20ms情况下需要1000个连接数负载, 由于逻辑分库为6个, 理想情况下水平散列分摊到6个库上,即1000/6≈166.6,即每个逻辑库负载166.6个连接数

166.6向上取整 167 / 60 = 至少3

50000qps,20ms,单个应用需要3个连接数配置

压测

50000

30ms

50000qps/(单个连接数每秒吞吐量 1000ms/30ms)≈ 1515,即50000qps在性能30ms情况下需要1515个连接数负载, 由于逻辑分库为6个, 理想情况下水平散列分摊到6个库上,即1515/6=252.5,即每个逻辑库负载252.5个连接数

252.5向上取整253 253 / 60 = 至少5

50000qps,30ms,单个应用需要5个连接数配置

压测

50000

50ms

50000qps/(单个连接数每秒吞吐量 1000ms/50ms)≈ 2500,即50000qps在性能50ms情况下需要2500个连接数负载, 由于逻辑分库为6个, 理想情况下水平散列分摊到6个库上,即2500/6≈416.6,即每个逻辑库负载416.6个连接数

416.6向上取整417 417 / 60 = 至少7

50000qps,50ms,单个应用需要7个连接数配置


综上分析:峰值调用量,由于调用量大,不考虑散列极端情况,单个应用的数据库连接数需要在2~7个之间浮动,该情况能够覆盖压测对数据库连接池的要求


综合评估 & 配置调整


日常需求,60实例,1200~1500qps,单应用1个连接数
大促需求,60实例,1Wqps,单应用1~2个连接数
压测需求,60实例,5Wqps,单应用2~7个连接数


为了避免频繁创建和回收,设置initialSize为3,满足日常和大促的最大连接数要求;
minIdle为3,在满足日常及大促峰值最大使用情况下即时线程充足处于空闲状态也不要回收,保持最大使用情况的连接数量进行保持,避免频繁销毁创建;
maxIdle为5,超过该值进行回收,一般压测DB性能好也不会超过该值,若超过后可以回收减少资源消耗和占用
maxActive为7~8,为了分摊tph压力,提高单机CPU、内存利用率,采用单机双实例,共60实例进行负载
物理分库A,逻辑分库6073=1260 + 主库60*4=240,max最大1500,不超过limit限制
物理分库B,逻辑分库60*8*3=1440,max最大1440,不超过limit限制

网络异常,图片无法展示
|

单库配置


<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">

<property name="driverClassName" value="${db.jdbc.driverClassName}"/>

<property name="url" value="${db.jdbc.url}"/>

<property name="username" value="${db.jdbc.username}"/>

<property name="password" value="${db.jdbc.password}"/>

<property name="initialSize" value="2"/>

<property name="minIdle" value="2"/>

<property name="maxIdle" value="3"/>

<property name="maxActive" value="4"/>

<property name="maxWait" value="2000"/>

<property name="timeBetweenEvictionRunsMillis" value="60000"/>

<property name="minEvictableIdleTimeMillis" value="180000"/>

</bean>


物理A库(逻辑1-3库)配置


<bean id="targetDataSource1" class="org.apache.commons.dbcp.BasicDataSource">

<property name="driverClassName" value="${db.jdbc.driverClassName}"/>

<property name="url" value="${db1.jdbc.url}"/>

<property name="username" value="${db1.jdbc.username}"/>

<property name="password" value="${db1.jdbc.password}"/>

<property name="initialSize" value="3"/>

<property name="minIdle" value="3"/>

<property name="maxIdle" value="5"/>

<property name="maxActive" value="7"/>

<property name="maxWait" value="2000"/>

<property name="timeBetweenEvictionRunsMillis" value="60000"/>

<property name="minEvictableIdleTimeMillis" value="180000"/>

</bean>


物理B库(逻辑4-6库)配置


<bean id="targetDataSource1" class="org.apache.commons.dbcp.BasicDataSource">

<property name="driverClassName" value="${db.jdbc.driverClassName}"/>

<property name="url" value="${db1.jdbc.url}"/>

<property name="username" value="${db1.jdbc.username}"/>

<property name="password" value="${db1.jdbc.password}"/>

<property name="initialSize" value="3"/>

<property name="minIdle" value="3"/>

<property name="maxIdle" value="5"/>

<property name="maxActive" value="8"/>

<property name="maxWait" value="2000"/>

<property name="timeBetweenEvictionRunsMillis" value="60000"/>

<property name="minEvictableIdleTimeMillis" value="180000"/>

</bean>


1.4 实测结果


dbcp耗时过长问题解除,当前连接数满足日常、大促、压测各场景需要。


二、网络耗时问题排查


2.1 问题排查


有依赖方反馈偶尔RPC调用超时,于是进行排查,发现该时段机器批量超时

网络异常,图片无法展示
|

但是调用量无明显增加,至少本地服务没有流量洪峰
网络异常,图片无法展示
|


2.2 原因分析


初步判断,怀疑是网络问题,然后到链路工具去查看该时段内服务调用链的耗时情况

网络异常,图片无法展示
|

发现本地BIZ服务调用本地MANAGE服务存在网络超时,由于BIZ对外提供服务,之前压测存在网络问题全部机器都更换为万兆网卡,但是MANAGE的千兆网卡由于资源紧张暂时没有调整,结合PE排查后,建议更换千兆网卡为万兆网卡


2.3 解决过程


淘汰千兆网卡机器,更换为万兆网卡,去除服务不安全隐患问题


2.4 实测结果


外部RPC恢复正常,超时情况解决


三、缓存耗时问题排查


3.1 问题排查


在观察性能接口方法性能时,发现会有偶发性的tp999增高,如下图

网络异常,图片无法展示
|

跟踪了几轮后,发现经常是10.XXX.XXX.119这台机器ip有性能变差的问题,然后跟进链路工具查看链路耗时详情查看
网络异常,图片无法展示
|


3.2 原因分析


发现是Redis耗时较长,于是咨询运维同事如何排查Redis的耗时操作
答复是要查看是客户端延时还是服务端延时,如果是服务端延时看一下是否有慢查询,大key或热key


然后观察几轮后,发现均是10.XXX.XXX.119这台机器的Redis耗时过长,怀疑是网络问题,于是到Redis后台查看客户端延迟监控数据,果然基本都是10.XXX.XXX.119这台机器客户端性能差

网络异常,图片无法展示
|


3.3 解决过程


进一步沟通,反馈“这种是发生网络重传了,网络重传基本200ms左右”,看链路工具上单个方法的Redis调用次数是5次,这个业务方法正常应该会有2次,数据验证了这个说法
目前处理的方法是下线网络有问题的机器,后面替换掉。


3.4 实测结果


缓存耗时问题得到解决


四、日志耗时优化


4.1 问题排查


通过性能工具查看偶有耗时过长操作如下

网络异常,图片无法展示
|

定位该操作均不定时偶发在不同的、但同一个IP上,查看了每个耗时详情,均是logback耗时过长
网络异常,图片无法展示
|


4.2 原因分析


初步判断是logback同步写日志存在竞争导致耗时过长
一般日志的性能损耗有如下:
1、日志写文件同步锁竞争消耗
2、打印行号性能损失,而且接口调用量越大,线程争夺线程栈资源的情况越严重
关于日志优化的文章很多,可以百度查看,这里不加赘述


4.3 解决过程


1、日志异步写,但有丢日志风险,根据业务情况取舍
2、日志降级,借助统一配置中心可以实时动态修改日志级别,对日志打印进行降级操作,日志降级的好处一般是info级别日志不再进行打印和输出,这部分日志丢失,仅打印error级别日志,因此性能会提升很多
3、关闭行号打印后观察一段数据,因logback产生的抖动明显减少


4.4 实测结果


服务性能稳定,因logback导致的偶尔抖动消失

相关文章
|
JavaScript 前端开发 Java
springboot整合minio+vue实现大文件分片上传,断点续传(复制可用,包含minio工具类)
springboot整合minio+vue实现大文件分片上传,断点续传(复制可用,包含minio工具类)
4614 2
|
安全 关系型数据库 MySQL
如何将数据从MySQL同步到其他系统
【10月更文挑战第17天】如何将数据从MySQL同步到其他系统
2210 0
|
负载均衡 网络协议 安全
负载均衡4层和7层区别
所谓四层就是基于IP+端口的负载均衡;七层就是基于URL等应用层信息的负载均衡
|
5月前
|
人工智能 运维 网络安全
OpenClaw、Hermes Agent、Claude Code 接入配置阿里云百炼大模型保姆级教程
当下AI智能体与终端编程工具已经成为开发者提效的核心利器,OpenClaw、Hermes Agent、Claude Code凭借强大的代码生成、任务自动化、流程调度、工程运维能力,被广泛应用于个人开发、团队协作、服务器运维、业务流程自动化等各类场景。
1382 1
OpenClaw、Hermes Agent、Claude Code 接入配置阿里云百炼大模型保姆级教程
|
7月前
|
Java 编译器 Windows
JDK 19安装教程 Windows版:详细步骤+环境变量验证(含java/javac/java -version检测)
本文详细指导JDK 19的下载、安装与验证全流程:含网盘下载链接、解压建议、管理员运行安装程序、默认路径推荐及cmd命令验证(java/javac/java -version),步骤清晰,新手友好,助你快速完成环境配置。(238字)
1101 3
可直接编辑jar包的IDEA插件-JarEditor
IDEA自带的反编译插件虽可查看jar包中的class文件,但无法直接编辑。为解决此问题,作者开发了JarEditor插件,可在IDEA中直接编辑jar文件内的class及资源文件,无需解压或手动编译。点击Jar Editor可修改代码,通过Save/Compile保存并编译,Build Jar则将更改写回jar包。该插件简化了jar包编辑流程,提高了开发效率。
2219 5
可直接编辑jar包的IDEA插件-JarEditor
|
存储 人工智能 算法
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
这篇文章详细介绍了Dijkstra和Floyd算法,这两种算法分别用于解决单源和多源最短路径问题,并且提供了Java语言的实现代码。
1492 3
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
|
Java API 调度
SpringBoot整合XXL-JOB【01】- 初识XXL-JOB
XXL-JOB 是一个分布式任务调度平台,设计目标为开发迅速、学习简单、轻量级、易扩展。它解决了分布式环境下定时任务重复执行的问题,无需额外加锁,降低了维护成本。XXL-JOB 由调度中心和执行器两部分组成,前者管理任务,后者执行具体逻辑,使代码结构更清晰。适用于多机部署场景,支持统一管理任务的启停和频率调整。
2702 8
SpringBoot整合XXL-JOB【01】- 初识XXL-JOB
|
算法 NoSQL 容器
启发式搜索: A*算法
启发式搜索: A*算法
|
搜索推荐
【异常】Caused by: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information: /127.0.0.1:9300
Caused by: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information: /127.0.0.1:9300
5479 0
【异常】Caused by: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information: /127.0.0.1:9300

热门文章

最新文章