Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
后端镜像
java镜像
Springside4
提交
824dcb96
S
Springside4
项目概览
后端镜像
/
java镜像
/
Springside4
通知
0
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
S
Springside4
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
824dcb96
编写于
2月 08, 2013
作者:
C
Calvin
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
#171 Redis增加session timer方案, 基于redis的job系统的最终版了吧
上级
12922de6
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
133 addition
and
35 deletion
+133
-35
examples/showcase/src/main/java/org/springside/examples/showcase/demos/redis/RedisMassInsertionBenchmark.java
...les/showcase/demos/redis/RedisMassInsertionBenchmark.java
+1
-0
examples/showcase/src/main/java/org/springside/examples/showcase/demos/redis/job/JobConsumer.java
...ngside/examples/showcase/demos/redis/job/JobConsumer.java
+19
-15
examples/showcase/src/main/java/org/springside/examples/showcase/demos/redis/job/JobManager.java
...ingside/examples/showcase/demos/redis/job/JobManager.java
+30
-20
examples/showcase/src/main/java/org/springside/examples/showcase/demos/redis/job/JobProducer.java
...ngside/examples/showcase/demos/redis/job/JobProducer.java
+83
-0
未找到文件。
examples/showcase/src/main/java/org/springside/examples/showcase/demos/redis/RedisMassInsertionBenchmark.java
浏览文件 @
824dcb96
...
...
@@ -94,6 +94,7 @@ public class RedisMassInsertionBenchmark extends ConcurrentBenchmark {
printProgressMessage
(
i
);
}
}
pl
.
sync
();
}
finally
{
onThreadFinish
();
pool
.
returnResource
(
jedis
);
...
...
examples/showcase/src/main/java/org/springside/examples/showcase/demos/redis/
sessionTimer/RedisSessionTimer
Consumer.java
→
examples/showcase/src/main/java/org/springside/examples/showcase/demos/redis/
job/Job
Consumer.java
浏览文件 @
824dcb96
package
org.springside.examples.showcase.demos.redis.
sessionTimer
;
package
org.springside.examples.showcase.demos.redis.
job
;
import
java.util.List
;
import
java.util.concurrent.ExecutorService
;
...
...
@@ -17,7 +17,7 @@ import com.google.common.util.concurrent.RateLimiter;
*
* @author calvin
*/
public
class
RedisSessionTimer
Consumer
implements
Runnable
{
public
class
Job
Consumer
implements
Runnable
{
private
static
final
int
THREAD_COUNT
=
10
;
private
static
final
int
PRINT_BETWEEN_SECONDS
=
10
;
...
...
@@ -38,27 +38,31 @@ public class RedisSessionTimerConsumer implements Runnable {
ExecutorService
threadPool
=
Executors
.
newFixedThreadPool
(
THREAD_COUNT
);
for
(
int
i
=
0
;
i
<
THREAD_COUNT
;
i
++)
{
RedisSessionTimerConsumer
consumer
=
new
RedisSessionTimer
Consumer
();
JobConsumer
consumer
=
new
Job
Consumer
();
threadPool
.
submit
(
consumer
);
}
System
.
out
.
println
(
"Hit enter to stop"
);
System
.
in
.
read
();
System
.
out
.
println
(
"Shuting down"
);
threadPool
.
shutdownNow
();
boolean
shutdownSucess
=
threadPool
.
awaitTermination
(
5
,
TimeUnit
.
SECONDS
);
tearDown
();
if
(!
shutdownSucess
)
{
System
.
out
.
println
(
"Forcing exiting."
);
System
.
exit
(-
1
);
while
(
true
)
{
char
c
=
(
char
)
System
.
in
.
read
();
if
(
c
==
'\n'
)
{
System
.
out
.
println
(
"Shuting down"
);
threadPool
.
shutdownNow
();
boolean
shutdownSucess
=
threadPool
.
awaitTermination
(
5
,
TimeUnit
.
SECONDS
);
tearDown
();
if
(!
shutdownSucess
)
{
System
.
out
.
println
(
"Forcing exiting."
);
System
.
exit
(-
1
);
}
}
}
}
public
static
void
setUp
()
{
JedisPoolConfig
poolConfig
=
new
JedisPoolConfig
();
poolConfig
.
setMaxActive
(
THREAD_COUNT
);
pool
=
new
JedisPool
(
poolConfig
,
RedisSessionTimerDistributor
.
HOST
,
RedisSessionTimerDistributor
.
PORT
,
RedisSessionTimerDistributor
.
TIMEOUT
);
pool
=
new
JedisPool
(
poolConfig
,
JobManager
.
HOST
,
JobManager
.
PORT
,
JobManager
.
TIMEOUT
);
}
public
static
void
tearDown
()
{
...
...
@@ -72,11 +76,11 @@ public class RedisSessionTimerConsumer implements Runnable {
//Jedis的brpop 不会被中断, 所以下面的判断基本没用, 全靠外围的强行退出.
while
(!
Thread
.
currentThread
().
isInterrupted
())
{
//fetch job
List
<
String
>
result
=
jedis
.
brpop
(
0
,
RedisSessionTimerDistributo
r
.
JOB_KEY
);
List
<
String
>
result
=
jedis
.
brpop
(
0
,
JobManage
r
.
JOB_KEY
);
String
id
=
result
.
get
(
1
);
//ack job
jedis
.
zrem
(
RedisSessionTimerDistributo
r
.
ACK_KEY
,
id
);
jedis
.
zrem
(
JobManage
r
.
ACK_KEY
,
id
);
int
count
=
counter
.
incrementAndGet
();
int
localCount
=
localCounter
.
incrementAndGet
();
...
...
examples/showcase/src/main/java/org/springside/examples/showcase/demos/redis/
sessionTimer/RedisSessionTimerDistributo
r.java
→
examples/showcase/src/main/java/org/springside/examples/showcase/demos/redis/
job/JobManage
r.java
浏览文件 @
824dcb96
package
org.springside.examples.showcase.demos.redis.
sessionTimer
;
package
org.springside.examples.showcase.demos.redis.
job
;
import
java.util.concurrent.Executors
;
import
java.util.concurrent.ScheduledExecutorService
;
import
java.util.concurrent.TimeUnit
;
import
java.util.concurrent.atomic.AtomicLong
;
import
redis.clients.jedis.Jedis
;
import
redis.clients.jedis.Protocol
;
...
...
@@ -15,38 +16,44 @@ import com.google.common.util.concurrent.RateLimiter;
*
* @author calvin
*/
public
class
RedisSessionTimerDistributo
r
implements
Runnable
{
public
class
JobManage
r
implements
Runnable
{
public
static
final
String
TIMER_KEY
=
"ss.timer"
;
public
static
final
String
JOB_KEY
=
"ss.job"
;
public
static
final
String
ACK_KEY
=
"ss.ack"
;
public
static
final
String
TIMER_KEY
=
"ss.job:schedule"
;
public
static
final
String
JOB_KEY
=
"ss.job:queue"
;
public
static
final
String
ACK_KEY
=
"ss.job:ack"
;
public
static
final
int
EXPECT_TPS
=
2500
;
public
static
final
int
DELAY_SECONDS
=
10
;
public
static
final
String
HOST
=
"localhost"
;
public
static
final
int
PORT
=
Protocol
.
DEFAULT_PORT
;
public
static
final
int
TIMEOUT
=
5000
;
private
static
final
int
PRINT_BETWEEN_SECONDS
=
20
;
private
static
int
BATCH_SIZE
=
2500
;
private
Jedis
jedis
;
private
String
scriptSha
;
private
int
loop
=
1
;
private
long
totalTime
;
private
AtomicLong
totalTime
=
new
AtomicLong
(
0
)
;
private
RateLimiter
printRate
=
RateLimiter
.
create
(
1
d
/
PRINT_BETWEEN_SECONDS
);
public
static
void
main
(
String
[]
args
)
throws
Exception
{
RedisSessionTimerDistributor
distributor
=
new
RedisSessionTimerDistributo
r
();
JobManager
distributor
=
new
JobManage
r
();
distributor
.
setUp
();
try
{
ScheduledExecutorService
threadPool
=
Executors
.
newScheduledThreadPool
(
1
);
threadPool
.
scheduleAtFixedRate
(
distributor
,
5
,
1
,
TimeUnit
.
SECONDS
);
threadPool
.
scheduleAtFixedRate
(
distributor
,
10
,
1
,
TimeUnit
.
SECONDS
);
System
.
out
.
println
(
"Hit enter to stop."
);
System
.
in
.
read
();
System
.
out
.
println
(
"Shuting down"
);
threadPool
.
shutdownNow
();
threadPool
.
awaitTermination
(
3
,
TimeUnit
.
SECONDS
);
while
(
true
)
{
char
c
=
(
char
)
System
.
in
.
read
();
if
(
c
==
'\n'
)
{
System
.
out
.
println
(
"Shuting down"
);
threadPool
.
shutdownNow
();
threadPool
.
awaitTermination
(
3
,
TimeUnit
.
SECONDS
);
}
}
}
finally
{
distributor
.
tearDown
();
}
...
...
@@ -54,16 +61,16 @@ public class RedisSessionTimerDistributor implements Runnable {
public
void
setUp
()
{
jedis
=
new
Jedis
(
HOST
,
PORT
,
TIMEOUT
);
String
script
=
"local jobWithScores=redis.call('zrangebyscore', KEYS[1], 0, ARGV[1], 'withscores')\n"
;
String
script
=
"local jobWithScores=redis.call('zrangebyscore', KEYS[1], '-inf', ARGV[1], 'withscores')\n"
;
script
+=
" redis.call('zremrangebyscore', KEYS[1], '-inf', ARGV[1])\n"
;
script
+=
" for i=1,ARGV[2] do \n"
;
script
+=
" redis.call('lpush', KEYS[2], jobWithScores[i*2-1])\n"
;
script
+=
" end\n"
;
script
+=
" for i=1,ARGV[2] do \n"
;
script
+=
" redis.call('zadd', KEYS[3], jobWithScores[i*2], jobWithScores[i*2-1])\n"
;
script
+=
" end\n"
;
script
+=
" redis.call('zremrangebyscore', KEYS[1], 0, ARGV[1])"
;
System
.
out
.
println
(
script
);
System
.
out
.
println
(
"Lua Scripts is:\n"
+
script
);
scriptSha
=
jedis
.
scriptLoad
(
script
);
}
...
...
@@ -74,13 +81,16 @@ public class RedisSessionTimerDistributor implements Runnable {
@Override
public
void
run
()
{
long
startTime
=
System
.
currentTimeMillis
();
jedis
.
evalsha
(
scriptSha
,
Lists
.
newArrayList
(
TIMER_KEY
,
JOB_KEY
,
ACK_KEY
),
Lists
.
newArrayList
(
String
.
valueOf
(
loop
*
BATCH_SIZE
-
1
),
String
.
valueOf
(
BATCH_SIZE
)));
loop
++;
Lists
.
newArrayList
(
String
.
valueOf
(
startTime
),
String
.
valueOf
(
EXPECT_TPS
)));
long
spendTime
=
System
.
currentTimeMillis
()
-
startTime
;
totalTime
+=
spendTime
;
totalTime
.
addAndGet
(
spendTime
);
loop
++;
if
(
printRate
.
tryAcquire
())
{
System
.
out
.
printf
(
"
Average time %d ms \n"
,
totalTime
/
loop
);
System
.
out
.
printf
(
"
Last time %,d ms, average time %,d ms \n"
,
spendTime
,
totalTime
.
longValue
()
/
loop
);
}
}
}
examples/showcase/src/main/java/org/springside/examples/showcase/demos/redis/
sessionTimer/RedisSessionTimer
Producer.java
→
examples/showcase/src/main/java/org/springside/examples/showcase/demos/redis/
job/Job
Producer.java
浏览文件 @
824dcb96
package
org.springside.examples.showcase.demos.redis.sessionTimer
;
package
org.springside.examples.showcase.demos.redis.job
;
import
java.util.concurrent.atomic.AtomicLong
;
import
org.springside.modules.test.benchmark.BenchmarkTask
;
import
org.springside.modules.test.benchmark.ConcurrentBenchmark
;
...
...
@@ -8,23 +10,26 @@ import redis.clients.jedis.JedisPool;
import
redis.clients.jedis.JedisPoolConfig
;
/**
* 将
Timer放入ss.timer(S
orted set).
* 将
Job放入ss.job:schedule(s
orted set).
*
* @author calvin
*/
public
class
RedisSessionTimer
Producer
extends
ConcurrentBenchmark
{
private
static
final
int
THREAD_COUNT
=
10
;
private
static
final
long
LOOP_COUNT
=
25
00
*
60
;
public
class
Job
Producer
extends
ConcurrentBenchmark
{
private
static
final
int
THREAD_COUNT
=
5
;
private
static
final
long
LOOP_COUNT
=
50
00
*
60
;
private
static
final
int
PRINT_BETWEEN_SECONDS
=
10
;
private
static
AtomicLong
idGenerator
=
new
AtomicLong
(
0
);
private
static
long
expireTime
;
private
JedisPool
pool
;
public
static
void
main
(
String
[]
args
)
throws
Exception
{
RedisSessionTimerProducer
benchmark
=
new
RedisSessionTimer
Producer
(
THREAD_COUNT
,
LOOP_COUNT
);
JobProducer
benchmark
=
new
Job
Producer
(
THREAD_COUNT
,
LOOP_COUNT
);
benchmark
.
run
();
}
public
RedisSessionTimer
Producer
(
int
threadCount
,
long
loopCount
)
{
public
Job
Producer
(
int
threadCount
,
long
loopCount
)
{
super
(
threadCount
,
loopCount
);
}
...
...
@@ -33,8 +38,8 @@ public class RedisSessionTimerProducer extends ConcurrentBenchmark {
//create jedis pool
JedisPoolConfig
poolConfig
=
new
JedisPoolConfig
();
poolConfig
.
setMaxActive
(
THREAD_COUNT
);
pool
=
new
JedisPool
(
poolConfig
,
RedisSessionTimerDistributor
.
HOST
,
RedisSessionTimerDistributor
.
PORT
,
RedisSessionTimerDistributor
.
TIMEOUT
)
;
pool
=
new
JedisPool
(
poolConfig
,
JobManager
.
HOST
,
JobManager
.
PORT
,
JobManager
.
TIMEOUT
);
expireTime
=
System
.
currentTimeMillis
()
+
JobManager
.
DELAY_SECONDS
*
1000
;
}
@Override
...
...
@@ -44,12 +49,12 @@ public class RedisSessionTimerProducer extends ConcurrentBenchmark {
@Override
protected
BenchmarkTask
createTask
(
int
index
)
{
return
new
SessionTimer
ProducerTask
(
index
,
this
,
PRINT_BETWEEN_SECONDS
);
return
new
Job
ProducerTask
(
index
,
this
,
PRINT_BETWEEN_SECONDS
);
}
public
class
SessionTimer
ProducerTask
extends
BenchmarkTask
{
public
class
Job
ProducerTask
extends
BenchmarkTask
{
public
SessionTimer
ProducerTask
(
int
index
,
ConcurrentBenchmark
parent
,
int
printBetweenSeconds
)
{
public
Job
ProducerTask
(
int
index
,
ConcurrentBenchmark
parent
,
int
printBetweenSeconds
)
{
super
(
index
,
parent
,
printBetweenSeconds
);
}
...
...
@@ -59,10 +64,14 @@ public class RedisSessionTimerProducer extends ConcurrentBenchmark {
onThreadStart
();
try
{
for
(
int
i
=
0
;
i
<
loopCount
;
i
++)
{
long
scheduleTime
=
taskSequence
*
loopCount
+
i
;
jedis
.
zadd
(
RedisSessionTimerDistributor
.
TIMER_KEY
,
scheduleTime
,
String
.
valueOf
(
scheduleTime
));
long
jobId
=
idGenerator
.
getAndIncrement
();
jedis
.
zadd
(
JobManager
.
TIMER_KEY
,
expireTime
,
String
.
valueOf
(
jobId
));
//达到TPS上限后,expireTime往后滚动一秒
if
(
jobId
%
JobManager
.
EXPECT_TPS
==
0
)
{
expireTime
+=
1000
;
}
printProgressMessage
(
i
);
}
}
finally
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录