change route to resource

This commit is contained in:
Francis Dong
2020-12-25 10:34:59 +08:00
parent be024d1cfc
commit cc2918fdd0
4 changed files with 130 additions and 130 deletions

View File

@@ -29,16 +29,15 @@ public class FlowStat {
public static long INTERVAL = 1000;
/**
* Route ID for all routes entry
* Resource ID for all resources entry
*/
public static String ALL_TOUTES = "_ALL_ROUTES";
public static String ALL_RESOURCES = "_ALL_RESOURCES";
/**
* A string Route ID as key
* A string Resource ID as key
*/
public ConcurrentMap<String, RouteStat> routeStats = new ConcurrentHashMap<>();
public ConcurrentMap<String, ResourceStat> resourceStats = new ConcurrentHashMap<>();
private ExecutorService pool = Executors.newFixedThreadPool(1);
public FlowStat() {
@@ -69,84 +68,84 @@ public class FlowStat {
}
/**
* Increment concurrent request counter of the specified route
* Increment concurrent request counter of the specified resource
*
* @param routeId Route ID
* @param resourceId Resource ID
*/
public void incrConcurrentRequest(String routeId) {
RouteStat routeStat = getRouteStat(routeId);
RouteStat allRouteStat = getRouteStat(ALL_TOUTES);
routeStat.incrConcurrentRequest();
allRouteStat.incrConcurrentRequest();
public void incrConcurrentRequest(String resourceId) {
ResourceStat ResourceStat = getResourceStat(resourceId);
ResourceStat allResourceStat = getResourceStat(ALL_RESOURCES);
ResourceStat.incrConcurrentRequest();
allResourceStat.incrConcurrentRequest();
}
/**
* Returns the current concurrent requests of the specified route<br/>
* Returns the current concurrent requests of the specified resource<br/>
* <br/>
* Returns the current concurrent connections of all routes:<br/>
* getConnection(FlowStat.ALL_TOUTES)
* Returns the current concurrent connections of all resources:<br/>
* getConnection(FlowStat.ALL_RESOURCES)
*
* @param routeId Route ID
* @param resourceId Resource ID
*/
public int getConcurrentRequests(String routeId) {
RouteStat routeStat = getRouteStat(routeId);
return routeStat.getConcurrentRequests().get();
public int getConcurrentRequests(String resourceId) {
ResourceStat ResourceStat = getResourceStat(resourceId);
return ResourceStat.getConcurrentRequests().get();
}
/**
* Add request to current time slot and decrement concurrent connection counter
*
* @param routeId Route ID
* @param rt Response time of request
* @param isSuccess Whether the request is success or not
* @param resourceId Resource ID
* @param rt Response time of request
* @param isSuccess Whether the request is success or not
*/
public void incrRequest(String routeId, long rt, boolean isSuccess) {
incrRequestToTimeSlot(routeId, currentTimeSlotId(), rt, isSuccess);
public void incrRequest(String resourceId, long rt, boolean isSuccess) {
incrRequestToTimeSlot(resourceId, currentTimeSlotId(), rt, isSuccess);
}
/**
* Add request to the specified time slot and decrement concurrent connection
* counter
*
* @param routeId Route ID
* @param resourceId Resource ID
* @param timeSlotId TimeSlot ID
* @param rt Response time of request
* @param isSuccess Whether the request is success or not
* @return
*/
public void incrRequestToTimeSlot(String routeId, long timeSlotId, long rt, boolean isSuccess) {
if (routeId == null) {
public void incrRequestToTimeSlot(String resourceId, long timeSlotId, long rt, boolean isSuccess) {
if (resourceId == null) {
return;
}
RouteStat routeStat = getRouteStat(routeId);
RouteStat allRouteStat = getRouteStat(ALL_TOUTES);
routeStat.incrRequestToTimeSlot(timeSlotId, rt, isSuccess);
allRouteStat.incrRequestToTimeSlot(timeSlotId, rt, isSuccess);
ResourceStat ResourceStat = getResourceStat(resourceId);
ResourceStat allResourceStat = getResourceStat(ALL_RESOURCES);
ResourceStat.incrRequestToTimeSlot(timeSlotId, rt, isSuccess);
allResourceStat.incrRequestToTimeSlot(timeSlotId, rt, isSuccess);
}
private RouteStat getRouteStat(String routeId) {
RouteStat routeStat = null;
if (routeStats.containsKey(routeId)) {
routeStat = routeStats.get(routeId);
private ResourceStat getResourceStat(String resourceId) {
ResourceStat ResourceStat = null;
if (resourceStats.containsKey(resourceId)) {
ResourceStat = resourceStats.get(resourceId);
} else {
routeStat = new RouteStat(routeId);
RouteStat rs = routeStats.putIfAbsent(routeId, routeStat);
ResourceStat = new ResourceStat(resourceId);
ResourceStat rs = resourceStats.putIfAbsent(resourceId, ResourceStat);
if (rs != null) {
routeStat = rs;
ResourceStat = rs;
}
}
return routeStat;
return ResourceStat;
}
/**
* Returns current TimeWindowStat of the specified route
* Returns current TimeWindowStat of the specified resource
*
* @param routeId
* @param resourceId
* @return
*/
public TimeWindowStat getCurrentTimeWindowStat(String routeId) {
public TimeWindowStat getCurrentTimeWindowStat(String resourceId) {
long startTimeMilli = currentTimeSlotId();
return getTimeWindowStat(routeId, startTimeMilli, startTimeMilli + 1000);
return getTimeWindowStat(resourceId, startTimeMilli, startTimeMilli + 1000);
}
/**
@@ -155,54 +154,55 @@ public class FlowStat {
* @param timeMilli
* @return
*/
public TimeWindowStat getPreviousSecondStat(String routeId, long timeMilli) {
public TimeWindowStat getPreviousSecondStat(String resourceId, long timeMilli) {
long endTimeMilli = (timeMilli / INTERVAL) * INTERVAL;
return getTimeWindowStat(routeId, endTimeMilli - 1000, endTimeMilli);
return getTimeWindowStat(resourceId, endTimeMilli - 1000, endTimeMilli);
}
/**
* Returns the timeWindowStat of the specific route in the specified time window
* [startTimeMilli, endTimeMilli)
* Returns the timeWindowStat of the specific resource in the specified time
* window [startTimeMilli, endTimeMilli)
*
* @param startTimeMilli included
* @param endTimemilli excluded
* @return
*/
public TimeWindowStat getTimeWindowStat(String routeId, long startTimeMilli, long endTimeMilli) {
public TimeWindowStat getTimeWindowStat(String resourceId, long startTimeMilli, long endTimeMilli) {
long startSlotId = (startTimeMilli / INTERVAL) * INTERVAL;
long endSlotId = (endTimeMilli / INTERVAL) * INTERVAL;
if (startSlotId == endSlotId) {
endSlotId = endSlotId + INTERVAL;
}
if (routeStats.containsKey(routeId)) {
RouteStat routeStat = routeStats.get(routeId);
return routeStat.getTimeWindowStat(startSlotId, endSlotId);
if (resourceStats.containsKey(resourceId)) {
ResourceStat ResourceStat = resourceStats.get(resourceId);
return ResourceStat.getTimeWindowStat(startSlotId, endSlotId);
}
return null;
}
/**
* Returns the RouteTimeWindowStat list in the specified time window
* Returns the ResourceTimeWindowStat list in the specified time window
* [startTimeMilli, endTimeMilli), The time slot unit is one second
*
* @param routeId optional, returns RouteSlot list of all routes while
* routeId is null
* @param resourceId optional, returns ResourceSlot list of all resources
* while resourceId is null
* @param startTimeMilli
* @param endTimeMilli
* @return
*/
@SuppressWarnings("unused")
public List<RouteTimeWindowStat> getRouteTimeWindowStats(String routeId, long startTimeMilli, long endTimeMilli) {
return this.getRouteTimeWindowStats(routeId, startTimeMilli, endTimeMilli, INTERVAL);
public List<ResourceTimeWindowStat> getResourceTimeWindowStats(String resourceId, long startTimeMilli,
long endTimeMilli) {
return this.getResourceTimeWindowStats(resourceId, startTimeMilli, endTimeMilli, 1);
}
/**
* Returns the RouteTimeWindowStat list in the specified time window
* Returns the ResourceTimeWindow list in the specified time window
* [startTimeMilli, endTimeMilli)
*
* @param routeId optional, returns RouteTimeWindowStat list of all
* routes while routeId is null
* @param resourceId optional, returns ResourceTimeWindowStat list of all
* resources while resourceId is null
* @param startTimeMilli
* @param endTimeMilli
* @param slotIntervalInSec interval of custom time slot in millisecond, such as
@@ -210,9 +210,9 @@ public class FlowStat {
* @return
*/
@SuppressWarnings("unused")
public List<RouteTimeWindowStat> getRouteTimeWindowStats(String routeId, long startTimeMilli, long endTimeMilli,
long slotIntervalInSec) {
List<RouteTimeWindowStat> list = new ArrayList<>();
public List<ResourceTimeWindowStat> getResourceTimeWindowStats(String resourceId, long startTimeMilli,
long endTimeMilli, long slotIntervalInSec) {
List<ResourceTimeWindowStat> list = new ArrayList<>();
long startSlotId = (startTimeMilli / INTERVAL) * INTERVAL;
long endSlotId = (endTimeMilli / INTERVAL) * INTERVAL;
@@ -224,33 +224,33 @@ public class FlowStat {
}
long slotInterval = slotIntervalInSec * 1000;
if (routeId == null) {
Set<Map.Entry<String, RouteStat>> entrys = routeStats.entrySet();
for (Entry<String, RouteStat> entry : entrys) {
if (resourceId == null) {
Set<Map.Entry<String, ResourceStat>> entrys = resourceStats.entrySet();
for (Entry<String, ResourceStat> entry : entrys) {
String rid = entry.getKey();
RouteTimeWindowStat routeWin = new RouteTimeWindowStat(rid);
ResourceTimeWindowStat resourceWin = new ResourceTimeWindowStat(rid);
for (long i = startSlotId; i < endSlotId;) {
TimeWindowStat tws = getTimeWindowStat(routeId, startSlotId, endSlotId);
TimeWindowStat tws = getTimeWindowStat(resourceId, startSlotId, endSlotId);
if (tws != null) {
routeWin.getWindows().add(tws);
resourceWin.getWindows().add(tws);
}
i = i + slotInterval;
}
if (routeWin.getWindows().size() > 0) {
list.add(routeWin);
if (resourceWin.getWindows().size() > 0) {
list.add(resourceWin);
}
}
} else {
RouteTimeWindowStat routeWin = new RouteTimeWindowStat(routeId);
ResourceTimeWindowStat resourceWin = new ResourceTimeWindowStat(resourceId);
for (long i = startSlotId; i < endSlotId;) {
TimeWindowStat tws = getTimeWindowStat(routeId, startSlotId, endSlotId);
TimeWindowStat tws = getTimeWindowStat(resourceId, startSlotId, endSlotId);
if (tws != null) {
routeWin.getWindows().add(tws);
resourceWin.getWindows().add(tws);
}
i = i + slotInterval;
}
if (routeWin.getWindows().size() > 0) {
list.add(routeWin);
if (resourceWin.getWindows().size() > 0) {
list.add(resourceWin);
}
}
return list;
@@ -272,11 +272,11 @@ public class FlowStat {
log.debug("housekeeping start");
long slotId = stat.currentTimeSlotId() - n;
for (long i = lastSlotId; i < slotId;) {
Set<Map.Entry<String, RouteStat>> entrys = stat.routeStats.entrySet();
for (Entry<String, RouteStat> entry : entrys) {
String routeId = entry.getKey();
Set<Map.Entry<String, ResourceStat>> entrys = stat.resourceStats.entrySet();
for (Entry<String, ResourceStat> entry : entrys) {
String resourceId = entry.getKey();
ConcurrentMap<Long, TimeSlot> timeSlots = entry.getValue().getTimeSlots();
log.debug("housekeeping remove slot: routeId={} slotId=={}", routeId, i);
log.debug("housekeeping remove slot: resourceId={} slotId=={}", resourceId, i);
timeSlots.remove(i);
}
i = i + FlowStat.INTERVAL;

View File

@@ -10,12 +10,12 @@ import java.util.concurrent.atomic.AtomicInteger;
* @author Francis Dong
*
*/
public class RouteStat {
public class ResourceStat {
/**
* Route ID
* Resource ID
*/
private String routeId;
private String resourceId;
/**
* Request count of time slot, the beginning timestamp(timeId) as key
@@ -27,12 +27,12 @@ public class RouteStat {
*/
private AtomicInteger concurrentRequests = new AtomicInteger(0);
public RouteStat(String routeId) {
this.routeId = routeId;
public ResourceStat(String resourceId) {
this.resourceId = resourceId;
}
/**
* Increment concurrent request counter of the route
* Increment concurrent request counter of the resource
*
*/
public void incrConcurrentRequest() {
@@ -117,12 +117,12 @@ public class RouteStat {
return tws;
}
public String getRouteId() {
return routeId;
public String getResourceId() {
return resourceId;
}
public void setRouteId(String routeId) {
this.routeId = routeId;
public void setResourceId(String resourceId) {
this.resourceId = resourceId;
}
public ConcurrentMap<Long, TimeSlot> getTimeSlots() {

View File

@@ -8,25 +8,25 @@ import java.util.List;
* @author Francis Dong
*
*/
public class RouteTimeWindowStat {
public class ResourceTimeWindowStat {
/**
* Route ID
* Resource ID
*/
private String routeId;
private String resourceId;
private List<TimeWindowStat> windows = new ArrayList<>();
public RouteTimeWindowStat(String routeId) {
this.routeId = routeId;
public ResourceTimeWindowStat(String resourceId) {
this.resourceId = resourceId;
}
public String getRouteId() {
return routeId;
public String getResourceId() {
return resourceId;
}
public void setRouteId(String routeId) {
this.routeId = routeId;
public void setResourceId(String resourceId) {
this.resourceId = resourceId;
}
public List<TimeWindowStat> getWindows() {

View File

@@ -27,14 +27,14 @@ public class FlowStatTests {
public void testIncr() throws Throwable {
long t = stat.currentTimeSlotId();
long slotId = t + 1000;
String routeId = "a";
String resourceId = "a";
stat.incrRequestToTimeSlot(routeId, t, 100l, true);
TimeWindowStat tws = stat.getPreviousSecondStat(routeId, slotId);
stat.incrRequestToTimeSlot(resourceId, t, 100l, true);
TimeWindowStat tws = stat.getPreviousSecondStat(resourceId, slotId);
assertEquals(1, tws.getTotal());
stat.incrRequestToTimeSlot(routeId, t, 300l, false);
tws = stat.getPreviousSecondStat(routeId, slotId);
stat.incrRequestToTimeSlot(resourceId, t, 300l, false);
tws = stat.getPreviousSecondStat(resourceId, slotId);
assertEquals(2, tws.getTotal());
assertEquals(200, tws.getAvgRt());
assertEquals(100, tws.getMin());
@@ -42,25 +42,25 @@ public class FlowStatTests {
assertEquals(2, tws.getRps().intValue());
assertEquals(1, tws.getErrors());
// System.out.println(JacksonUtils.writeValueAsString(stat.routeStats));
// System.out.println(JacksonUtils.writeValueAsString(stat.resourceStats));
}
@Test
public void testStat() throws Throwable {
// requests per slot per route
// requests per slot per resource
int requests = 100;
int threads = 10;
int routes = 10;
int resources = 10;
int slots = 100;
long rt = 100;
long t1 = System.currentTimeMillis();
long start = (t1 / FlowStat.INTERVAL) * FlowStat.INTERVAL;
int totalRequests = requests * threads * routes * slots;
int totalRequests = requests * threads * resources * slots;
ExecutorService pool = Executors.newFixedThreadPool(10);
for (int i = 0; i < threads; i++) {
pool.submit(new Job(requests, routes, slots, start, rt));
pool.submit(new Job(requests, resources, slots, start, rt));
}
pool.shutdown();
if (pool.awaitTermination(20, TimeUnit.SECONDS)) {
@@ -73,29 +73,29 @@ public class FlowStatTests {
System.out.println("total elapsed time" + (t2 - t1) + "ms");
System.out.println("Testing Time Window" + (end - start) + "ms");
int route1 = 1;
int route2 = 2;
int resource1 = 1;
int resource2 = 2;
int rtBase1 = 1;
int rtBase3 = 3;
TimeWindowStat tws1 = stat.getTimeWindowStat("route-" + route1, start, end);
TimeWindowStat tws2 = stat.getTimeWindowStat("route-" + route2, start, end);
TimeWindowStat tws1 = stat.getTimeWindowStat("resource-" + resource1, start, end);
TimeWindowStat tws2 = stat.getTimeWindowStat("resource-" + resource2, start, end);
TimeWindowStat tws = stat.getTimeWindowStat(FlowStat.ALL_TOUTES, start, end);
assertEquals(totalRequests / routes, tws1.getTotal());
assertEquals(totalRequests / resources, tws1.getTotal());
assertEquals(rt * rtBase1, tws1.getAvgRt());
assertEquals(rt * rtBase1, tws1.getMin());
assertEquals(rt * rtBase1, tws1.getMax());
assertEquals(totalRequests / routes / nsecs, tws1.getRps().intValue());
assertEquals(totalRequests / routes / 10, tws1.getErrors().intValue());
System.out.println("RPS of route1: " + tws1.getRps().intValue());
assertEquals(totalRequests / resources / nsecs, tws1.getRps().intValue());
assertEquals(totalRequests / resources / 10, tws1.getErrors().intValue());
System.out.println("RPS of resource1: " + tws1.getRps().intValue());
assertEquals(totalRequests / routes, tws2.getTotal());
assertEquals(totalRequests / resources, tws2.getTotal());
assertEquals(rt * rtBase3, tws2.getAvgRt());
assertEquals(rt * rtBase3, tws2.getMin());
assertEquals(rt * rtBase3, tws2.getMax());
assertEquals(totalRequests / routes / nsecs, tws2.getRps().intValue());
assertEquals(totalRequests / routes / 10, tws2.getErrors().intValue());
System.out.println("RPS of route2: " + tws2.getRps().intValue());
assertEquals(totalRequests / resources / nsecs, tws2.getRps().intValue());
assertEquals(totalRequests / resources / 10, tws2.getErrors().intValue());
System.out.println("RPS of resource2: " + tws2.getRps().intValue());
assertEquals(totalRequests, tws.getTotal());
assertEquals((rt * rtBase1 + rt * rtBase3) / 2, tws.getAvgRt());
@@ -103,14 +103,14 @@ public class FlowStatTests {
assertEquals(rt * rtBase3, tws.getMax());
assertEquals(totalRequests / nsecs, tws.getRps().intValue());
assertEquals(totalRequests / 10, tws.getErrors().intValue());
System.out.println("RPS of all routes: " + tws.getRps().intValue());
System.out.println("RPS of all resources: " + tws.getRps().intValue());
// performance of getTimeWindowStat
for (int n = 0; n < 10; n++) {
long t3 = System.currentTimeMillis();
int times = 100000;
for (int i = 0; i < times; i++) {
stat.getTimeWindowStat("route-" + route1, start, end);
stat.getTimeWindowStat("resource-" + resource1, start, end);
}
long t4 = System.currentTimeMillis();
System.out.println("performance of getTimeWindowStat: " + (t4 - t3) + "ms " + times + " times");
@@ -121,9 +121,9 @@ public class FlowStatTests {
}
}
// System.out.println(JacksonUtils.writeValueAsString(stat.routeStats));
// System.out.println(JacksonUtils.writeValueAsString(stat.resourceStats));
List<RouteTimeWindowStat> list = stat.getRouteTimeWindowStats("route-" + 1, start, end, 10);
List<ResourceTimeWindowStat> list = stat.getResourceTimeWindowStats("resource-" + 1, start, end, 10);
System.out.println(JacksonUtils.writeValueAsString(list));
} else {
System.out.println("timeout");
@@ -133,16 +133,16 @@ public class FlowStatTests {
class Job implements Runnable {
public Job(int requests, int routes, int slots, long startSlotId, long rt) {
public Job(int requests, int resources, int slots, long startSlotId, long rt) {
this.requests = requests;
this.routes = routes;
this.resources = resources;
this.slots = slots;
this.startSlotId = startSlotId;
this.rt = rt;
}
private int requests = 0;
private int routes = 0;
private int resources = 0;
private int slots = 0;
private long startSlotId = 0;
private long rt = 0;
@@ -151,12 +151,12 @@ public class FlowStatTests {
public void run() {
for (int m = 0; m < slots; m++) {
for (int i = 0; i < requests; i++) {
for (int j = 0; j < routes; j++) {
stat.incrConcurrentRequest("route-" + j);
for (int j = 0; j < resources; j++) {
stat.incrConcurrentRequest("resource-" + j);
// 10% error
boolean isSuccess = i % 10 == 1 ? false : true;
// rt will be triple while even
stat.incrRequestToTimeSlot("route-" + j, startSlotId + (m * FlowStat.INTERVAL),
stat.incrRequestToTimeSlot("resource-" + j, startSlotId + (m * FlowStat.INTERVAL),
rt * (j % 2 == 0 ? 3 : 1), isSuccess);
}
try {