You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by li...@apache.org on 2018/09/12 01:41:17 UTC

[incubator-servicecomb-java-chassis] 01/13: [SCB-881] define stages of consumer/producer/edge invocation

This is an automated email from the ASF dual-hosted git repository.

liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git

commit aa5dad0ec84b92a040518c38833c5a5699114092
Author: wujimin <wu...@huawei.com>
AuthorDate: Tue Sep 4 22:00:30 2018 +0800

    [SCB-881] define stages of consumer/producer/edge invocation
---
 .../core/invocation/InvocationStageTrace.java      | 353 +++++++++++++++++++++
 .../core/invocation/TestInvocationStageTrace.java  | 224 +++++++++++++
 2 files changed, 577 insertions(+)

diff --git a/core/src/main/java/org/apache/servicecomb/core/invocation/InvocationStageTrace.java b/core/src/main/java/org/apache/servicecomb/core/invocation/InvocationStageTrace.java
new file mode 100644
index 0000000..6cf6aa2
--- /dev/null
+++ b/core/src/main/java/org/apache/servicecomb/core/invocation/InvocationStageTrace.java
@@ -0,0 +1,353 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.core.invocation;
+
+import org.apache.servicecomb.core.Invocation;
+
+/**
+ * <pre>
+ * important:
+ *   all time point is about invocation stage, not java method
+ *   all time is nanoTime
+ *   not all stage relate to a event, currently, we only have 4 event:
+ *     start/finish/startBusiness/finishBusiness
+ *
+ * for consumer:
+ *   start -> startHandlersRequest -> startClientFiltersRequest -> startSend -> finishGetConnection -> finishWriteToBuffer
+ *                                                                                                             /
+ *                                                                                                           \/
+ *   finish <- finishHandlersResponse <- finishClientFiltersResponse <- startClientFiltersResponse <- finishReceiveResponse
+ *
+ * for producer:
+ *     ? ->
+ *   start -> startSchedule -> startExecution -> startServerFiltersRequest -> startHandlersRequest -> startBusinessMethod-----
+ *                                                                                                                           |
+ *                                                                                                                          \/
+ *   finish <- finishWriteToBuffer <- finishServerFiltersResponse <- finishHandlersResponse <- finishBusiness <- finishBusinessMethod
+ * for edge:
+ *   ? ->
+ *   start -> startSchedule -> startExecution -> startServerFiltersRequest --
+ *                                                                         /
+ *      ------------------------------------------------------------------
+ *    /
+ *   ---> startHandlersRequest -> startClientFiltersRequest -> startSend -> finishGetConnection -> finishWriteToBuffer
+ *                                                                                                         /
+ *                                                                                                       \/
+ *         finishHandlersResponse <- finishClientFiltersResponse <- startClientFiltersResponse <- finishReceiveResponse
+ *                        |
+ *                       \/
+ *  finish <- finishServerFiltersResponse
+ * </pre>
+ */
+public class InvocationStageTrace {
+  public static final String PREPARE = "prepare";
+
+  public static final String HANDLERS_REQUEST = "handlers request";
+
+  public static final String HANDLERS_RESPONSE = "handlers response";
+
+  public static final String CLIENT_FILTERS_REQUEST = "client filters request";
+
+  public static final String CONSUMER_SEND_REQUEST = "send request";
+
+  public static final String CONSUMER_GET_CONNECTION = "get connection";
+
+  public static final String CONSUMER_WRITE_TO_BUF = "write to buf";
+
+  public static final String CONSUMER_WAIT_RESPONSE = "wait response";
+
+  public static final String CONSUMER_WAKE_CONSUMER = "wake consumer";
+
+  public static final String CLIENT_FILTERS_RESPONSE = "client filters response";
+
+  public static final String THREAD_POOL_QUEUE = "threadPoolQueue";
+
+  public static final String SERVER_FILTERS_REQUEST = "server filters request";
+
+  public static final String SERVER_FILTERS_RESPONSE = "server filters response";
+
+  public static final String PRODUCER_SEND_RESPONSE = "send response";
+
+  private Invocation invocation;
+
+  private long start;
+
+  private long startHandlersRequest;
+
+  private long startClientFiltersRequest;
+
+  // only for consumer
+  private long startSend;
+
+  // only for consumer
+  private long finishGetConnection;
+
+  // only for consumer
+  private long finishWriteToBuffer;
+
+  // only for consumer
+  private long finishReceiveResponse;
+
+  private long startClientFiltersResponse;
+
+  private long finishClientFiltersResponse;
+
+  private long finishHandlersResponse;
+
+  private long finish;
+
+  // only for producer: put producer task to thread pool
+  private long startSchedule;
+
+  private long startServerFiltersRequest;
+
+  private long finishServerFiltersResponse;
+
+  // only for producer: start execute in work thread
+  //           for reactive mode, work thread is eventloop
+  private long startExecution;
+
+  // only for producer
+  private long startBusinessMethod;
+
+  // only for producer
+  private long finishBusiness;
+
+  public InvocationStageTrace(Invocation invocation) {
+    this.invocation = invocation;
+  }
+
+  public void start(long start) {
+    this.start = start;
+  }
+
+  public long getStart() {
+    return start;
+  }
+
+  public long getStartHandlersRequest() {
+    return startHandlersRequest;
+  }
+
+  public void startHandlersRequest() {
+    this.startHandlersRequest = System.nanoTime();
+  }
+
+  public long getStartClientFiltersRequest() {
+    return startClientFiltersRequest;
+  }
+
+  public void startClientFiltersRequest() {
+    this.startClientFiltersRequest = System.nanoTime();
+  }
+
+  public long getStartSchedule() {
+    return startSchedule;
+  }
+
+  public void startSchedule() {
+    this.startSchedule = System.nanoTime();
+  }
+
+  public long getStartExecution() {
+    return startExecution;
+  }
+
+  public void startExecution() {
+    this.startExecution = System.nanoTime();
+  }
+
+  public long getStartSend() {
+    return startSend;
+  }
+
+  public void startSend() {
+    this.startSend = System.nanoTime();
+  }
+
+  public long getFinishGetConnection() {
+    return finishGetConnection;
+  }
+
+  public void finishGetConnection(long finishGetConnection) {
+    this.finishGetConnection = finishGetConnection;
+  }
+
+  public long getFinishWriteToBuffer() {
+    return finishWriteToBuffer;
+  }
+
+  public void finishWriteToBuffer(long finishWriteToBuffer) {
+    this.finishWriteToBuffer = finishWriteToBuffer;
+  }
+
+  public long getFinishReceiveResponse() {
+    return finishReceiveResponse;
+  }
+
+  public void finishReceiveResponse() {
+    this.finishReceiveResponse = System.nanoTime();
+  }
+
+  public long getStartClientFiltersResponse() {
+    return startClientFiltersResponse;
+  }
+
+  public void startClientFiltersResponse() {
+    this.startClientFiltersResponse = System.nanoTime();
+  }
+
+  public long getFinishClientFiltersResponse() {
+    return finishClientFiltersResponse;
+  }
+
+  public void finishClientFiltersResponse() {
+    this.finishClientFiltersResponse = System.nanoTime();
+  }
+
+  public long getFinishHandlersResponse() {
+    return finishHandlersResponse;
+  }
+
+  public void finishHandlersResponse() {
+    this.finishHandlersResponse = System.nanoTime();
+  }
+
+  public long getStartServerFiltersRequest() {
+    return startServerFiltersRequest;
+  }
+
+  public void startServerFiltersRequest() {
+    this.startServerFiltersRequest = System.nanoTime();
+  }
+
+  public long getFinishServerFiltersResponse() {
+    return finishServerFiltersResponse;
+  }
+
+  public void finishServerFiltersResponse() {
+    this.finishServerFiltersResponse = System.nanoTime();
+  }
+
+  public long getStartBusinessMethod() {
+    return startBusinessMethod;
+  }
+
+  public void startBusinessMethod() {
+    this.startBusinessMethod = System.nanoTime();
+  }
+
+  public long getFinishBusiness() {
+    return finishBusiness;
+  }
+
+  public void finishBusiness() {
+    this.finishBusiness = System.nanoTime();
+  }
+
+  public long getFinish() {
+    return finish;
+  }
+
+  public void finish() {
+    this.finish = System.nanoTime();
+  }
+
+  private double calc(long finish, long start) {
+    if (finish == 0) {
+      return Double.NaN;
+    }
+
+    return finish - start;
+  }
+
+  public double calcTotalTime() {
+    return calc(finish, start);
+  }
+
+  public double calcInvocationPrepareTime() {
+    if (invocation.isConsumer() && !invocation.isEdge()) {
+      return calc(startHandlersRequest, start);
+    }
+
+    return calc(startSchedule, start);
+  }
+
+  public double calcHandlersRequestTime() {
+    if (invocation.isConsumer()) {
+      return calc(startClientFiltersRequest, startHandlersRequest);
+    }
+
+    return calc(startBusinessMethod, startHandlersRequest);
+  }
+
+  public double calcClientFiltersRequestTime() {
+    return calc(startSend, startClientFiltersRequest);
+  }
+
+  public double calcServerFiltersRequestTime() {
+    return calc(startHandlersRequest, startServerFiltersRequest);
+  }
+
+  public double calcSendRequestTime() {
+    return calc(finishWriteToBuffer, startSend);
+  }
+
+  public double calcGetConnectionTime() {
+    return calc(finishGetConnection, startSend);
+  }
+
+  public double calcWriteToBufferTime() {
+    return calc(finishWriteToBuffer, finishGetConnection);
+  }
+
+  public double calcReceiveResponseTime() {
+    return calc(finishReceiveResponse, finishWriteToBuffer);
+  }
+
+  public double calcWakeConsumer() {
+    return calc(startClientFiltersResponse, finishReceiveResponse);
+  }
+
+  public double calcClientFiltersResponseTime() {
+    return calc(finishClientFiltersResponse, startClientFiltersResponse);
+  }
+
+  public double calcServerFiltersResponseTime() {
+    return calc(finishServerFiltersResponse, finishHandlersResponse);
+  }
+
+  public double calcHandlersResponseTime() {
+    if (invocation.isConsumer()) {
+      return calc(finishHandlersResponse, finishClientFiltersResponse);
+    }
+
+    return calc(finishHandlersResponse, finishBusiness);
+  }
+
+  public double calcThreadPoolQueueTime() {
+    return calc(startExecution, startSchedule);
+  }
+
+  public double calcBusinessTime() {
+    return calc(finishBusiness, startBusinessMethod);
+  }
+
+  public double calcSendResponseTime() {
+    return calc(finish, finishServerFiltersResponse);
+  }
+}
diff --git a/core/src/test/java/org/apache/servicecomb/core/invocation/TestInvocationStageTrace.java b/core/src/test/java/org/apache/servicecomb/core/invocation/TestInvocationStageTrace.java
new file mode 100644
index 0000000..64c468d
--- /dev/null
+++ b/core/src/test/java/org/apache/servicecomb/core/invocation/TestInvocationStageTrace.java
@@ -0,0 +1,224 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.core.invocation;
+
+import org.apache.servicecomb.core.Endpoint;
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.core.definition.OperationMeta;
+import org.apache.servicecomb.core.provider.consumer.ReferenceConfig;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import mockit.Mock;
+import mockit.MockUp;
+import mockit.Mocked;
+
+public class TestInvocationStageTrace {
+  Invocation invocation;
+
+  InvocationStageTrace stageTrace;
+
+  @Mocked
+  Endpoint endpoint;
+
+  @Mocked
+  ReferenceConfig referenceConfig;
+
+  @Mocked
+  OperationMeta operationMeta;
+
+  Object[] args = new Object[] {};
+
+  static long nanoTime = 0;
+
+  @BeforeClass
+  public static void classSetup() {
+    new MockUp<System>() {
+      @Mock
+      long nanoTime() {
+        return nanoTime;
+      }
+    };
+  }
+
+  @Test
+  public void consumer() {
+    invocation = new Invocation(referenceConfig, operationMeta, args);
+    stageTrace = new InvocationStageTrace(invocation);
+
+    stageTrace.start(1);
+    nanoTime = 2;
+    stageTrace.startHandlersRequest();
+    nanoTime = 3;
+    stageTrace.startClientFiltersRequest();
+    nanoTime = 4;
+    stageTrace.startSend();
+    stageTrace.finishGetConnection(5);
+    stageTrace.finishWriteToBuffer(6);
+    nanoTime = 7;
+    stageTrace.finishReceiveResponse();
+    nanoTime = 8;
+    stageTrace.startClientFiltersResponse();
+    nanoTime = 9;
+    stageTrace.finishClientFiltersResponse();
+    nanoTime = 10;
+    stageTrace.finishHandlersResponse();
+    nanoTime = 11;
+    stageTrace.finish();
+
+    Assert.assertEquals(1, stageTrace.getStart());
+    Assert.assertEquals(2, stageTrace.getStartHandlersRequest());
+    Assert.assertEquals(3, stageTrace.getStartClientFiltersRequest());
+    Assert.assertEquals(4, stageTrace.getStartSend());
+    Assert.assertEquals(5, stageTrace.getFinishGetConnection());
+    Assert.assertEquals(6, stageTrace.getFinishWriteToBuffer());
+    Assert.assertEquals(7, stageTrace.getFinishReceiveResponse());
+    Assert.assertEquals(8, stageTrace.getStartClientFiltersResponse());
+    Assert.assertEquals(9, stageTrace.getFinishClientFiltersResponse());
+    Assert.assertEquals(10, stageTrace.getFinishHandlersResponse());
+    Assert.assertEquals(11, stageTrace.getFinish());
+
+    Assert.assertEquals(1f, stageTrace.calcInvocationPrepareTime(), 0.1f);
+    Assert.assertEquals(1f, stageTrace.calcHandlersRequestTime(), 0.1f);
+    Assert.assertEquals(1f, stageTrace.calcClientFiltersRequestTime(), 0.1f);
+    Assert.assertEquals(2f, stageTrace.calcSendRequestTime(), 0.1f);
+    Assert.assertEquals(1f, stageTrace.calcGetConnectionTime(), 0.1f);
+    Assert.assertEquals(1f, stageTrace.calcWriteToBufferTime(), 0.1f);
+    Assert.assertEquals(1f, stageTrace.calcReceiveResponseTime(), 0.1f);
+    Assert.assertEquals(1f, stageTrace.calcWakeConsumer(), 0.1f);
+    Assert.assertEquals(1f, stageTrace.calcClientFiltersResponseTime(), 0.1f);
+    Assert.assertEquals(1f, stageTrace.calcHandlersResponseTime(), 0.1f);
+    Assert.assertEquals(10f, stageTrace.calcTotalTime(), 0.1f);
+  }
+
+  @Test
+  public void producer() {
+    invocation = new Invocation(endpoint, operationMeta, args);
+    stageTrace = new InvocationStageTrace(invocation);
+
+    stageTrace.start(1);
+    nanoTime = 2;
+    stageTrace.startSchedule();
+    nanoTime = 3;
+    stageTrace.startExecution();
+    nanoTime = 4;
+    stageTrace.startServerFiltersRequest();
+    nanoTime = 5;
+    stageTrace.startHandlersRequest();
+    nanoTime = 6;
+    stageTrace.startBusinessMethod();
+    nanoTime = 7;
+    stageTrace.finishBusiness();
+    nanoTime = 8;
+    stageTrace.finishHandlersResponse();
+    nanoTime = 9;
+    stageTrace.finishServerFiltersResponse();
+    nanoTime = 10;
+    stageTrace.finish();
+
+    Assert.assertEquals(1, stageTrace.getStart());
+    Assert.assertEquals(2, stageTrace.getStartSchedule());
+    Assert.assertEquals(3, stageTrace.getStartExecution());
+    Assert.assertEquals(4, stageTrace.getStartServerFiltersRequest());
+    Assert.assertEquals(5, stageTrace.getStartHandlersRequest());
+    Assert.assertEquals(6, stageTrace.getStartBusinessMethod());
+    Assert.assertEquals(7, stageTrace.getFinishBusiness());
+    Assert.assertEquals(8, stageTrace.getFinishHandlersResponse());
+    Assert.assertEquals(9, stageTrace.getFinishServerFiltersResponse());
+    Assert.assertEquals(10, stageTrace.getFinish());
+
+    Assert.assertEquals(1f, stageTrace.calcInvocationPrepareTime(), 0.1f);
+    Assert.assertEquals(1f, stageTrace.calcThreadPoolQueueTime(), 0.1f);
+    Assert.assertEquals(1f, stageTrace.calcServerFiltersRequestTime(), 0.1f);
+    Assert.assertEquals(1f, stageTrace.calcHandlersRequestTime(), 0.1f);
+    Assert.assertEquals(1f, stageTrace.calcBusinessTime(), 0.1f);
+    Assert.assertEquals(1f, stageTrace.calcHandlersResponseTime(), 0.1f);
+    Assert.assertEquals(1f, stageTrace.calcServerFiltersResponseTime(), 0.1f);
+    Assert.assertEquals(1f, stageTrace.calcSendResponseTime(), 0.1f);
+    Assert.assertEquals(9f, stageTrace.calcTotalTime(), 0.1f);
+  }
+
+  @Test
+  public void edge() {
+    invocation = new Invocation(referenceConfig, operationMeta, args);
+    stageTrace = new InvocationStageTrace(invocation);
+    invocation.setEdge(true);
+
+    stageTrace.start(1);
+    nanoTime = 2;
+    stageTrace.startSchedule();
+    nanoTime = 3;
+    stageTrace.startExecution();
+    nanoTime = 4;
+    stageTrace.startServerFiltersRequest();
+    nanoTime = 5;
+    stageTrace.startHandlersRequest();
+    nanoTime = 6;
+    stageTrace.startClientFiltersRequest();
+    nanoTime = 7;
+    stageTrace.startSend();
+    stageTrace.finishGetConnection(8);
+    stageTrace.finishWriteToBuffer(9);
+    nanoTime = 10;
+    stageTrace.finishReceiveResponse();
+    nanoTime = 11;
+    stageTrace.startClientFiltersResponse();
+    nanoTime = 12;
+    stageTrace.finishClientFiltersResponse();
+    nanoTime = 13;
+    stageTrace.finishHandlersResponse();
+    nanoTime = 14;
+    stageTrace.finishServerFiltersResponse();
+    nanoTime = 15;
+    stageTrace.finish();
+
+    Assert.assertEquals(1, stageTrace.getStart());
+    Assert.assertEquals(2, stageTrace.getStartSchedule());
+    Assert.assertEquals(3, stageTrace.getStartExecution());
+    Assert.assertEquals(4, stageTrace.getStartServerFiltersRequest());
+    Assert.assertEquals(5, stageTrace.getStartHandlersRequest());
+    Assert.assertEquals(6, stageTrace.getStartClientFiltersRequest());
+    Assert.assertEquals(7, stageTrace.getStartSend());
+    Assert.assertEquals(8, stageTrace.getFinishGetConnection());
+    Assert.assertEquals(9, stageTrace.getFinishWriteToBuffer());
+    Assert.assertEquals(10, stageTrace.getFinishReceiveResponse());
+    Assert.assertEquals(11, stageTrace.getStartClientFiltersResponse());
+    Assert.assertEquals(12, stageTrace.getFinishClientFiltersResponse());
+    Assert.assertEquals(13, stageTrace.getFinishHandlersResponse());
+    Assert.assertEquals(14, stageTrace.getFinishServerFiltersResponse());
+    Assert.assertEquals(15, stageTrace.getFinish());
+
+    Assert.assertEquals(1f, stageTrace.calcInvocationPrepareTime(), 0.1f);
+    Assert.assertEquals(1f, stageTrace.calcThreadPoolQueueTime(), 0.1f);
+    Assert.assertEquals(1f, stageTrace.calcServerFiltersRequestTime(), 0.1f);
+
+    Assert.assertEquals(1f, stageTrace.calcHandlersRequestTime(), 0.1f);
+    Assert.assertEquals(1f, stageTrace.calcClientFiltersRequestTime(), 0.1f);
+    Assert.assertEquals(1f, stageTrace.calcGetConnectionTime(), 0.1f);
+    Assert.assertEquals(1f, stageTrace.calcWriteToBufferTime(), 0.1f);
+    Assert.assertEquals(1f, stageTrace.calcReceiveResponseTime(), 0.1f);
+    Assert.assertEquals(1f, stageTrace.calcWakeConsumer(), 0.1f);
+    Assert.assertEquals(1f, stageTrace.calcClientFiltersResponseTime(), 0.1f);
+    Assert.assertEquals(1f, stageTrace.calcHandlersResponseTime(), 0.1f);
+
+    Assert.assertEquals(1f, stageTrace.calcServerFiltersResponseTime(), 0.1f);
+    Assert.assertEquals(1f, stageTrace.calcSendResponseTime(), 0.1f);
+
+    Assert.assertEquals(14f, stageTrace.calcTotalTime(), 0.1f);
+  }
+}