From 1874cdfdd7928fdb15defd075f7ebb7f3d61ca5b Mon Sep 17 00:00:00 2001 From: "xueli.xue" Date: Sun, 12 Mar 2017 22:05:32 +0800 Subject: [PATCH] =?UTF-8?q?=E6=89=A7=E8=A1=8C=E5=99=A8LFU=E7=AD=96?= =?UTF-8?q?=E7=95=A5=E5=8A=9F=E8=83=BD=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../job/admin/core/route/ExecutorRouter.java | 2 +- .../core/route/strategy/ExecutorRouteLFU.java | 39 +++++++++++++++++-- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/ExecutorRouter.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/ExecutorRouter.java index 0a77c3b0..bf884ba8 100644 --- a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/ExecutorRouter.java +++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/ExecutorRouter.java @@ -25,7 +25,7 @@ public abstract class ExecutorRouter { for (int i = 0; i < 100; i++) { - String ret = ExecutorRouter.route(666, new ArrayList(Arrays.asList("127.0.0.1:0000", "127.0.0.1:2222", "127.0.0.1:3333")), ExecutorRouteStrategyEnum.LEAST_RECENTLY_USED.name()); + String ret = ExecutorRouter.route(666, new ArrayList(Arrays.asList("127.0.0.1:0000", "127.0.0.1:2222", "127.0.0.1:3333")), ExecutorRouteStrategyEnum.LEAST_FREQUENTLY_USED.name()); System.out.println(ret); } diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteLFU.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteLFU.java index 4069d90c..56e74b42 100644 --- a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteLFU.java +++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/strategy/ExecutorRouteLFU.java @@ -2,7 +2,8 @@ package com.xxl.job.admin.core.route.strategy; import com.xxl.job.admin.core.route.ExecutorRouter; -import java.util.ArrayList; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; /** * 单个JOB对应的每个执行器,使用频率最低的优先被选举 @@ -13,12 +14,44 @@ import java.util.ArrayList; */ public class ExecutorRouteLFU extends ExecutorRouter { + private static ConcurrentHashMap> jobLfuMap = new ConcurrentHashMap>(); + private static long CACHE_VALID_TIME = 0; + @Override public String route(int jobId, ArrayList addressList) { - // TODO + // cache clear + if (System.currentTimeMillis() > CACHE_VALID_TIME) { + jobLfuMap.clear(); + CACHE_VALID_TIME = System.currentTimeMillis() + 1000*60*60*24; + } + + // lfu item init + HashMap lfuItemMap = jobLfuMap.get(jobId); // Key排序可以用TreeMap+构造入参Compare;Value排序暂时只能通过ArrayList; + if (lfuItemMap == null) { + lfuItemMap = new HashMap(); + jobLfuMap.put(jobId, lfuItemMap); + } + for (String address: addressList) { + if (!lfuItemMap.containsKey(address)) { + lfuItemMap.put(address, 0); + } + } + + // load least userd count address + List> lfuItemList = new ArrayList>(lfuItemMap.entrySet()); + Collections.sort(lfuItemList, new Comparator>() { + @Override + public int compare(Map.Entry o1, Map.Entry o2) { + return o1.getValue().compareTo(o2.getValue()); + } + }); + + Map.Entry addressItem = lfuItemList.get(0); + String minAddress = addressItem.getKey(); + addressItem.setValue(addressItem.getValue() + 1); - return addressList.get(0); + return addressItem.getKey(); } }