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);
+ }
+}