dongyukun
2024-12-31 0a2b23ad3f30dfb01c5d590fb98f39e93bfe1932
提交 | 用户 | 时间
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 }