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

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


The following commit(s) were added to refs/heads/main by this push:
     new d22e51aedf Added support for Lettuce reactive Redis commands (#788)
d22e51aedf is described below

commit d22e51aedf82524a4ca3aeea3e4b7e9196c71b72
Author: wuwen <[email protected]>
AuthorDate: Tue Feb 24 14:15:47 2026 +0800

    Added support for Lettuce reactive Redis commands (#788)
---
 .github/workflows/plugins-jdk17-test.1.yaml        |   1 +
 .github/workflows/plugins-test.1.yaml              |   1 +
 CHANGES.md                                         |   2 +-
 ...ReactiveCreatePublisherMethodInterceptorV5.java |  89 ++++++++++++++++
 .../RedisReactiveCommandsInstrumentationV5.java    |  89 ++++++++++++++++
 .../src/main/resources/skywalking-plugin.def       |   3 +-
 ...eactiveCreatePublisherMethodInterceptorV65.java |  93 ++++++++++++++++
 .../RedisReactiveCommandsInstrumentationV65.java   |  89 ++++++++++++++++
 .../src/main/resources/skywalking-plugin.def       |   3 +-
 .../common/RedisChannelWriterInterceptor.java      |  29 ++++-
 .../RedisCommandCancelMethodInterceptor.java       |   4 +-
 ...mandCompleteExceptionallyMethodInterceptor.java |   4 +-
 .../RedisCommandCompleteMethodInterceptor.java     |   4 +-
 .../lettuce/common/RedisCommandEnhanceInfo.java    |  59 +++++++++++
 .../RedisSubscriptionConstructorInterceptor.java   |  39 +++++++
 ...disSubscriptionSubscribeMethodInterceptor.java} |  47 +++++----
 .../define/RedisSubscriptionInstrumentation.java   |  86 +++++++++++++++
 .../src/main/resources/skywalking-plugin.def       |   3 +-
 .../config/expectedData.yaml                       | 105 ++++++++++++++++++
 .../lettuce/controller/LettuceController.java      |  16 +++
 .../lettuce-scenario/config/expectedData.yaml      | 105 ++++++++++++++++++
 .../lettuce/controller/LettuceController.java      |  16 +++
 .../lettuce-webflux-5x-scenario/bin/startup.sh     |   6 +-
 .../config/expectedData.yaml                       |  51 +++++++--
 .../lettuce-webflux-5x-scenario/configuration.yml  |  15 ++-
 .../scenarios/lettuce-webflux-5x-scenario/pom.xml  |  98 +++++++++++++++++
 .../src/main/assembly/assembly.xml                 |  41 ++++++++
 .../apm/testcase/lettuce/Application.java          |  34 ++++++
 .../apm/testcase/lettuce/RedisClientConfig.java    |  37 +++++++
 .../controller/LettuceReactiveController.java      |  68 ++++++++++++
 .../src/main/resources/application.properties      |  18 ++++
 .../src/main/resources/log4j2.xml                  |  30 ++++++
 .../support-version.list                           |   4 +-
 .../lettuce-webflux-6x-scenario/bin/startup.sh     |   6 +-
 .../config/expectedData.yaml                       |  68 +++++++++---
 .../lettuce-webflux-6x-scenario/configuration.yml  |  15 ++-
 .../scenarios/lettuce-webflux-6x-scenario/pom.xml  | 117 +++++++++++++++++++++
 .../src/main/assembly/assembly.xml                 |  41 ++++++++
 .../apm/testcase/lettuce/Application.java          |  30 ++++++
 .../apm/testcase/lettuce/RedisClientConfig.java    |  37 +++++++
 .../controller/LettuceReactiveController.java      |  63 +++++++++++
 .../src/main/resources/application.properties      |  18 ++++
 .../support-version.list                           |   5 +-
 43 files changed, 1621 insertions(+), 68 deletions(-)

diff --git a/.github/workflows/plugins-jdk17-test.1.yaml 
b/.github/workflows/plugins-jdk17-test.1.yaml
index 0aa6266813..939393713b 100644
--- a/.github/workflows/plugins-jdk17-test.1.yaml
+++ b/.github/workflows/plugins-jdk17-test.1.yaml
@@ -80,6 +80,7 @@ jobs:
           - c3p0-0.9.2.x-0.10.x-scenario
           - spring-scheduled-6.x-scenario
           - caffeine-3.x-scenario
+          - lettuce-webflux-6x-scenario
     steps:
       - uses: actions/checkout@v2
         with:
diff --git a/.github/workflows/plugins-test.1.yaml 
b/.github/workflows/plugins-test.1.yaml
index 5b67f1d22d..21d5f04eab 100644
--- a/.github/workflows/plugins-test.1.yaml
+++ b/.github/workflows/plugins-test.1.yaml
@@ -88,6 +88,7 @@ jobs:
           - kotlin-coroutine-scenario
           - lettuce-scenario
           - lettuce-6.5.x-scenario
+          - lettuce-webflux-5x-scenario
           - mongodb-3.x-scenario
           - mongodb-4.x-scenario
           - netty-socketio-scenario
diff --git a/CHANGES.md b/CHANGES.md
index eaa28ff2c8..29acf896e1 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -5,7 +5,7 @@ Release Notes.
 9.7.0
 ------------------
 
-
+* Added support for Lettuce reactive Redis commands.
 
 All issues and pull requests are 
[here](https://github.com/apache/skywalking/milestone/249?closed=1)
 
diff --git 
a/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-5.x-6.4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/lettuce/v5/RedisReactiveCreatePublisherMethodInterceptorV5.java
 
b/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-5.x-6.4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/lettuce/v5/RedisReactiveCreatePublisherMethodInterceptorV5.java
new file mode 100644
index 0000000000..12ddea18f7
--- /dev/null
+++ 
b/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-5.x-6.4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/lettuce/v5/RedisReactiveCreatePublisherMethodInterceptorV5.java
@@ -0,0 +1,89 @@
+/*
+ * 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.skywalking.apm.plugin.lettuce.v5;
+
+import org.apache.skywalking.apm.agent.core.context.ContextManager;
+import org.apache.skywalking.apm.agent.core.context.ContextSnapshot;
+import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
+import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.v2.InstanceMethodsAroundInterceptorV2;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.v2.MethodInvocationContext;
+import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+import reactor.util.context.Context;
+
+import java.lang.reflect.Method;
+import java.util.function.Function;
+
+/**
+ * Intercepts reactive publisher factory methods (createMono/createFlux)
+ * to ensure the SkyWalking context snapshot is propagated via Reactor Context.
+ *
+ * <p>If the Reactor Context does not already contain a snapshot, this 
interceptor
+ * captures the current active context and writes it into the subscriber 
context
+ * as a fallback propagation mechanism.</p>
+ */
+public class RedisReactiveCreatePublisherMethodInterceptorV5 implements 
InstanceMethodsAroundInterceptorV2 {
+
+    private static final String SNAPSHOT_KEY = "SKYWALKING_CONTEXT_SNAPSHOT";
+
+    @Override
+    public void beforeMethod(EnhancedInstance objInst, Method method, Object[] 
allArguments, Class<?>[] argumentsTypes,
+                             MethodInvocationContext context) {
+    }
+
+    @Override
+    public Object afterMethod(EnhancedInstance objInst, Method method, 
Object[] allArguments, Class<?>[] argumentsTypes, Object ret, 
MethodInvocationContext context) {
+
+        if (!(ret instanceof Mono) && !(ret instanceof Flux)) {
+            return ret;
+        }
+        final AbstractSpan localSpan = 
ContextManager.createLocalSpan("Lettuce/Reactive/" + method.getName());
+        localSpan.setComponent(ComponentsDefine.LETTUCE);
+        SpanLayer.asCache(localSpan);
+
+        try {
+            final ContextSnapshot snapshot = ContextManager.capture();
+
+            Function<Context, Context> contextFunction = ctx -> {
+                if (ctx.hasKey(SNAPSHOT_KEY)) {
+                    return ctx;
+                }
+                return ctx.put(SNAPSHOT_KEY, snapshot);
+            };
+
+            if (ret instanceof Mono) {
+                Mono<?> original = (Mono<?>) ret;
+                return original.subscriberContext(contextFunction);
+            } else {
+                Flux<?> original = (Flux<?>) ret;
+                return original.subscriberContext(contextFunction);
+            }
+        } finally {
+            ContextManager.stopSpan();
+        }
+    }
+
+    @Override
+    public void handleMethodException(EnhancedInstance objInst, Method method, 
Object[] allArguments, Class<?>[]
+            argumentsTypes, Throwable t, MethodInvocationContext context) {
+    }
+}
diff --git 
a/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-5.x-6.4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/lettuce/v5/define/RedisReactiveCommandsInstrumentationV5.java
 
b/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-5.x-6.4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/lettuce/v5/define/RedisReactiveCommandsInstrumentationV5.java
new file mode 100644
index 0000000000..65716edd68
--- /dev/null
+++ 
b/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-5.x-6.4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/lettuce/v5/define/RedisReactiveCommandsInstrumentationV5.java
@@ -0,0 +1,89 @@
+/*
+ * 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.skywalking.apm.plugin.lettuce.v5.define;
+
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+import org.apache.skywalking.apm.agent.core.plugin.WitnessMethod;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.v2.ClassInstanceMethodsEnhancePluginDefineV2;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.v2.InstanceMethodsInterceptV2Point;
+import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
+
+import java.util.Collections;
+import java.util.List;
+
+import static net.bytebuddy.matcher.ElementMatchers.named;
+import static net.bytebuddy.matcher.ElementMatchers.namedOneOf;
+import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
+import static 
org.apache.skywalking.apm.agent.core.plugin.match.HierarchyMatch.byHierarchyMatch;
+
+/**
+ *
+ */
+public class RedisReactiveCommandsInstrumentationV5 extends 
ClassInstanceMethodsEnhancePluginDefineV2 {
+
+    private static final String ENHANCE_CLASS = 
"io.lettuce.core.AbstractRedisReactiveCommands";
+
+    private static final String REDIS_REACTIVE_CREATEMONO_METHOD_INTERCEPTOR = 
"org.apache.skywalking.apm.plugin.lettuce.v5.RedisReactiveCreatePublisherMethodInterceptorV5";
+
+    @Override
+    public InstanceMethodsInterceptV2Point[] 
getInstanceMethodsInterceptV2Points() {
+        return new InstanceMethodsInterceptV2Point[]{
+                new InstanceMethodsInterceptV2Point() {
+                    @Override
+                    public ElementMatcher<MethodDescription> 
getMethodsMatcher() {
+                        return namedOneOf(
+                                "createMono",
+                                "createFlux",
+                                "createDissolvingFlux"
+                        ).and(takesArguments(1));
+                    }
+
+                    @Override
+                    public String getMethodsInterceptorV2() {
+                        return REDIS_REACTIVE_CREATEMONO_METHOD_INTERCEPTOR;
+                    }
+
+                    @Override
+                    public boolean isOverrideArgs() {
+                        return false;
+                    }
+                }
+        };
+    }
+
+    @Override
+    public ClassMatch enhanceClass() {
+        return byHierarchyMatch(ENHANCE_CLASS);
+    }
+
+    @Override
+    public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
+        return new ConstructorInterceptPoint[0];
+    }
+
+    @Override
+    protected List<WitnessMethod> witnessMethods() {
+        return Collections.singletonList(new WitnessMethod(
+                "reactor.core.publisher.Mono",
+                named("subscriberContext")
+        ));
+    }
+}
diff --git 
a/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-5.x-6.4.x-plugin/src/main/resources/skywalking-plugin.def
 
b/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-5.x-6.4.x-plugin/src/main/resources/skywalking-plugin.def
index 1ff563829d..006ef23680 100644
--- 
a/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-5.x-6.4.x-plugin/src/main/resources/skywalking-plugin.def
+++ 
b/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-5.x-6.4.x-plugin/src/main/resources/skywalking-plugin.def
@@ -14,4 +14,5 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-lettuce-5.x-6.4.x=org.apache.skywalking.apm.plugin.lettuce.v5.define.RedisChannelWriterInstrumentationV5
\ No newline at end of file
+lettuce-5.x-6.4.x=org.apache.skywalking.apm.plugin.lettuce.v5.define.RedisChannelWriterInstrumentationV5
+lettuce-5.x-6.4.x=org.apache.skywalking.apm.plugin.lettuce.v5.define.RedisReactiveCommandsInstrumentationV5
\ No newline at end of file
diff --git 
a/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-6.5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/lettuce/v65/RedisReactiveCreatePublisherMethodInterceptorV65.java
 
b/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-6.5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/lettuce/v65/RedisReactiveCreatePublisherMethodInterceptorV65.java
new file mode 100644
index 0000000000..36320b5cd1
--- /dev/null
+++ 
b/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-6.5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/lettuce/v65/RedisReactiveCreatePublisherMethodInterceptorV65.java
@@ -0,0 +1,93 @@
+/*
+ * 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.skywalking.apm.plugin.lettuce.v65;
+
+import org.apache.skywalking.apm.agent.core.context.ContextManager;
+import org.apache.skywalking.apm.agent.core.context.ContextSnapshot;
+import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
+import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.v2.InstanceMethodsAroundInterceptorV2;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.v2.MethodInvocationContext;
+import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
+import org.reactivestreams.Publisher;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+import java.lang.reflect.Method;
+
+/**
+ * Intercepts reactive publisher factory methods (createMono/createFlux)
+ * to ensure the SkyWalking context snapshot is propagated via Reactor Context.
+ *
+ * <p>If the Reactor Context does not already contain a snapshot, this 
interceptor
+ * captures the current active context and writes it into the subscriber 
context
+ * as a fallback propagation mechanism.</p>
+ */
+public class RedisReactiveCreatePublisherMethodInterceptorV65 implements 
InstanceMethodsAroundInterceptorV2 {
+
+    private static final String SNAPSHOT_KEY = "SKYWALKING_CONTEXT_SNAPSHOT";
+
+    @Override
+    public void beforeMethod(EnhancedInstance objInst, Method method, Object[] 
allArguments, Class<?>[] argumentsTypes,
+                             MethodInvocationContext context) {
+    }
+
+    @Override
+    public Object afterMethod(EnhancedInstance objInst, Method method, 
Object[] allArguments, Class<?>[] argumentsTypes, Object ret, 
MethodInvocationContext context) {
+
+        if (!(ret instanceof Mono) && !(ret instanceof Flux)) {
+            return ret;
+        }
+
+        final AbstractSpan localSpan = 
ContextManager.createLocalSpan("Lettuce/Reactive/" + method.getName());
+        localSpan.setComponent(ComponentsDefine.LETTUCE);
+        SpanLayer.asCache(localSpan);
+
+        try {
+            final ContextSnapshot snapshot = ContextManager.capture();
+            
+            return wrapPublisher((Publisher<?>) ret, snapshot);
+        } finally {
+            ContextManager.stopSpan();
+        }
+    }
+
+    private <T> Publisher<T> wrapPublisher(Publisher<T> original, 
ContextSnapshot snapshot) {
+        if (original instanceof Mono) {
+            return Mono.deferContextual(ctxView -> {
+                if (ctxView.hasKey(SNAPSHOT_KEY)) {
+                    return (Mono<T>) original;
+                }
+                return ((Mono<T>) original).contextWrite(c -> 
c.put(SNAPSHOT_KEY, snapshot));
+            });
+        } else {
+            return Flux.deferContextual(ctxView -> {
+                if (ctxView.hasKey(SNAPSHOT_KEY)) {
+                    return original;
+                }
+                return ((Flux<T>) original).contextWrite(c -> 
c.put(SNAPSHOT_KEY, snapshot));
+            });
+        }
+    }
+
+    @Override
+    public void handleMethodException(EnhancedInstance objInst, Method method, 
Object[] allArguments, Class<?>[] argumentsTypes, Throwable t, 
MethodInvocationContext context) {
+    }
+}
diff --git 
a/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-6.5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/lettuce/v65/define/RedisReactiveCommandsInstrumentationV65.java
 
b/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-6.5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/lettuce/v65/define/RedisReactiveCommandsInstrumentationV65.java
new file mode 100644
index 0000000000..f1c22b88ee
--- /dev/null
+++ 
b/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-6.5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/lettuce/v65/define/RedisReactiveCommandsInstrumentationV65.java
@@ -0,0 +1,89 @@
+/*
+ * 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.skywalking.apm.plugin.lettuce.v65.define;
+
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+import net.bytebuddy.matcher.ElementMatchers;
+import org.apache.skywalking.apm.agent.core.plugin.WitnessMethod;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.v2.ClassInstanceMethodsEnhancePluginDefineV2;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.v2.InstanceMethodsInterceptV2Point;
+import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
+
+import java.util.Collections;
+import java.util.List;
+
+import static net.bytebuddy.matcher.ElementMatchers.namedOneOf;
+import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
+import static 
org.apache.skywalking.apm.agent.core.plugin.match.HierarchyMatch.byHierarchyMatch;
+
+/**
+ *
+ */
+public class RedisReactiveCommandsInstrumentationV65 extends 
ClassInstanceMethodsEnhancePluginDefineV2 {
+
+    private static final String ENHANCE_CLASS = 
"io.lettuce.core.AbstractRedisReactiveCommands";
+
+    private static final String REDIS_REACTIVE_CREATEMONO_METHOD_INTERCEPTOR = 
"org.apache.skywalking.apm.plugin.lettuce.v65.RedisReactiveCreatePublisherMethodInterceptorV65";
+
+    @Override
+    public InstanceMethodsInterceptV2Point[] 
getInstanceMethodsInterceptV2Points() {
+        return new InstanceMethodsInterceptV2Point[]{
+                new InstanceMethodsInterceptV2Point() {
+                    @Override
+                    public ElementMatcher<MethodDescription> 
getMethodsMatcher() {
+                        return namedOneOf(
+                                "createMono",
+                                "createFlux",
+                                "createDissolvingFlux"
+                        ).and(takesArguments(1));
+                    }
+
+                    @Override
+                    public String getMethodsInterceptorV2() {
+                        return REDIS_REACTIVE_CREATEMONO_METHOD_INTERCEPTOR;
+                    }
+
+                    @Override
+                    public boolean isOverrideArgs() {
+                        return false;
+                    }
+                }
+        };
+    }
+
+    @Override
+    public ClassMatch enhanceClass() {
+        return byHierarchyMatch(ENHANCE_CLASS);
+    }
+
+    @Override
+    public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
+        return new ConstructorInterceptPoint[0];
+    }
+
+    @Override
+    protected List<WitnessMethod> witnessMethods() {
+        return Collections.singletonList(new WitnessMethod(
+                "reactor.core.publisher.Mono",
+                ElementMatchers.named("deferContextual")
+        ));
+    }
+}
diff --git 
a/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-6.5.x-plugin/src/main/resources/skywalking-plugin.def
 
b/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-6.5.x-plugin/src/main/resources/skywalking-plugin.def
index a503891244..aac68f9479 100644
--- 
a/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-6.5.x-plugin/src/main/resources/skywalking-plugin.def
+++ 
b/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-6.5.x-plugin/src/main/resources/skywalking-plugin.def
@@ -14,4 +14,5 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-lettuce-6.5.x=org.apache.skywalking.apm.plugin.lettuce.v65.define.RedisChannelWriterInstrumentationV65
\ No newline at end of file
+lettuce-6.5.x=org.apache.skywalking.apm.plugin.lettuce.v65.define.RedisChannelWriterInstrumentationV65
+lettuce-6.5.x=org.apache.skywalking.apm.plugin.lettuce.v65.define.RedisReactiveCommandsInstrumentationV65
\ No newline at end of file
diff --git 
a/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-common/src/main/java/org/apache/skywalking/apm/plugin/lettuce/common/RedisChannelWriterInterceptor.java
 
b/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-common/src/main/java/org/apache/skywalking/apm/plugin/lettuce/common/RedisChannelWriterInterceptor.java
index f8b66f1349..9a94e186d8 100644
--- 
a/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-common/src/main/java/org/apache/skywalking/apm/plugin/lettuce/common/RedisChannelWriterInterceptor.java
+++ 
b/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-common/src/main/java/org/apache/skywalking/apm/plugin/lettuce/common/RedisChannelWriterInterceptor.java
@@ -57,12 +57,17 @@ public class RedisChannelWriterInterceptor implements 
InstanceMethodsAroundInter
         }
         EnhancedInstance enhancedCommand = (EnhancedInstance) 
spanCarrierCommand;
 
+        RedisCommandEnhanceInfo redisCommandEnhanceInfo = 
(RedisCommandEnhanceInfo) enhancedCommand.getSkyWalkingDynamicField();
+        
+        if (redisCommandEnhanceInfo == null) {
+            redisCommandEnhanceInfo = new RedisCommandEnhanceInfo();
+        }
+
         // command has been handle by another channel writer (cluster or 
sentinel case)
-        if (enhancedCommand.getSkyWalkingDynamicField() != null) {
+        if (redisCommandEnhanceInfo.getSpan() != null) {
             //set peer in last channel writer (delegate)
             if (peer != null) {
-                AbstractSpan span = (AbstractSpan) 
enhancedCommand.getSkyWalkingDynamicField();
-                span.setPeer(peer);
+                redisCommandEnhanceInfo.getSpan().setPeer(peer);
             }
             return;
         }
@@ -81,7 +86,16 @@ public class RedisChannelWriterInterceptor implements 
InstanceMethodsAroundInter
             operationName = operationName + "BATCH_WRITE";
             command = "BATCH_WRITE";
         }
+
+        if (redisCommandEnhanceInfo.getSnapshot() != null) {
+            AbstractSpan localSpan = 
ContextManager.createLocalSpan("RedisReactive/local");
+            localSpan.setComponent(ComponentsDefine.LETTUCE);
+            SpanLayer.asCache(localSpan);
+            ContextManager.continued(redisCommandEnhanceInfo.getSnapshot());
+        }
+        
         AbstractSpan span = ContextManager.createExitSpan(operationName, peer);
+        
         span.setComponent(ComponentsDefine.LETTUCE);
         Tags.CACHE_TYPE.set(span, "Redis");
         if (StringUtil.isNotEmpty(key)) {
@@ -92,7 +106,12 @@ public class RedisChannelWriterInterceptor implements 
InstanceMethodsAroundInter
         SpanLayer.asCache(span);
         span.prepareForAsync();
         ContextManager.stopSpan();
-        enhancedCommand.setSkyWalkingDynamicField(span);
+
+        if (redisCommandEnhanceInfo.getSnapshot() != null) {
+            ContextManager.stopSpan();
+        }
+        
+        
enhancedCommand.setSkyWalkingDynamicField(redisCommandEnhanceInfo.setSpan(span));
     }
 
     private String getArgsKey(RedisCommand<?, ?, ?> redisCommand) {
@@ -124,7 +143,7 @@ public class RedisChannelWriterInterceptor implements 
InstanceMethodsAroundInter
         RedisCommand<?, ?, ?> redisCommand = 
getSpanCarrierCommand(allArguments[0]);
         if (redisCommand instanceof EnhancedInstance && ((EnhancedInstance) 
redisCommand).getSkyWalkingDynamicField() != null) {
             EnhancedInstance enhancedRedisCommand = (EnhancedInstance) 
redisCommand;
-            AbstractSpan abstractSpan = (AbstractSpan) 
enhancedRedisCommand.getSkyWalkingDynamicField();
+            AbstractSpan abstractSpan = ((RedisCommandEnhanceInfo) 
enhancedRedisCommand.getSkyWalkingDynamicField()).getSpan();
             enhancedRedisCommand.setSkyWalkingDynamicField(null);
             abstractSpan.log(t);
             abstractSpan.asyncFinish();
diff --git 
a/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-common/src/main/java/org/apache/skywalking/apm/plugin/lettuce/common/RedisCommandCancelMethodInterceptor.java
 
b/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-common/src/main/java/org/apache/skywalking/apm/plugin/lettuce/common/RedisCommandCancelMethodInterceptor.java
index 7fb9f3c943..82f4d6e55d 100644
--- 
a/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-common/src/main/java/org/apache/skywalking/apm/plugin/lettuce/common/RedisCommandCancelMethodInterceptor.java
+++ 
b/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-common/src/main/java/org/apache/skywalking/apm/plugin/lettuce/common/RedisCommandCancelMethodInterceptor.java
@@ -37,7 +37,7 @@ public class RedisCommandCancelMethodInterceptor implements 
InstanceMethodsAroun
     @Override
     public Object afterMethod(EnhancedInstance objInst, Method method, 
Object[] allArguments, Class<?>[] argumentsTypes, Object ret) {
         if (objInst.getSkyWalkingDynamicField() != null) {
-            AbstractSpan span = (AbstractSpan) 
objInst.getSkyWalkingDynamicField();
+            AbstractSpan span = ((RedisCommandEnhanceInfo) 
objInst.getSkyWalkingDynamicField()).getSpan();
             span.errorOccurred();
             span.tag(new StringTag(CANCEL_SIGNAL_TAG), COMMAND_CANCEL_VALUE);
             span.asyncFinish();
@@ -49,7 +49,7 @@ public class RedisCommandCancelMethodInterceptor implements 
InstanceMethodsAroun
     @Override
     public void handleMethodException(EnhancedInstance objInst, Method method, 
Object[] allArguments, Class<?>[] argumentsTypes, Throwable t) {
         if (objInst.getSkyWalkingDynamicField() != null) {
-            AbstractSpan span = (AbstractSpan) 
objInst.getSkyWalkingDynamicField();
+            AbstractSpan span = ((RedisCommandEnhanceInfo) 
objInst.getSkyWalkingDynamicField()).getSpan();
             span.log(t);
         }
     }
diff --git 
a/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-common/src/main/java/org/apache/skywalking/apm/plugin/lettuce/common/RedisCommandCompleteExceptionallyMethodInterceptor.java
 
b/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-common/src/main/java/org/apache/skywalking/apm/plugin/lettuce/common/RedisCommandCompleteExceptionallyMethodInterceptor.java
index bdde0712df..022c2622ee 100644
--- 
a/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-common/src/main/java/org/apache/skywalking/apm/plugin/lettuce/common/RedisCommandCompleteExceptionallyMethodInterceptor.java
+++ 
b/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-common/src/main/java/org/apache/skywalking/apm/plugin/lettuce/common/RedisCommandCompleteExceptionallyMethodInterceptor.java
@@ -35,7 +35,7 @@ public class 
RedisCommandCompleteExceptionallyMethodInterceptor implements Insta
     public Object afterMethod(EnhancedInstance objInst, Method method, 
Object[] allArguments, Class<?>[] argumentsTypes, Object ret) {
         if (objInst.getSkyWalkingDynamicField() != null) {
             Throwable t = (Throwable) allArguments[0];
-            AbstractSpan span = (AbstractSpan) 
objInst.getSkyWalkingDynamicField();
+            AbstractSpan span = ((RedisCommandEnhanceInfo) 
objInst.getSkyWalkingDynamicField()).getSpan();
             span.log(t);
             span.asyncFinish();
             objInst.setSkyWalkingDynamicField(null);
@@ -46,7 +46,7 @@ public class 
RedisCommandCompleteExceptionallyMethodInterceptor implements Insta
     @Override
     public void handleMethodException(EnhancedInstance objInst, Method method, 
Object[] allArguments, Class<?>[] argumentsTypes, Throwable t) {
         if (objInst.getSkyWalkingDynamicField() != null) {
-            AbstractSpan span = (AbstractSpan) 
objInst.getSkyWalkingDynamicField();
+            AbstractSpan span = ((RedisCommandEnhanceInfo) 
objInst.getSkyWalkingDynamicField()).getSpan();
             span.log(t);
         }
     }
diff --git 
a/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-common/src/main/java/org/apache/skywalking/apm/plugin/lettuce/common/RedisCommandCompleteMethodInterceptor.java
 
b/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-common/src/main/java/org/apache/skywalking/apm/plugin/lettuce/common/RedisCommandCompleteMethodInterceptor.java
index d2ede33ba7..725f2742bd 100644
--- 
a/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-common/src/main/java/org/apache/skywalking/apm/plugin/lettuce/common/RedisCommandCompleteMethodInterceptor.java
+++ 
b/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-common/src/main/java/org/apache/skywalking/apm/plugin/lettuce/common/RedisCommandCompleteMethodInterceptor.java
@@ -34,7 +34,7 @@ public class RedisCommandCompleteMethodInterceptor implements 
InstanceMethodsAro
     @Override
     public Object afterMethod(EnhancedInstance objInst, Method method, 
Object[] allArguments, Class<?>[] argumentsTypes, Object ret) {
         if (objInst.getSkyWalkingDynamicField() != null) {
-            AbstractSpan span = (AbstractSpan) 
objInst.getSkyWalkingDynamicField();
+            AbstractSpan span = ((RedisCommandEnhanceInfo) 
objInst.getSkyWalkingDynamicField()).getSpan();
             span.asyncFinish();
             objInst.setSkyWalkingDynamicField(null);
         }
@@ -45,7 +45,7 @@ public class RedisCommandCompleteMethodInterceptor implements 
InstanceMethodsAro
     public void handleMethodException(EnhancedInstance objInst, Method method, 
Object[] allArguments,
                                       Class<?>[] argumentsTypes, Throwable t) {
         if (objInst.getSkyWalkingDynamicField() != null) {
-            AbstractSpan span = (AbstractSpan) 
objInst.getSkyWalkingDynamicField();
+            AbstractSpan span = ((RedisCommandEnhanceInfo) 
objInst.getSkyWalkingDynamicField()).getSpan();
             span.log(t);
         }
     }
diff --git 
a/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-common/src/main/java/org/apache/skywalking/apm/plugin/lettuce/common/RedisCommandEnhanceInfo.java
 
b/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-common/src/main/java/org/apache/skywalking/apm/plugin/lettuce/common/RedisCommandEnhanceInfo.java
new file mode 100644
index 0000000000..942d5e18f4
--- /dev/null
+++ 
b/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-common/src/main/java/org/apache/skywalking/apm/plugin/lettuce/common/RedisCommandEnhanceInfo.java
@@ -0,0 +1,59 @@
+/*
+ * 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.skywalking.apm.plugin.lettuce.common;
+
+import org.apache.skywalking.apm.agent.core.context.ContextSnapshot;
+import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
+
+/**
+ * RedisCommandEnhanceInfo holds SkyWalking tracing data for Lettuce commands
+ * executed in different asynchronous models.
+ *
+ * <p>The {@link AbstractSpan} is used for non-reactive (blocking) commands
+ * that are executed asynchronously, where the span needs to be created
+ * at command submission time and finished when the command completes.</p>
+ *
+ * <p>The {@link ContextSnapshot} is used for reactive commands, where the
+ * tracing context is captured from Reactor {@code Context} and later
+ * continued at subscription or execution time to bridge reactive
+ * boundaries.</p>
+ */
+class RedisCommandEnhanceInfo {
+    
+    private AbstractSpan span;
+    private ContextSnapshot snapshot;
+
+    public AbstractSpan getSpan() {
+        return span;
+    }
+
+    public RedisCommandEnhanceInfo setSpan(AbstractSpan span) {
+        this.span = span;
+        return this;
+    }
+
+    public ContextSnapshot getSnapshot() {
+        return snapshot;
+    }
+
+    public RedisCommandEnhanceInfo setSnapshot(ContextSnapshot snapshot) {
+        this.snapshot = snapshot;
+        return this;
+    }
+}
diff --git 
a/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-common/src/main/java/org/apache/skywalking/apm/plugin/lettuce/common/RedisSubscriptionConstructorInterceptor.java
 
b/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-common/src/main/java/org/apache/skywalking/apm/plugin/lettuce/common/RedisSubscriptionConstructorInterceptor.java
new file mode 100644
index 0000000000..7c79ebde93
--- /dev/null
+++ 
b/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-common/src/main/java/org/apache/skywalking/apm/plugin/lettuce/common/RedisSubscriptionConstructorInterceptor.java
@@ -0,0 +1,39 @@
+/*
+ * 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.skywalking.apm.plugin.lettuce.common;
+
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor;
+
+/**
+ * Interceptor for RedisSubscription constructor.
+ * <p>
+ * This interceptor captures the {@link io.lettuce.core.protocol.RedisCommand} 
instance
+ * at subscription construction time and stores it into SkyWalking dynamic 
field.
+ * </p>
+ */
+public class RedisSubscriptionConstructorInterceptor implements 
InstanceConstructorInterceptor {
+
+    @Override
+    public void onConstruct(EnhancedInstance objInst, Object[] allArguments) {
+        // allArguments[1] is the RedisCommand passed to the RedisSubscription 
constructor
+        objInst.setSkyWalkingDynamicField(allArguments[1]);
+    }
+
+}
diff --git 
a/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-common/src/main/java/org/apache/skywalking/apm/plugin/lettuce/common/RedisCommandCancelMethodInterceptor.java
 
b/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-common/src/main/java/org/apache/skywalking/apm/plugin/lettuce/common/RedisSubscriptionSubscribeMethodInterceptor.java
similarity index 53%
copy from 
apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-common/src/main/java/org/apache/skywalking/apm/plugin/lettuce/common/RedisCommandCancelMethodInterceptor.java
copy to 
apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-common/src/main/java/org/apache/skywalking/apm/plugin/lettuce/common/RedisSubscriptionSubscribeMethodInterceptor.java
index 7fb9f3c943..0ea108a247 100644
--- 
a/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-common/src/main/java/org/apache/skywalking/apm/plugin/lettuce/common/RedisCommandCancelMethodInterceptor.java
+++ 
b/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-common/src/main/java/org/apache/skywalking/apm/plugin/lettuce/common/RedisSubscriptionSubscribeMethodInterceptor.java
@@ -18,39 +18,44 @@
 
 package org.apache.skywalking.apm.plugin.lettuce.common;
 
-import org.apache.skywalking.apm.agent.core.context.tag.StringTag;
-import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
+import org.apache.skywalking.apm.agent.core.context.ContextSnapshot;
 import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
-import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.v2.InstanceMethodsAroundInterceptorV2;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.v2.MethodInvocationContext;
+import reactor.core.CoreSubscriber;
 
 import java.lang.reflect.Method;
 
-public class RedisCommandCancelMethodInterceptor implements 
InstanceMethodsAroundInterceptor {
-    private static final String CANCEL_SIGNAL_TAG = "signalType";
-    private static final String COMMAND_CANCEL_VALUE = "cancel";
+/**
+ * Interceptor for {@code 
RedisPublisher.RedisSubscription#subscribe(Subscriber)} method.
+ *
+ * <p>
+ * This interceptor works together with the constructor interceptor of
+ * {@code RedisSubscription}:
+ * </p>
+ */
+public class RedisSubscriptionSubscribeMethodInterceptor implements 
InstanceMethodsAroundInterceptorV2 {
 
     @Override
-    public void beforeMethod(EnhancedInstance objInst, Method method, Object[] 
allArguments, Class<?>[] argumentsTypes, MethodInterceptResult result) {
+    public void beforeMethod(EnhancedInstance objInst, Method method, Object[] 
allArguments, Class<?>[] argumentsTypes, MethodInvocationContext context) {
+        if (allArguments[0] instanceof CoreSubscriber) {
+            CoreSubscriber<?> subscriber = (CoreSubscriber<?>) allArguments[0];
+            // get ContextSnapshot from reactor context,  the snapshot is set 
to reactor context by any other plugin
+            // such as DispatcherHandlerHandleMethodInterceptor in 
spring-webflux-5.x-plugin
+            Object skywalkingContextSnapshot = 
subscriber.currentContext().getOrDefault("SKYWALKING_CONTEXT_SNAPSHOT", null);
+            if (skywalkingContextSnapshot != null) {
+                ((EnhancedInstance) 
objInst.getSkyWalkingDynamicField()).setSkyWalkingDynamicField(new 
RedisCommandEnhanceInfo()
+                        .setSnapshot((ContextSnapshot) 
skywalkingContextSnapshot));
+            }
+        }
     }
 
     @Override
-    public Object afterMethod(EnhancedInstance objInst, Method method, 
Object[] allArguments, Class<?>[] argumentsTypes, Object ret) {
-        if (objInst.getSkyWalkingDynamicField() != null) {
-            AbstractSpan span = (AbstractSpan) 
objInst.getSkyWalkingDynamicField();
-            span.errorOccurred();
-            span.tag(new StringTag(CANCEL_SIGNAL_TAG), COMMAND_CANCEL_VALUE);
-            span.asyncFinish();
-            objInst.setSkyWalkingDynamicField(null);
-        }
+    public Object afterMethod(EnhancedInstance objInst, Method method, 
Object[] allArguments, Class<?>[] argumentsTypes, Object ret, 
MethodInvocationContext context) {
         return ret;
     }
 
     @Override
-    public void handleMethodException(EnhancedInstance objInst, Method method, 
Object[] allArguments, Class<?>[] argumentsTypes, Throwable t) {
-        if (objInst.getSkyWalkingDynamicField() != null) {
-            AbstractSpan span = (AbstractSpan) 
objInst.getSkyWalkingDynamicField();
-            span.log(t);
-        }
+    public void handleMethodException(EnhancedInstance objInst, Method method, 
Object[] allArguments, Class<?>[] argumentsTypes, Throwable t, 
MethodInvocationContext context) {
     }
 }
diff --git 
a/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-common/src/main/java/org/apache/skywalking/apm/plugin/lettuce/common/define/RedisSubscriptionInstrumentation.java
 
b/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-common/src/main/java/org/apache/skywalking/apm/plugin/lettuce/common/define/RedisSubscriptionInstrumentation.java
new file mode 100644
index 0000000000..7e7ccc7632
--- /dev/null
+++ 
b/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-common/src/main/java/org/apache/skywalking/apm/plugin/lettuce/common/define/RedisSubscriptionInstrumentation.java
@@ -0,0 +1,86 @@
+/*
+ * 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.skywalking.apm.plugin.lettuce.common.define;
+
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.v2.ClassInstanceMethodsEnhancePluginDefineV2;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.v2.InstanceMethodsInterceptV2Point;
+import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
+
+import static net.bytebuddy.matcher.ElementMatchers.any;
+import static net.bytebuddy.matcher.ElementMatchers.named;
+import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
+import static 
org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
+
+/**
+ * 
+ */
+public class RedisSubscriptionInstrumentation extends 
ClassInstanceMethodsEnhancePluginDefineV2 {
+
+    private static final String ENHANCE_CLASS = 
"io.lettuce.core.RedisPublisher$RedisSubscription";
+    
+    private static final String 
REDIS_SUBSCRIPTION_SUBSCRIBE_METHOD_INTERCEPTOR = 
"org.apache.skywalking.apm.plugin.lettuce.common.RedisSubscriptionSubscribeMethodInterceptor";
+    private static final String REDIS_SUBSCRIPTION_CONST_METHOD_INTERCEPTOR = 
"org.apache.skywalking.apm.plugin.lettuce.common.RedisSubscriptionConstructorInterceptor";
+
+    @Override
+    public InstanceMethodsInterceptV2Point[] 
getInstanceMethodsInterceptV2Points() {
+        return new InstanceMethodsInterceptV2Point[]{
+                new InstanceMethodsInterceptV2Point() {
+                    @Override
+                    public ElementMatcher<MethodDescription> 
getMethodsMatcher() {
+                        return named("subscribe");
+                    }
+
+                    @Override
+                    public String getMethodsInterceptorV2() {
+                        return REDIS_SUBSCRIPTION_SUBSCRIBE_METHOD_INTERCEPTOR;
+                    }
+
+                    @Override
+                    public boolean isOverrideArgs() {
+                        return false;
+                    }
+                }
+        };
+    }
+
+    @Override
+    public ClassMatch enhanceClass() {
+        return byName(ENHANCE_CLASS);
+    }
+
+    @Override
+    public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
+        return new ConstructorInterceptPoint[] {
+                new ConstructorInterceptPoint() {
+                    @Override
+                    public ElementMatcher<MethodDescription> 
getConstructorMatcher() {
+                        return any().and(takesArgument(1, 
named("io.lettuce.core.protocol.RedisCommand")));
+                    }
+
+                    @Override
+                    public String getConstructorInterceptor() {
+                        return REDIS_SUBSCRIPTION_CONST_METHOD_INTERCEPTOR;
+                    }
+                }
+        };
+    }
+}
diff --git 
a/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-common/src/main/resources/skywalking-plugin.def
 
b/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-common/src/main/resources/skywalking-plugin.def
index e0521938a7..e17d02461c 100644
--- 
a/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-common/src/main/resources/skywalking-plugin.def
+++ 
b/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-common/src/main/resources/skywalking-plugin.def
@@ -15,4 +15,5 @@
 # limitations under the License.
 
 
lettuce-common=org.apache.skywalking.apm.plugin.lettuce.common.define.DefaultEndpointInstrumentation
-lettuce-common=org.apache.skywalking.apm.plugin.lettuce.common.define.RedisCommandInstrumentation
\ No newline at end of file
+lettuce-common=org.apache.skywalking.apm.plugin.lettuce.common.define.RedisCommandInstrumentation
+lettuce-common=org.apache.skywalking.apm.plugin.lettuce.common.define.RedisSubscriptionInstrumentation
\ No newline at end of file
diff --git 
a/test/plugin/scenarios/lettuce-6.5.x-scenario/config/expectedData.yaml 
b/test/plugin/scenarios/lettuce-6.5.x-scenario/config/expectedData.yaml
index 2a938caea9..dbeb6b6138 100644
--- a/test/plugin/scenarios/lettuce-6.5.x-scenario/config/expectedData.yaml
+++ b/test/plugin/scenarios/lettuce-6.5.x-scenario/config/expectedData.yaml
@@ -34,6 +34,60 @@ segmentItems:
               - {key: url, value: 
'http://localhost:8080/lettuce-6.5.x-scenario/case/healthCheck'}
               - {key: http.method, value: HEAD}
               - {key: http.status_code, value: '200'}
+      - segmentId: not null
+        spans:
+          - operationName: Lettuce/SET
+            parentSpanId: 0
+            spanId: 1
+            spanLayer: Cache
+            startTime: not null
+            endTime: not null
+            componentId: 57
+            isError: false
+            spanType: Exit
+            peer: not null
+            skipAnalysis: false
+            tags:
+              - { key: cache.type, value: Redis }
+              - { key: cache.key, value: key0 }
+              - { key: cache.cmd, value: SET }
+              - { key: cache.op, value: write }
+          - operationName: RedisReactive/local
+            parentSpanId: -1
+            spanId: 0
+            isError: false
+            spanType: Local
+            refs:
+              - { parentEndpoint: 
GET:/lettuce-6.5.x-scenario/case/lettuce-case, networkAddress: '', refType: 
CrossThread,
+                parentSpanId: 5, parentTraceSegmentId: not null, 
parentServiceInstance: not
+                    null, parentService: not null, traceId: not null }
+      - segmentId: not null
+        spans:
+          - operationName: Lettuce/SET
+            parentSpanId: 0
+            spanId: 1
+            spanLayer: Cache
+            startTime: not null
+            endTime: not null
+            componentId: 57
+            isError: false
+            spanType: Exit
+            peer: not null
+            skipAnalysis: false
+            tags:
+              - { key: cache.type, value: Redis }
+              - { key: cache.key, value: key1 }
+              - { key: cache.cmd, value: SET }
+              - { key: cache.op, value: write }
+          - operationName: RedisReactive/local
+            parentSpanId: -1
+            spanId: 0
+            isError: false
+            spanType: Local
+            refs:
+              - { parentEndpoint: 
GET:/lettuce-6.5.x-scenario/case/lettuce-case, networkAddress: '', refType: 
CrossThread,
+                parentSpanId: 6, parentTraceSegmentId: not null, 
parentServiceInstance: not
+                    null, parentService: not null, traceId: not null }
       - segmentId: not null
         spans:
           - operationName: Lettuce/GET
@@ -84,6 +138,57 @@ segmentItems:
               - { key: cache.key, value: key1 }
               - { key: cache.cmd, value: SET }
               - { key: cache.op, value: write }
+          - operationName: Lettuce/Reactive/createMono
+            parentSpanId: 0
+            spanId: 4
+            spanLayer: Cache
+            startTime: not null
+            endTime: not null
+            componentId: 57
+            isError: false
+            spanType: Local
+            skipAnalysis: false
+          - operationName: Lettuce/Reactive/createMono
+            parentSpanId: 0
+            spanId: 5
+            spanLayer: Cache
+            startTime: not null
+            endTime: not null
+            componentId: 57
+            isError: false
+            spanType: Local
+            skipAnalysis: false
+          - operationName: Lettuce/Reactive/createMono
+            parentSpanId: 0
+            spanId: 6
+            spanLayer: Cache
+            startTime: not null
+            endTime: not null
+            componentId: 57
+            isError: false
+            spanType: Local
+            skipAnalysis: false
+          - operationName: Lettuce/GET
+            parentSpanId: 7
+            spanId: 8
+            spanLayer: Cache
+            startTime: not null
+            endTime: not null
+            componentId: 57
+            isError: false
+            spanType: Exit
+            peer: not null
+            skipAnalysis: false
+            tags:
+              - { key: cache.type, value: Redis }
+              - { key: cache.key, value: key }
+              - { key: cache.cmd, value: GET }
+              - { key: cache.op, value: read }
+          - operationName: RedisReactive/local
+            parentSpanId: 0
+            spanId: 7
+            isError: false
+            spanType: Local
           - operationName: GET:/lettuce-6.5.x-scenario/case/lettuce-case
             parentSpanId: -1
             spanId: 0
diff --git 
a/test/plugin/scenarios/lettuce-6.5.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/lettuce/controller/LettuceController.java
 
b/test/plugin/scenarios/lettuce-6.5.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/lettuce/controller/LettuceController.java
index c2f391b07c..d2cc201025 100644
--- 
a/test/plugin/scenarios/lettuce-6.5.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/lettuce/controller/LettuceController.java
+++ 
b/test/plugin/scenarios/lettuce-6.5.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/lettuce/controller/LettuceController.java
@@ -23,6 +23,7 @@ import io.lettuce.core.RedisClient;
 import io.lettuce.core.RedisFuture;
 import io.lettuce.core.api.StatefulRedisConnection;
 import io.lettuce.core.api.async.RedisAsyncCommands;
+import io.lettuce.core.api.reactive.RedisReactiveCommands;
 import io.lettuce.core.api.sync.RedisCommands;
 import java.util.ArrayList;
 import java.util.List;
@@ -32,6 +33,8 @@ import org.springframework.context.annotation.PropertySource;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.ResponseBody;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
 
 @Controller
 @RequestMapping("/case")
@@ -58,8 +61,21 @@ public class LettuceController {
         asyncCommands.flushCommands();
         LettuceFutures.awaitAll(5, TimeUnit.SECONDS, futures.toArray(new 
RedisFuture[futures.size()]));
 
+        StatefulRedisConnection<String, String> connection2 = 
redisClient.connect();
+        RedisReactiveCommands<String, String> reactiveCommands = 
connection2.reactive();
+
+        Mono<String> result = reactiveCommands.get("key")
+                .then(Flux.concat(
+                        reactiveCommands.set("key0", "value0"),
+                        reactiveCommands.set("key1", "value1")
+                ).then())
+                .thenReturn("Success");
+
+        result.block();
+        
         connection0.close();
         connection1.close();
+        connection2.close();
         redisClient.shutdown();
         return "Success";
     }
diff --git a/test/plugin/scenarios/lettuce-scenario/config/expectedData.yaml 
b/test/plugin/scenarios/lettuce-scenario/config/expectedData.yaml
index 43db792872..884191cfe3 100644
--- a/test/plugin/scenarios/lettuce-scenario/config/expectedData.yaml
+++ b/test/plugin/scenarios/lettuce-scenario/config/expectedData.yaml
@@ -34,6 +34,60 @@ segmentItems:
               - {key: url, value: 
'http://localhost:8080/lettuce-scenario/case/healthCheck'}
               - {key: http.method, value: HEAD}
               - {key: http.status_code, value: '200'}
+      - segmentId: not null
+        spans:
+          - operationName: Lettuce/SET
+            parentSpanId: 0
+            spanId: 1
+            spanLayer: Cache
+            startTime: not null
+            endTime: not null
+            componentId: 57
+            isError: false
+            spanType: Exit
+            peer: not null
+            skipAnalysis: false
+            tags:
+              - { key: cache.type, value: Redis }
+              - { key: cache.key, value: key0 }
+              - { key: cache.cmd, value: SET }
+              - { key: cache.op, value: write }
+          - operationName: RedisReactive/local
+            parentSpanId: -1
+            spanId: 0
+            isError: false
+            spanType: Local
+            refs:
+              - { parentEndpoint: GET:/lettuce-scenario/case/lettuce-case, 
networkAddress: '', refType: CrossThread,
+                parentSpanId: 5, parentTraceSegmentId: not null, 
parentServiceInstance: not
+                    null, parentService: not null, traceId: not null }
+      - segmentId: not null
+        spans:
+          - operationName: Lettuce/SET
+            parentSpanId: 0
+            spanId: 1
+            spanLayer: Cache
+            startTime: not null
+            endTime: not null
+            componentId: 57
+            isError: false
+            spanType: Exit
+            peer: not null
+            skipAnalysis: false
+            tags:
+              - { key: cache.type, value: Redis }
+              - { key: cache.key, value: key1 }
+              - { key: cache.cmd, value: SET }
+              - { key: cache.op, value: write }
+          - operationName: RedisReactive/local
+            parentSpanId: -1
+            spanId: 0
+            isError: false
+            spanType: Local
+            refs:
+              - { parentEndpoint: GET:/lettuce-scenario/case/lettuce-case, 
networkAddress: '', refType: CrossThread,
+                parentSpanId: 6, parentTraceSegmentId: not null, 
parentServiceInstance: not
+                    null, parentService: not null, traceId: not null }
       - segmentId: not null
         spans:
           - operationName: Lettuce/GET
@@ -84,6 +138,57 @@ segmentItems:
               - { key: cache.key, value: key1 }
               - { key: cache.cmd, value: SET }
               - { key: cache.op, value: write }
+          - operationName: Lettuce/Reactive/createMono
+            parentSpanId: 0
+            spanId: 4
+            spanLayer: Cache
+            startTime: not null
+            endTime: not null
+            componentId: 57
+            isError: false
+            spanType: Local
+            skipAnalysis: false
+          - operationName: Lettuce/Reactive/createMono
+            parentSpanId: 0
+            spanId: 5
+            spanLayer: Cache
+            startTime: not null
+            endTime: not null
+            componentId: 57
+            isError: false
+            spanType: Local
+            skipAnalysis: false
+          - operationName: Lettuce/Reactive/createMono
+            parentSpanId: 0
+            spanId: 6
+            spanLayer: Cache
+            startTime: not null
+            endTime: not null
+            componentId: 57
+            isError: false
+            spanType: Local
+            skipAnalysis: false
+          - operationName: Lettuce/GET
+            parentSpanId: 7
+            spanId: 8
+            spanLayer: Cache
+            startTime: not null
+            endTime: not null
+            componentId: 57
+            isError: false
+            spanType: Exit
+            peer: not null
+            skipAnalysis: false
+            tags:
+              - { key: cache.type, value: Redis }
+              - { key: cache.key, value: key }
+              - { key: cache.cmd, value: GET }
+              - { key: cache.op, value: read }
+          - operationName: RedisReactive/local
+            parentSpanId: 0
+            spanId: 7
+            isError: false
+            spanType: Local
           - operationName: GET:/lettuce-scenario/case/lettuce-case
             parentSpanId: -1
             spanId: 0
diff --git 
a/test/plugin/scenarios/lettuce-scenario/src/main/java/org/apache/skywalking/apm/testcase/lettuce/controller/LettuceController.java
 
b/test/plugin/scenarios/lettuce-scenario/src/main/java/org/apache/skywalking/apm/testcase/lettuce/controller/LettuceController.java
index c2f391b07c..d2cc201025 100644
--- 
a/test/plugin/scenarios/lettuce-scenario/src/main/java/org/apache/skywalking/apm/testcase/lettuce/controller/LettuceController.java
+++ 
b/test/plugin/scenarios/lettuce-scenario/src/main/java/org/apache/skywalking/apm/testcase/lettuce/controller/LettuceController.java
@@ -23,6 +23,7 @@ import io.lettuce.core.RedisClient;
 import io.lettuce.core.RedisFuture;
 import io.lettuce.core.api.StatefulRedisConnection;
 import io.lettuce.core.api.async.RedisAsyncCommands;
+import io.lettuce.core.api.reactive.RedisReactiveCommands;
 import io.lettuce.core.api.sync.RedisCommands;
 import java.util.ArrayList;
 import java.util.List;
@@ -32,6 +33,8 @@ import org.springframework.context.annotation.PropertySource;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.ResponseBody;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
 
 @Controller
 @RequestMapping("/case")
@@ -58,8 +61,21 @@ public class LettuceController {
         asyncCommands.flushCommands();
         LettuceFutures.awaitAll(5, TimeUnit.SECONDS, futures.toArray(new 
RedisFuture[futures.size()]));
 
+        StatefulRedisConnection<String, String> connection2 = 
redisClient.connect();
+        RedisReactiveCommands<String, String> reactiveCommands = 
connection2.reactive();
+
+        Mono<String> result = reactiveCommands.get("key")
+                .then(Flux.concat(
+                        reactiveCommands.set("key0", "value0"),
+                        reactiveCommands.set("key1", "value1")
+                ).then())
+                .thenReturn("Success");
+
+        result.block();
+        
         connection0.close();
         connection1.close();
+        connection2.close();
         redisClient.shutdown();
         return "Success";
     }
diff --git 
a/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-6.5.x-plugin/src/main/resources/skywalking-plugin.def
 b/test/plugin/scenarios/lettuce-webflux-5x-scenario/bin/startup.sh
similarity index 79%
copy from 
apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-6.5.x-plugin/src/main/resources/skywalking-plugin.def
copy to test/plugin/scenarios/lettuce-webflux-5x-scenario/bin/startup.sh
index a503891244..d719f14162 100644
--- 
a/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-6.5.x-plugin/src/main/resources/skywalking-plugin.def
+++ b/test/plugin/scenarios/lettuce-webflux-5x-scenario/bin/startup.sh
@@ -1,3 +1,5 @@
+#!/bin/bash
+#
 # 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
@@ -14,4 +16,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-lettuce-6.5.x=org.apache.skywalking.apm.plugin.lettuce.v65.define.RedisChannelWriterInstrumentationV65
\ No newline at end of file
+home="$(cd "$(dirname $0)"; pwd)"
+
+java -Dredis.host=${REDIS_SERVERS} -jar 
-Dskywalking.plugin.lettuce.trace_redis_parameters=true ${agent_opts} 
${home}/../libs/lettuce-webflux-5x-scenario.jar &
\ No newline at end of file
diff --git 
a/test/plugin/scenarios/lettuce-6.5.x-scenario/config/expectedData.yaml 
b/test/plugin/scenarios/lettuce-webflux-5x-scenario/config/expectedData.yaml
similarity index 63%
copy from test/plugin/scenarios/lettuce-6.5.x-scenario/config/expectedData.yaml
copy to 
test/plugin/scenarios/lettuce-webflux-5x-scenario/config/expectedData.yaml
index 2a938caea9..cdc04a6242 100644
--- a/test/plugin/scenarios/lettuce-6.5.x-scenario/config/expectedData.yaml
+++ b/test/plugin/scenarios/lettuce-webflux-5x-scenario/config/expectedData.yaml
@@ -14,24 +14,24 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 segmentItems:
-  - serviceName: lettuce-6.5.x-scenario
+  - serviceName: lettuce-webflux-5x-scenario
     segmentSize: nq 0
     segments:
       - segmentId: not null
         spans:
-          - operationName: HEAD:/lettuce-6.5.x-scenario/case/healthCheck
+          - operationName: /case/healthCheck
             parentSpanId: -1
             spanId: 0
             spanLayer: Http
             startTime: not null
             endTime: not null
-            componentId: 1
+            componentId: 67
             isError: false
             spanType: Entry
             peer: ''
             skipAnalysis: false
             tags:
-              - {key: url, value: 
'http://localhost:8080/lettuce-6.5.x-scenario/case/healthCheck'}
+              - {key: url, value: 'http://localhost:8080/case/healthCheck'}
               - {key: http.method, value: HEAD}
               - {key: http.status_code, value: '200'}
       - segmentId: not null
@@ -52,9 +52,20 @@ segmentItems:
               - {key: cache.key, value: key}
               - {key: cache.cmd, value: GET}
               - {key: cache.op, value: read}
+          - operationName: RedisReactive/local
+            parentSpanId: -1
+            spanId: 0
+            isError: false
+            spanType: Local
+            refs:
+              - { parentEndpoint: /case/lettuce-case, networkAddress: '', 
refType: CrossThread,
+                parentSpanId: 0, parentTraceSegmentId: not null, 
parentServiceInstance: not
+                    null, parentService: not null, traceId: not null }
+      - segmentId: not null
+        spans:        
           - operationName: Lettuce/SET
             parentSpanId: 0
-            spanId: 2
+            spanId: 1
             spanLayer: Cache
             startTime: not null
             endTime: not null
@@ -68,9 +79,20 @@ segmentItems:
               - { key: cache.key, value: key0 }
               - { key: cache.cmd, value: SET }
               - { key: cache.op, value: write }
+          - operationName: RedisReactive/local
+            parentSpanId: -1
+            spanId: 0
+            isError: false
+            spanType: Local
+            refs:
+              - { parentEndpoint: /case/lettuce-case, networkAddress: '', 
refType: CrossThread,
+                parentSpanId: 0, parentTraceSegmentId: not null, 
parentServiceInstance: not
+                    null, parentService: not null, traceId: not null }
+      - segmentId: not null
+        spans:    
           - operationName: Lettuce/SET
             parentSpanId: 0
-            spanId: 3
+            spanId: 1
             spanLayer: Cache
             startTime: not null
             endTime: not null
@@ -84,18 +106,29 @@ segmentItems:
               - { key: cache.key, value: key1 }
               - { key: cache.cmd, value: SET }
               - { key: cache.op, value: write }
-          - operationName: GET:/lettuce-6.5.x-scenario/case/lettuce-case
+          - operationName: RedisReactive/local
+            parentSpanId: -1
+            spanId: 0
+            isError: false
+            spanType: Local
+            refs:
+              - { parentEndpoint: /case/lettuce-case, networkAddress: '', 
refType: CrossThread,
+                parentSpanId: 0, parentTraceSegmentId: not null, 
parentServiceInstance: not
+                    null, parentService: not null, traceId: not null }  
+      - segmentId: not null
+        spans:    
+          - operationName: /case/lettuce-case
             parentSpanId: -1
             spanId: 0
             spanLayer: Http
             startTime: not null
             endTime: not null
-            componentId: 1
+            componentId: 67
             isError: false
             spanType: Entry
             peer: ''
             skipAnalysis: false
             tags:
-              - {key: url, value: 
'http://localhost:8080/lettuce-6.5.x-scenario/case/lettuce-case'}
+              - {key: url, value: 'http://localhost:8080/case/lettuce-case'}
               - {key: http.method, value: GET}
               - {key: http.status_code, value: '200'}
diff --git 
a/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-6.5.x-plugin/src/main/resources/skywalking-plugin.def
 b/test/plugin/scenarios/lettuce-webflux-5x-scenario/configuration.yml
similarity index 67%
copy from 
apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-6.5.x-plugin/src/main/resources/skywalking-plugin.def
copy to test/plugin/scenarios/lettuce-webflux-5x-scenario/configuration.yml
index a503891244..d016d55400 100644
--- 
a/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-6.5.x-plugin/src/main/resources/skywalking-plugin.def
+++ b/test/plugin/scenarios/lettuce-webflux-5x-scenario/configuration.yml
@@ -14,4 +14,17 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-lettuce-6.5.x=org.apache.skywalking.apm.plugin.lettuce.v65.define.RedisChannelWriterInstrumentationV65
\ No newline at end of file
+type: jvm
+entryService: http://localhost:8080/case/lettuce-case
+healthCheck: http://localhost:8080/case/healthCheck
+startScript: ./bin/startup.sh
+withPlugins: apm-spring-webflux-5.x-*.jar
+runningMode: with_optional
+environment:
+  - REDIS_SERVERS=redis-server:6379
+depends_on:
+  - redis-server
+dependencies:
+  redis-server:
+    image: redis:3.2.9-alpine
+    hostname: redis-server
diff --git a/test/plugin/scenarios/lettuce-webflux-5x-scenario/pom.xml 
b/test/plugin/scenarios/lettuce-webflux-5x-scenario/pom.xml
new file mode 100644
index 0000000000..bf393539a2
--- /dev/null
+++ b/test/plugin/scenarios/lettuce-webflux-5x-scenario/pom.xml
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  ~
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0";
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.apache.skywalking</groupId>
+    <artifactId>lettuce-webflux-5x-scenario</artifactId>
+    <version>5.0.0</version>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <compiler.version>1.8</compiler.version>
+        <maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
+        <test.framework.version>5.1.8.RELEASE</test.framework.version>
+        <docker.image.version>${test.framework.version}</docker.image.version>
+        <spring.boot.version>2.1.6.RELEASE</spring.boot.version>
+    </properties>
+
+    <name>skywalking-lettuce-webflux-5x-scenario</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>io.lettuce</groupId>
+            <artifactId>lettuce-core</artifactId>
+            <version>${test.framework.version}</version>
+        </dependency>
+        <!-- Spring Boot-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-webflux</artifactId>
+            <version>${spring.boot.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <finalName>lettuce-webflux-5x-scenario</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>${spring.boot.version}</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>${maven-compiler-plugin.version}</version>
+                <configuration>
+                    <source>${compiler.version}</source>
+                    <target>${compiler.version}</target>
+                    <encoding>${project.build.sourceEncoding}</encoding>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>assemble</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>single</goal>
+                        </goals>
+                        <configuration>
+                            <descriptors>
+                                
<descriptor>src/main/assembly/assembly.xml</descriptor>
+                            </descriptors>
+                            <outputDirectory>./target/</outputDirectory>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file
diff --git 
a/test/plugin/scenarios/lettuce-webflux-5x-scenario/src/main/assembly/assembly.xml
 
b/test/plugin/scenarios/lettuce-webflux-5x-scenario/src/main/assembly/assembly.xml
new file mode 100644
index 0000000000..ffc45011aa
--- /dev/null
+++ 
b/test/plugin/scenarios/lettuce-webflux-5x-scenario/src/main/assembly/assembly.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  ~
+  -->
+<assembly
+    
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2";
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+    
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2
 http://maven.apache.org/xsd/assembly-1.1.2.xsd";>
+    <formats>
+        <format>zip</format>
+    </formats>
+
+    <fileSets>
+        <fileSet>
+            <directory>./bin</directory>
+            <fileMode>0775</fileMode>
+        </fileSet>
+    </fileSets>
+
+    <files>
+        <file>
+            
<source>${project.build.directory}/lettuce-webflux-5x-scenario.jar</source>
+            <outputDirectory>./libs</outputDirectory>
+            <fileMode>0775</fileMode>
+        </file>
+    </files>
+</assembly>
diff --git 
a/test/plugin/scenarios/lettuce-webflux-5x-scenario/src/main/java/org/apache/skywalking/apm/testcase/lettuce/Application.java
 
b/test/plugin/scenarios/lettuce-webflux-5x-scenario/src/main/java/org/apache/skywalking/apm/testcase/lettuce/Application.java
new file mode 100644
index 0000000000..dae1948397
--- /dev/null
+++ 
b/test/plugin/scenarios/lettuce-webflux-5x-scenario/src/main/java/org/apache/skywalking/apm/testcase/lettuce/Application.java
@@ -0,0 +1,34 @@
+/*
+ * 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.skywalking.apm.testcase.lettuce;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class Application {
+
+    public static void main(String[] args) {
+        try {
+            SpringApplication.run(Application.class, args);
+        } catch (Exception e) {
+            // Never do this
+        }
+    }
+}
diff --git 
a/test/plugin/scenarios/lettuce-webflux-5x-scenario/src/main/java/org/apache/skywalking/apm/testcase/lettuce/RedisClientConfig.java
 
b/test/plugin/scenarios/lettuce-webflux-5x-scenario/src/main/java/org/apache/skywalking/apm/testcase/lettuce/RedisClientConfig.java
new file mode 100644
index 0000000000..0898d08338
--- /dev/null
+++ 
b/test/plugin/scenarios/lettuce-webflux-5x-scenario/src/main/java/org/apache/skywalking/apm/testcase/lettuce/RedisClientConfig.java
@@ -0,0 +1,37 @@
+/*
+ * 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.skywalking.apm.testcase.lettuce;
+
+import io.lettuce.core.RedisClient;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ *
+ */
+@Configuration
+public class RedisClientConfig {
+
+    @Bean(destroyMethod = "shutdown")
+    public RedisClient redisClient(@Value("${redis.servers:127.0.0.1:6379}") 
String address) {
+
+        return RedisClient.create("redis://" + address);
+    }
+}
diff --git 
a/test/plugin/scenarios/lettuce-webflux-5x-scenario/src/main/java/org/apache/skywalking/apm/testcase/lettuce/controller/LettuceReactiveController.java
 
b/test/plugin/scenarios/lettuce-webflux-5x-scenario/src/main/java/org/apache/skywalking/apm/testcase/lettuce/controller/LettuceReactiveController.java
new file mode 100644
index 0000000000..2664bd2713
--- /dev/null
+++ 
b/test/plugin/scenarios/lettuce-webflux-5x-scenario/src/main/java/org/apache/skywalking/apm/testcase/lettuce/controller/LettuceReactiveController.java
@@ -0,0 +1,68 @@
+/*
+ * 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.skywalking.apm.testcase.lettuce.controller;
+
+import io.lettuce.core.RedisClient;
+import io.lettuce.core.api.reactive.RedisReactiveCommands;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+import javax.annotation.Resource;
+
+@RestController
+@RequestMapping("/case")
+@PropertySource("classpath:application.properties")
+public class LettuceReactiveController {
+
+    @Value("${redis.servers:127.0.0.1:6379}")
+    private String address;
+
+    @Resource
+    private RedisClient redisClient;
+
+    @GetMapping("/lettuce-case")
+    public Mono<String> lettuceCase() {
+
+        return Mono.usingWhen(
+                Mono.fromCallable(() -> redisClient.connect()),
+                connection -> {
+                    RedisReactiveCommands<String, String> cmd = 
connection.reactive();
+                    return cmd.get("key")
+                            .then(Flux.concat(
+                                    cmd.set("key0", "value0"),
+                                    cmd.set("key1", "value1")
+                            ).then())
+                            .thenReturn("Success");
+                },
+                connection -> Mono.fromFuture(connection.closeAsync()),
+                connection -> Mono.fromFuture(connection.closeAsync()),
+                connection -> Mono.fromFuture(connection.closeAsync())
+        );
+    }
+
+    @GetMapping("/healthCheck")
+    public Mono<String> healthCheck() {
+        return Mono.just("healthCheck");
+    }
+}
diff --git 
a/test/plugin/scenarios/lettuce-webflux-5x-scenario/src/main/resources/application.properties
 
b/test/plugin/scenarios/lettuce-webflux-5x-scenario/src/main/resources/application.properties
new file mode 100644
index 0000000000..d3b193de12
--- /dev/null
+++ 
b/test/plugin/scenarios/lettuce-webflux-5x-scenario/src/main/resources/application.properties
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+#
+server.port=8080
diff --git 
a/test/plugin/scenarios/lettuce-webflux-5x-scenario/src/main/resources/log4j2.xml
 
b/test/plugin/scenarios/lettuce-webflux-5x-scenario/src/main/resources/log4j2.xml
new file mode 100644
index 0000000000..9849ed5a8a
--- /dev/null
+++ 
b/test/plugin/scenarios/lettuce-webflux-5x-scenario/src/main/resources/log4j2.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  ~
+  -->
+<Configuration status="WARN">
+    <Appenders>
+        <Console name="Console" target="SYSTEM_ERR">
+            <PatternLayout charset="UTF-8" pattern="[%d{yyyy-MM-dd 
HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
+        </Console>
+    </Appenders>
+    <Loggers>
+        <Root level="WARN">
+            <AppenderRef ref="Console"/>
+        </Root>
+    </Loggers>
+</Configuration>
\ No newline at end of file
diff --git 
a/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-6.5.x-plugin/src/main/resources/skywalking-plugin.def
 b/test/plugin/scenarios/lettuce-webflux-5x-scenario/support-version.list
similarity index 88%
copy from 
apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-6.5.x-plugin/src/main/resources/skywalking-plugin.def
copy to test/plugin/scenarios/lettuce-webflux-5x-scenario/support-version.list
index a503891244..a7e848bbbf 100644
--- 
a/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-6.5.x-plugin/src/main/resources/skywalking-plugin.def
+++ b/test/plugin/scenarios/lettuce-webflux-5x-scenario/support-version.list
@@ -14,4 +14,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-lettuce-6.5.x=org.apache.skywalking.apm.plugin.lettuce.v65.define.RedisChannelWriterInstrumentationV65
\ No newline at end of file
+5.1.8.RELEASE
+5.2.1.RELEASE
+6.1.4.RELEASE
\ No newline at end of file
diff --git 
a/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-6.5.x-plugin/src/main/resources/skywalking-plugin.def
 b/test/plugin/scenarios/lettuce-webflux-6x-scenario/bin/startup.sh
similarity index 79%
copy from 
apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-6.5.x-plugin/src/main/resources/skywalking-plugin.def
copy to test/plugin/scenarios/lettuce-webflux-6x-scenario/bin/startup.sh
index a503891244..686b12f52a 100644
--- 
a/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-6.5.x-plugin/src/main/resources/skywalking-plugin.def
+++ b/test/plugin/scenarios/lettuce-webflux-6x-scenario/bin/startup.sh
@@ -1,3 +1,5 @@
+#!/bin/bash
+#
 # 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
@@ -14,4 +16,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-lettuce-6.5.x=org.apache.skywalking.apm.plugin.lettuce.v65.define.RedisChannelWriterInstrumentationV65
\ No newline at end of file
+home="$(cd "$(dirname $0)"; pwd)"
+
+java -Dredis.host=${REDIS_SERVERS} -jar 
-Dskywalking.plugin.lettuce.trace_redis_parameters=true ${agent_opts} 
${home}/../libs/lettuce-webflux-6x-scenario.jar &
\ No newline at end of file
diff --git 
a/test/plugin/scenarios/lettuce-6.5.x-scenario/config/expectedData.yaml 
b/test/plugin/scenarios/lettuce-webflux-6x-scenario/config/expectedData.yaml
similarity index 55%
copy from test/plugin/scenarios/lettuce-6.5.x-scenario/config/expectedData.yaml
copy to 
test/plugin/scenarios/lettuce-webflux-6x-scenario/config/expectedData.yaml
index 2a938caea9..e5857aa054 100644
--- a/test/plugin/scenarios/lettuce-6.5.x-scenario/config/expectedData.yaml
+++ b/test/plugin/scenarios/lettuce-webflux-6x-scenario/config/expectedData.yaml
@@ -14,26 +14,26 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 segmentItems:
-  - serviceName: lettuce-6.5.x-scenario
+  - serviceName: lettuce-webflux-6x-scenario
     segmentSize: nq 0
     segments:
       - segmentId: not null
         spans:
-          - operationName: HEAD:/lettuce-6.5.x-scenario/case/healthCheck
+          - operationName: /case/healthCheck
             parentSpanId: -1
             spanId: 0
             spanLayer: Http
             startTime: not null
             endTime: not null
-            componentId: 1
+            componentId: 67
             isError: false
             spanType: Entry
             peer: ''
             skipAnalysis: false
             tags:
-              - {key: url, value: 
'http://localhost:8080/lettuce-6.5.x-scenario/case/healthCheck'}
-              - {key: http.method, value: HEAD}
-              - {key: http.status_code, value: '200'}
+              - { key: url, value: 'http://localhost:8080/case/healthCheck' }
+              - { key: http.method, value: HEAD }
+              - { key: http.status_code, value: '200' }
       - segmentId: not null
         spans:
           - operationName: Lettuce/GET
@@ -48,13 +48,24 @@ segmentItems:
             peer: not null
             skipAnalysis: false
             tags:
-              - {key: cache.type, value: Redis}
-              - {key: cache.key, value: key}
-              - {key: cache.cmd, value: GET}
-              - {key: cache.op, value: read}
+              - { key: cache.type, value: Redis }
+              - { key: cache.key, value: key }
+              - { key: cache.cmd, value: GET }
+              - { key: cache.op, value: read }
+          - operationName: RedisReactive/local
+            parentSpanId: -1
+            spanId: 0
+            isError: false
+            spanType: Local
+            refs:
+              - { parentEndpoint: /case/lettuce-case, networkAddress: '', 
refType: CrossThread,
+                parentSpanId: 0, parentTraceSegmentId: not null, 
parentServiceInstance: not
+                    null, parentService: not null, traceId: not null }
+      - segmentId: not null
+        spans:
           - operationName: Lettuce/SET
             parentSpanId: 0
-            spanId: 2
+            spanId: 1
             spanLayer: Cache
             startTime: not null
             endTime: not null
@@ -68,9 +79,20 @@ segmentItems:
               - { key: cache.key, value: key0 }
               - { key: cache.cmd, value: SET }
               - { key: cache.op, value: write }
+          - operationName: RedisReactive/local
+            parentSpanId: -1
+            spanId: 0
+            isError: false
+            spanType: Local
+            refs:
+              - { parentEndpoint: /case/lettuce-case, networkAddress: '', 
refType: CrossThread,
+                parentSpanId: 0, parentTraceSegmentId: not null, 
parentServiceInstance: not
+                    null, parentService: not null, traceId: not null }
+      - segmentId: not null
+        spans:
           - operationName: Lettuce/SET
             parentSpanId: 0
-            spanId: 3
+            spanId: 1
             spanLayer: Cache
             startTime: not null
             endTime: not null
@@ -84,18 +106,30 @@ segmentItems:
               - { key: cache.key, value: key1 }
               - { key: cache.cmd, value: SET }
               - { key: cache.op, value: write }
-          - operationName: GET:/lettuce-6.5.x-scenario/case/lettuce-case
+          - operationName: RedisReactive/local
+            parentSpanId: -1
+            spanId: 0
+            isError: false
+            spanType: Local
+            refs:
+              - { parentEndpoint: /case/lettuce-case, networkAddress: '', 
refType: CrossThread,
+                parentSpanId: 0, parentTraceSegmentId: not null, 
parentServiceInstance: not
+                    null, parentService: not null, traceId: not null }
+      - segmentId: not null
+        spans:
+          - operationName: /case/lettuce-case
             parentSpanId: -1
             spanId: 0
             spanLayer: Http
             startTime: not null
             endTime: not null
-            componentId: 1
+            componentId: 67
             isError: false
             spanType: Entry
             peer: ''
             skipAnalysis: false
             tags:
-              - {key: url, value: 
'http://localhost:8080/lettuce-6.5.x-scenario/case/lettuce-case'}
-              - {key: http.method, value: GET}
-              - {key: http.status_code, value: '200'}
+              - { key: url, value: 'http://localhost:8080/case/lettuce-case' }
+              - { key: http.method, value: GET }
+              - { key: http.status_code, value: '200' }
+    
\ No newline at end of file
diff --git 
a/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-6.5.x-plugin/src/main/resources/skywalking-plugin.def
 b/test/plugin/scenarios/lettuce-webflux-6x-scenario/configuration.yml
similarity index 67%
copy from 
apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-6.5.x-plugin/src/main/resources/skywalking-plugin.def
copy to test/plugin/scenarios/lettuce-webflux-6x-scenario/configuration.yml
index a503891244..a3eecec7bb 100644
--- 
a/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-6.5.x-plugin/src/main/resources/skywalking-plugin.def
+++ b/test/plugin/scenarios/lettuce-webflux-6x-scenario/configuration.yml
@@ -14,4 +14,17 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-lettuce-6.5.x=org.apache.skywalking.apm.plugin.lettuce.v65.define.RedisChannelWriterInstrumentationV65
\ No newline at end of file
+type: jvm
+entryService: http://localhost:8080/case/lettuce-case
+healthCheck: http://localhost:8080/case/healthCheck
+startScript: ./bin/startup.sh
+withPlugins: apm-spring-webflux-6.x-*.jar
+runningMode: with_optional
+environment:
+  - REDIS_SERVERS=redis-server:6379
+depends_on:
+  - redis-server
+dependencies:
+  redis-server:
+    image: redis:3.2.9-alpine
+    hostname: redis-server
diff --git a/test/plugin/scenarios/lettuce-webflux-6x-scenario/pom.xml 
b/test/plugin/scenarios/lettuce-webflux-6x-scenario/pom.xml
new file mode 100644
index 0000000000..2e05615440
--- /dev/null
+++ b/test/plugin/scenarios/lettuce-webflux-6x-scenario/pom.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  ~
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0";
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.apache.skywalking</groupId>
+    <artifactId>lettuce-webflux-6x-scenario</artifactId>
+    <version>5.0.0</version>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <compiler.version>17</compiler.version>
+        <maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
+        <test.framework.version>6.4.2.RELEASE</test.framework.version>
+        <docker.image.version>${test.framework.version}</docker.image.version>
+        <spring.boot.version>3.0.13</spring.boot.version>
+    </properties>
+
+    <name>skywalking-lettuce-webflux-6x-scenario</name>
+    
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-dependencies</artifactId>
+                <version>${spring.boot.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <dependencies>
+        <dependency>
+            <groupId>io.lettuce</groupId>
+            <artifactId>lettuce-core</artifactId>
+            <version>${test.framework.version}</version>
+        </dependency>
+        <!-- Spring Boot-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-webflux</artifactId>
+            <version>${spring.boot.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.apache.logging.log4j</groupId>
+                    <artifactId>log4j-api</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        
+    </dependencies>
+
+    <build>
+        <finalName>lettuce-webflux-6x-scenario</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>${spring.boot.version}</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>${maven-compiler-plugin.version}</version>
+                <configuration>
+                    <source>${compiler.version}</source>
+                    <target>${compiler.version}</target>
+                    <encoding>${project.build.sourceEncoding}</encoding>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>assemble</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>single</goal>
+                        </goals>
+                        <configuration>
+                            <descriptors>
+                                
<descriptor>src/main/assembly/assembly.xml</descriptor>
+                            </descriptors>
+                            <outputDirectory>./target/</outputDirectory>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file
diff --git 
a/test/plugin/scenarios/lettuce-webflux-6x-scenario/src/main/assembly/assembly.xml
 
b/test/plugin/scenarios/lettuce-webflux-6x-scenario/src/main/assembly/assembly.xml
new file mode 100644
index 0000000000..87c9882cab
--- /dev/null
+++ 
b/test/plugin/scenarios/lettuce-webflux-6x-scenario/src/main/assembly/assembly.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  ~
+  -->
+<assembly
+    
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2";
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+    
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2
 http://maven.apache.org/xsd/assembly-1.1.2.xsd";>
+    <formats>
+        <format>zip</format>
+    </formats>
+
+    <fileSets>
+        <fileSet>
+            <directory>./bin</directory>
+            <fileMode>0775</fileMode>
+        </fileSet>
+    </fileSets>
+
+    <files>
+        <file>
+            
<source>${project.build.directory}/lettuce-webflux-6x-scenario.jar</source>
+            <outputDirectory>./libs</outputDirectory>
+            <fileMode>0775</fileMode>
+        </file>
+    </files>
+</assembly>
diff --git 
a/test/plugin/scenarios/lettuce-webflux-6x-scenario/src/main/java/org/apache/skywalking/apm/testcase/lettuce/Application.java
 
b/test/plugin/scenarios/lettuce-webflux-6x-scenario/src/main/java/org/apache/skywalking/apm/testcase/lettuce/Application.java
new file mode 100644
index 0000000000..f96b624013
--- /dev/null
+++ 
b/test/plugin/scenarios/lettuce-webflux-6x-scenario/src/main/java/org/apache/skywalking/apm/testcase/lettuce/Application.java
@@ -0,0 +1,30 @@
+/*
+ * 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.skywalking.apm.testcase.lettuce;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class Application {
+
+    public static void main(String[] args) {
+        SpringApplication.run(Application.class, args);
+    }
+}
diff --git 
a/test/plugin/scenarios/lettuce-webflux-6x-scenario/src/main/java/org/apache/skywalking/apm/testcase/lettuce/RedisClientConfig.java
 
b/test/plugin/scenarios/lettuce-webflux-6x-scenario/src/main/java/org/apache/skywalking/apm/testcase/lettuce/RedisClientConfig.java
new file mode 100644
index 0000000000..0898d08338
--- /dev/null
+++ 
b/test/plugin/scenarios/lettuce-webflux-6x-scenario/src/main/java/org/apache/skywalking/apm/testcase/lettuce/RedisClientConfig.java
@@ -0,0 +1,37 @@
+/*
+ * 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.skywalking.apm.testcase.lettuce;
+
+import io.lettuce.core.RedisClient;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ *
+ */
+@Configuration
+public class RedisClientConfig {
+
+    @Bean(destroyMethod = "shutdown")
+    public RedisClient redisClient(@Value("${redis.servers:127.0.0.1:6379}") 
String address) {
+
+        return RedisClient.create("redis://" + address);
+    }
+}
diff --git 
a/test/plugin/scenarios/lettuce-webflux-6x-scenario/src/main/java/org/apache/skywalking/apm/testcase/lettuce/controller/LettuceReactiveController.java
 
b/test/plugin/scenarios/lettuce-webflux-6x-scenario/src/main/java/org/apache/skywalking/apm/testcase/lettuce/controller/LettuceReactiveController.java
new file mode 100644
index 0000000000..697369fcf8
--- /dev/null
+++ 
b/test/plugin/scenarios/lettuce-webflux-6x-scenario/src/main/java/org/apache/skywalking/apm/testcase/lettuce/controller/LettuceReactiveController.java
@@ -0,0 +1,63 @@
+/*
+ * 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.skywalking.apm.testcase.lettuce.controller;
+
+import io.lettuce.core.RedisClient;
+import io.lettuce.core.api.reactive.RedisReactiveCommands;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+@RestController
+@RequestMapping("/case")
+public class LettuceReactiveController {
+
+    @Value("${redis.servers:127.0.0.1:6379}")
+    private String address;
+
+    @Autowired
+    private RedisClient redisClient;
+
+    @GetMapping("/lettuce-case")
+    public Mono<String> lettuceCase() {
+
+        return Mono.usingWhen(
+                Mono.fromCallable(() -> redisClient.connect()),
+                connection -> {
+                    RedisReactiveCommands<String, String> cmd = 
connection.reactive();
+                    return cmd.get("key")
+                            .then(Flux.concat(
+                                    cmd.set("key0", "value0"),
+                                    cmd.set("key1", "value1")
+                            ).then())
+                            .thenReturn("Success");
+                },
+                connection -> Mono.fromFuture(connection.closeAsync())
+        );
+    }
+
+    @GetMapping("/healthCheck")
+    public Mono<String> healthCheck() {
+        return Mono.just("healthCheck");
+    }
+}
diff --git 
a/test/plugin/scenarios/lettuce-webflux-6x-scenario/src/main/resources/application.properties
 
b/test/plugin/scenarios/lettuce-webflux-6x-scenario/src/main/resources/application.properties
new file mode 100644
index 0000000000..afdb52cef7
--- /dev/null
+++ 
b/test/plugin/scenarios/lettuce-webflux-6x-scenario/src/main/resources/application.properties
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+#
+server.port=8080
\ No newline at end of file
diff --git 
a/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-6.5.x-plugin/src/main/resources/skywalking-plugin.def
 b/test/plugin/scenarios/lettuce-webflux-6x-scenario/support-version.list
similarity index 88%
copy from 
apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-6.5.x-plugin/src/main/resources/skywalking-plugin.def
copy to test/plugin/scenarios/lettuce-webflux-6x-scenario/support-version.list
index a503891244..2cba7f3294 100644
--- 
a/apm-sniffer/apm-sdk-plugin/lettuce-plugins/lettuce-6.5.x-plugin/src/main/resources/skywalking-plugin.def
+++ b/test/plugin/scenarios/lettuce-webflux-6x-scenario/support-version.list
@@ -14,4 +14,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-lettuce-6.5.x=org.apache.skywalking.apm.plugin.lettuce.v65.define.RedisChannelWriterInstrumentationV65
\ No newline at end of file
+6.4.2.RELEASE
+6.5.5.RELEASE
+6.6.0.RELEASE
+6.7.1.RELEASE
\ No newline at end of file

Reply via email to