You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2020/03/08 06:47:17 UTC

[skywalking] 01/01: Support lazy ContextCarrier injection and lazy peer id setting for exit span

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

wusheng pushed a commit to branch exist-span-inject
in repository https://gitbox.apache.org/repos/asf/skywalking.git

commit 1414ce7cdb16ccc051646f238e1040279bb4a3ce
Author: Wu Sheng <wu...@foxmail.com>
AuthorDate: Sun Mar 8 14:46:57 2020 +0800

    Support lazy ContextCarrier injection and lazy peer id setting for exit span
---
 .../agent/core/context/AbstractTracerContext.java  | 12 +++-
 .../agent/core/context/IgnoredTracerContext.java   |  5 ++
 .../apm/agent/core/context/TracingContext.java     | 79 ++++++++++++++++------
 .../apm/agent/core/context/trace/ExitSpan.java     | 21 +++---
 .../trace/{WithPeerInfo.java => ExitTypeSpan.java} |  9 ++-
 .../apm/agent/core/context/trace/NoopExitSpan.java |  9 ++-
 6 files changed, 103 insertions(+), 32 deletions(-)

diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/AbstractTracerContext.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/AbstractTracerContext.java
index 7ce1c59..db060c6 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/AbstractTracerContext.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/AbstractTracerContext.java
@@ -32,6 +32,15 @@ public interface AbstractTracerContext {
     void inject(ContextCarrier carrier);
 
     /**
+     * Prepare for the cross-process propagation based on the given exit span. The given exit span should belong to the
+     * current context. How to initialize the carrier, depends on the implementation.
+     *
+     * @param carrier  to carry the context for crossing process.
+     * @param exitSpan to represent the scope of current injection.
+     */
+    void _inject(AbstractSpan exitSpan, ContextCarrier carrier);
+
+    /**
      * Build the reference between this segment and a cross-process segment. How to build, depends on the
      * implementation.
      *
@@ -82,7 +91,8 @@ public interface AbstractTracerContext {
      * Create an exit span
      *
      * @param operationName most likely a service name of remote
-     * @param remotePeer    the network id(ip:port, hostname:port or ip1:port1,ip2,port, etc.)
+     * @param remotePeer    the network id(ip:port, hostname:port or ip1:port1,ip2,port, etc.). Remote peer could be set
+     *                      later, but must be before injecting.
      * @return the span represent an exit point of this segment.
      */
     AbstractSpan createExitSpan(String operationName, String remotePeer);
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/IgnoredTracerContext.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/IgnoredTracerContext.java
index 1a5d8c6..3b6924c 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/IgnoredTracerContext.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/IgnoredTracerContext.java
@@ -44,6 +44,11 @@ public class IgnoredTracerContext implements AbstractTracerContext {
     }
 
     @Override
+    public void _inject(final AbstractSpan exitSpan, final ContextCarrier carrier) {
+
+    }
+
+    @Override
     public void extract(ContextCarrier carrier) {
 
     }
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/TracingContext.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/TracingContext.java
index fdf148d..58a4d94 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/TracingContext.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/TracingContext.java
@@ -29,12 +29,12 @@ import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
 import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan;
 import org.apache.skywalking.apm.agent.core.context.trace.EntrySpan;
 import org.apache.skywalking.apm.agent.core.context.trace.ExitSpan;
+import org.apache.skywalking.apm.agent.core.context.trace.ExitTypeSpan;
 import org.apache.skywalking.apm.agent.core.context.trace.LocalSpan;
 import org.apache.skywalking.apm.agent.core.context.trace.NoopExitSpan;
 import org.apache.skywalking.apm.agent.core.context.trace.NoopSpan;
 import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment;
 import org.apache.skywalking.apm.agent.core.context.trace.TraceSegmentRef;
-import org.apache.skywalking.apm.agent.core.context.trace.WithPeerInfo;
 import org.apache.skywalking.apm.agent.core.dictionary.DictionaryManager;
 import org.apache.skywalking.apm.agent.core.dictionary.DictionaryUtil;
 import org.apache.skywalking.apm.agent.core.logging.api.ILog;
@@ -129,21 +129,39 @@ public class TracingContext implements AbstractTracerContext {
      * Inject the context into the given carrier, only when the active span is an exit one.
      *
      * @param carrier to carry the context for crossing process.
-     * @throws IllegalStateException if the active span isn't an exit one. Ref to {@link AbstractTracerContext#inject(ContextCarrier)}
+     * @throws IllegalStateException if (1) the active span isn't an exit one. (2) doesn't include peer. Ref to {@link
+     *                               AbstractTracerContext#inject(ContextCarrier)}
      */
     @Override
     public void inject(ContextCarrier carrier) {
-        AbstractSpan span = this.activeSpan();
-        if (!span.isExit()) {
+        this._inject(this.activeSpan(), carrier);
+    }
+
+    /**
+     * Inject the context into the given carrier and given span, only when the active span is an exit one. This method
+     * wouldn't be opened in {@link ContextManager} like {@link #inject(ContextCarrier)}, it is only supported to be
+     * called inside the {@link ExitTypeSpan#inject(ContextCarrier)}
+     *
+     * @param carrier  to carry the context for crossing process.
+     * @param exitSpan to represent the scope of current injection.
+     * @throws IllegalStateException if (1) the span isn't an exit one. (2) doesn't include peer. Ref to {@link
+     *                               AbstractTracerContext#_inject(AbstractSpan, ContextCarrier)}
+     */
+    @Override
+    public void _inject(AbstractSpan exitSpan, ContextCarrier carrier) {
+        if (!exitSpan.isExit()) {
             throw new IllegalStateException("Inject can be done only in Exit Span");
         }
 
-        WithPeerInfo spanWithPeer = (WithPeerInfo) span;
+        ExitTypeSpan spanWithPeer = (ExitTypeSpan) exitSpan;
         String peer = spanWithPeer.getPeer();
         int peerId = spanWithPeer.getPeerId();
+        if (StringUtil.isEmpty(peer) && DictionaryUtil.isNull(peerId)) {
+            throw new IllegalStateException("Exit span doesn't include meaningful peer information.");
+        }
 
         carrier.setTraceSegmentId(this.segment.getTraceSegmentId());
-        carrier.setSpanId(span.getSpanId());
+        carrier.setSpanId(exitSpan.getSpanId());
 
         carrier.setParentServiceInstanceId(segment.getApplicationInstanceId());
 
@@ -235,7 +253,8 @@ public class TracingContext implements AbstractTracerContext {
     @Override
     public ContextSnapshot capture() {
         List<TraceSegmentRef> refs = this.segment.getRefs();
-        ContextSnapshot snapshot = new ContextSnapshot(segment.getTraceSegmentId(), activeSpan().getSpanId(), segment.getRelatedGlobalTraces());
+        ContextSnapshot snapshot = new ContextSnapshot(
+            segment.getTraceSegmentId(), activeSpan().getSpanId(), segment.getRelatedGlobalTraces());
         int entryOperationId;
         String entryOperationName = "";
         int entryApplicationInstanceId;
@@ -332,15 +351,23 @@ public class TracingContext implements AbstractTracerContext {
         if (parentSpan != null && parentSpan.isEntry()) {
             entrySpan = (AbstractTracingSpan) DictionaryManager.findEndpointSection()
                                                                .findOnly(segment.getServiceId(), operationName)
-                                                               .doInCondition(parentSpan::setOperationId, () -> parentSpan
-                                                                   .setOperationName(operationName));
+                                                               .doInCondition(
+                                                                   parentSpan::setOperationId, () -> parentSpan
+                                                                       .setOperationName(operationName));
             return entrySpan.start();
         } else {
             entrySpan = (AbstractTracingSpan) DictionaryManager.findEndpointSection()
                                                                .findOnly(segment.getServiceId(), operationName)
-                                                               .doInCondition(operationId -> new EntrySpan(spanIdGenerator++, parentSpanId, operationId, owner), () -> {
-                                                                   return new EntrySpan(spanIdGenerator++, parentSpanId, operationName, owner);
-                                                               });
+                                                               .doInCondition(
+                                                                   operationId -> new EntrySpan(spanIdGenerator++,
+                                                                                                parentSpanId,
+                                                                                                operationId, owner
+                                                                   ), () -> {
+                                                                       return new EntrySpan(
+                                                                           spanIdGenerator++, parentSpanId,
+                                                                           operationName, owner
+                                                                       );
+                                                                   });
             entrySpan.start();
             return push(entrySpan);
         }
@@ -373,7 +400,8 @@ public class TracingContext implements AbstractTracerContext {
      * Create an exit span
      *
      * @param operationName most likely a service name of remote
-     * @param remotePeer    the network id(ip:port, hostname:port or ip1:port1,ip2,port, etc.)
+     * @param remotePeer    the network id(ip:port, hostname:port or ip1:port1,ip2,port, etc.). Remote peer could be set
+     *                      later, but must be before injecting.
      * @return the span represent an exit point of this segment.
      * @see ExitSpan
      */
@@ -391,11 +419,21 @@ public class TracingContext implements AbstractTracerContext {
             exitSpan = parentSpan;
         } else {
             final int parentSpanId = parentSpan == null ? -1 : parentSpan.getSpanId();
-            exitSpan = (AbstractSpan) DictionaryManager.findNetworkAddressSection()
-                                                       .find(remotePeer)
-                                                       .doInCondition(peerId -> new ExitSpan(spanIdGenerator++, parentSpanId, operationName, peerId, owner), () -> {
-                                                           return new ExitSpan(spanIdGenerator++, parentSpanId, operationName, remotePeer, owner);
-                                                       });
+            if (StringUtil.isEmpty(remotePeer)) {
+                exitSpan = new ExitSpan(spanIdGenerator++, parentSpanId, operationName, owner);
+            } else {
+                exitSpan = (AbstractSpan) DictionaryManager.findNetworkAddressSection()
+                                                           .find(remotePeer)
+                                                           .doInCondition(
+                                                               peerId -> new ExitSpan(spanIdGenerator++, parentSpanId,
+                                                                                      operationName, peerId, owner
+                                                               ), () -> {
+                                                                   return new ExitSpan(
+                                                                       spanIdGenerator++, parentSpanId, operationName,
+                                                                       remotePeer, owner
+                                                                   );
+                                                               });
+            }
             push(exitSpan);
         }
         exitSpan.start();
@@ -622,7 +660,10 @@ public class TracingContext implements AbstractTracerContext {
         if (spanIdGenerator >= Config.Agent.SPAN_LIMIT_PER_SEGMENT) {
             long currentTimeMillis = System.currentTimeMillis();
             if (currentTimeMillis - lastWarningTimestamp > 30 * 1000) {
-                logger.warn(new RuntimeException("Shadow tracing context. Thread dump"), "More than {} spans required to create", Config.Agent.SPAN_LIMIT_PER_SEGMENT);
+                logger.warn(
+                    new RuntimeException("Shadow tracing context. Thread dump"),
+                    "More than {} spans required to create", Config.Agent.SPAN_LIMIT_PER_SEGMENT
+                );
                 lastWarningTimestamp = currentTimeMillis;
             }
             return true;
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/ExitSpan.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/ExitSpan.java
index 4d167b2..f9b65e8 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/ExitSpan.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/ExitSpan.java
@@ -18,6 +18,7 @@
 
 package org.apache.skywalking.apm.agent.core.context.trace;
 
+import org.apache.skywalking.apm.agent.core.context.ContextCarrier;
 import org.apache.skywalking.apm.agent.core.context.TracingContext;
 import org.apache.skywalking.apm.agent.core.context.tag.AbstractTag;
 import org.apache.skywalking.apm.network.trace.component.Component;
@@ -33,24 +34,19 @@ import org.apache.skywalking.apm.network.trace.component.Component;
  * Such as: Dubbox - Apache Httpcomponent - ...(Remote) The <code>ExitSpan</code> represents the Dubbox span, and ignore
  * the httpcomponent span's info.
  */
-public class ExitSpan extends StackBasedTracingSpan implements WithPeerInfo {
-
+public class ExitSpan extends StackBasedTracingSpan implements ExitTypeSpan {
     public ExitSpan(int spanId, int parentSpanId, String operationName, String peer, TracingContext owner) {
         super(spanId, parentSpanId, operationName, peer, owner);
     }
 
-    public ExitSpan(int spanId, int parentSpanId, int operationId, int peerId, TracingContext owner) {
-        super(spanId, parentSpanId, operationId, peerId, owner);
-    }
-
-    public ExitSpan(int spanId, int parentSpanId, int operationId, String peer, TracingContext owner) {
-        super(spanId, parentSpanId, operationId, peer, owner);
-    }
-
     public ExitSpan(int spanId, int parentSpanId, String operationName, int peerId, TracingContext owner) {
         super(spanId, parentSpanId, operationName, peerId, owner);
     }
 
+    public ExitSpan(int spanId, int parentSpanId, String operationName, TracingContext owner) {
+        super(spanId, parentSpanId, operationName, owner);
+    }
+
     /**
      * Set the {@link #startTime}, when the first start, which means the first service provided.
      */
@@ -142,6 +138,11 @@ public class ExitSpan extends StackBasedTracingSpan implements WithPeerInfo {
     }
 
     @Override
+    public void inject(final ContextCarrier carrier) {
+        this.owner._inject(this, carrier);
+    }
+
+    @Override
     public boolean isEntry() {
         return false;
     }
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/WithPeerInfo.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/ExitTypeSpan.java
similarity index 82%
rename from apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/WithPeerInfo.java
rename to apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/ExitTypeSpan.java
index 249febe..0b235fd 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/WithPeerInfo.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/ExitTypeSpan.java
@@ -18,8 +18,15 @@
 
 package org.apache.skywalking.apm.agent.core.context.trace;
 
-public interface WithPeerInfo {
+import org.apache.skywalking.apm.agent.core.context.ContextCarrier;
+
+/**
+ * The exit span has some additional behaviours
+ */
+public interface ExitTypeSpan {
     int getPeerId();
 
     String getPeer();
+
+    void inject(ContextCarrier carrier);
 }
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/NoopExitSpan.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/NoopExitSpan.java
index bb2018b..84c00ee 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/NoopExitSpan.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/NoopExitSpan.java
@@ -18,7 +18,9 @@
 
 package org.apache.skywalking.apm.agent.core.context.trace;
 
-public class NoopExitSpan extends NoopSpan implements WithPeerInfo {
+import org.apache.skywalking.apm.agent.core.context.ContextCarrier;
+
+public class NoopExitSpan extends NoopSpan implements ExitTypeSpan {
 
     private String peer;
     private int peerId;
@@ -42,6 +44,11 @@ public class NoopExitSpan extends NoopSpan implements WithPeerInfo {
     }
 
     @Override
+    public void inject(final ContextCarrier carrier) {
+
+    }
+
+    @Override
     public boolean isExit() {
         return true;
     }