Browse Source

Refactor the mechanism of recording error in Entry and StatisticSlot

* Also polish related complete callbacks

Signed-off-by: Eric Zhao <sczyh16@gmail.com>
master
Eric Zhao 4 years ago
parent
commit
7f3165740a
5 changed files with 71 additions and 47 deletions
  1. +30
    -5
      sentinel-core/src/main/java/com/alibaba/csp/sentinel/Entry.java
  2. +13
    -5
      sentinel-core/src/main/java/com/alibaba/csp/sentinel/metric/extension/callback/MetricExitCallback.java
  3. +26
    -35
      sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/statistic/StatisticSlot.java
  4. +1
    -1
      sentinel-core/src/test/java/com/alibaba/csp/sentinel/metric/extension/callback/MetricExitCallbackTest.java
  5. +1
    -1
      sentinel-extension/sentinel-parameter-flow-control/src/main/java/com/alibaba/csp/sentinel/slots/statistic/ParamFlowStatisticExitCallback.java

+ 30
- 5
sentinel-core/src/main/java/com/alibaba/csp/sentinel/Entry.java View File

@@ -15,6 +15,7 @@
*/
package com.alibaba.csp.sentinel;

import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.util.TimeUtil;
import com.alibaba.csp.sentinel.context.ContextUtil;
import com.alibaba.csp.sentinel.node.Node;
@@ -44,6 +45,7 @@ import com.alibaba.csp.sentinel.context.Context;
* @author qinan.qn
* @author jialiang.linjl
* @author leyou(lihao)
* @author Eric Zhao
* @see SphU
* @see Context
* @see ContextUtil
@@ -52,18 +54,23 @@ public abstract class Entry implements AutoCloseable {

private static final Object[] OBJECTS0 = new Object[0];

private long createTime;
private final long createTimestamp;
private long completeTimestamp;

private Node curNode;
/**
* {@link Node} of the specific origin, Usually the origin is the Service Consumer.
*/
private Node originNode;

private Throwable error;
protected ResourceWrapper resourceWrapper;
private BlockException blockError;

protected final ResourceWrapper resourceWrapper;

public Entry(ResourceWrapper resourceWrapper) {
this.resourceWrapper = resourceWrapper;
this.createTime = TimeUtil.currentTimeMillis();
this.createTimestamp = TimeUtil.currentTimeMillis();
}

public ResourceWrapper getResourceWrapper() {
@@ -119,8 +126,17 @@ public abstract class Entry implements AutoCloseable {
*/
public abstract Node getLastNode();

public long getCreateTime() {
return createTime;
public long getCreateTimestamp() {
return createTimestamp;
}

public long getCompleteTimestamp() {
return completeTimestamp;
}

public Entry setCompleteTimestamp(long completeTimestamp) {
this.completeTimestamp = completeTimestamp;
return this;
}

public Node getCurNode() {
@@ -131,6 +147,15 @@ public abstract class Entry implements AutoCloseable {
this.curNode = node;
}

public BlockException getBlockError() {
return blockError;
}

public Entry setBlockError(BlockException blockError) {
this.blockError = blockError;
return this;
}

public Throwable getError() {
return error;
}


+ 13
- 5
sentinel-core/src/main/java/com/alibaba/csp/sentinel/metric/extension/callback/MetricExitCallback.java View File

@@ -14,14 +14,22 @@ import com.alibaba.csp.sentinel.util.TimeUtil;
* @since 1.6.1
*/
public class MetricExitCallback implements ProcessorSlotExitCallback {

@Override
public void onExit(Context context, ResourceWrapper resourceWrapper, int count, Object... args) {
for (MetricExtension m : MetricExtensionProvider.getMetricExtensions()) {
if (context.getCurEntry().getError() == null) {
long realRt = TimeUtil.currentTimeMillis() - context.getCurEntry().getCreateTime();
m.addRt(resourceWrapper.getName(), realRt, args);
m.addSuccess(resourceWrapper.getName(), count, args);
m.decreaseThreadNum(resourceWrapper.getName(), args);
if (context.getCurEntry().getBlockError() != null) {
continue;
}
String resource = resourceWrapper.getName();
long realRt = TimeUtil.currentTimeMillis() - context.getCurEntry().getCreateTimestamp();
m.addRt(resource, realRt, args);
m.addSuccess(resource, count, args);
m.decreaseThreadNum(resource, args);

Throwable ex = context.getCurEntry().getError();
if (ex != null) {
m.addException(resource, count, ex);
}
}
}


+ 26
- 35
sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/statistic/StatisticSlot.java View File

@@ -17,7 +17,7 @@ package com.alibaba.csp.sentinel.slots.statistic;

import java.util.Collection;

import com.alibaba.csp.sentinel.config.SentinelConfig;
import com.alibaba.csp.sentinel.node.Node;
import com.alibaba.csp.sentinel.slotchain.ProcessorSlotEntryCallback;
import com.alibaba.csp.sentinel.slotchain.ProcessorSlotExitCallback;
import com.alibaba.csp.sentinel.slots.block.flow.PriorityWaitException;
@@ -95,7 +95,7 @@ public class StatisticSlot extends AbstractLinkedProcessorSlot<DefaultNode> {
}
} catch (BlockException e) {
// Blocked, set block exception to current entry.
context.getCurEntry().setError(e);
context.getCurEntry().setBlockError(e);

// Add block count.
node.increaseBlockQps(count);
@@ -115,52 +115,31 @@ public class StatisticSlot extends AbstractLinkedProcessorSlot<DefaultNode> {

throw e;
} catch (Throwable e) {
// Unexpected error, set error to current entry.
// Unexpected internal error, set error to current entry.
context.getCurEntry().setError(e);

// This should not happen.
node.increaseExceptionQps(count);
if (context.getCurEntry().getOriginNode() != null) {
context.getCurEntry().getOriginNode().increaseExceptionQps(count);
}

if (resourceWrapper.getEntryType() == EntryType.IN) {
Constants.ENTRY_NODE.increaseExceptionQps(count);
}
throw e;
}
}

@Override
public void exit(Context context, ResourceWrapper resourceWrapper, int count, Object... args) {
DefaultNode node = (DefaultNode)context.getCurNode();

if (context.getCurEntry().getError() == null) {
// Calculate response time (max RT is statisticMaxRt from SentinelConfig).
long rt = TimeUtil.currentTimeMillis() - context.getCurEntry().getCreateTime();
int maxStatisticRt = SentinelConfig.statisticMaxRt();
if (rt > maxStatisticRt) {
rt = maxStatisticRt;
}
Node node = context.getCurNode();

// Record response time and success count.
node.addRtAndSuccess(rt, count);
if (context.getCurEntry().getOriginNode() != null) {
context.getCurEntry().getOriginNode().addRtAndSuccess(rt, count);
}
if (context.getCurEntry().getBlockError() == null) {
// Calculate response time (use completeStatTime as the time of completion).
long completeStatTime = TimeUtil.currentTimeMillis();
context.getCurEntry().setCompleteTimestamp(completeStatTime);
long rt = completeStatTime - context.getCurEntry().getCreateTimestamp();

node.decreaseThreadNum();

if (context.getCurEntry().getOriginNode() != null) {
context.getCurEntry().getOriginNode().decreaseThreadNum();
}
Throwable error = context.getCurEntry().getError();

// Record response time and success count.
recordCompleteFor(node, count, rt, error);
recordCompleteFor(context.getCurEntry().getOriginNode(), count, rt, error);
if (resourceWrapper.getEntryType() == EntryType.IN) {
Constants.ENTRY_NODE.addRtAndSuccess(rt, count);
Constants.ENTRY_NODE.decreaseThreadNum();
recordCompleteFor(Constants.ENTRY_NODE, count, rt, error);
}
} else {
// Error may happen.
}

// Handle exit event with registered exit callback handlers.
@@ -171,4 +150,16 @@ public class StatisticSlot extends AbstractLinkedProcessorSlot<DefaultNode> {

fireExit(context, resourceWrapper, count);
}

private void recordCompleteFor(Node node, int batchCount, long rt, Throwable error) {
if (node == null) {
return;
}
node.addRtAndSuccess(rt, batchCount);
node.decreaseThreadNum();

if (error != null && !(error instanceof BlockException)) {
node.increaseExceptionQps(batchCount);
}
}
}

+ 1
- 1
sentinel-core/src/test/java/com/alibaba/csp/sentinel/metric/extension/callback/MetricExitCallbackTest.java View File

@@ -55,7 +55,7 @@ public class MetricExitCallbackTest extends AbstractTimeBasedTest {

int deltaMs = 100;
when(entry.getError()).thenReturn(null);
when(entry.getCreateTime()).thenReturn(curMillis - deltaMs);
when(entry.getCreateTimestamp()).thenReturn(curMillis - deltaMs);
when(context.getCurEntry()).thenReturn(entry);
exitCallback.onExit(context, resourceWrapper, count, args);
Assert.assertEquals(prevRt + deltaMs, extension.rt);


+ 1
- 1
sentinel-extension/sentinel-parameter-flow-control/src/main/java/com/alibaba/csp/sentinel/slots/statistic/ParamFlowStatisticExitCallback.java View File

@@ -29,7 +29,7 @@ public class ParamFlowStatisticExitCallback implements ProcessorSlotExitCallback

@Override
public void onExit(Context context, ResourceWrapper resourceWrapper, int count, Object... args) {
if (context.getCurEntry().getError() == null) {
if (context.getCurEntry().getBlockError() == null) {
ParameterMetric parameterMetric = ParameterMetricStorage.getParamMetric(resourceWrapper);

if (parameterMetric != null) {


Loading…
Cancel
Save