提交 | 用户 | 时间
|
e7c126
|
1 |
package com.xxl.job.admin.core.route.strategy; |
H |
2 |
|
|
3 |
import com.xxl.job.admin.core.route.ExecutorRouter; |
|
4 |
import com.xxl.job.core.biz.model.ReturnT; |
|
5 |
import com.xxl.job.core.biz.model.TriggerParam; |
|
6 |
|
|
7 |
import java.util.ArrayList; |
|
8 |
import java.util.LinkedHashMap; |
|
9 |
import java.util.List; |
|
10 |
import java.util.concurrent.ConcurrentHashMap; |
|
11 |
import java.util.concurrent.ConcurrentMap; |
|
12 |
|
|
13 |
/** |
|
14 |
* 单个JOB对应的每个执行器,最久为使用的优先被选举 |
|
15 |
* a、LFU(Least Frequently Used):最不经常使用,频率/次数 |
|
16 |
* b(*)、LRU(Least Recently Used):最近最久未使用,时间 |
|
17 |
* |
|
18 |
* Created by xuxueli on 17/3/10. |
|
19 |
*/ |
|
20 |
public class ExecutorRouteLRU extends ExecutorRouter { |
|
21 |
|
|
22 |
private static ConcurrentMap<Integer, LinkedHashMap<String, String>> jobLRUMap = new ConcurrentHashMap<Integer, LinkedHashMap<String, String>>(); |
|
23 |
private static long CACHE_VALID_TIME = 0; |
|
24 |
|
|
25 |
public String route(int jobId, List<String> addressList) { |
|
26 |
|
|
27 |
// cache clear |
|
28 |
if (System.currentTimeMillis() > CACHE_VALID_TIME) { |
|
29 |
jobLRUMap.clear(); |
|
30 |
CACHE_VALID_TIME = System.currentTimeMillis() + 1000*60*60*24; |
|
31 |
} |
|
32 |
|
|
33 |
// init lru |
|
34 |
LinkedHashMap<String, String> lruItem = jobLRUMap.get(jobId); |
|
35 |
if (lruItem == null) { |
|
36 |
/** |
|
37 |
* LinkedHashMap |
|
38 |
* a、accessOrder:true=访问顺序排序(get/put时排序);false=插入顺序排期; |
|
39 |
* b、removeEldestEntry:新增元素时将会调用,返回true时会删除最老元素;可封装LinkedHashMap并重写该方法,比如定义最大容量,超出是返回true即可实现固定长度的LRU算法; |
|
40 |
*/ |
|
41 |
lruItem = new LinkedHashMap<String, String>(16, 0.75f, true); |
|
42 |
jobLRUMap.putIfAbsent(jobId, lruItem); |
|
43 |
} |
|
44 |
|
|
45 |
// put new |
|
46 |
for (String address: addressList) { |
|
47 |
if (!lruItem.containsKey(address)) { |
|
48 |
lruItem.put(address, address); |
|
49 |
} |
|
50 |
} |
|
51 |
// remove old |
|
52 |
List<String> delKeys = new ArrayList<>(); |
|
53 |
for (String existKey: lruItem.keySet()) { |
|
54 |
if (!addressList.contains(existKey)) { |
|
55 |
delKeys.add(existKey); |
|
56 |
} |
|
57 |
} |
|
58 |
if (delKeys.size() > 0) { |
|
59 |
for (String delKey: delKeys) { |
|
60 |
lruItem.remove(delKey); |
|
61 |
} |
|
62 |
} |
|
63 |
|
|
64 |
// load |
|
65 |
String eldestKey = lruItem.entrySet().iterator().next().getKey(); |
|
66 |
String eldestValue = lruItem.get(eldestKey); |
|
67 |
return eldestValue; |
|
68 |
} |
|
69 |
|
|
70 |
@Override |
|
71 |
public ReturnT<String> route(TriggerParam triggerParam, List<String> addressList) { |
|
72 |
String address = route(triggerParam.getJobId(), addressList); |
|
73 |
return new ReturnT<String>(address); |
|
74 |
} |
|
75 |
|
|
76 |
} |