You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shenyu.apache.org by zh...@apache.org on 2023/01/09 03:35:15 UTC

[shenyu] branch master updated: [ISSUE #3450]Add brpc-plugin (#4300)

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

zhangzicheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shenyu.git


The following commit(s) were added to refs/heads/master by this push:
     new 01988f4f0 [ISSUE #3450]Add brpc-plugin (#4300)
01988f4f0 is described below

commit 01988f4f039ec945eb1e4e9d2837e21be3e394be
Author: SongTao Zhuang <51...@users.noreply.github.com>
AuthorDate: Mon Jan 9 11:35:09 2023 +0800

    [ISSUE #3450]Add brpc-plugin (#4300)
    
    * add: brpc plugin
    
    * ci: common
    
    * add: spring boot starter plugin brpc
    
    * delete: spring boot starter plugin brpc
---
 .../apache/shenyu/common/constant/Constants.java   |   5 +
 .../dto/convert/plugin/BrpcRegisterConfig.java     | 183 +++++++++++
 shenyu-plugin/pom.xml                              |   1 +
 .../shenyu/plugin/api/result/ShenyuResultEnum.java |   4 +
 .../plugin/base/RpcParamTransformPlugin.java       |   3 +-
 shenyu-plugin/shenyu-plugin-brpc/pom.xml           |  60 ++++
 .../org/apache/shenyu/plugin/brpc/BrpcPlugin.java  | 112 +++++++
 .../plugin/brpc/cache/ApplicationConfigCache.java  | 353 +++++++++++++++++++++
 .../brpc/context/BrpcShenyuContextDecorator.java   |  43 +++
 .../brpc/exception/ShenyuBrpcPluginException.java  |  38 +++
 .../plugin/brpc/handler/BrpcMetaDataHandler.java   |  69 ++++
 .../plugin/brpc/handler/BrpcPluginDataHandler.java |  57 ++++
 .../shenyu/plugin/brpc/proxy/BrpcProxyService.java | 147 +++++++++
 .../shenyu/plugin/brpc/util/ProxyInfoUtil.java     | 178 +++++++++++
 .../apache/shenyu/plugin/brpc/BrpcPluginTest.java  | 107 +++++++
 .../brpc/cache/ApplicationConfigCacheTest.java     | 101 ++++++
 .../context/BrpcShenyuContextDecoratorTest.java    |  57 ++++
 .../brpc/handler/BrpcPluginDataHandlerTest.java    |  52 +++
 .../shenyu/plugin/brpc/util/ProxyInfoUtilTest.java |  81 +++++
 .../plugin/context/path/ContextPathPlugin.java     |   3 +-
 .../plugin/response/strategy/RPCMessageWriter.java |   2 +-
 .../shenyu/plugin/rewrite/RewritePlugin.java       |   3 +-
 22 files changed, 1655 insertions(+), 4 deletions(-)

diff --git a/shenyu-common/src/main/java/org/apache/shenyu/common/constant/Constants.java b/shenyu-common/src/main/java/org/apache/shenyu/common/constant/Constants.java
index 55052d52d..e45485890 100644
--- a/shenyu-common/src/main/java/org/apache/shenyu/common/constant/Constants.java
+++ b/shenyu-common/src/main/java/org/apache/shenyu/common/constant/Constants.java
@@ -82,6 +82,11 @@ public interface Constants {
      */
     String MOTAN_RPC_RESULT_EMPTY = "motan has not return value!";
 
+    /**
+     * The constant BRPC_RPC_RESULT_EMPTY.
+     */
+    String BRPC_RPC_RESULT_EMPTY = "brpc has not return value!";
+
     /**
      * The constant CLIENT_RESPONSE_RESULT_TYPE.
      */
diff --git a/shenyu-common/src/main/java/org/apache/shenyu/common/dto/convert/plugin/BrpcRegisterConfig.java b/shenyu-common/src/main/java/org/apache/shenyu/common/dto/convert/plugin/BrpcRegisterConfig.java
new file mode 100644
index 000000000..a97c56107
--- /dev/null
+++ b/shenyu-common/src/main/java/org/apache/shenyu/common/dto/convert/plugin/BrpcRegisterConfig.java
@@ -0,0 +1,183 @@
+/*
+ * 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.shenyu.common.dto.convert.plugin;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+/**
+ * The type brpc register config.
+ */
+public class BrpcRegisterConfig implements Serializable {
+
+    private static final long serialVersionUID = -1124348422759120146L;
+
+    private String address;
+
+    private Integer port;
+
+    private String threadpool;
+
+    private Integer corethreads;
+
+    private Integer threads;
+
+    private Integer queues;
+
+
+    /**
+     * get address.
+     *
+     * @return address
+     */
+    public String getAddress() {
+        return address;
+    }
+
+    /**
+     * set address.
+     *
+     * @param address address
+     */
+    public void setAddress(final String address) {
+        this.address = address;
+    }
+
+    /**
+     * get port.
+     *
+     * @return port
+     */
+    public Integer getPort() {
+        return port;
+    }
+
+    /**
+     * set port.
+     *
+     * @param port port
+     */
+    public void setPort(final Integer port) {
+        this.port = port;
+    }
+
+    /**
+     * get threadpool.
+     *
+     * @return threadpool
+     */
+    public String getThreadpool() {
+        return threadpool;
+    }
+
+    /**
+     * set threadpool.
+     *
+     * @param threadpool threadpool
+     */
+    public void setThreadpool(final String threadpool) {
+        this.threadpool = threadpool;
+    }
+
+    /**
+     * get corethreads.
+     *
+     * @return corethreads
+     */
+    public Integer getCorethreads() {
+        return corethreads;
+    }
+
+    /**
+     * set corethreads.
+     *
+     * @param corethreads corethreads
+     */
+    public void setCorethreads(final Integer corethreads) {
+        this.corethreads = corethreads;
+    }
+
+    /**
+     * get threads.
+     *
+     * @return threads
+     */
+    public Integer getThreads() {
+        return threads;
+    }
+
+    /**
+     * set threads.
+     *
+     * @param threads threads
+     */
+    public void setThreads(final Integer threads) {
+        this.threads = threads;
+    }
+
+    /**
+     * get queues.
+     *
+     * @return queues
+     */
+    public Integer getQueues() {
+        return queues;
+    }
+
+    /**
+     * set queues.
+     *
+     * @param queues queues
+     */
+    public void setQueues(final Integer queues) {
+        this.queues = queues;
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        BrpcRegisterConfig that = (BrpcRegisterConfig) o;
+        return Objects.equals(address, that.address) && Objects.equals(port, that.port)
+                && Objects.equals(threadpool, that.threadpool) && Objects.equals(corethreads, that.corethreads)
+                && Objects.equals(threads, that.threads) && Objects.equals(queues, that.queues);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(address, port, threadpool, corethreads, threads, queues);
+    }
+
+    @Override
+    public String toString() {
+        return "BrpcRegisterConfig{"
+                + "address='" + address
+                + '\''
+                + ", port=" + port
+                + ", threadpool='" + threadpool
+                + '\''
+                + ", corethreads=" + corethreads
+                + ", threads=" + threads
+                + ", queues=" + queues
+                + '}';
+    }
+}
diff --git a/shenyu-plugin/pom.xml b/shenyu-plugin/pom.xml
index 46bfd1fcb..de6994057 100644
--- a/shenyu-plugin/pom.xml
+++ b/shenyu-plugin/pom.xml
@@ -64,5 +64,6 @@
         <module>shenyu-plugin-mock</module>
         <module>shenyu-plugin-casdoor</module>
         <module>shenyu-plugin-key-auth</module>
+        <module>shenyu-plugin-brpc</module>
     </modules>
 </project>
diff --git a/shenyu-plugin/shenyu-plugin-api/src/main/java/org/apache/shenyu/plugin/api/result/ShenyuResultEnum.java b/shenyu-plugin/shenyu-plugin-api/src/main/java/org/apache/shenyu/plugin/api/result/ShenyuResultEnum.java
index b0d76cbb7..eafff3621 100644
--- a/shenyu-plugin/shenyu-plugin-api/src/main/java/org/apache/shenyu/plugin/api/result/ShenyuResultEnum.java
+++ b/shenyu-plugin/shenyu-plugin-api/src/main/java/org/apache/shenyu/plugin/api/result/ShenyuResultEnum.java
@@ -107,6 +107,10 @@ public enum ShenyuResultEnum {
      */
     MOTAN_HAVE_BODY_PARAM(437, "Motan must have body param, please enter the JSON format in the body!"),
 
+    /**
+     * Brpc have body param shenyu result enum.
+     */
+    BRPC_HAVE_BODY_PARAM(438, "Brpc must have body param, please enter the JSON format in the body!"),
 
     /**
      * full selector type enum.
diff --git a/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/RpcParamTransformPlugin.java b/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/RpcParamTransformPlugin.java
index fd5b01edd..c40263070 100644
--- a/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/RpcParamTransformPlugin.java
+++ b/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/RpcParamTransformPlugin.java
@@ -113,7 +113,8 @@ public class RpcParamTransformPlugin implements ShenyuPlugin {
                 RpcTypeEnum.GRPC,
                 RpcTypeEnum.TARS,
                 RpcTypeEnum.MOTAN,
-                RpcTypeEnum.SOFA);
+                RpcTypeEnum.SOFA,
+                RpcTypeEnum.BRPC);
     }
 
     @NonNull
diff --git a/shenyu-plugin/shenyu-plugin-brpc/pom.xml b/shenyu-plugin/shenyu-plugin-brpc/pom.xml
new file mode 100644
index 000000000..f0cf7e107
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-brpc/pom.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.
+  -->
+
+<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">
+    <parent>
+        <groupId>org.apache.shenyu</groupId>
+        <artifactId>shenyu-plugin</artifactId>
+        <version>2.5.1-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>shenyu-plugin-brpc</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.shenyu</groupId>
+            <artifactId>shenyu-plugin-base</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>io.projectreactor</groupId>
+            <artifactId>reactor-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>com.baidu.cloud</groupId>
+            <artifactId>spring-cloud-starter-baidu-starlight</artifactId>
+            <version>${brpc.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
+            <version>${spring-cloud.version}</version>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/shenyu-plugin/shenyu-plugin-brpc/src/main/java/org/apache/shenyu/plugin/brpc/BrpcPlugin.java b/shenyu-plugin/shenyu-plugin-brpc/src/main/java/org/apache/shenyu/plugin/brpc/BrpcPlugin.java
new file mode 100644
index 000000000..33847e4d1
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-brpc/src/main/java/org/apache/shenyu/plugin/brpc/BrpcPlugin.java
@@ -0,0 +1,112 @@
+/*
+ * 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.shenyu.plugin.brpc;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shenyu.common.constant.Constants;
+import org.apache.shenyu.common.dto.MetaData;
+import org.apache.shenyu.common.dto.RuleData;
+import org.apache.shenyu.common.dto.SelectorData;
+import org.apache.shenyu.common.enums.PluginEnum;
+import org.apache.shenyu.common.enums.RpcTypeEnum;
+import org.apache.shenyu.plugin.api.ShenyuPluginChain;
+import org.apache.shenyu.plugin.api.context.ShenyuContext;
+import org.apache.shenyu.plugin.api.result.ShenyuResultEnum;
+import org.apache.shenyu.plugin.api.result.ShenyuResultWrap;
+import org.apache.shenyu.plugin.api.utils.WebFluxResultUtils;
+import org.apache.shenyu.plugin.base.AbstractShenyuPlugin;
+import org.apache.shenyu.plugin.brpc.proxy.BrpcProxyService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+import java.util.Objects;
+
+/**
+ * The type brpc plugin.
+ */
+public class BrpcPlugin extends AbstractShenyuPlugin {
+
+    private static final Logger LOG = LoggerFactory.getLogger(BrpcPlugin.class);
+
+    private final BrpcProxyService brpcProxyService;
+
+    /**
+     * Instantiates a new brpc plugin.
+     *
+     * @param brpcProxyService the brpc proxy service
+     */
+    public BrpcPlugin(final BrpcProxyService brpcProxyService) {
+        this.brpcProxyService = brpcProxyService;
+    }
+
+    @Override
+    protected Mono<Void> doExecute(final ServerWebExchange exchange, final ShenyuPluginChain chain, final SelectorData selector, final RuleData rule) {
+        String param = exchange.getAttribute(Constants.PARAM_TRANSFORM);
+        ShenyuContext shenyuContext = exchange.getAttribute(Constants.CONTEXT);
+        assert shenyuContext != null;
+        MetaData metaData = exchange.getAttribute(Constants.META_DATA);
+        if (!checkMetaData(metaData)) {
+            assert metaData != null;
+            LOG.error("path is :{}, meta data have error.... {}", shenyuContext.getPath(), metaData);
+            exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
+            Object error = ShenyuResultWrap.error(exchange, ShenyuResultEnum.META_DATA_ERROR);
+            return WebFluxResultUtils.result(exchange, error);
+        }
+        if (StringUtils.isNoneBlank(metaData.getParameterTypes()) && StringUtils.isBlank(param)) {
+            exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
+            Object error = ShenyuResultWrap.error(exchange, ShenyuResultEnum.BRPC_HAVE_BODY_PARAM);
+            return WebFluxResultUtils.result(exchange, error);
+        }
+        final Mono<Object> result = brpcProxyService.genericInvoker(param, metaData, exchange);
+        return result.then(chain.execute(exchange));
+    }
+
+    @Override
+    public int getOrder() {
+        return PluginEnum.BRPC.getCode();
+    }
+
+    @Override
+    public String named() {
+        return PluginEnum.BRPC.getName();
+    }
+
+    @Override
+    public boolean skip(final ServerWebExchange exchange) {
+        return skipExcept(exchange, RpcTypeEnum.BRPC);
+    }
+
+    @Override
+    protected Mono<Void> handleSelectorIfNull(final String pluginName, final ServerWebExchange exchange, final ShenyuPluginChain chain) {
+        return WebFluxResultUtils.noSelectorResult(pluginName, exchange);
+    }
+
+    @Override
+    protected Mono<Void> handleRuleIfNull(final String pluginName, final ServerWebExchange exchange, final ShenyuPluginChain chain) {
+        return WebFluxResultUtils.noRuleResult(pluginName, exchange);
+    }
+
+    private boolean checkMetaData(final MetaData metaData) {
+        return Objects.nonNull(metaData)
+                && StringUtils.isNoneBlank(metaData.getMethodName())
+                && StringUtils.isNoneBlank(metaData.getServiceName());
+    }
+}
diff --git a/shenyu-plugin/shenyu-plugin-brpc/src/main/java/org/apache/shenyu/plugin/brpc/cache/ApplicationConfigCache.java b/shenyu-plugin/shenyu-plugin-brpc/src/main/java/org/apache/shenyu/plugin/brpc/cache/ApplicationConfigCache.java
new file mode 100644
index 000000000..e130fff42
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-brpc/src/main/java/org/apache/shenyu/plugin/brpc/cache/ApplicationConfigCache.java
@@ -0,0 +1,353 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.plugin.brpc.cache;
+
+import com.baidu.cloud.starlight.api.rpc.StarlightClient;
+import com.baidu.cloud.starlight.api.rpc.config.ServiceConfig;
+import com.baidu.cloud.starlight.api.rpc.config.TransportConfig;
+import com.baidu.cloud.starlight.core.rpc.SingleStarlightClient;
+import com.baidu.cloud.starlight.core.rpc.generic.AsyncGenericService;
+import com.baidu.cloud.starlight.core.rpc.proxy.JDKProxyFactory;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.shenyu.common.constant.Constants;
+import org.apache.shenyu.common.dto.MetaData;
+import org.apache.shenyu.common.dto.convert.plugin.BrpcRegisterConfig;
+import org.apache.shenyu.common.utils.GsonUtils;
+import org.apache.shenyu.plugin.brpc.exception.ShenyuBrpcPluginException;
+import org.apache.shenyu.plugin.brpc.util.ProxyInfoUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.lang.NonNull;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutionException;
+
+/**
+ * Brpc config cache.
+ */
+public final class ApplicationConfigCache {
+
+    /**
+     * The constant PARAM_MAP.
+     */
+    public static final ConcurrentMap<String, BrpcParamInfo> PARAM_MAP = new ConcurrentHashMap<>();
+
+    private static final String BRPC_PROTOCOL = "brpc";
+
+    private static final Logger LOG = LoggerFactory.getLogger(ApplicationConfigCache.class);
+
+    private StarlightClient clientConfig;
+
+    private JDKProxyFactory proxyFactory;
+
+    private final LoadingCache<String, AsyncGenericService> cache = CacheBuilder.newBuilder()
+            .maximumSize(Constants.CACHE_MAX_COUNT)
+            .build(new CacheLoader<String, AsyncGenericService>() {
+                @Override
+                public AsyncGenericService load(@NonNull final String key) {
+                    return null;
+                }
+            });
+
+    private ApplicationConfigCache() {
+    }
+
+    /**
+     * init service.
+     *
+     * @param metaData the meta data
+     * @return service
+     */
+    public AsyncGenericService initService(final MetaData metaData) {
+        try {
+            AsyncGenericService service = cache.get(metaData.getPath());
+            if (Objects.nonNull(service)) {
+                return service;
+            }
+        } catch (Exception e) {
+            LOG.warn("init brpc ref ex:{}", e.getMessage());
+        }
+        return build(metaData);
+    }
+
+    /**
+     * init brpc config.
+     *
+     * @param brpcRegisterConfig the config of brpc
+     */
+    public void init(final BrpcRegisterConfig brpcRegisterConfig) {
+        if (Objects.isNull(clientConfig)) {
+            TransportConfig config = new TransportConfig();
+            clientConfig = new SingleStarlightClient(brpcRegisterConfig.getAddress(), brpcRegisterConfig.getPort(), config);
+            clientConfig.init();
+            proxyFactory = new JDKProxyFactory();
+        }
+    }
+
+    /**
+     * Build service.
+     *
+     * @param metaData the meta data
+     * @return service
+     */
+    public AsyncGenericService build(final MetaData metaData) {
+        if (Objects.isNull(clientConfig)) {
+            throw new UnsupportedOperationException("unsupport!!");
+        }
+        ServiceConfig serviceConfig = new ServiceConfig();
+        serviceConfig.setProtocol(BRPC_PROTOCOL);
+        serviceConfig.setServiceId(metaData.getServiceName());
+
+        BrpcParamExtInfo brpcParamExtInfo =
+                GsonUtils.getInstance().fromJson(metaData.getRpcExt(), BrpcParamExtInfo.class);
+        brpcParamExtInfo.getMethodInfo().forEach(methodInfo -> {
+            if (CollectionUtils.isNotEmpty(methodInfo.getParamTypes())) {
+                try {
+                    Class<?>[] paramTypes = new Class[methodInfo.getParamTypes().size()];
+                    String[] paramNames = new String[methodInfo.getParamTypes().size()];
+                    for (int i = 0; i < methodInfo.getParamTypes().size(); i++) {
+                        Pair<String, String> pair = methodInfo.getParamTypes().get(i);
+                        paramTypes[i] = ProxyInfoUtil.getParamClass(pair.getKey());
+                        paramNames[i] = pair.getValue();
+                        PARAM_MAP.put(methodInfo.getMethodName(), new BrpcParamInfo(paramTypes, paramNames));
+                    }
+                } catch (Exception e) {
+                    LOG.error("failed to init brpc, {}", e.getMessage());
+                    throw new ShenyuBrpcPluginException(e.getCause());
+                }
+            }
+        });
+        AsyncGenericService service = proxyFactory.getProxy(AsyncGenericService.class, serviceConfig, clientConfig);
+        cache.put(metaData.getPath(), service);
+        return service;
+    }
+
+    /**
+     * Get service.
+     *
+     * @param path path
+     * @return the service
+     */
+    public AsyncGenericService get(final String path) {
+        try {
+            return cache.get(path);
+        } catch (ExecutionException e) {
+            throw new ShenyuBrpcPluginException(e.getCause());
+        }
+    }
+
+    /**
+     * Invalidate.
+     *
+     * @param path the path name
+     */
+    public void invalidate(final String path) {
+        cache.invalidate(path);
+    }
+
+    /**
+     * Invalidate all.
+     */
+    public void invalidateAll() {
+        cache.invalidateAll();
+    }
+
+    /**
+     * Get param info key.
+     *
+     * @param className  className
+     * @param methodName methodName
+     * @return the key
+     */
+    public static String getClassMethodKey(final String className, final String methodName) {
+        return String.join("_", className, methodName);
+    }
+
+    /**
+     * Gets the client config.
+     *
+     * @return the client config
+     */
+    public StarlightClient getClientConfig() {
+        return clientConfig;
+    }
+
+    /**
+     * Gets the proxy factory.
+     *
+     * @return the proxy factory
+     */
+    public JDKProxyFactory getProxyFactory() {
+        return proxyFactory;
+    }
+
+    /**
+     * Gets instance.
+     *
+     * @return the instance
+     */
+    public static ApplicationConfigCache getInstance() {
+        return ApplicationConfigCacheInstance.INSTANCE;
+    }
+
+    /**
+     * The type Application config cache instance.
+     */
+    static final class ApplicationConfigCacheInstance {
+
+        /**
+         * The Instance.
+         */
+        static final ApplicationConfigCache INSTANCE = new ApplicationConfigCache();
+
+        private ApplicationConfigCacheInstance() {
+
+        }
+    }
+
+    /**
+     * The type Brpc param ext info.
+     */
+    public static class MethodInfo {
+
+        private String methodName;
+
+        private List<Pair<String, String>> paramTypes;
+
+        /**
+         * Gets method name.
+         *
+         * @return the method name
+         */
+        public String getMethodName() {
+            return methodName;
+        }
+
+        /**
+         * Sets method name.
+         *
+         * @param methodName the method name
+         */
+        public void setMethodName(final String methodName) {
+            this.methodName = methodName;
+        }
+
+
+        /**
+         * Gets paramTypes.
+         *
+         * @return the paramTypes
+         */
+        public List<Pair<String, String>> getParamTypes() {
+            return paramTypes;
+        }
+
+        /**
+         * Sets paramTypes.
+         *
+         * @param paramTypes the paramTypes
+         */
+        public void setParamTypes(final List<Pair<String, String>> paramTypes) {
+            this.paramTypes = paramTypes;
+        }
+    }
+
+    /**
+     * The type Brpc param ext info.
+     */
+    public static class BrpcParamExtInfo {
+
+        private List<MethodInfo> methodInfo;
+
+        /**
+         * Gets method info.
+         *
+         * @return the method info
+         */
+        public List<MethodInfo> getMethodInfo() {
+            return methodInfo;
+        }
+
+        /**
+         * Sets method info.
+         *
+         * @param methodInfo the method info
+         */
+        public void setMethodInfo(final List<MethodInfo> methodInfo) {
+            this.methodInfo = methodInfo;
+        }
+    }
+
+    /**
+     * The type Brpc param ext info.
+     */
+    public static class BrpcParamInfo {
+
+        private Class<?>[] paramTypes;
+
+        private String[] paramNames;
+
+        BrpcParamInfo(final Class<?>[] paramTypes, final String[] paramNames) {
+            this.paramTypes = paramTypes;
+            this.paramNames = paramNames;
+        }
+
+        /**
+         * Get param types class [ ].
+         *
+         * @return the class [ ]
+         */
+        public Class<?>[] getParamTypes() {
+            return paramTypes;
+        }
+
+        /**
+         * Sets param types.
+         *
+         * @param paramTypes the param types
+         */
+        public void setParamTypes(final Class<?>[] paramTypes) {
+            this.paramTypes = paramTypes;
+        }
+
+        /**
+         * Get param names string [ ].
+         *
+         * @return the string [ ]
+         */
+        public String[] getParamNames() {
+            return paramNames;
+        }
+
+        /**
+         * Sets param names.
+         *
+         * @param paramNames the param names
+         */
+        public void setParamNames(final String[] paramNames) {
+            this.paramNames = paramNames;
+        }
+    }
+}
diff --git a/shenyu-plugin/shenyu-plugin-brpc/src/main/java/org/apache/shenyu/plugin/brpc/context/BrpcShenyuContextDecorator.java b/shenyu-plugin/shenyu-plugin-brpc/src/main/java/org/apache/shenyu/plugin/brpc/context/BrpcShenyuContextDecorator.java
new file mode 100644
index 000000000..49576693e
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-brpc/src/main/java/org/apache/shenyu/plugin/brpc/context/BrpcShenyuContextDecorator.java
@@ -0,0 +1,43 @@
+/*
+ * 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.shenyu.plugin.brpc.context;
+
+import org.apache.shenyu.common.dto.MetaData;
+import org.apache.shenyu.common.enums.RpcTypeEnum;
+import org.apache.shenyu.plugin.api.context.ShenyuContext;
+import org.apache.shenyu.plugin.api.context.ShenyuContextDecorator;
+
+/**
+ * The type Brpc shenyu context decorator.
+ */
+public class BrpcShenyuContextDecorator implements ShenyuContextDecorator {
+
+    @Override
+    public ShenyuContext decorator(final ShenyuContext shenyuContext, final MetaData metaData) {
+        shenyuContext.setModule(metaData.getAppName());
+        shenyuContext.setMethod(metaData.getServiceName());
+        shenyuContext.setContextPath(metaData.getContextPath());
+        shenyuContext.setRpcType(RpcTypeEnum.BRPC.getName());
+        return shenyuContext;
+    }
+
+    @Override
+    public String rpcType() {
+        return RpcTypeEnum.BRPC.getName();
+    }
+}
diff --git a/shenyu-plugin/shenyu-plugin-brpc/src/main/java/org/apache/shenyu/plugin/brpc/exception/ShenyuBrpcPluginException.java b/shenyu-plugin/shenyu-plugin-brpc/src/main/java/org/apache/shenyu/plugin/brpc/exception/ShenyuBrpcPluginException.java
new file mode 100644
index 000000000..58af8692f
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-brpc/src/main/java/org/apache/shenyu/plugin/brpc/exception/ShenyuBrpcPluginException.java
@@ -0,0 +1,38 @@
+/*
+ * 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.shenyu.plugin.brpc.exception;
+
+import org.apache.shenyu.common.exception.ShenyuException;
+
+/**
+ * ShenyuBrpcPluginException.
+ */
+public class ShenyuBrpcPluginException extends ShenyuException {
+    
+    public ShenyuBrpcPluginException(final Throwable e) {
+        super(e);
+    }
+    
+    public ShenyuBrpcPluginException(final String message) {
+        super(message);
+    }
+    
+    public ShenyuBrpcPluginException(final String message, final Throwable throwable) {
+        super(message, throwable);
+    }
+}
diff --git a/shenyu-plugin/shenyu-plugin-brpc/src/main/java/org/apache/shenyu/plugin/brpc/handler/BrpcMetaDataHandler.java b/shenyu-plugin/shenyu-plugin-brpc/src/main/java/org/apache/shenyu/plugin/brpc/handler/BrpcMetaDataHandler.java
new file mode 100644
index 000000000..233097eda
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-brpc/src/main/java/org/apache/shenyu/plugin/brpc/handler/BrpcMetaDataHandler.java
@@ -0,0 +1,69 @@
+/*
+ * 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.shenyu.plugin.brpc.handler;
+
+import com.google.common.collect.Maps;
+import org.apache.shenyu.common.dto.MetaData;
+import org.apache.shenyu.common.enums.RpcTypeEnum;
+import org.apache.shenyu.plugin.base.handler.MetaDataHandler;
+import org.apache.shenyu.plugin.brpc.cache.ApplicationConfigCache;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Objects;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * The brpc metadata handler.
+ */
+public class BrpcMetaDataHandler implements MetaDataHandler {
+
+    private static final Logger LOG = LoggerFactory.getLogger(BrpcMetaDataHandler.class);
+
+    private static final ConcurrentMap<String, MetaData> META_DATA = Maps.newConcurrentMap();
+
+    @Override
+    public void handle(final MetaData metaData) {
+        try {
+            MetaData exist = META_DATA.get(metaData.getPath());
+            if (Objects.isNull(exist) || Objects.isNull(ApplicationConfigCache.getInstance().get(exist.getPath()))) {
+                // The first initialization
+                ApplicationConfigCache.getInstance().initService(metaData);
+            } else {
+                if (!exist.getServiceName().equals(metaData.getServiceName()) || !exist.getRpcExt().equals(metaData.getRpcExt())) {
+                    // update
+                    ApplicationConfigCache.getInstance().build(metaData);
+                }
+            }
+            META_DATA.put(metaData.getPath(), metaData);
+        } catch (Exception e) {
+            LOG.error("brpc sync metadata is error, please check brpc service. MetaData: [{}]", metaData, e);
+        }
+    }
+
+    @Override
+    public void remove(final MetaData metaData) {
+        ApplicationConfigCache.getInstance().invalidate(metaData.getPath());
+        META_DATA.remove(metaData.getPath());
+    }
+
+    @Override
+    public String rpcType() {
+        return RpcTypeEnum.BRPC.getName();
+    }
+}
diff --git a/shenyu-plugin/shenyu-plugin-brpc/src/main/java/org/apache/shenyu/plugin/brpc/handler/BrpcPluginDataHandler.java b/shenyu-plugin/shenyu-plugin-brpc/src/main/java/org/apache/shenyu/plugin/brpc/handler/BrpcPluginDataHandler.java
new file mode 100644
index 000000000..56704ee98
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-brpc/src/main/java/org/apache/shenyu/plugin/brpc/handler/BrpcPluginDataHandler.java
@@ -0,0 +1,57 @@
+/*
+ * 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.shenyu.plugin.brpc.handler;
+
+import org.apache.shenyu.common.dto.convert.plugin.BrpcRegisterConfig;
+import org.apache.shenyu.common.dto.PluginData;
+import org.apache.shenyu.common.enums.PluginEnum;
+import org.apache.shenyu.common.utils.GsonUtils;
+import org.apache.shenyu.plugin.base.handler.PluginDataHandler;
+import org.apache.shenyu.common.utils.Singleton;
+import org.apache.shenyu.plugin.brpc.cache.ApplicationConfigCache;
+
+import java.util.Objects;
+
+/**
+ * The type brpc plugin data handler.
+ */
+public class BrpcPluginDataHandler implements PluginDataHandler {
+
+    @Override
+    public void handlerPlugin(final PluginData pluginData) {
+        if (null != pluginData && pluginData.getEnabled()) {
+            BrpcRegisterConfig brpcRegisterConfig = GsonUtils.getInstance().fromJson(pluginData.getConfig(), BrpcRegisterConfig.class);
+            BrpcRegisterConfig exist = Singleton.INST.get(BrpcRegisterConfig.class);
+            if (Objects.isNull(brpcRegisterConfig)) {
+                return;
+            }
+            if (Objects.isNull(exist) || !brpcRegisterConfig.equals(exist)) {
+                // If it is null, initialize it
+                ApplicationConfigCache.getInstance().init(brpcRegisterConfig);
+                ApplicationConfigCache.getInstance().invalidateAll();
+            }
+            Singleton.INST.single(BrpcRegisterConfig.class, brpcRegisterConfig);
+        }
+    }
+
+    @Override
+    public String pluginNamed() {
+        return PluginEnum.BRPC.getName();
+    }
+
+}
diff --git a/shenyu-plugin/shenyu-plugin-brpc/src/main/java/org/apache/shenyu/plugin/brpc/proxy/BrpcProxyService.java b/shenyu-plugin/shenyu-plugin-brpc/src/main/java/org/apache/shenyu/plugin/brpc/proxy/BrpcProxyService.java
new file mode 100644
index 000000000..2c6bdef40
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-brpc/src/main/java/org/apache/shenyu/plugin/brpc/proxy/BrpcProxyService.java
@@ -0,0 +1,147 @@
+/*
+ * 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.shenyu.plugin.brpc.proxy;
+
+import com.baidu.cloud.starlight.core.rpc.generic.AsyncGenericService;
+import org.apache.shenyu.common.concurrent.ShenyuThreadFactory;
+import org.apache.shenyu.common.concurrent.ShenyuThreadPoolExecutor;
+import org.apache.shenyu.common.constant.Constants;
+import org.apache.shenyu.common.dto.MetaData;
+import org.apache.shenyu.common.dto.convert.plugin.BrpcRegisterConfig;
+import org.apache.shenyu.common.enums.ResultEnum;
+import org.apache.shenyu.common.exception.ShenyuException;
+import org.apache.shenyu.common.utils.GsonUtils;
+import org.apache.shenyu.common.utils.Singleton;
+import org.apache.shenyu.plugin.api.utils.SpringBeanUtils;
+import org.apache.shenyu.plugin.brpc.cache.ApplicationConfigCache;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Brpc proxy service.
+ */
+public class BrpcProxyService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(BrpcProxyService.class);
+
+    private final ThreadFactory factory = ShenyuThreadFactory.create("shenyu-brpc", true);
+
+    private ExecutorService threadPool;
+
+    /**
+     * Generic invoker object.
+     *
+     * @param body     the body
+     * @param metaData the meta data
+     * @param exchange the exchange
+     * @return the object
+     * @throws ShenyuException the shenyu exception
+     */
+    @SuppressWarnings("all")
+    public Mono<Object> genericInvoker(final String body, final MetaData metaData, final ServerWebExchange exchange) throws ShenyuException {
+        ApplicationConfigCache.BrpcParamInfo brpcParamInfo = ApplicationConfigCache.PARAM_MAP.get(metaData.getMethodName());
+        Object[] params;
+        if (Objects.isNull(brpcParamInfo)) {
+            params = new Object[0];
+        } else {
+            int num = brpcParamInfo.getParamTypes().length;
+            params = new Object[num];
+            Map<String, Object> bodyMap = GsonUtils.getInstance().convertToMap(body);
+            for (int i = 0; i < num; i++) {
+                params[i] = bodyMap.get(brpcParamInfo.getParamNames()[i]).toString();
+            }
+        }
+        initThreadPool();
+        CompletableFuture<Object> future = null;
+        future = new CompletableFuture<>().supplyAsync(() -> getValue(metaData, params), threadPool);
+        return Mono.fromFuture(future.thenApply(ret -> {
+            if (Objects.isNull(ret)) {
+                ret = Constants.BRPC_RPC_RESULT_EMPTY;
+            }
+            exchange.getAttributes().put(Constants.RPC_RESULT, ret);
+            exchange.getAttributes().put(Constants.CLIENT_RESPONSE_RESULT_TYPE, ResultEnum.SUCCESS.getName());
+            return ret;
+        })).onErrorMap(ShenyuException::new);
+    }
+
+    private Map<String, String> getValue(final MetaData metaData, final Object[] params) {
+        try {
+            AsyncGenericService service = ApplicationConfigCache.getInstance().get(metaData.getPath());
+            if (Objects.isNull(service)) {
+                ApplicationConfigCache.getInstance().invalidate(metaData.getPath());
+                service = ApplicationConfigCache.getInstance().initService(metaData);
+            }
+            Map<String, String> result = (Map<String, String>) service.$invokeFuture(metaData.getMethodName(), params).get();
+            return result;
+        } catch (Exception e) {
+            LOG.error("Exception caught in BrpcProxyService#genericInvoker.", e);
+            return null;
+        }
+    }
+
+    private void initThreadPool() {
+        if (Objects.nonNull(threadPool)) {
+            return;
+        }
+        BrpcRegisterConfig config = Singleton.INST.get(BrpcRegisterConfig.class);
+        if (Objects.isNull(config)) {
+            // should not execute to here
+            threadPool = new ThreadPoolExecutor(0, Integer.MAX_VALUE,
+                    60L, TimeUnit.SECONDS,
+                    new SynchronousQueue<Runnable>(),
+                    factory);
+            return;
+        }
+        final String threadpool = Optional.ofNullable(config.getThreadpool()).orElse(Constants.CACHED);
+        switch (threadpool) {
+            case Constants.SHARED:
+                try {
+                    threadPool = SpringBeanUtils.getInstance().getBean(ShenyuThreadPoolExecutor.class);
+                    return;
+                } catch (NoSuchBeanDefinitionException t) {
+                    throw new ShenyuException("shared thread pool is not enable, config ${shenyu.sharedPool.enable} in your xml/yml !", t);
+                }
+            case Constants.FIXED:
+            case Constants.EAGER:
+            case Constants.LIMITED:
+                throw new UnsupportedOperationException();
+            case Constants.CACHED:
+            default:
+                int corePoolSize = Optional.ofNullable(config.getCorethreads()).orElse(0);
+                int maximumPoolSize = Optional.ofNullable(config.getThreads()).orElse(Integer.MAX_VALUE);
+                int queueSize = Optional.ofNullable(config.getQueues()).orElse(0);
+                threadPool = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, 60L, TimeUnit.SECONDS,
+                        queueSize > 0 ? new LinkedBlockingQueue<>(queueSize) : new SynchronousQueue<>(), factory);
+        }
+    }
+
+}
diff --git a/shenyu-plugin/shenyu-plugin-brpc/src/main/java/org/apache/shenyu/plugin/brpc/util/ProxyInfoUtil.java b/shenyu-plugin/shenyu-plugin-brpc/src/main/java/org/apache/shenyu/plugin/brpc/util/ProxyInfoUtil.java
new file mode 100644
index 000000000..a8bcb3363
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-brpc/src/main/java/org/apache/shenyu/plugin/brpc/util/ProxyInfoUtil.java
@@ -0,0 +1,178 @@
+/*
+ * 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.shenyu.plugin.brpc.util;
+
+import org.apache.shenyu.common.dto.MetaData;
+import org.apache.shenyu.common.utils.GsonUtils;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Function;
+
+/**
+ * Proxy info util.
+ */
+public final class ProxyInfoUtil {
+    
+    private static final Map<String, PrimitiveType> PRIMITIVE_TYPE;
+    
+    static {
+        PRIMITIVE_TYPE = new HashMap<>();
+        PRIMITIVE_TYPE.put("int", new PrimitiveType(int.class, o -> {
+            if (o instanceof String) {
+                return Integer.valueOf((String) o);
+            }
+            return ((Long) o).intValue();
+        }));
+        PRIMITIVE_TYPE.put("double", new PrimitiveType(double.class, o -> {
+            if (o instanceof String) {
+                return Double.valueOf((String) o);
+            }
+            return o;
+        }));
+        PRIMITIVE_TYPE.put("long", new PrimitiveType(long.class, o -> {
+            if (o instanceof String) {
+                return Long.valueOf((String) o);
+            }
+            return o;
+        }));
+        PRIMITIVE_TYPE.put("short", new PrimitiveType(short.class, o -> {
+            if (o instanceof String) {
+                return Short.valueOf((String) o);
+            }
+            return ((Long) o).shortValue();
+        }));
+        PRIMITIVE_TYPE.put("byte", new PrimitiveType(byte.class, o -> {
+            if (o instanceof String) {
+                return Byte.valueOf((String) o);
+            }
+            return ((Long) o).byteValue();
+        }));
+        PRIMITIVE_TYPE.put("boolean", new PrimitiveType(boolean.class, o -> {
+            if (o instanceof String) {
+                return Byte.valueOf((String) o);
+            }
+            return o;
+        }));
+        PRIMITIVE_TYPE.put("char", new PrimitiveType(char.class, o -> {
+            if (o instanceof String) {
+                return String.valueOf(o).charAt(0);
+            }
+            return o;
+        }));
+        PRIMITIVE_TYPE.put("float", new PrimitiveType(float.class, o -> {
+            if (o instanceof String) {
+                return Float.valueOf((String) o);
+            }
+            return ((Double) o).floatValue();
+        }));
+    }
+    
+    private ProxyInfoUtil() {
+    }
+    
+    /**
+     * Get class type by name.
+     *
+     * @param className className
+     * @return the type to invoke
+     * @throws ClassNotFoundException ClassNotFoundException
+     */
+    public static Class<?> getParamClass(final String className) throws ClassNotFoundException {
+        if (PRIMITIVE_TYPE.containsKey(className)) {
+            return PRIMITIVE_TYPE.get(className).getClazz();
+        } else {
+            return Class.forName(className);
+        }
+    }
+    
+    /**
+     * Get proxy class name to get brpc proxy.
+     *
+     * @param metaData metaData
+     * @return className
+     */
+    public static String getProxyName(final MetaData metaData) {
+        return metaData.getPath().replace("/", "") + metaData.getMethodName() + "Proxy";
+    }
+    
+    /**
+     * Get methodName to get brpc proxy.
+     *
+     * @param methodName methodName
+     * @return methodName
+     */
+    public static String getMethodName(final String methodName) {
+        return methodName;
+    }
+    
+    /**
+     * Get objectName to get brpc proxy.
+     *
+     * @param upstreamUrl upstream url
+     * @param serviceName service name
+     * @return objectName
+     */
+    public static String getObjectName(final String upstreamUrl, final String serviceName) {
+        String[] ipAndPort = upstreamUrl.split(":");
+        return serviceName + "@tcp -h " + ipAndPort[0] + " -p " + ipAndPort[1];
+    }
+    
+    /**
+     * Get param to invoke brpc server.
+     *
+     * @param paramTypes paramTypes
+     * @param paramNames paramNames
+     * @param body       body
+     * @return the param to invoke
+     */
+    public static Object[] getParamArray(final Class<?>[] paramTypes, final String[] paramNames, final String body) {
+        Map<String, Object> bodyMap = GsonUtils.getInstance().convertToMap(body);
+        Object[] param = new Object[paramNames.length];
+        for (int i = 0; i < paramNames.length; i++) {
+            String paramName = paramNames[i];
+            Class<?> paramType = paramTypes[i];
+            if (PRIMITIVE_TYPE.containsKey(paramType.getName())) {
+                param[i] = PRIMITIVE_TYPE.get(paramType.getName()).getFunc().apply(bodyMap.get(paramName));
+            } else {
+                param[i] = bodyMap.get(paramName);
+            }
+        }
+        return param;
+    }
+    
+    static class PrimitiveType {
+        
+        private final Class<?> clazz;
+        
+        private final Function<Object, Object> func;
+        
+        PrimitiveType(final Class<?> clazz, final Function<Object, Object> func) {
+            this.clazz = clazz;
+            this.func = func;
+        }
+        
+        public Class<?> getClazz() {
+            return clazz;
+        }
+        
+        public Function<Object, Object> getFunc() {
+            return func;
+        }
+    }
+}
diff --git a/shenyu-plugin/shenyu-plugin-brpc/src/test/java/org/apache/shenyu/plugin/brpc/BrpcPluginTest.java b/shenyu-plugin/shenyu-plugin-brpc/src/test/java/org/apache/shenyu/plugin/brpc/BrpcPluginTest.java
new file mode 100644
index 000000000..bc4758581
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-brpc/src/test/java/org/apache/shenyu/plugin/brpc/BrpcPluginTest.java
@@ -0,0 +1,107 @@
+/*
+ * 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.shenyu.plugin.brpc;
+
+import org.apache.shenyu.common.constant.Constants;
+import org.apache.shenyu.common.dto.MetaData;
+import org.apache.shenyu.common.dto.RuleData;
+import org.apache.shenyu.common.dto.SelectorData;
+import org.apache.shenyu.plugin.api.ShenyuPluginChain;
+import org.apache.shenyu.plugin.api.context.ShenyuContext;
+import org.apache.shenyu.plugin.brpc.proxy.BrpcProxyService;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
+import org.springframework.mock.web.server.MockServerWebExchange;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+import reactor.test.StepVerifier;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+/**
+ * The Test Case For {@link BrpcPlugin}.
+ */
+public class BrpcPluginTest {
+
+    private static final String PARAM = "{\"name\":\"brpc\"}";
+
+    private BrpcPlugin brpcPlugin;
+
+    private ShenyuPluginChain chain;
+
+    private SelectorData selectorData;
+
+    private ServerWebExchange exchange;
+
+    private RuleData ruleData;
+
+    private MetaData metaData;
+
+    private BrpcProxyService brpcProxyService;
+
+    @BeforeEach
+    public void setUp() {
+        this.ruleData = mock(RuleData.class);
+        this.chain = mock(ShenyuPluginChain.class);
+        this.selectorData = mock(SelectorData.class);
+        this.exchange = MockServerWebExchange.from(MockServerHttpRequest.get("localhost").build());
+        this.metaData = new MetaData();
+        this.metaData.setAppName("brpc");
+        this.metaData.setContextPath("/brpc");
+        this.metaData.setPath("/brpc/hello");
+        this.metaData.setRpcType("brpc");
+        this.metaData.setServiceName("org.apache.shenyu.examples.brpc.service.DemoService");
+        this.metaData.setMethodName("hello");
+        this.metaData.setParameterTypes("java.lang.String");
+        this.metaData.setEnabled(true);
+        metaData.setRpcExt("{\"methodInfo\":[{\"methodName\":\"hello\",\"params\":[{\"left\":\"java.lang.String\",\"right\":\"name\"}]}]}");
+        ShenyuContext shenyuContext = mock(ShenyuContext.class);
+        exchange.getAttributes().put(Constants.CONTEXT, shenyuContext);
+        exchange.getAttributes().put(Constants.PARAM_TRANSFORM, PARAM);
+        exchange.getAttributes().put(Constants.META_DATA, metaData);
+        this.brpcProxyService = mock(BrpcProxyService.class);
+        when(brpcProxyService.genericInvoker(PARAM, metaData, exchange)).thenReturn(Mono.empty());
+        this.brpcPlugin = new BrpcPlugin(brpcProxyService);
+    }
+
+    @Test
+    public void testDoExecute() {
+        when(chain.execute(exchange)).thenReturn(Mono.empty());
+        Mono<Void> result = brpcPlugin.doExecute(exchange, chain, selectorData, ruleData);
+        StepVerifier.create(result).expectSubscription().verifyComplete();
+    }
+
+    @Test
+    public void testNamed() {
+        Assertions.assertEquals(brpcPlugin.named(), "brpc");
+    }
+
+    @Test
+    public void testSkip() {
+        final boolean result = brpcPlugin.skip(exchange);
+        Assertions.assertTrue(result);
+    }
+
+    @Test
+    public void testGetOrder() {
+        Assertions.assertEquals(brpcPlugin.getOrder(), 310);
+    }
+}
diff --git a/shenyu-plugin/shenyu-plugin-brpc/src/test/java/org/apache/shenyu/plugin/brpc/cache/ApplicationConfigCacheTest.java b/shenyu-plugin/shenyu-plugin-brpc/src/test/java/org/apache/shenyu/plugin/brpc/cache/ApplicationConfigCacheTest.java
new file mode 100644
index 000000000..894272dfa
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-brpc/src/test/java/org/apache/shenyu/plugin/brpc/cache/ApplicationConfigCacheTest.java
@@ -0,0 +1,101 @@
+/*
+ * 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.shenyu.plugin.brpc.cache;
+
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.shenyu.common.dto.PluginData;
+import org.apache.shenyu.common.dto.convert.plugin.BrpcRegisterConfig;
+import org.apache.shenyu.common.utils.GsonUtils;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+/**
+ * Test case for {@link ApplicationConfigCache}.
+ */
+public final class ApplicationConfigCacheTest {
+
+    private ApplicationConfigCache applicationConfigCacheUnderTest;
+
+    @BeforeEach
+    public void setUp() {
+        applicationConfigCacheUnderTest = ApplicationConfigCache.getInstance();
+    }
+
+    @Test
+    public void testGetClassMethodKey() {
+        assertEquals("className_methodName", ApplicationConfigCache.getClassMethodKey("className", "methodName"));
+    }
+
+    @Test
+    public void testGetInstance() {
+        assertNotNull(this.applicationConfigCacheUnderTest);
+    }
+
+    @Test
+    public void testMethodInfo() {
+        List<Pair<String, String>> params = new ArrayList<>();
+        Pair<String, String> pair = Pair.of("left", "right");
+        params.add(pair);
+        ApplicationConfigCache.MethodInfo methodInfo = new ApplicationConfigCache.MethodInfo();
+        methodInfo.setParamTypes(params);
+        Assertions.assertEquals(methodInfo.getParamTypes().get(0).getLeft(), "left");
+    }
+
+    @Test
+    public void testBrpcParamInfo() {
+        ApplicationConfigCache.BrpcParamInfo paramInfo = new ApplicationConfigCache.BrpcParamInfo(null, null);
+        paramInfo.setParamNames(new String[]{"test"});
+        paramInfo.setParamTypes(new Class<?>[]{ApplicationConfigCache.class});
+        Assertions.assertEquals(paramInfo.getParamNames()[0], "test");
+        Assertions.assertEquals(paramInfo.getParamTypes()[0], ApplicationConfigCache.class);
+    }
+
+    @Test
+    public void testBrpcParamExtInfo() {
+        ApplicationConfigCache.BrpcParamExtInfo paramExtInfo = new ApplicationConfigCache.BrpcParamExtInfo();
+        ApplicationConfigCache.MethodInfo methodInfo = new ApplicationConfigCache.MethodInfo();
+        methodInfo.setMethodName("methodName");
+        List<ApplicationConfigCache.MethodInfo> list = new ArrayList<>();
+        list.add(methodInfo);
+        paramExtInfo.setMethodInfo(list);
+        Assertions.assertEquals(paramExtInfo.getMethodInfo().get(0).getMethodName(), "methodName");
+    }
+
+    @Test
+    public void testApplicationConfigCache() {
+        ApplicationConfigCache applicationConfigCache = ApplicationConfigCache.getInstance();
+        Assertions.assertEquals(applicationConfigCache.getInstance().getClass(), ApplicationConfigCache.class);
+        PluginData pluginData = new PluginData();
+        pluginData.setEnabled(true);
+        pluginData.setConfig("{\"address\" : \"127.0.0.1\", \"port\" : \"8005\"}");
+        BrpcRegisterConfig registerConfig = GsonUtils.getInstance().fromJson(pluginData.getConfig(), BrpcRegisterConfig.class);
+        applicationConfigCache.init(registerConfig);
+        Assertions.assertNotNull(applicationConfigCache.getClientConfig());
+        Assertions.assertNotNull(applicationConfigCache.getProxyFactory());
+        Assertions.assertTrue(applicationConfigCache.getClientConfig().isActive());
+        applicationConfigCache.getClientConfig().destroy();
+        Assertions.assertFalse(applicationConfigCache.getClientConfig().isActive());
+    }
+}
diff --git a/shenyu-plugin/shenyu-plugin-brpc/src/test/java/org/apache/shenyu/plugin/brpc/context/BrpcShenyuContextDecoratorTest.java b/shenyu-plugin/shenyu-plugin-brpc/src/test/java/org/apache/shenyu/plugin/brpc/context/BrpcShenyuContextDecoratorTest.java
new file mode 100644
index 000000000..385086935
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-brpc/src/test/java/org/apache/shenyu/plugin/brpc/context/BrpcShenyuContextDecoratorTest.java
@@ -0,0 +1,57 @@
+/*
+ * 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.shenyu.plugin.brpc.context;
+
+import org.apache.shenyu.common.dto.MetaData;
+import org.apache.shenyu.plugin.api.context.ShenyuContext;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+/**
+ * The Test Case For {@link BrpcShenyuContextDecorator}.
+ */
+public final class BrpcShenyuContextDecoratorTest {
+
+    private BrpcShenyuContextDecorator brpcShenyuContextDecorator;
+
+    private ShenyuContext shenyuContext;
+
+    private MetaData metaData;
+
+    @BeforeEach
+    public void setUp() {
+        this.brpcShenyuContextDecorator = new BrpcShenyuContextDecorator();
+        this.metaData = new MetaData();
+        this.shenyuContext = new ShenyuContext();
+    }
+
+    @Test
+    public void testDecorator() {
+        metaData.setAppName("app");
+        metaData.setServiceName("service");
+        metaData.setContextPath("localhost");
+        brpcShenyuContextDecorator.decorator(shenyuContext, metaData);
+        Assertions.assertEquals(shenyuContext.getModule(), "app");
+    }
+
+    @Test
+    public void testRpcType() {
+        Assertions.assertEquals(brpcShenyuContextDecorator.rpcType(), "brpc");
+    }
+}
diff --git a/shenyu-plugin/shenyu-plugin-brpc/src/test/java/org/apache/shenyu/plugin/brpc/handler/BrpcPluginDataHandlerTest.java b/shenyu-plugin/shenyu-plugin-brpc/src/test/java/org/apache/shenyu/plugin/brpc/handler/BrpcPluginDataHandlerTest.java
new file mode 100644
index 000000000..4c880064c
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-brpc/src/test/java/org/apache/shenyu/plugin/brpc/handler/BrpcPluginDataHandlerTest.java
@@ -0,0 +1,52 @@
+/*
+ * 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.shenyu.plugin.brpc.handler;
+
+import org.apache.shenyu.common.dto.PluginData;
+import org.apache.shenyu.common.enums.PluginEnum;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Test case for {@link BrpcPluginDataHandler}.
+ */
+public final class BrpcPluginDataHandlerTest {
+    
+    private BrpcPluginDataHandler brpcPluginDataHandlerUnderTest;
+    
+    @BeforeEach
+    public void setUp() {
+        brpcPluginDataHandlerUnderTest = new BrpcPluginDataHandler();
+    }
+    
+    @Test
+    public void testHandlerPlugin() {
+        final PluginData pluginData = new PluginData("id", "name", "config", "0", false);
+        brpcPluginDataHandlerUnderTest.handlerPlugin(pluginData);
+        assertTrue(pluginData.getName().endsWith("name"));
+    }
+    
+    @Test
+    public void testPluginNamed() {
+        final String result = brpcPluginDataHandlerUnderTest.pluginNamed();
+        assertEquals(PluginEnum.BRPC.getName(), result);
+    }
+}
diff --git a/shenyu-plugin/shenyu-plugin-brpc/src/test/java/org/apache/shenyu/plugin/brpc/util/ProxyInfoUtilTest.java b/shenyu-plugin/shenyu-plugin-brpc/src/test/java/org/apache/shenyu/plugin/brpc/util/ProxyInfoUtilTest.java
new file mode 100644
index 000000000..73ff80e26
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-brpc/src/test/java/org/apache/shenyu/plugin/brpc/util/ProxyInfoUtilTest.java
@@ -0,0 +1,81 @@
+/*
+ * 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.shenyu.plugin.brpc.util;
+
+import org.apache.shenyu.common.dto.MetaData;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+/**
+ * Test case for {@link ProxyInfoUtil}.
+ */
+@ExtendWith(MockitoExtension.class)
+public class ProxyInfoUtilTest {
+
+    @Test
+    public void testGetParamClass() throws Exception {
+        assertEquals(int.class, ProxyInfoUtil.getParamClass("int"));
+        assertEquals(long.class, ProxyInfoUtil.getParamClass("long"));
+        assertEquals(short.class, ProxyInfoUtil.getParamClass("short"));
+        assertEquals(byte.class, ProxyInfoUtil.getParamClass("byte"));
+        assertEquals(boolean.class, ProxyInfoUtil.getParamClass("boolean"));
+        assertEquals(char.class, ProxyInfoUtil.getParamClass("char"));
+        assertEquals(float.class, ProxyInfoUtil.getParamClass("float"));
+        assertEquals(Integer.class, ProxyInfoUtil.getParamClass("java.lang.Integer"));
+    }
+
+    @Test
+    public void testGetParamClassThrowsClassNotFoundException() throws Exception {
+        assertThrows(ClassNotFoundException.class, () -> {
+            ProxyInfoUtil.getParamClass("className");
+        });
+    }
+
+    @Test
+    public void testGetPrxName() {
+        final MetaData metaData = new MetaData("id", "appName", "contextPath", "/path",
+                "rpcType", "serviceName", "methodName", "parameterTypes",
+                "rpcExt", false);
+        final String result = ProxyInfoUtil.getProxyName(metaData);
+        assertEquals("pathmethodNameProxy", result);
+    }
+
+    @Test
+    public void testGetMethodName() {
+        assertEquals("methodName", ProxyInfoUtil.getMethodName("methodName"));
+    }
+
+    @Test
+    public void testGetObjectName() {
+        final String result = ProxyInfoUtil.getObjectName("127.0.0.1:8005", "serviceName");
+        assertEquals("serviceName@tcp -h 127.0.0.1 -p 8005", result);
+    }
+
+    @Test
+    public void testGetParamArray() {
+        assertArrayEquals(new Object[]{11, Double.valueOf("1.321321312"), Long.valueOf("131231312"), Short.valueOf("11"), Byte.valueOf("0"), false, 'a', 1.321321312F},
+                ProxyInfoUtil.getParamArray(new Class<?>[]{int.class, double.class, long.class, short.class, byte.class, boolean.class, char.class, float.class},
+                        new String[]{"int", "double", "long", "short", "byte", "boolean", "char", "float"},
+                        "{\"int\":11,\"double\":1.321321312,\"long\":131231312,\"short\":11,\"byte\":0,\"boolean\":false,\"char\":'a',\"float\":1.321321312}"));
+    }
+}
diff --git a/shenyu-plugin/shenyu-plugin-context-path/src/main/java/org/apache/shenyu/plugin/context/path/ContextPathPlugin.java b/shenyu-plugin/shenyu-plugin-context-path/src/main/java/org/apache/shenyu/plugin/context/path/ContextPathPlugin.java
index 0c19a3850..d93e3ff37 100644
--- a/shenyu-plugin/shenyu-plugin-context-path/src/main/java/org/apache/shenyu/plugin/context/path/ContextPathPlugin.java
+++ b/shenyu-plugin/shenyu-plugin-context-path/src/main/java/org/apache/shenyu/plugin/context/path/ContextPathPlugin.java
@@ -81,7 +81,8 @@ public class ContextPathPlugin extends AbstractShenyuPlugin {
                 RpcTypeEnum.GRPC,
                 RpcTypeEnum.TARS,
                 RpcTypeEnum.MOTAN,
-                RpcTypeEnum.SOFA);
+                RpcTypeEnum.SOFA,
+                RpcTypeEnum.BRPC);
     }
     
     private ContextMappingRuleHandle buildRuleHandle(final RuleData rule) {
diff --git a/shenyu-plugin/shenyu-plugin-response/src/main/java/org/apache/shenyu/plugin/response/strategy/RPCMessageWriter.java b/shenyu-plugin/shenyu-plugin-response/src/main/java/org/apache/shenyu/plugin/response/strategy/RPCMessageWriter.java
index e893d511d..1dc7bc46c 100644
--- a/shenyu-plugin/shenyu-plugin-response/src/main/java/org/apache/shenyu/plugin/response/strategy/RPCMessageWriter.java
+++ b/shenyu-plugin/shenyu-plugin-response/src/main/java/org/apache/shenyu/plugin/response/strategy/RPCMessageWriter.java
@@ -58,6 +58,6 @@ public class RPCMessageWriter implements MessageWriter {
     @Override
     public List<String> supportTypes() {
         return Lists.newArrayList(RpcTypeEnum.DUBBO.getName(), RpcTypeEnum.SOFA.getName(), 
-                RpcTypeEnum.GRPC.getName(), RpcTypeEnum.MOTAN.getName(), RpcTypeEnum.TARS.getName());
+                RpcTypeEnum.GRPC.getName(), RpcTypeEnum.MOTAN.getName(), RpcTypeEnum.TARS.getName(), RpcTypeEnum.BRPC.getName());
     }
 }
diff --git a/shenyu-plugin/shenyu-plugin-rewrite/src/main/java/org/apache/shenyu/plugin/rewrite/RewritePlugin.java b/shenyu-plugin/shenyu-plugin-rewrite/src/main/java/org/apache/shenyu/plugin/rewrite/RewritePlugin.java
index 9b5efb696..845516ff9 100644
--- a/shenyu-plugin/shenyu-plugin-rewrite/src/main/java/org/apache/shenyu/plugin/rewrite/RewritePlugin.java
+++ b/shenyu-plugin/shenyu-plugin-rewrite/src/main/java/org/apache/shenyu/plugin/rewrite/RewritePlugin.java
@@ -69,7 +69,8 @@ public class RewritePlugin extends AbstractShenyuPlugin {
                 RpcTypeEnum.GRPC,
                 RpcTypeEnum.TARS,
                 RpcTypeEnum.MOTAN,
-                RpcTypeEnum.SOFA);
+                RpcTypeEnum.SOFA,
+                RpcTypeEnum.BRPC);
     }
 
     @Override