Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
weixin_57962205
redisson
提交
2d02d8fb
R
redisson
项目概览
weixin_57962205
/
redisson
与 Fork 源项目一致
从无法访问的项目Fork
通知
10
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
redisson
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
2d02d8fb
编写于
5月 10, 2021
作者:
N
Nikita Koksharov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Fixed - frequent Redis master failover causes memory leak in IdleConnectionWatcher. #3581
上级
5206a5b6
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
43 addition
and
35 deletion
+43
-35
redisson/src/main/java/org/redisson/connection/ClientConnectionsEntry.java
.../java/org/redisson/connection/ClientConnectionsEntry.java
+7
-2
redisson/src/main/java/org/redisson/connection/IdleConnectionWatcher.java
...n/java/org/redisson/connection/IdleConnectionWatcher.java
+29
-26
redisson/src/main/java/org/redisson/connection/MasterSlaveEntry.java
...c/main/java/org/redisson/connection/MasterSlaveEntry.java
+6
-6
redisson/src/main/java/org/redisson/connection/balancer/LoadBalancerManager.java
...org/redisson/connection/balancer/LoadBalancerManager.java
+1
-1
未找到文件。
redisson/src/main/java/org/redisson/connection/ClientConnectionsEntry.java
浏览文件 @
2d02d8fb
...
...
@@ -67,12 +67,12 @@ public class ClientConnectionsEntry {
this
.
freeSubscribeConnectionsCounter
=
new
AsyncSemaphore
(
subscribePoolMaxSize
);
if
(
subscribePoolMaxSize
>
0
)
{
connectionManager
.
getConnectionWatcher
().
add
(
subscribePoolMinSize
,
subscribePoolMaxSize
,
freeSubscribeConnections
,
freeSubscribeConnectionsCounter
,
c
->
{
connectionManager
.
getConnectionWatcher
().
add
(
this
,
subscribePoolMinSize
,
subscribePoolMaxSize
,
freeSubscribeConnections
,
freeSubscribeConnectionsCounter
,
c
->
{
freeSubscribeConnections
.
remove
(
c
);
return
allSubscribeConnections
.
remove
(
c
);
});
}
connectionManager
.
getConnectionWatcher
().
add
(
poolMinSize
,
poolMaxSize
,
freeConnections
,
freeConnectionsCounter
,
c
->
{
connectionManager
.
getConnectionWatcher
().
add
(
this
,
poolMinSize
,
poolMaxSize
,
freeConnections
,
freeConnectionsCounter
,
c
->
{
freeConnections
.
remove
(
c
);
return
allConnections
.
remove
(
c
);
});
...
...
@@ -115,6 +115,11 @@ public class ClientConnectionsEntry {
firstFailTime
.
compareAndSet
(
0
,
System
.
currentTimeMillis
());
}
public
RFuture
<
Void
>
shutdownAsync
()
{
connectionManager
.
getConnectionWatcher
().
remove
(
this
);
return
client
.
shutdownAsync
();
}
public
RedisClient
getClient
()
{
return
client
;
}
...
...
redisson/src/main/java/org/redisson/connection/IdleConnectionWatcher.java
浏览文件 @
2d02d8fb
...
...
@@ -26,10 +26,13 @@ import org.slf4j.Logger;
import
org.slf4j.LoggerFactory
;
import
java.util.Collection
;
import
java.util.Map
;
import
java.util.Queue
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.concurrent.ConcurrentLinkedQueue
;
import
java.util.concurrent.TimeUnit
;
import
java.util.function.Function
;
import
java.util.stream.Collectors
;
public
class
IdleConnectionWatcher
{
...
...
@@ -55,37 +58,32 @@ public class IdleConnectionWatcher {
};
private
final
Queue
<
Entry
>
entries
=
new
ConcurrentLinkedQueue
<>();
private
final
Map
<
ClientConnectionsEntry
,
Queue
<
Entry
>>
entries
=
new
ConcurrentHashMap
<>();
private
final
ScheduledFuture
<?>
monitorFuture
;
public
IdleConnectionWatcher
(
ConnectionManager
manager
,
MasterSlaveServersConfig
config
)
{
monitorFuture
=
manager
.
getGroup
().
scheduleWithFixedDelay
(
new
Runnable
()
{
@Override
public
void
run
()
{
long
currTime
=
System
.
nanoTime
();
for
(
Entry
entry
:
entries
)
{
if
(!
validateAmount
(
entry
))
{
continue
;
}
monitorFuture
=
manager
.
getGroup
().
scheduleWithFixedDelay
(()
->
{
long
currTime
=
System
.
nanoTime
();
for
(
Entry
entry
:
entries
.
values
().
stream
().
flatMap
(
m
->
m
.
stream
()).
collect
(
Collectors
.
toList
()))
{
if
(!
validateAmount
(
entry
))
{
continue
;
}
for
(
RedisConnection
c
:
entry
.
connections
)
{
long
timeInPool
=
TimeUnit
.
NANOSECONDS
.
toMillis
(
currTime
-
c
.
getLastUsageTime
());
if
(
timeInPool
>
config
.
getIdleConnectionTimeout
()
&&
validateAmount
(
entry
)
&&
entry
.
deleteHandler
.
apply
(
c
))
{
ChannelFuture
future
=
c
.
closeAsync
();
future
.
addListener
(
new
FutureListener
<
Void
>()
{
@Override
public
void
operationComplete
(
Future
<
Void
>
future
)
throws
Exception
{
log
.
debug
(
"Connection {} has been closed due to idle timeout. Not used for {} ms"
,
c
.
getChannel
(),
timeInPool
);
}
});
}
for
(
RedisConnection
c
:
entry
.
connections
)
{
long
timeInPool
=
TimeUnit
.
NANOSECONDS
.
toMillis
(
currTime
-
c
.
getLastUsageTime
());
if
(
timeInPool
>
config
.
getIdleConnectionTimeout
()
&&
validateAmount
(
entry
)
&&
entry
.
deleteHandler
.
apply
(
c
))
{
ChannelFuture
future
=
c
.
closeAsync
();
future
.
addListener
(
new
FutureListener
<
Void
>()
{
@Override
public
void
operationComplete
(
Future
<
Void
>
future
)
throws
Exception
{
log
.
debug
(
"Connection {} has been closed due to idle timeout. Not used for {} ms"
,
c
.
getChannel
(),
timeInPool
);
}
});
}
}
}
},
config
.
getIdleConnectionTimeout
(),
config
.
getIdleConnectionTimeout
(),
TimeUnit
.
MILLISECONDS
);
}
...
...
@@ -93,9 +91,14 @@ public class IdleConnectionWatcher {
return
entry
.
maximumAmount
-
entry
.
freeConnectionsCounter
.
getCounter
()
+
entry
.
connections
.
size
()
>
entry
.
minimumAmount
;
}
public
void
add
(
int
minimumAmount
,
int
maximumAmount
,
Collection
<?
extends
RedisConnection
>
connections
,
public
void
remove
(
ClientConnectionsEntry
entry
)
{
entries
.
remove
(
entry
);
}
public
void
add
(
ClientConnectionsEntry
entry
,
int
minimumAmount
,
int
maximumAmount
,
Collection
<?
extends
RedisConnection
>
connections
,
AsyncSemaphore
freeConnectionsCounter
,
Function
<
RedisConnection
,
Boolean
>
deleteHandler
)
{
entries
.
add
(
new
Entry
(
minimumAmount
,
maximumAmount
,
connections
,
freeConnectionsCounter
,
deleteHandler
));
Queue
<
Entry
>
list
=
entries
.
computeIfAbsent
(
entry
,
k
->
new
ConcurrentLinkedQueue
<>());
list
.
add
(
new
Entry
(
minimumAmount
,
maximumAmount
,
connections
,
freeConnectionsCounter
,
deleteHandler
));
}
public
void
stop
()
{
...
...
redisson/src/main/java/org/redisson/connection/MasterSlaveEntry.java
浏览文件 @
2d02d8fb
...
...
@@ -123,11 +123,11 @@ public class MasterSlaveEntry {
}
masterEntry
=
new
ClientConnectionsEntry
(
client
,
config
.
getMasterConnectionMinimumIdleSize
(),
client
,
config
.
getMasterConnectionMinimumIdleSize
(),
config
.
getMasterConnectionPoolSize
(),
config
.
getSubscriptionConnectionMinimumIdleSize
(),
config
.
getSubscriptionConnectionPoolSize
(),
config
.
getSubscriptionConnectionPoolSize
(),
connectionManager
,
NodeType
.
MASTER
);
...
...
@@ -440,7 +440,7 @@ public class MasterSlaveEntry {
if
(
oldMaster
!=
masterEntry
)
{
writeConnectionPool
.
remove
(
masterEntry
);
pubSubConnectionPool
.
remove
(
masterEntry
);
masterEntry
.
getClient
().
shutdownAsync
();
masterEntry
.
shutdownAsync
();
masterEntry
=
oldMaster
;
}
log
.
error
(
"Unable to change master from: "
+
oldMaster
.
getClient
().
getAddr
()
+
" to: "
+
address
,
e
);
...
...
@@ -465,7 +465,7 @@ public class MasterSlaveEntry {
&&
slaveBalancer
.
getAvailableClients
()
>
1
)
{
slaveDown
(
newMasterClient
.
getAddr
(),
FreezeReason
.
SYSTEM
);
}
oldMaster
.
getClient
().
shutdownAsync
();
oldMaster
.
shutdownAsync
();
log
.
info
(
"master {} has changed to {}"
,
oldMaster
.
getClient
().
getAddr
(),
masterEntry
.
getClient
().
getAddr
());
});
}
...
...
@@ -478,7 +478,7 @@ public class MasterSlaveEntry {
RPromise
<
Void
>
result
=
new
RedissonPromise
<
Void
>();
CountableListener
<
Void
>
listener
=
new
CountableListener
<
Void
>(
result
,
null
,
2
);
if
(
masterEntry
!=
null
)
{
masterEntry
.
getClient
().
shutdownAsync
().
onComplete
(
listener
);
masterEntry
.
shutdownAsync
().
onComplete
(
listener
);
}
slaveBalancer
.
shutdownAsync
().
onComplete
(
listener
);
return
result
;
...
...
redisson/src/main/java/org/redisson/connection/balancer/LoadBalancerManager.java
浏览文件 @
2d02d8fb
...
...
@@ -294,7 +294,7 @@ public class LoadBalancerManager {
RPromise
<
Void
>
result
=
new
RedissonPromise
<
Void
>();
CountableListener
<
Void
>
listener
=
new
CountableListener
<
Void
>(
result
,
null
,
client2Entry
.
values
().
size
());
for
(
ClientConnectionsEntry
entry
:
client2Entry
.
values
())
{
entry
.
getClient
().
shutdownAsync
().
onComplete
(
listener
);
entry
.
shutdownAsync
().
onComplete
(
listener
);
}
return
result
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录