You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@dubbo.apache.org by al...@apache.org on 2022/11/30 06:44:28 UTC

[dubbo-samples] branch master updated: Add samples for isolation executor between provider services (#575)

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

albumenj pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo-samples.git


The following commit(s) were added to refs/heads/master by this push:
     new 4ffb3886 Add samples for isolation executor between provider services (#575)
4ffb3886 is described below

commit 4ffb38868c5aae6fc16a39ffdec9ba74594a2a05
Author: 灼华 <10...@qq.com>
AuthorDate: Wed Nov 30 14:44:22 2022 +0800

    Add samples for isolation executor between provider services (#575)
---
 dubbo-samples-isolation-executor/README.md         |   3 +
 .../case-configuration.yml                         |  19 +++
 .../case-versions.conf                             |  24 +++
 dubbo-samples-isolation-executor/pom.xml           |  87 ++++++++++
 .../java/org/apache/dubbo/samples/Application.java |  37 +++++
 .../apache/dubbo/samples/api/ApiIsolationTest.java | 176 +++++++++++++++++++++
 .../org/apache/dubbo/samples/spring/BaseTest.java  | 102 ++++++++++++
 .../spring/annotation/AnnotationIsolationTest.java | 132 ++++++++++++++++
 .../annotation/consumer/dubbo/DemoServiceV1.java   |  32 ++++
 .../annotation/consumer/dubbo/HelloServiceV2.java  |  32 ++++
 .../annotation/consumer/dubbo/HelloServiceV3.java  |  32 ++++
 .../annotation/consumer/tri/DemoServiceV1.java     |  32 ++++
 .../annotation/consumer/tri/HelloServiceV2.java    |  32 ++++
 .../annotation/consumer/tri/HelloServiceV3.java    |  32 ++++
 .../annotation/provider/DemoServiceImplV1.java     |  28 ++++
 .../annotation/provider/HelloServiceImplV2.java    |  32 ++++
 .../annotation/provider/HelloServiceImplV3.java    |  33 ++++
 .../spring/support/DemoServiceExecutor.java        |  30 ++++
 .../spring/support/HelloServiceExecutor.java       |  31 ++++
 .../dubbo/samples/spring/xml/XmlIsolationTest.java |  54 +++++++
 .../apache/dubbo/samples/support/DemoService.java  |  21 +++
 .../dubbo/samples/support/DemoServiceImpl.java     |  26 +++
 .../apache/dubbo/samples/support/HelloService.java |  22 +++
 .../dubbo/samples/support/HelloServiceImpl.java    |  24 +++
 .../META-INF/isolation/dubbo-consumer.xml          |  51 ++++++
 .../META-INF/isolation/dubbo-provider.xml          |  60 +++++++
 .../src/main/resources/log4j.properties            |  26 +++
 pom.xml                                            |   1 +
 28 files changed, 1211 insertions(+)

diff --git a/dubbo-samples-isolation-executor/README.md b/dubbo-samples-isolation-executor/README.md
new file mode 100644
index 00000000..c312b467
--- /dev/null
+++ b/dubbo-samples-isolation-executor/README.md
@@ -0,0 +1,3 @@
+There are three ways to configure the isolated thread pool: API, Spring-Annotation and Spring-XML.
+
+The entry for the three configuration cases is: ApiIsolationTest, AnnotationIsolationTest, XmlIsolationTest.
\ No newline at end of file
diff --git a/dubbo-samples-isolation-executor/case-configuration.yml b/dubbo-samples-isolation-executor/case-configuration.yml
new file mode 100644
index 00000000..0d6b4c42
--- /dev/null
+++ b/dubbo-samples-isolation-executor/case-configuration.yml
@@ -0,0 +1,19 @@
+# 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.
+
+from: app-external-zookeeper.yml
+
+props:
+  project_name: dubbo-samples-isolation-executor
+  main_class: org.apache.dubbo.samples.Application
diff --git a/dubbo-samples-isolation-executor/case-versions.conf b/dubbo-samples-isolation-executor/case-versions.conf
new file mode 100644
index 00000000..444eaa30
--- /dev/null
+++ b/dubbo-samples-isolation-executor/case-versions.conf
@@ -0,0 +1,24 @@
+#
+#
+#   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.
+#
+
+
+# Supported component versions of the test case
+
+# Spring app
+dubbo.version=[ >=3.2.0 ]
+spring.version=4.*, 5.*
diff --git a/dubbo-samples-isolation-executor/pom.xml b/dubbo-samples-isolation-executor/pom.xml
new file mode 100644
index 00000000..6aa2502c
--- /dev/null
+++ b/dubbo-samples-isolation-executor/pom.xml
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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.dubbo</groupId>
+    <artifactId>dubbo-samples-isolation-executor</artifactId>
+    <version>1.0-SNAPSHOT</version>
+
+    <properties>
+        <dubbo.version>3.2.0-beta.1</dubbo.version>
+        <junit.version>4.12</junit.version>
+        <maven-compiler-plugin.version>3.7.0</maven-compiler-plugin.version>
+        <source.level>1.8</source.level>
+        <target.level>1.8</target.level>
+    </properties>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.apache.dubbo</groupId>
+                <artifactId>dubbo-bom</artifactId>
+                <version>${dubbo.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.dubbo</groupId>
+                <artifactId>dubbo-dependencies-zookeeper</artifactId>
+                <version>${dubbo.version}</version>
+                <type>pom</type>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.dubbo</groupId>
+                <artifactId>dubbo-dependencies-bom</artifactId>
+                <version>${dubbo.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+
+        </dependencies>
+    </dependencyManagement>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-rpc-triple</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-dependencies-zookeeper</artifactId>
+            <type>pom</type>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-common</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.google.protobuf</groupId>
+            <artifactId>protobuf-java</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>${maven-compiler-plugin.version}</version>
+                <configuration>
+                    <source>${source.level}</source>
+                    <target>${target.level}</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/Application.java b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/Application.java
new file mode 100644
index 00000000..79a3c910
--- /dev/null
+++ b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/Application.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.dubbo.samples;
+
+import org.apache.dubbo.samples.api.ApiIsolationTest;
+import org.apache.dubbo.samples.spring.annotation.AnnotationIsolationTest;
+import org.apache.dubbo.samples.spring.xml.XmlIsolationTest;
+
+public class Application {
+    public static void main(String[] args) {
+        // Use the Api configuration way and test it
+        ApiIsolationTest apiIsolationTest = new ApiIsolationTest();
+        apiIsolationTest.test();
+
+        // Use the Spring-XML configuration way and test it
+        XmlIsolationTest xmlIsolationTest = new XmlIsolationTest();
+        xmlIsolationTest.test();
+
+        // Use the Spring-Annotation configuration way and test it
+        AnnotationIsolationTest annotationIsolationTest = new AnnotationIsolationTest();
+        annotationIsolationTest.test();
+    }
+}
diff --git a/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/api/ApiIsolationTest.java b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/api/ApiIsolationTest.java
new file mode 100644
index 00000000..0ef4b851
--- /dev/null
+++ b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/api/ApiIsolationTest.java
@@ -0,0 +1,176 @@
+/*
+ * 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.dubbo.samples.api;
+
+import org.apache.dubbo.common.threadlocal.NamedInternalThreadFactory;
+import org.apache.dubbo.common.threadpool.manager.ExecutorRepository;
+import org.apache.dubbo.common.threadpool.manager.IsolationExecutorRepository;
+import org.apache.dubbo.common.utils.NamedThreadFactory;
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.ProtocolConfig;
+import org.apache.dubbo.config.RegistryConfig;
+import org.apache.dubbo.config.ServiceConfig;
+import org.apache.dubbo.config.bootstrap.DubboBootstrap;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+import org.apache.dubbo.rpc.model.FrameworkModel;
+import org.apache.dubbo.samples.support.DemoService;
+import org.apache.dubbo.samples.support.DemoServiceImpl;
+import org.apache.dubbo.samples.support.HelloService;
+import org.apache.dubbo.samples.support.HelloServiceImpl;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static org.apache.dubbo.common.constants.CommonConstants.EXECUTOR_MANAGEMENT_MODE_ISOLATION;
+
+public class ApiIsolationTest {
+
+    private static final String version1 = "1.0";
+    private static final String version2 = "2.0";
+    private static final String version3 = "3.0";
+
+    public void test() {
+        RegistryConfig registryConfig = new RegistryConfig("zookeeper://127.0.0.1:2181");
+
+        DubboBootstrap providerBootstrap = null;
+        DubboBootstrap consumerBootstrap1 = null;
+        DubboBootstrap consumerBootstrap2 = null;
+
+        try {
+
+            // provider app
+            providerBootstrap = DubboBootstrap.newInstance();
+
+            ServiceConfig serviceConfig1 = new ServiceConfig();
+            serviceConfig1.setInterface(DemoService.class);
+            serviceConfig1.setRef(new DemoServiceImpl());
+            serviceConfig1.setVersion(version1);
+            // set executor1 for serviceConfig1, max threads is 10
+            NamedThreadFactory threadFactory1 = new NamedThreadFactory("DemoService-executor");
+            ExecutorService executor1 = Executors.newFixedThreadPool(10, threadFactory1);
+            serviceConfig1.setExecutor(executor1);
+
+            ServiceConfig serviceConfig2 = new ServiceConfig();
+            serviceConfig2.setInterface(HelloService.class);
+            serviceConfig2.setRef(new HelloServiceImpl());
+            serviceConfig2.setVersion(version2);
+            // set executor2 for serviceConfig2, max threads is 100
+            NamedThreadFactory threadFactory2 = new NamedThreadFactory("HelloService-executor");
+            ExecutorService executor2 = Executors.newFixedThreadPool(100, threadFactory2);
+            serviceConfig2.setExecutor(executor2);
+
+            ServiceConfig serviceConfig3 = new ServiceConfig();
+            serviceConfig3.setInterface(HelloService.class);
+            serviceConfig3.setRef(new HelloServiceImpl());
+            serviceConfig3.setVersion(version3);
+            // Because executor is not set for serviceConfig3, the default executor of serviceConfig3 is built using
+            // the threadpool parameter of the protocolConfig ( FixedThreadpool , max threads is 200)
+            serviceConfig3.setExecutor(null);
+
+            // It takes effect only if [executor-management-mode=isolation] is configured
+            ApplicationConfig applicationConfig = new ApplicationConfig("provider-app");
+            applicationConfig.setExecutorManagementMode(EXECUTOR_MANAGEMENT_MODE_ISOLATION);
+
+            providerBootstrap
+                    .application(applicationConfig)
+                    .registry(registryConfig)
+                    // export with tri and dubbo protocol
+                    .protocol(new ProtocolConfig("tri", 20001))
+                    .protocol(new ProtocolConfig("dubbo", 20002))
+                    .service(serviceConfig1)
+                    .service(serviceConfig2)
+                    .service(serviceConfig3);
+
+            providerBootstrap.start();
+
+            // Verify that the executor is the previously configured
+            ApplicationModel applicationModel = providerBootstrap.getApplicationModel();
+            ExecutorRepository repository = ExecutorRepository.getInstance(applicationModel);
+            assert repository instanceof IsolationExecutorRepository;
+            assert executor1.equals(repository.getExecutor(serviceConfig1.toUrl()));
+            assert executor2.equals(repository.getExecutor(serviceConfig2.toUrl()));
+            // the default executor of serviceConfig3 is built using the threadpool parameter of the protocol
+            ThreadPoolExecutor executor3 = (ThreadPoolExecutor) repository.getExecutor(serviceConfig3.toUrl());
+            assert executor3.getThreadFactory() instanceof NamedInternalThreadFactory;
+            NamedInternalThreadFactory threadFactory3 = (NamedInternalThreadFactory) executor3.getThreadFactory();
+
+            // consumer app start with dubbo protocol and rpc call
+            consumerBootstrap1 = configConsumerBootstrapWithProtocol("dubbo", registryConfig);
+            rpcInvoke(consumerBootstrap1);
+
+            // consumer app start with tri protocol and rpc call
+            consumerBootstrap2 = configConsumerBootstrapWithProtocol("tri", registryConfig);
+            rpcInvoke(consumerBootstrap2);
+
+            // Verify that when the provider accepts different service requests,
+            // whether to use the respective executor(threadFactory) of different services to create threads
+            AtomicInteger threadNum1 = threadFactory1.getThreadNum();
+            AtomicInteger threadNum2 = threadFactory2.getThreadNum();
+            AtomicInteger threadNum3 = threadFactory3.getThreadNum();
+            assert threadNum1.get() == 11;
+            assert threadNum2.get() == 101;
+            assert threadNum3.get() == 201;
+
+        } finally {
+            if (providerBootstrap != null) {
+                providerBootstrap.destroy();
+            }
+            if (consumerBootstrap1 != null) {
+                consumerBootstrap1.destroy();
+            }
+            if (consumerBootstrap2 != null) {
+                consumerBootstrap2.destroy();
+            }
+            FrameworkModel.destroyAll();
+        }
+    }
+
+
+    private static void rpcInvoke(DubboBootstrap consumerBootstrap) {
+        DemoService demoServiceV1 = consumerBootstrap.getCache().get(DemoService.class.getName() + ":" + version1);
+        HelloService helloServiceV2 = consumerBootstrap.getCache().get(HelloService.class.getName() + ":" + version2);
+        HelloService helloServiceV3 = consumerBootstrap.getCache().get(HelloService.class.getName() + ":" + version3);
+        for (int i = 0; i < 250; i++) {
+            String response = demoServiceV1.sayName("name, version = " + version1);
+            assert response.equals("say:" + "name, version = " + version1);
+        }
+        for (int i = 0; i < 250; i++) {
+            String response = helloServiceV2.sayHello("hello, version = " + version2);
+            assert response.equals("Hello, " + response);
+
+        }
+        for (int i = 0; i < 250; i++) {
+            String response = helloServiceV3.sayHello("hello, version = " + version3);
+            assert response.equals("Hello, " + response);
+        }
+    }
+
+    private static DubboBootstrap configConsumerBootstrapWithProtocol(String protocol, RegistryConfig registryConfig) {
+        DubboBootstrap consumerBootstrap;
+        consumerBootstrap = DubboBootstrap.newInstance();
+        consumerBootstrap.application("consumer-app")
+                .registry(registryConfig)
+                .reference(builder -> builder.interfaceClass(DemoService.class).version(version1).protocol(protocol).injvm(false))
+                .reference(builder -> builder.interfaceClass(HelloService.class).version(version2).protocol(protocol).injvm(false))
+                .reference(builder -> builder.interfaceClass(HelloService.class).version(version3).protocol(protocol).injvm(false));
+        consumerBootstrap.start();
+        return consumerBootstrap;
+    }
+
+}
diff --git a/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/BaseTest.java b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/BaseTest.java
new file mode 100644
index 00000000..34a015d4
--- /dev/null
+++ b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/BaseTest.java
@@ -0,0 +1,102 @@
+/*
+ * 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.dubbo.samples.spring;
+
+import org.apache.dubbo.common.threadlocal.NamedInternalThreadFactory;
+import org.apache.dubbo.common.threadpool.manager.ExecutorRepository;
+import org.apache.dubbo.common.threadpool.manager.IsolationExecutorRepository;
+import org.apache.dubbo.common.utils.NamedThreadFactory;
+import org.apache.dubbo.config.ServiceConfig;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+import org.apache.dubbo.samples.spring.support.DemoServiceExecutor;
+import org.apache.dubbo.samples.spring.support.HelloServiceExecutor;
+import org.apache.dubbo.samples.support.DemoService;
+import org.apache.dubbo.samples.support.HelloService;
+import org.springframework.context.ApplicationContext;
+
+import java.util.Map;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public abstract class BaseTest {
+
+    protected ServiceConfig serviceConfig1;
+    protected ServiceConfig serviceConfig2;
+    protected ServiceConfig serviceConfig3;
+
+    protected void assertExecutor(ApplicationContext providerContext, ApplicationContext consumerContext) {
+
+        // find configured "executor-demo-service" executor
+        Map<String, DemoServiceExecutor> beansOfType1 = providerContext.getBeansOfType(DemoServiceExecutor.class);
+        ThreadPoolExecutor executor1 = beansOfType1.get("executor-demo-service");
+        NamedThreadFactory threadFactory1 = (NamedThreadFactory) executor1.getThreadFactory();
+
+        // find configured "executor-hello-service" executor
+        Map<String, HelloServiceExecutor> beansOfType2 = providerContext.getBeansOfType(HelloServiceExecutor.class);
+        ThreadPoolExecutor executor2 = beansOfType2.get("executor-hello-service");
+        NamedThreadFactory threadFactory2 = (NamedThreadFactory) executor2.getThreadFactory();
+
+        // Verify that the executor is the previously configured
+        Map<String, ApplicationModel> applicationModelMap = providerContext.getBeansOfType(ApplicationModel.class);
+        ApplicationModel applicationModel = applicationModelMap.get(ApplicationModel.class.getName());
+        ExecutorRepository repository = ExecutorRepository.getInstance(applicationModel);
+        assert repository instanceof IsolationExecutorRepository;
+        assert executor1.equals(repository.getExecutor(serviceConfig1.toUrl()));
+        assert executor2.equals(repository.getExecutor(serviceConfig2.toUrl()));
+        // the default executor of serviceConfig3 is built using the threadpool parameter of the protocol
+        ThreadPoolExecutor executor3 = (ThreadPoolExecutor) repository.getExecutor(serviceConfig3.toUrl());
+        assert executor3.getThreadFactory() instanceof NamedInternalThreadFactory;
+        NamedInternalThreadFactory threadFactory3 = (NamedInternalThreadFactory) executor3.getThreadFactory();
+
+        // rpc invoke with dubbo protocol
+        DemoService demoServiceV1 = consumerContext.getBean("dubbo-demoServiceV1", DemoService.class);
+        HelloService helloServiceV2 = consumerContext.getBean("dubbo-helloServiceV2", HelloService.class);
+        HelloService helloServiceV3 = consumerContext.getBean("dubbo-helloServiceV3", HelloService.class);
+        rpcInvoke(demoServiceV1, helloServiceV2, helloServiceV3);
+
+        // rpc invoke with tri protocol
+        demoServiceV1 = consumerContext.getBean("tri-demoServiceV1", DemoService.class);
+        helloServiceV2 = consumerContext.getBean("tri-helloServiceV2", HelloService.class);
+        helloServiceV3 = consumerContext.getBean("tri-helloServiceV3", HelloService.class);
+        rpcInvoke(demoServiceV1, helloServiceV2, helloServiceV3);
+
+        // Verify that when the provider accepts different service requests,
+        // whether to use the respective executor(threadFactory) of different services to create threads
+        AtomicInteger threadNum1 = threadFactory1.getThreadNum();
+        AtomicInteger threadNum2 = threadFactory2.getThreadNum();
+        AtomicInteger threadNum3 = threadFactory3.getThreadNum();
+        assert threadNum1.get() == 11;
+        assert threadNum2.get() == 101;
+        assert threadNum3.get() == 201;
+    }
+
+    private void rpcInvoke(DemoService demoServiceV1, HelloService helloServiceV2, HelloService helloServiceV3) {
+        for (int i = 0; i < 250; i++) {
+            String response = demoServiceV1.sayName("name");
+            assert response.equals("say:" + response);
+        }
+        for (int i = 0; i < 250; i++) {
+            String response = helloServiceV2.sayHello("hello");
+            assert response.equals("Hello, " + response);
+        }
+        for (int i = 0; i < 250; i++) {
+            String response = helloServiceV3.sayHello("hello");
+            assert response.equals("Hello, " + response);
+        }
+    }
+
+}
diff --git a/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/annotation/AnnotationIsolationTest.java b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/annotation/AnnotationIsolationTest.java
new file mode 100644
index 00000000..98fb47bc
--- /dev/null
+++ b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/annotation/AnnotationIsolationTest.java
@@ -0,0 +1,132 @@
+/*
+ * 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.dubbo.samples.spring.annotation;
+
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.ProtocolConfig;
+import org.apache.dubbo.config.RegistryConfig;
+import org.apache.dubbo.config.ServiceConfig;
+import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
+import org.apache.dubbo.samples.spring.BaseTest;
+import org.apache.dubbo.samples.spring.support.DemoServiceExecutor;
+import org.apache.dubbo.samples.spring.support.HelloServiceExecutor;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.Map;
+import java.util.concurrent.Executor;
+
+import static org.apache.dubbo.common.constants.CommonConstants.EXECUTOR_MANAGEMENT_MODE_ISOLATION;
+
+public class AnnotationIsolationTest extends BaseTest {
+
+    public void test() {
+        // start provider app
+        AnnotationConfigApplicationContext providerContext = new AnnotationConfigApplicationContext(ProviderConfiguration.class);
+        providerContext.start();
+
+        // start consumer app
+        AnnotationConfigApplicationContext consumerContext = new AnnotationConfigApplicationContext(ConsumerConfiguration.class);
+        consumerContext.start();
+
+        // getAndSet serviceConfig
+        setServiceConfig(providerContext);
+
+        // assert isolation of executor
+        assertExecutor(providerContext, consumerContext);
+
+        // close context
+        providerContext.close();
+        consumerContext.close();
+
+    }
+
+    private void setServiceConfig(AnnotationConfigApplicationContext providerContext) {
+        Map<String, ServiceConfig> serviceConfigMap = providerContext.getBeansOfType(ServiceConfig.class);
+        serviceConfig1 = serviceConfigMap.get("ServiceBean:org.apache.dubbo.samples.support.DemoService:1.0.0:Group1");
+        serviceConfig2 = serviceConfigMap.get("ServiceBean:org.apache.dubbo.samples.support.HelloService:2.0.0:Group2");
+        serviceConfig3 = serviceConfigMap.get("ServiceBean:org.apache.dubbo.samples.support.HelloService:3.0.0:Group3");
+    }
+
+    // note scanBasePackages, refer three service with dubbo and tri protocol
+    @Configuration
+    @EnableDubbo(scanBasePackages = "org.apache.dubbo.samples.spring.annotation.consumer")
+    @ComponentScan(value = {"org.apache.dubbo.samples.spring.annotation.consumer"})
+    static class ConsumerConfiguration {
+        @Bean
+        public RegistryConfig registryConfig() {
+            RegistryConfig registryConfig = new RegistryConfig();
+            registryConfig.setAddress("zookeeper://127.0.0.1:2181");
+            return registryConfig;
+        }
+
+        @Bean
+        public ApplicationConfig applicationConfig() {
+            ApplicationConfig applicationConfig = new ApplicationConfig("consumer-app");
+            return applicationConfig;
+        }
+    }
+
+    // note scanBasePackages, expose three service with dubbo and tri protocol
+    @Configuration
+    @EnableDubbo(scanBasePackages = "org.apache.dubbo.samples.spring.annotation.provider")
+    static class ProviderConfiguration {
+        @Bean
+        public RegistryConfig registryConfig() {
+            RegistryConfig registryConfig = new RegistryConfig();
+            registryConfig.setAddress("zookeeper://127.0.0.1:2181");
+            return registryConfig;
+        }
+
+        // NOTE: we need config executor-management-mode="isolation"
+        @Bean
+        public ApplicationConfig applicationConfig() {
+            ApplicationConfig applicationConfig = new ApplicationConfig("provider-app");
+
+            applicationConfig.setExecutorManagementMode(EXECUTOR_MANAGEMENT_MODE_ISOLATION);
+            return applicationConfig;
+        }
+
+        // expose services with dubbo protocol
+        @Bean
+        public ProtocolConfig dubbo() {
+            ProtocolConfig protocolConfig = new ProtocolConfig("dubbo");
+            return protocolConfig;
+        }
+
+        // expose services with tri protocol
+        @Bean
+        public ProtocolConfig tri() {
+            ProtocolConfig protocolConfig = new ProtocolConfig("tri");
+            return protocolConfig;
+        }
+
+        // customized thread pool
+        @Bean("executor-demo-service")
+        public Executor demoServiceExecutor() {
+            return new DemoServiceExecutor();
+        }
+
+        // customized thread pool
+        @Bean("executor-hello-service")
+        public Executor helloServiceExecutor() {
+            return new HelloServiceExecutor();
+        }
+    }
+}
diff --git a/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/annotation/consumer/dubbo/DemoServiceV1.java b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/annotation/consumer/dubbo/DemoServiceV1.java
new file mode 100644
index 00000000..f17e4dcd
--- /dev/null
+++ b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/annotation/consumer/dubbo/DemoServiceV1.java
@@ -0,0 +1,32 @@
+/*
+ * 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.dubbo.samples.spring.annotation.consumer.dubbo;
+
+import org.apache.dubbo.config.annotation.DubboReference;
+import org.apache.dubbo.samples.support.DemoService;
+import org.springframework.stereotype.Component;
+
+@Component("dubbo-demoServiceV1")
+public class DemoServiceV1 implements DemoService {
+    @DubboReference(version = "1.0.0", group = "Group1", scope = "remote", protocol = "dubbo")
+    private DemoService demoService;
+
+    @Override
+    public String sayName(String name) {
+        return demoService.sayName(name);
+    }
+}
diff --git a/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/annotation/consumer/dubbo/HelloServiceV2.java b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/annotation/consumer/dubbo/HelloServiceV2.java
new file mode 100644
index 00000000..090ec2d8
--- /dev/null
+++ b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/annotation/consumer/dubbo/HelloServiceV2.java
@@ -0,0 +1,32 @@
+/*
+ * 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.dubbo.samples.spring.annotation.consumer.dubbo;
+
+import org.apache.dubbo.config.annotation.DubboReference;
+import org.apache.dubbo.samples.support.HelloService;
+import org.springframework.stereotype.Component;
+
+@Component("dubbo-helloServiceV2")
+public class HelloServiceV2 implements HelloService {
+    @DubboReference(version = "2.0.0", group = "Group2", scope = "remote", protocol = "dubbo")
+    private HelloService helloService;
+
+    @Override
+    public String sayHello(String name) {
+        return helloService.sayHello(name);
+    }
+}
diff --git a/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/annotation/consumer/dubbo/HelloServiceV3.java b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/annotation/consumer/dubbo/HelloServiceV3.java
new file mode 100644
index 00000000..d3a69818
--- /dev/null
+++ b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/annotation/consumer/dubbo/HelloServiceV3.java
@@ -0,0 +1,32 @@
+/*
+ * 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.dubbo.samples.spring.annotation.consumer.dubbo;
+
+import org.apache.dubbo.config.annotation.DubboReference;
+import org.apache.dubbo.samples.support.HelloService;
+import org.springframework.stereotype.Component;
+
+@Component("dubbo-helloServiceV3")
+public class HelloServiceV3 implements HelloService {
+    @DubboReference(version = "3.0.0", group = "Group3", scope = "remote", protocol = "dubbo")
+    private HelloService helloService;
+
+    @Override
+    public String sayHello(String name) {
+        return helloService.sayHello(name);
+    }
+}
diff --git a/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/annotation/consumer/tri/DemoServiceV1.java b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/annotation/consumer/tri/DemoServiceV1.java
new file mode 100644
index 00000000..28f76aa7
--- /dev/null
+++ b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/annotation/consumer/tri/DemoServiceV1.java
@@ -0,0 +1,32 @@
+/*
+ * 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.dubbo.samples.spring.annotation.consumer.tri;
+
+import org.apache.dubbo.config.annotation.DubboReference;
+import org.apache.dubbo.samples.support.DemoService;
+import org.springframework.stereotype.Component;
+
+@Component("tri-demoServiceV1")
+public class DemoServiceV1 implements DemoService {
+    @DubboReference(version = "1.0.0",group = "Group1", scope = "remote", protocol = "tri")
+    private DemoService demoService;
+
+    @Override
+    public String sayName(String name) {
+        return demoService.sayName(name);
+    }
+}
diff --git a/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/annotation/consumer/tri/HelloServiceV2.java b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/annotation/consumer/tri/HelloServiceV2.java
new file mode 100644
index 00000000..abadc55f
--- /dev/null
+++ b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/annotation/consumer/tri/HelloServiceV2.java
@@ -0,0 +1,32 @@
+/*
+ * 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.dubbo.samples.spring.annotation.consumer.tri;
+
+import org.apache.dubbo.config.annotation.DubboReference;
+import org.apache.dubbo.samples.support.HelloService;
+import org.springframework.stereotype.Component;
+
+@Component("tri-helloServiceV2")
+public class HelloServiceV2 implements HelloService {
+    @DubboReference(version = "2.0.0", group = "Group2", scope = "remote", protocol = "tri")
+    private HelloService helloService;
+
+    @Override
+    public String sayHello(String name) {
+        return helloService.sayHello(name);
+    }
+}
diff --git a/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/annotation/consumer/tri/HelloServiceV3.java b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/annotation/consumer/tri/HelloServiceV3.java
new file mode 100644
index 00000000..3e4302f7
--- /dev/null
+++ b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/annotation/consumer/tri/HelloServiceV3.java
@@ -0,0 +1,32 @@
+/*
+ * 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.dubbo.samples.spring.annotation.consumer.tri;
+
+import org.apache.dubbo.config.annotation.DubboReference;
+import org.apache.dubbo.samples.support.HelloService;
+import org.springframework.stereotype.Component;
+
+@Component("tri-helloServiceV3")
+public class HelloServiceV3 implements HelloService {
+    @DubboReference(version = "3.0.0", group = "Group3", scope = "remote", protocol = "tri")
+    private HelloService helloService;
+
+    @Override
+    public String sayHello(String name) {
+        return helloService.sayHello(name);
+    }
+}
diff --git a/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/annotation/provider/DemoServiceImplV1.java b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/annotation/provider/DemoServiceImplV1.java
new file mode 100644
index 00000000..6bf3cfde
--- /dev/null
+++ b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/annotation/provider/DemoServiceImplV1.java
@@ -0,0 +1,28 @@
+/*
+ * 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.dubbo.samples.spring.annotation.provider;
+
+import org.apache.dubbo.config.annotation.DubboService;
+import org.apache.dubbo.samples.support.DemoService;
+
+@DubboService(executor = "executor-demo-service", version = "1.0.0", group = "Group1")
+public class DemoServiceImplV1 implements DemoService {
+    @Override
+    public String sayName(String name) {
+        return "server name";
+    }
+}
diff --git a/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/annotation/provider/HelloServiceImplV2.java b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/annotation/provider/HelloServiceImplV2.java
new file mode 100644
index 00000000..fc45d056
--- /dev/null
+++ b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/annotation/provider/HelloServiceImplV2.java
@@ -0,0 +1,32 @@
+/*
+ * 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.dubbo.samples.spring.annotation.provider;
+
+import org.apache.dubbo.config.annotation.DubboService;
+import org.apache.dubbo.samples.support.HelloService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@DubboService(version = "3.0.0", group = "Group3")
+public class HelloServiceImplV2 implements HelloService {
+    private static final Logger logger = LoggerFactory.getLogger(HelloServiceImplV2.class);
+
+    @Override
+    public String sayHello(String name) {
+        return "server hello";
+    }
+}
diff --git a/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/annotation/provider/HelloServiceImplV3.java b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/annotation/provider/HelloServiceImplV3.java
new file mode 100644
index 00000000..21aa0150
--- /dev/null
+++ b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/annotation/provider/HelloServiceImplV3.java
@@ -0,0 +1,33 @@
+/*
+ * 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.dubbo.samples.spring.annotation.provider;
+
+import org.apache.dubbo.config.annotation.DubboService;
+import org.apache.dubbo.samples.support.HelloService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@DubboService(executor = "executor-hello-service", version = "2.0.0", group = "Group2")
+public class HelloServiceImplV3 implements HelloService {
+    private static final Logger logger = LoggerFactory.getLogger(HelloServiceImplV3.class);
+
+    @Override
+    public String sayHello(String name) {
+        return "server hello";
+    }
+
+}
diff --git a/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/support/DemoServiceExecutor.java b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/support/DemoServiceExecutor.java
new file mode 100644
index 00000000..b38d70bc
--- /dev/null
+++ b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/support/DemoServiceExecutor.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.dubbo.samples.spring.support;
+
+import org.apache.dubbo.common.utils.NamedThreadFactory;
+
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+public class DemoServiceExecutor extends ThreadPoolExecutor {
+    public DemoServiceExecutor() {
+        super(10, 10, 60, TimeUnit.SECONDS, new LinkedBlockingDeque<>(),
+            new NamedThreadFactory("DemoServiceExecutor"));
+    }
+}
diff --git a/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/support/HelloServiceExecutor.java b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/support/HelloServiceExecutor.java
new file mode 100644
index 00000000..9d9a86ce
--- /dev/null
+++ b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/support/HelloServiceExecutor.java
@@ -0,0 +1,31 @@
+/*
+ * 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.dubbo.samples.spring.support;
+
+import org.apache.dubbo.common.utils.NamedThreadFactory;
+
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+public class HelloServiceExecutor extends ThreadPoolExecutor {
+    public HelloServiceExecutor() {
+        super(100, 100, 60, TimeUnit.SECONDS, new LinkedBlockingDeque<>(),
+            new NamedThreadFactory("HelloServiceExecutor"));
+    }
+
+}
diff --git a/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/xml/XmlIsolationTest.java b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/xml/XmlIsolationTest.java
new file mode 100644
index 00000000..06bed9e6
--- /dev/null
+++ b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/spring/xml/XmlIsolationTest.java
@@ -0,0 +1,54 @@
+/*
+ * 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.dubbo.samples.spring.xml;
+
+import org.apache.dubbo.config.ServiceConfig;
+import org.apache.dubbo.samples.spring.BaseTest;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+import java.util.Map;
+
+public class XmlIsolationTest extends BaseTest {
+
+    public void test() {
+        // start provider app
+        ClassPathXmlApplicationContext providerContext = new ClassPathXmlApplicationContext("META-INF/isolation/dubbo-provider.xml");
+        providerContext.start();
+
+        // start consumer app
+        ClassPathXmlApplicationContext consumerContext = new ClassPathXmlApplicationContext("META-INF/isolation/dubbo-consumer.xml");
+        consumerContext.start();
+
+        // getAndSet serviceConfig
+        setServiceConfig(providerContext);
+
+        // assert isolation of executor
+        assertExecutor(providerContext, consumerContext);
+
+        // close context
+        providerContext.close();
+        consumerContext.close();
+    }
+
+    private void setServiceConfig(ClassPathXmlApplicationContext providerContext) {
+        Map<String, ServiceConfig> serviceConfigMap = providerContext.getBeansOfType(ServiceConfig.class);
+        serviceConfig1 = serviceConfigMap.get("org.apache.dubbo.config.spring.ServiceBean#0");
+        serviceConfig2 = serviceConfigMap.get("org.apache.dubbo.config.spring.ServiceBean#1");
+        serviceConfig3 = serviceConfigMap.get("org.apache.dubbo.config.spring.ServiceBean#2");
+    }
+
+}
diff --git a/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/support/DemoService.java b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/support/DemoService.java
new file mode 100644
index 00000000..5ea98c1a
--- /dev/null
+++ b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/support/DemoService.java
@@ -0,0 +1,21 @@
+/*
+ * 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.dubbo.samples.support;
+
+public interface DemoService {
+    String sayName(String name);
+}
diff --git a/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/support/DemoServiceImpl.java b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/support/DemoServiceImpl.java
new file mode 100644
index 00000000..36e1cb8a
--- /dev/null
+++ b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/support/DemoServiceImpl.java
@@ -0,0 +1,26 @@
+/*
+ * 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.dubbo.samples.support;
+
+public class DemoServiceImpl implements DemoService {
+
+    private String prefix = "say:";
+
+    public String sayName(String name) {
+        return prefix + name;
+    }
+}
diff --git a/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/support/HelloService.java b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/support/HelloService.java
new file mode 100644
index 00000000..15aed430
--- /dev/null
+++ b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/support/HelloService.java
@@ -0,0 +1,22 @@
+/*
+ * 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.dubbo.samples.support;
+
+public interface HelloService {
+    String sayHello(String name);
+}
diff --git a/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/support/HelloServiceImpl.java b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/support/HelloServiceImpl.java
new file mode 100644
index 00000000..12a5a664
--- /dev/null
+++ b/dubbo-samples-isolation-executor/src/main/java/org/apache/dubbo/samples/support/HelloServiceImpl.java
@@ -0,0 +1,24 @@
+/*
+ * 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.dubbo.samples.support;
+
+public class HelloServiceImpl implements HelloService {
+
+    public String sayHello(String name) {
+        return "Hello, " + name;
+    }
+}
diff --git a/dubbo-samples-isolation-executor/src/main/resources/META-INF/isolation/dubbo-consumer.xml b/dubbo-samples-isolation-executor/src/main/resources/META-INF/isolation/dubbo-consumer.xml
new file mode 100644
index 00000000..7794d55c
--- /dev/null
+++ b/dubbo-samples-isolation-executor/src/main/resources/META-INF/isolation/dubbo-consumer.xml
@@ -0,0 +1,51 @@
+<?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.
+  -->
+<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
+       xmlns="http://www.springframework.org/schema/beans"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
+       http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
+
+    <dubbo:application name="demo-consumer">
+    </dubbo:application>
+
+    <dubbo:metadata-report address="zookeeper://127.0.0.1:2181"/>
+
+    <dubbo:registry id="demo1" address="zookeeper://127.0.0.1:2181?registry-type=service"/>
+
+    <!-- refer with dubbo protocol-->
+    <dubbo:reference version="1.0.0" group="Group1" id="dubbo-demoServiceV1" check="false" scope="remote"
+                     interface="org.apache.dubbo.samples.support.DemoService" protocol="dubbo"/>
+
+    <dubbo:reference version="2.0.0" group="Group2" id="dubbo-helloServiceV2" check="false" scope="remote"
+                     interface="org.apache.dubbo.samples.support.HelloService" protocol="dubbo"/>
+
+    <dubbo:reference version="3.0.0" group="Group3" id="dubbo-helloServiceV3" check="false" scope="remote"
+                     interface="org.apache.dubbo.samples.support.HelloService" protocol="dubbo"/>
+
+    <!-- refer with tri protocol-->
+    <dubbo:reference version="1.0.0" group="Group1" id="tri-demoServiceV1" check="false" scope="remote"
+                     interface="org.apache.dubbo.samples.support.DemoService" protocol="tri"/>
+
+    <dubbo:reference version="2.0.0" group="Group2" id="tri-helloServiceV2" check="false" scope="remote"
+                     interface="org.apache.dubbo.samples.support.HelloService" protocol="tri"/>
+
+    <dubbo:reference version="3.0.0" group="Group3" id="tri-helloServiceV3" check="false" scope="remote"
+                     interface="org.apache.dubbo.samples.support.HelloService" protocol="tri"/>
+
+</beans>
diff --git a/dubbo-samples-isolation-executor/src/main/resources/META-INF/isolation/dubbo-provider.xml b/dubbo-samples-isolation-executor/src/main/resources/META-INF/isolation/dubbo-provider.xml
new file mode 100644
index 00000000..74677f67
--- /dev/null
+++ b/dubbo-samples-isolation-executor/src/main/resources/META-INF/isolation/dubbo-provider.xml
@@ -0,0 +1,60 @@
+<?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.
+  -->
+<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
+       xmlns="http://www.springframework.org/schema/beans"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
+       http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
+
+    <!-- NOTE: we need config executor-management-mode="isolation" -->
+    <dubbo:application name="demo-provider" executor-management-mode="isolation">
+    </dubbo:application>
+
+    <dubbo:config-center address="zookeeper://127.0.0.1:2181"/>
+    <dubbo:metadata-report address="zookeeper://127.0.0.1:2181"/>
+    <dubbo:registry id="registry1" address="zookeeper://127.0.0.1:2181?registry-type=service"/>
+
+    <dubbo:protocol name="dubbo" port="-1"/>
+    <dubbo:protocol name="tri" port="-1"/>
+
+    <!-- expose three service with dubbo and tri protocol-->
+    <bean id="demoServiceV1" class="org.apache.dubbo.samples.support.DemoServiceImpl"/>
+    <bean id="helloServiceV2" class="org.apache.dubbo.samples.support.HelloServiceImpl"/>
+    <bean id="helloServiceV3" class="org.apache.dubbo.samples.support.HelloServiceImpl"/>
+
+    <!-- customized thread pool -->
+    <bean id="executor-demo-service"
+          class="org.apache.dubbo.samples.spring.support.DemoServiceExecutor"/>
+    <bean id="executor-hello-service"
+          class="org.apache.dubbo.samples.spring.support.HelloServiceExecutor"/>
+
+    <!-- this service use [executor="executor-demo-service"] as isolated thread pool-->
+    <dubbo:service executor="executor-demo-service"
+                   interface="org.apache.dubbo.samples.support.DemoService" version="1.0.0" group="Group1"
+                   timeout="3000" ref="demoServiceV1" registry="registry1" protocol="dubbo,tri"/>
+
+    <!-- this service use [executor="executor-hello-service"] as isolated thread pool-->
+    <dubbo:service executor="executor-hello-service"
+                   interface="org.apache.dubbo.samples.support.HelloService" version="2.0.0" group="Group2"
+                   timeout="5000" ref="helloServiceV2" registry="registry1" protocol="dubbo,tri"/>
+
+    <!-- not set executor for this service, the default executor built using threadpool parameter of the protocolConfig -->
+    <dubbo:service interface="org.apache.dubbo.samples.support.HelloService" version="3.0.0" group="Group3"
+                   timeout="5000" ref="helloServiceV3" registry="registry1" protocol="dubbo,tri"/>
+
+</beans>
diff --git a/dubbo-samples-isolation-executor/src/main/resources/log4j.properties b/dubbo-samples-isolation-executor/src/main/resources/log4j.properties
new file mode 100644
index 00000000..72328731
--- /dev/null
+++ b/dubbo-samples-isolation-executor/src/main/resources/log4j.properties
@@ -0,0 +1,26 @@
+#
+#
+#   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.
+#  
+#
+
+###set log levels###
+log4j.rootLogger=info, stdout
+###output to the console###
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=[%d{dd/MM/yy hh:mm:ss:sss z}] %t %5p %c{2}: %m%n
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 6807b3cb..8ab8283b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -93,6 +93,7 @@
         <module>dubbo-samples-triple-reactor</module>
         <module>dubbo-samples-rocketmq</module>
         <module>dubbo-samples-port-unification</module>
+        <module>dubbo-samples-isolation-executor</module>
     </modules>
 
     <repositories>


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org