You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by zt...@apache.org on 2022/01/03 07:58:59 UTC

[dubbo-go-pixiu] branch develop updated: add http2 listener for grpc proxy (#315)

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

ztelur pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/dubbo-go-pixiu.git


The following commit(s) were added to refs/heads/develop by this push:
     new 7946f64  add http2 listener for grpc proxy (#315)
7946f64 is described below

commit 7946f64f3773c91a09d12b70cf5f75e196747f62
Author: randy <zt...@gmail.com>
AuthorDate: Mon Jan 3 15:58:53 2022 +0800

    add http2 listener for grpc proxy (#315)
    
    * split listener service interface
    
    * split listener service interface
    
    * update
    
    * update
    
    * update
    
    * update
    
    * add integration test
    
    * add integration test
    
    * update
    
    * fix golangci-lint
    
    * update
    
    * fix reviewdog
    
    * fix reviewdog
    
    * fix reviewdog
    
    * update for comment
    
    * rename to NetworkFilterChain
    
    * update
    
    Co-authored-by: Mark4z <36...@users.noreply.github.com>
    Co-authored-by: Xin.Zh <dr...@foxmail.com>
---
 docs/sample/dubbo/dubbo-registry.md                |   6 +-
 docs/sample/http/http-grpc.md                      |   6 +-
 docs/sample/http/http-http.md                      |   6 +-
 docs/user/config.md                                |   6 +-
 go.mod                                             |   4 +-
 go.sum                                             |   1 +
 pkg/common/constant/key.go                         |   1 +
 pkg/common/extension/filter/filter.go              |   5 +-
 .../listener.go => common/grpc/RoundTripper.go}    |  21 +-
 pkg/common/grpc/manager.go                         | 143 +++++++++
 pkg/common/http/manager.go                         |  40 ++-
 pkg/common/router/router.go                        |  13 +-
 pkg/common/router/router_test.go                   |   2 +-
 pkg/config/conf_test.yaml                          |   6 +-
 pkg/config/config_load.go                          |   6 +-
 pkg/config/config_load_test.go                     |  26 +-
 pkg/context/http/context.go                        |   1 -
 .../network/grpcconnectionmanager/plugin.go}       |  44 +--
 pkg/filterchain/network_filter_chain.go            |  84 ++++++
 .../listener.go => listener/http/http_listener.go} | 136 +++------
 pkg/listener/http2/http2_listener.go               | 121 ++++++++
 pkg/listener/listener.go                           |  57 ++++
 pkg/{server => listener}/listener_test.go          |  19 +-
 pkg/model/base.go                                  |  46 +--
 pkg/model/filter.go                                |   7 +-
 pkg/model/http.go                                  |   5 +
 pkg/model/listener.go                              |  57 +++-
 pkg/model/router.go                                |  10 +-
 pkg/pluginregistry/registry.go                     |   3 +
 pkg/server/listener_manager.go                     |  35 +--
 samples/dubbogo/http/pixiu/conf.yaml               |   6 +-
 samples/dubbogo/multi/config/conf.yaml             |   6 +-
 samples/dubbogo/simple/body/pixiu/conf.yaml        |   2 +-
 samples/dubbogo/simple/csrf/pixiu/conf.yaml        |   5 -
 samples/dubbogo/simple/jaeger/pixiu/conf.yaml      |   2 +-
 samples/dubbogo/simple/mix/pixiu/conf.yaml         |   6 +-
 samples/dubbogo/simple/proxy/pixiu/conf.yaml       |   6 +-
 samples/dubbogo/simple/query/pixiu/conf.yaml       |   6 +-
 .../darwin_amd64/pixiuconf}/conf.yaml              |   5 +-
 .../dist/darwin_amd64/server/log.yml}              |  56 ++--
 .../dist/darwin_amd64/server/server.yml}           |  52 ++--
 samples/dubbogo/simple/registry/pixiu/conf.yaml    |   6 +-
 samples/dubbogo/simple/triple/pixiu/conf.yaml      |   3 +-
 samples/dubbogo/simple/uri/conf.yaml               |   2 +-
 samples/dubbogo/simple/uri/pixiu/conf.yaml         |   6 +-
 samples/{http => }/grpc/pixiu/conf.yaml            |  17 +-
 samples/grpc/proto/hello_grpc.pb.go                | 320 +++++++++++++++++++++
 samples/grpc/proto/hello_grpc.proto                |  40 +++
 samples/grpc/proto/hello_grpc_grpc.pb.go           | 116 ++++++++
 samples/grpc/server/app/server.go                  |  85 ++++++
 .../grpc/test/pixiu_test.go                        |  55 ++--
 samples/http/grpc/pixiu/conf.yaml                  |   6 +-
 samples/http/simple/pixiu/conf.yaml                |   6 +-
 samples/https/pixiu/conf.yaml                      |   6 +-
 samples/seata/gateway/conf.yaml                    |  18 +-
 samples/seata/sidecar/server_a/conf.yaml           |   6 +-
 samples/seata/sidecar/server_b/conf.yaml           |   6 +-
 samples/seata/sidecar/server_c/conf.yaml           |   6 +-
 samples/springcloud/pixiu/conf.yaml                |   6 +-
 start_integrate_test.sh                            |   2 +
 60 files changed, 1315 insertions(+), 466 deletions(-)

diff --git a/docs/sample/dubbo/dubbo-registry.md b/docs/sample/dubbo/dubbo-registry.md
index 28202c8..8564e88 100644
--- a/docs/sample/dubbo/dubbo-registry.md
+++ b/docs/sample/dubbo/dubbo-registry.md
@@ -8,16 +8,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 8881
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/docs/sample/http/http-grpc.md b/docs/sample/http/http-grpc.md
index 24b8eb8..3dfaaf7 100644
--- a/docs/sample/http/http-grpc.md
+++ b/docs/sample/http/http-grpc.md
@@ -8,16 +8,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 8881
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/docs/sample/http/http-http.md b/docs/sample/http/http-http.md
index c854e4b..19c2e3e 100644
--- a/docs/sample/http/http-http.md
+++ b/docs/sample/http/http-http.md
@@ -9,16 +9,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 8888
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/docs/user/config.md b/docs/user/config.md
index 9cb00ab..9c1c082 100644
--- a/docs/user/config.md
+++ b/docs/user/config.md
@@ -16,16 +16,12 @@ This document mainly describes the pixiu config abstraction, there is a example
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 8888
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/go.mod b/go.mod
index 60a1611..4db1fbc 100644
--- a/go.mod
+++ b/go.mod
@@ -13,7 +13,7 @@ require (
 	github.com/dubbogo/dubbo-go-pixiu-filter v0.1.4
 	github.com/dubbogo/go-zookeeper v1.0.3
 	github.com/dubbogo/gost v1.11.19
-	github.com/emirpasic/gods v1.12.0
+	github.com/emirpasic/gods v1.12.0 // indirect
 	github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32
 	github.com/gin-gonic/gin v1.7.4
 	github.com/go-playground/assert/v2 v2.0.1
@@ -22,6 +22,7 @@ require (
 	github.com/goinggo/mapstructure v0.0.0-20140717182941-194205d9b4a9
 	github.com/golang-jwt/jwt/v4 v4.1.0
 	github.com/golang/protobuf v1.5.2
+	github.com/gorilla/mux v1.7.3 // indirect
 	github.com/jhump/protoreflect v1.9.0
 	github.com/mercari/grpc-http-proxy v0.1.2
 	github.com/mitchellh/mapstructure v1.4.2
@@ -45,6 +46,7 @@ require (
 	go.opentelemetry.io/otel/trace v1.0.0-RC2
 	go.uber.org/zap v1.19.1
 	golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97
+	golang.org/x/net v0.0.0-20211105192438-b53810dc28af
 	google.golang.org/grpc v1.42.0
 	google.golang.org/protobuf v1.27.1
 	gopkg.in/yaml.v2 v2.4.0
diff --git a/go.sum b/go.sum
index ebd28f4..61e837d 100644
--- a/go.sum
+++ b/go.sum
@@ -439,6 +439,7 @@ github.com/gopherjs/gopherjs v0.0.0-20190910122728-9d188e94fb99/go.mod h1:wJfORR
 github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU=
 github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
 github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
+github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
 github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
 github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
 github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
diff --git a/pkg/common/constant/key.go b/pkg/common/constant/key.go
index 884ee89..1fc0395 100644
--- a/pkg/common/constant/key.go
+++ b/pkg/common/constant/key.go
@@ -19,6 +19,7 @@ package constant
 
 const (
 	HTTPConnectManagerFilter = "dgp.filter.httpconnectionmanager"
+	GRPCConnectManagerFilter = "dgp.filter.grpcconnectionmanager"
 
 	HTTPAuthorityFilter    = "dgp.filter.http.authority"
 	HTTPProxyFilter        = "dgp.filter.http.httpproxy"
diff --git a/pkg/common/extension/filter/filter.go b/pkg/common/extension/filter/filter.go
index 5c203c1..d3030e7 100644
--- a/pkg/common/extension/filter/filter.go
+++ b/pkg/common/extension/filter/filter.go
@@ -19,6 +19,7 @@ package filter
 
 import (
 	"fmt"
+	stdHttp "net/http"
 )
 
 import (
@@ -83,8 +84,8 @@ type (
 
 	// NetworkFilter describe network filter
 	NetworkFilter interface {
-		// OnData handle the http context from worker
-		OnData(hc *http.HttpContext) error
+		// ServeHTTP handle request and response
+		ServeHTTP(w stdHttp.ResponseWriter, r *stdHttp.Request)
 	}
 )
 
diff --git a/pkg/model/listener.go b/pkg/common/grpc/RoundTripper.go
similarity index 67%
copy from pkg/model/listener.go
copy to pkg/common/grpc/RoundTripper.go
index 730f00d..6e44e44 100644
--- a/pkg/model/listener.go
+++ b/pkg/common/grpc/RoundTripper.go
@@ -15,13 +15,20 @@
  * limitations under the License.
  */
 
-package model
+package grpc
 
-// Listener is a server, listener a port
-type Listener struct {
-	Name    string  `yaml:"name" json:"name" mapstructure:"name"`
-	Address Address `yaml:"address" json:"address" mapstructure:"address"`
+import (
+	"net/http"
+)
 
-	FilterChains []FilterChain `yaml:"filter_chains" json:"filter_chains" mapstructure:"filter_chains"`
-	Config       interface{}   `yaml:"config" json:"config" mapstructure:"config"`
+import (
+	"golang.org/x/net/http2"
+)
+
+type HttpForwarder struct {
+	transport *http2.Transport
+}
+
+func (hf *HttpForwarder) Forward(r *http.Request) (*http.Response, error) {
+	return hf.transport.RoundTrip(r)
 }
diff --git a/pkg/common/grpc/manager.go b/pkg/common/grpc/manager.go
new file mode 100644
index 0000000..cf88cc4
--- /dev/null
+++ b/pkg/common/grpc/manager.go
@@ -0,0 +1,143 @@
+/*
+ * 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 grpc
+
+import (
+	"context"
+	"crypto/tls"
+	"encoding/json"
+	"io/ioutil"
+	"net"
+	stdHttp "net/http"
+)
+
+import (
+	"golang.org/x/net/http2"
+)
+
+import (
+	"github.com/apache/dubbo-go-pixiu/pkg/common/constant"
+	router2 "github.com/apache/dubbo-go-pixiu/pkg/common/router"
+	"github.com/apache/dubbo-go-pixiu/pkg/context/http"
+	pch "github.com/apache/dubbo-go-pixiu/pkg/context/http"
+	"github.com/apache/dubbo-go-pixiu/pkg/logger"
+	"github.com/apache/dubbo-go-pixiu/pkg/model"
+	"github.com/apache/dubbo-go-pixiu/pkg/server"
+)
+
+// GrpcConnectionManager network filter for grpc
+type GrpcConnectionManager struct {
+	config            *model.GRPCConnectionManagerConfig
+	routerCoordinator *router2.RouterCoordinator
+}
+
+// CreateGrpcConnectionManager create grpc connection manager
+func CreateGrpcConnectionManager(hcmc *model.GRPCConnectionManagerConfig, bs *model.Bootstrap) *GrpcConnectionManager {
+	hcm := &GrpcConnectionManager{config: hcmc}
+	hcm.routerCoordinator = router2.CreateRouterCoordinator(&hcmc.RouteConfig)
+	return hcm
+}
+
+// OnData receive data from listener
+func (gcm *GrpcConnectionManager) OnData(hc *pch.HttpContext) error {
+	panic("grpc connection manager OnData function shouldn't be called")
+}
+
+// ServeHTTP handle request and response
+func (gcm *GrpcConnectionManager) ServeHTTP(w stdHttp.ResponseWriter, r *stdHttp.Request) {
+
+	ra, err := gcm.routerCoordinator.RouteByPathAndName(r.RequestURI, r.Method)
+	if err != nil {
+		logger.Info("GrpcConnectionManager can't find route %v", err)
+		w.WriteHeader(stdHttp.StatusNotFound)
+		if _, err := w.Write(constant.Default404Body); err != nil {
+			logger.Warnf("WriteWithStatus error %v", err)
+		}
+	}
+
+	logger.Debugf("[dubbo-go-pixiu] client choose endpoint from cluster :%v", ra.Cluster)
+
+	clusterName := ra.Cluster
+	clusterManager := server.GetClusterManager()
+	endpoint := clusterManager.PickEndpoint(clusterName)
+	if endpoint == nil {
+		bt, _ := json.Marshal(http.ErrResponse{Message: "cluster not found endpoint"})
+		w.WriteHeader(stdHttp.StatusServiceUnavailable)
+		w.Write(bt)
+		return
+	}
+
+	newReq := r.Clone(context.Background())
+	newReq.URL.Scheme = "http"
+	newReq.URL.Host = endpoint.Address.GetAddress()
+
+	// todo: need cache?
+	forwarder := gcm.newHttpForwarder()
+	res, err := forwarder.Forward(newReq)
+
+	if err != nil {
+		logger.Info("GrpcConnectionManager forward request error %v", err)
+		bt, _ := json.Marshal(http.ErrResponse{Message: "pixiu forward error"})
+		w.WriteHeader(stdHttp.StatusServiceUnavailable)
+		w.Write(bt)
+		return
+	}
+
+	if err := gcm.response(w, res); err != nil {
+		logger.Info("GrpcConnectionManager response  error %v", err)
+	}
+}
+
+func (gcm *GrpcConnectionManager) response(w stdHttp.ResponseWriter, res *stdHttp.Response) error {
+	defer res.Body.Close()
+
+	copyHeader(w.Header(), res.Header)
+	w.WriteHeader(res.StatusCode)
+
+	bytes, err := ioutil.ReadAll(res.Body)
+	if err != nil {
+		return err
+	}
+	w.Write(bytes)
+
+	for k, vv := range res.Trailer {
+		k = stdHttp.TrailerPrefix + k
+		for _, v := range vv {
+			w.Header().Add(k, v)
+		}
+	}
+	return nil
+}
+
+func (gcm *GrpcConnectionManager) newHttpForwarder() *HttpForwarder {
+	transport := &http2.Transport{
+		DialTLS: func(network, addr string, _ *tls.Config) (net.Conn, error) {
+			return net.Dial(network, addr)
+		},
+		AllowHTTP: true,
+	}
+	return &HttpForwarder{transport: transport}
+}
+
+func copyHeader(dst, src stdHttp.Header) {
+	for k, vv := range src {
+		for _, v := range vv {
+			dst.Add(k, v)
+		}
+	}
+}
diff --git a/pkg/common/http/manager.go b/pkg/common/http/manager.go
index 2ecb8d7..ae291b8 100644
--- a/pkg/common/http/manager.go
+++ b/pkg/common/http/manager.go
@@ -21,7 +21,8 @@ import (
 	"context"
 	"fmt"
 	"io/ioutil"
-	"net/http"
+	stdHttp "net/http"
+	"sync"
 )
 
 import (
@@ -44,18 +45,27 @@ type HttpConnectionManager struct {
 	config            *model.HttpConnectionManagerConfig
 	routerCoordinator *router2.RouterCoordinator
 	filterManager     *filter.FilterManager
+	pool              sync.Pool
 }
 
 // CreateHttpConnectionManager create http connection manager
 func CreateHttpConnectionManager(hcmc *model.HttpConnectionManagerConfig, bs *model.Bootstrap) *HttpConnectionManager {
 	hcm := &HttpConnectionManager{config: hcmc}
-	hcm.routerCoordinator = router2.CreateRouterCoordinator(hcmc)
+	hcm.pool.New = func() interface{} {
+		return hcm.allocateContext()
+	}
+	hcm.routerCoordinator = router2.CreateRouterCoordinator(&hcmc.RouteConfig)
 	hcm.filterManager = filter.NewFilterManager(hcmc.HTTPFilters)
 	hcm.filterManager.Load()
 	return hcm
 }
 
-// OnData receive data from listener
+func (ls *HttpConnectionManager) allocateContext() *pch.HttpContext {
+	return &pch.HttpContext{
+		Params: make(map[string]interface{}),
+	}
+}
+
 func (hcm *HttpConnectionManager) OnData(hc *pch.HttpContext) error {
 	hc.Ctx = context.Background()
 	err := hcm.findRoute(hc)
@@ -66,6 +76,20 @@ func (hcm *HttpConnectionManager) OnData(hc *pch.HttpContext) error {
 	return nil
 }
 
+func (hcm *HttpConnectionManager) ServeHTTP(w stdHttp.ResponseWriter, r *stdHttp.Request) {
+	hc := hcm.pool.Get().(*pch.HttpContext)
+	defer hcm.pool.Put(hc)
+
+	hc.Request = r
+	hc.Writer = w
+	hc.Reset()
+
+	err := hcm.OnData(hc)
+	if err != nil {
+		logger.Errorf("ServeHTTP %v", err)
+	}
+}
+
 // handleHTTPRequest handle http request
 func (hcm *HttpConnectionManager) handleHTTPRequest(c *pch.HttpContext) {
 	filterChain := hcm.filterManager.CreateFilterChain(c)
@@ -74,7 +98,7 @@ func (hcm *HttpConnectionManager) handleHTTPRequest(c *pch.HttpContext) {
 	defer func() {
 		if err := recover(); err != nil {
 			logger.Warnf("[dubbopixiu go] Occur An Unexpected Err: %+v", err)
-			c.SendLocalReply(http.StatusInternalServerError, []byte(fmt.Sprintf("Occur An Unexpected Err: %v", err)))
+			c.SendLocalReply(stdHttp.StatusInternalServerError, []byte(fmt.Sprintf("Occur An Unexpected Err: %v", err)))
 		}
 	}()
 
@@ -101,7 +125,7 @@ func (hcm *HttpConnectionManager) buildTargetResponse(c *pch.HttpContext) {
 	}
 
 	switch res := c.SourceResp.(type) {
-	case *http.Response:
+	case *stdHttp.Response:
 		body, err := ioutil.ReadAll(res.Body)
 		if err != nil {
 			panic(err)
@@ -115,13 +139,13 @@ func (hcm *HttpConnectionManager) buildTargetResponse(c *pch.HttpContext) {
 		c.StatusCode(res.StatusCode)
 		c.TargetResp = &client.Response{Data: body}
 	case []byte:
-		c.StatusCode(http.StatusOK)
+		c.StatusCode(stdHttp.StatusOK)
 		c.AddHeader(constant.HeaderKeyContextType, constant.HeaderValueTextPlain)
 		c.TargetResp = &client.Response{Data: res}
 	default:
 		//dubbo go generic invoke
 		response := util.NewDubboResponse(res, false)
-		c.StatusCode(http.StatusOK)
+		c.StatusCode(stdHttp.StatusOK)
 		c.AddHeader(constant.HeaderKeyContextType, constant.HeaderValueJsonUtf8)
 		c.TargetResp = response
 	}
@@ -131,7 +155,7 @@ func (hcm *HttpConnectionManager) findRoute(hc *pch.HttpContext) error {
 	ra, err := hcm.routerCoordinator.Route(hc)
 	if err != nil {
 		hc.AddHeader(constant.HeaderKeyContextType, constant.HeaderValueTextPlain)
-		hc.SendLocalReply(http.StatusNotFound, constant.Default404Body)
+		hc.SendLocalReply(stdHttp.StatusNotFound, constant.Default404Body)
 
 		e := errors.Errorf("Requested URL %s not found", hc.GetUrl())
 		logger.Debug(e.Error())
diff --git a/pkg/common/router/router.go b/pkg/common/router/router.go
index ddbd3ce..80328f5 100644
--- a/pkg/common/router/router.go
+++ b/pkg/common/router/router.go
@@ -40,9 +40,9 @@ type (
 )
 
 // CreateRouterCoordinator create coordinator for http connection manager
-func CreateRouterCoordinator(hcmc *model.HttpConnectionManagerConfig) *RouterCoordinator {
-	rc := &RouterCoordinator{activeConfig: &hcmc.RouteConfig}
-	if hcmc.RouteConfig.Dynamic {
+func CreateRouterCoordinator(routeConfig *model.RouteConfiguration) *RouterCoordinator {
+	rc := &RouterCoordinator{activeConfig: routeConfig}
+	if routeConfig.Dynamic {
 		server.GetRouterManager().AddRouterListener(rc)
 	}
 	rc.initTrie()
@@ -57,6 +57,13 @@ func (rm *RouterCoordinator) Route(hc *http.HttpContext) (*model.RouteAction, er
 	return rm.activeConfig.Route(hc.Request)
 }
 
+func (rm *RouterCoordinator) RouteByPathAndName(path, method string) (*model.RouteAction, error) {
+	rm.rw.RLock()
+	defer rm.rw.RUnlock()
+
+	return rm.activeConfig.RouteByPathAndMethod(path, method)
+}
+
 func getTrieKey(method string, path string, isPrefix bool) string {
 	if isPrefix {
 		if !strings.HasSuffix(path, constant.PathSlash) {
diff --git a/pkg/common/router/router_test.go b/pkg/common/router/router_test.go
index 697a293..faa7eec 100644
--- a/pkg/common/router/router_test.go
+++ b/pkg/common/router/router_test.go
@@ -53,7 +53,7 @@ func TestCreateRouterCoordinator(t *testing.T) {
 		IdleTimeoutStr:    "100",
 	}
 
-	r := CreateRouterCoordinator(&hcmc)
+	r := CreateRouterCoordinator(&hcmc.RouteConfig)
 	request, err := http.NewRequest("POST", "http://www.dubbogopixiu.com/api/v1?name=tc", bytes.NewReader([]byte("{\"id\":\"12345\"}")))
 	assert.NoError(t, err)
 	c := mock.GetMockHTTPContext(request)
diff --git a/pkg/config/conf_test.yaml b/pkg/config/conf_test.yaml
index 2d4e6fb..170906c 100644
--- a/pkg/config/conf_test.yaml
+++ b/pkg/config/conf_test.yaml
@@ -20,16 +20,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTPS"
       address:
         socket_address:
-          protocol_type: "HTTPS"
           address: "0.0.0.0"
           port: 443
       filter_chains:
-        - filter_chain_match:
-            domains:
-              - api.dubbo.com
-              - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/pkg/config/config_load.go b/pkg/config/config_load.go
index 16d8b5b..870e1be 100644
--- a/pkg/config/config_load.go
+++ b/pkg/config/config_load.go
@@ -113,10 +113,10 @@ func GetProtocol(cfg *model.Bootstrap) (err error) {
 		return err
 	}
 	for _, l := range cfg.StaticResources.Listeners {
-		if l.Address.SocketAddress.ProtocolStr == "" {
-			l.Address.SocketAddress.ProtocolStr = constant.DefaultProtocolType
+		if l.ProtocolStr == "" {
+			l.ProtocolStr = constant.DefaultProtocolType
 		}
-		l.Address.SocketAddress.Protocol = model.ProtocolType(model.ProtocolTypeValue[l.Address.SocketAddress.ProtocolStr])
+		l.Protocol = model.ProtocolType(model.ProtocolTypeValue[l.ProtocolStr])
 	}
 	return nil
 }
diff --git a/pkg/config/config_load_test.go b/pkg/config/config_load_test.go
index 94aef4d..b83d6bb 100644
--- a/pkg/config/config_load_test.go
+++ b/pkg/config/config_load_test.go
@@ -84,12 +84,12 @@ func TestMain(m *testing.M) {
 		StaticResources: model.StaticResources{
 			Listeners: []*model.Listener{
 				{
-					Name: "net/http",
+					Name:        "net/http",
+					ProtocolStr: "HTTPS",
 					Address: model.Address{
 						SocketAddress: model.SocketAddress{
-							ProtocolStr: "HTTPS",
-							Address:     "0.0.0.0",
-							Port:        443,
+							Address: "0.0.0.0",
+							Port:    443,
 						},
 					},
 					Config: model.HttpConfig{
@@ -97,19 +97,11 @@ func TestMain(m *testing.M) {
 						WriteTimeoutStr: "5s",
 						ReadTimeoutStr:  "5s",
 					},
-					FilterChains: []model.FilterChain{
-						{
-							FilterChainMatch: model.FilterChainMatch{
-								Domains: []string{
-									"api.dubbo.com",
-									"api.pixiu.com",
-								},
-							},
-							Filters: []model.Filter{
-								{
-									Name:   "dgp.filter.httpconnectionmanager",
-									Config: inInterface,
-								},
+					FilterChain: model.FilterChain{
+						Filters: []model.NetworkFilter{
+							{
+								Name:   "dgp.filter.httpconnectionmanager",
+								Config: inInterface,
 							},
 						},
 					},
diff --git a/pkg/context/http/context.go b/pkg/context/http/context.go
index bd9c2a9..978ce68 100644
--- a/pkg/context/http/context.go
+++ b/pkg/context/http/context.go
@@ -63,7 +63,6 @@ type HttpContext struct {
 	SourceResp interface{}
 
 	HttpConnectionManager model.HttpConnectionManagerConfig
-	Listener              *model.Listener
 	Route                 *model.RouteAction
 	Api                   *router.API
 
diff --git a/pkg/server/listener_test.go b/pkg/filter/network/grpcconnectionmanager/plugin.go
similarity index 59%
copy from pkg/server/listener_test.go
copy to pkg/filter/network/grpcconnectionmanager/plugin.go
index b3401f7..3e66ac7 100644
--- a/pkg/server/listener_test.go
+++ b/pkg/filter/network/grpcconnectionmanager/plugin.go
@@ -15,32 +15,32 @@
  * limitations under the License.
  */
 
-package server
+package grpcconnectionmanager
 
 import (
-	ctxHttp "github.com/apache/dubbo-go-pixiu/pkg/context/http"
+	"github.com/apache/dubbo-go-pixiu/pkg/common/constant"
+	"github.com/apache/dubbo-go-pixiu/pkg/common/extension/filter"
+	"github.com/apache/dubbo-go-pixiu/pkg/common/grpc"
 	"github.com/apache/dubbo-go-pixiu/pkg/model"
 )
 
-func getTestContext() *ctxHttp.HttpContext {
-	l := ListenerService{
-		cfg: &model.Listener{
-			Name: "test",
-			Address: model.Address{
-				SocketAddress: model.SocketAddress{
-					Protocol: model.ProtocolTypeHTTP,
-					Address:  "0.0.0.0",
-					Port:     8888,
-				},
-			},
-			FilterChains: []model.FilterChain{},
-		},
-	}
+const (
+	Kind = constant.GRPCConnectManagerFilter
+)
+
+func init() {
+	filter.RegisterNetworkFilter(&Plugin{})
+}
+
+type (
+	Plugin struct{}
+)
+
+func (p *Plugin) Kind() string {
+	return Kind
+}
 
-	hc := &ctxHttp.HttpContext{
-		Listener: l.cfg,
-		Filters:  []ctxHttp.FilterFunc{},
-	}
-	hc.Reset()
-	return hc
+func (hp *Plugin) CreateFilter(config interface{}, bs *model.Bootstrap) (filter.NetworkFilter, error) {
+	hcmc := config.(*model.GRPCConnectionManagerConfig)
+	return grpc.CreateGrpcConnectionManager(hcmc, bs), nil
 }
diff --git a/pkg/filterchain/network_filter_chain.go b/pkg/filterchain/network_filter_chain.go
new file mode 100644
index 0000000..dd04607
--- /dev/null
+++ b/pkg/filterchain/network_filter_chain.go
@@ -0,0 +1,84 @@
+/*
+ * 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 filterchain
+
+import (
+	"net/http"
+)
+
+import (
+	"github.com/apache/dubbo-go-pixiu/pkg/common/constant"
+	"github.com/apache/dubbo-go-pixiu/pkg/common/extension/filter"
+	"github.com/apache/dubbo-go-pixiu/pkg/common/yaml"
+	"github.com/apache/dubbo-go-pixiu/pkg/logger"
+	"github.com/apache/dubbo-go-pixiu/pkg/model"
+)
+
+type NetworkFilterChain struct {
+	filtersArray []filter.NetworkFilter
+	config       model.FilterChain
+}
+
+func (fc NetworkFilterChain) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	// todo: only one filter will exist for now, needs change when more than one
+	for _, filter := range fc.filtersArray {
+		filter.ServeHTTP(w, r)
+	}
+}
+
+func CreateNetworkFilterChain(config model.FilterChain, bs *model.Bootstrap) *NetworkFilterChain {
+	filtersArray := make([]filter.NetworkFilter, len(config.Filters))
+	// todo: split code block like http filter manager
+	// todo: only one filter will exist for now, needs change when more than one
+	for i, f := range config.Filters {
+		if f.Name == constant.GRPCConnectManagerFilter {
+			gcmc := &model.GRPCConnectionManagerConfig{}
+			if err := yaml.ParseConfig(gcmc, f.Config); err != nil {
+				logger.Error("CreateNetworkFilterChain %s parse config error %s", f.Name, err)
+			}
+			p, err := filter.GetNetworkFilterPlugin(constant.GRPCConnectManagerFilter)
+			if err != nil {
+				logger.Error("CreateNetworkFilterChain %s getNetworkFilterPlugin error %s", f.Name, err)
+			}
+			filter, err := p.CreateFilter(gcmc, bs)
+			if err != nil {
+				logger.Error("CreateNetworkFilterChain %s createFilter error %s", f.Name, err)
+			}
+			filtersArray[i] = filter
+		} else if f.Name == constant.HTTPConnectManagerFilter {
+			hcmc := &model.HttpConnectionManagerConfig{}
+			if err := yaml.ParseConfig(hcmc, f.Config); err != nil {
+				logger.Error("CreateNetworkFilterChain parse %s config error %s", f.Name, err)
+			}
+			p, err := filter.GetNetworkFilterPlugin(constant.HTTPConnectManagerFilter)
+			if err != nil {
+				logger.Error("CreateNetworkFilterChain %s getNetworkFilterPlugin error %s", f.Name, err)
+			}
+			filter, err := p.CreateFilter(hcmc, bs)
+			if err != nil {
+				logger.Error("CreateNetworkFilterChain %s createFilter error %s", f.Name, err)
+			}
+			filtersArray[i] = filter
+		}
+	}
+
+	return &NetworkFilterChain{
+		filtersArray: filtersArray,
+		config:       config,
+	}
+}
diff --git a/pkg/server/listener.go b/pkg/listener/http/http_listener.go
similarity index 54%
rename from pkg/server/listener.go
rename to pkg/listener/http/http_listener.go
index b71212c..5fc477c 100644
--- a/pkg/server/listener.go
+++ b/pkg/listener/http/http_listener.go
@@ -15,83 +15,82 @@
  * limitations under the License.
  */
 
-package server
+package http
 
 import (
+	"fmt"
 	"log"
 	"net/http"
 	"strconv"
-	"sync"
 	"time"
 )
 
 import (
+	"github.com/pkg/errors"
 	"golang.org/x/crypto/acme/autocert"
 )
 
 import (
-	"github.com/apache/dubbo-go-pixiu/pkg/common/constant"
-	"github.com/apache/dubbo-go-pixiu/pkg/common/extension/filter"
-	"github.com/apache/dubbo-go-pixiu/pkg/common/yaml"
-	h "github.com/apache/dubbo-go-pixiu/pkg/context/http"
+	"github.com/apache/dubbo-go-pixiu/pkg/filterchain"
+	"github.com/apache/dubbo-go-pixiu/pkg/listener"
 	"github.com/apache/dubbo-go-pixiu/pkg/logger"
 	"github.com/apache/dubbo-go-pixiu/pkg/model"
 )
 
+func init() {
+	listener.SetListenerServiceFactory(model.ProtocolTypeHTTP, newHttpListenerService)
+}
+
 type (
 	// ListenerService the facade of a listener
-	ListenerService struct {
-		cfg *model.Listener
-		// TODO: just temporary because only one network filter
-		nf  filter.NetworkFilter
+	HttpListenerService struct {
+		listener.BaseListenerService
 		srv *http.Server
 	}
 
 	// DefaultHttpListener
 	DefaultHttpWorker struct {
-		pool sync.Pool
-		ls   *ListenerService
+		ls *HttpListenerService
 	}
 )
 
-// NewListenerService create listener service
-func CreateListenerService(lc *model.Listener, bs *model.Bootstrap) *ListenerService {
-	hcm := createHttpManager(lc, bs)
-	return &ListenerService{cfg: lc, nf: *hcm}
-}
-
-func (ls *ListenerService) GetNetworkFilter() filter.NetworkFilter {
-	return ls.nf
+func newHttpListenerService(lc *model.Listener, bs *model.Bootstrap) (listener.ListenerService, error) {
+	fc := filterchain.CreateNetworkFilterChain(lc.FilterChain, bs)
+	return &HttpListenerService{
+		BaseListenerService: listener.BaseListenerService{
+			Config:      lc,
+			FilterChain: fc,
+		},
+		srv: nil,
+	}, nil
 }
 
 // Start start the listener
-func (ls *ListenerService) Start() {
-	sa := ls.cfg.Address.SocketAddress
-	switch sa.Protocol {
+func (ls *HttpListenerService) Start() error {
+	switch ls.Config.Protocol {
 	case model.ProtocolTypeHTTP:
 		ls.httpListener()
 	case model.ProtocolTypeHTTPS:
 		ls.httpsListener()
 	default:
-		panic("unsupported protocol start: " + sa.ProtocolStr)
+		return errors.New(fmt.Sprintf("unsupported protocol start: %d", ls.Config.Protocol))
 	}
+	return nil
 }
 
-func (ls *ListenerService) httpsListener() {
-	hl := CreateDefaultHttpWorker(ls)
-	hl.pool.New = func() interface{} {
-		return ls.allocateContext()
-	}
+func (ls *HttpListenerService) httpsListener() {
+	hl := createDefaultHttpWorker(ls)
+
 	// user customize http config
 	var hc *model.HttpConfig
-	hc = model.MapInStruct(ls.cfg)
+	hc = model.MapInStruct(ls.Config)
 
 	mux := http.NewServeMux()
 	mux.HandleFunc("/", hl.ServeHTTP)
 	m := &autocert.Manager{
-		Cache:      autocert.DirCache(ls.cfg.Address.SocketAddress.CertsDir),
+		Cache:      autocert.DirCache(ls.Config.Address.SocketAddress.CertsDir),
 		Prompt:     autocert.AcceptTOS,
-		HostPolicy: autocert.HostWhitelist(ls.cfg.Address.SocketAddress.Domains...),
+		HostPolicy: autocert.HostWhitelist(ls.Config.Address.SocketAddress.Domains...),
 	}
 	ls.srv = &http.Server{
 		Addr:           ":https",
@@ -102,26 +101,23 @@ func (ls *ListenerService) httpsListener() {
 		MaxHeaderBytes: resolveInt2IntProp(hc.MaxHeaderBytes, 1<<20),
 		TLSConfig:      m.TLSConfig(),
 	}
-	autoLs := autocert.NewListener(ls.cfg.Address.SocketAddress.Domains...)
+	autoLs := autocert.NewListener(ls.Config.Address.SocketAddress.Domains...)
 	logger.Infof("[dubbo-go-server] httpsListener start at : %s", ls.srv.Addr)
 	err := ls.srv.Serve(autoLs)
 	logger.Info("[dubbo-go-server] httpsListener result:", err)
 }
 
-func (ls *ListenerService) httpListener() {
-	hl := CreateDefaultHttpWorker(ls)
-	hl.pool.New = func() interface{} {
-		return ls.allocateContext()
-	}
+func (ls *HttpListenerService) httpListener() {
+	hl := createDefaultHttpWorker(ls)
 
 	// user customize http config
 	var hc *model.HttpConfig
-	hc = model.MapInStruct(ls.cfg)
+	hc = model.MapInStruct(ls.Config)
 
 	mux := http.NewServeMux()
 	mux.HandleFunc("/", hl.ServeHTTP)
 
-	sa := ls.cfg.Address.SocketAddress
+	sa := ls.Config.Address.SocketAddress
 	ls.srv = &http.Server{
 		Addr:           resolveAddress(sa.Address + ":" + strconv.Itoa(sa.Port)),
 		Handler:        mux,
@@ -136,37 +132,16 @@ func (ls *ListenerService) httpListener() {
 	log.Println(ls.srv.ListenAndServe())
 }
 
-func (ls *ListenerService) allocateContext() *h.HttpContext {
-	return &h.HttpContext{
-		Listener: ls.cfg,
-		Params:   make(map[string]interface{}),
-	}
-}
-
-// NewDefaultHttpListener create http listener
-func CreateDefaultHttpWorker(ls *ListenerService) *DefaultHttpWorker {
+// createDefaultHttpWorker create http listener
+func createDefaultHttpWorker(ls *HttpListenerService) *DefaultHttpWorker {
 	return &DefaultHttpWorker{
-		pool: sync.Pool{},
-		ls:   ls,
+		ls: ls,
 	}
 }
 
 // ServeHTTP http request entrance.
 func (s *DefaultHttpWorker) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	hc := s.pool.Get().(*h.HttpContext)
-	defer s.pool.Put(hc)
-
-	hc.Request = r
-	hc.Writer = w
-	hc.Reset()
-
-	// now only one filter http_connection_manager, so just get it and call
-	err := s.ls.nf.OnData(hc)
-
-	if err != nil {
-		s.pool.Put(hc)
-		logger.Errorf("ServeHTTP %s", err)
-	}
+	s.ls.FilterChain.ServeHTTP(w, r)
 }
 
 func resolveInt2IntProp(currentV, defaultV int) int {
@@ -197,34 +172,3 @@ func resolveAddress(addr string) string {
 
 	return addr
 }
-
-func findHttpManager(l *model.Listener) *model.HttpConnectionManagerConfig {
-	for _, fc := range l.FilterChains {
-		for _, f := range fc.Filters {
-			if f.Name == constant.HTTPConnectManagerFilter {
-				hcmc := &model.HttpConnectionManagerConfig{}
-				if err := yaml.ParseConfig(hcmc, f.Config); err != nil {
-					return nil
-				}
-
-				return hcmc
-			}
-		}
-	}
-
-	return DefaultHttpConnectionManager()
-}
-
-func createHttpManager(lc *model.Listener, bs *model.Bootstrap) *filter.NetworkFilter {
-	p, err := filter.GetNetworkFilterPlugin(constant.HTTPConnectManagerFilter)
-	if err != nil {
-		panic(err)
-	}
-
-	hcmc := findHttpManager(lc)
-	hcm, err := p.CreateFilter(hcmc, bs)
-	if err != nil {
-		panic(err)
-	}
-	return &hcm
-}
diff --git a/pkg/listener/http2/http2_listener.go b/pkg/listener/http2/http2_listener.go
new file mode 100644
index 0000000..5da0dbb
--- /dev/null
+++ b/pkg/listener/http2/http2_listener.go
@@ -0,0 +1,121 @@
+/*
+ * 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 http2
+
+import (
+	"net"
+	"net/http"
+	"strconv"
+)
+
+import (
+	"golang.org/x/net/http2"
+	"golang.org/x/net/http2/h2c"
+)
+
+import (
+	"github.com/apache/dubbo-go-pixiu/pkg/filterchain"
+	"github.com/apache/dubbo-go-pixiu/pkg/listener"
+	"github.com/apache/dubbo-go-pixiu/pkg/logger"
+	"github.com/apache/dubbo-go-pixiu/pkg/model"
+)
+
+func init() {
+	listener.SetListenerServiceFactory(model.ProtocolTypeHTTP2, newHttp2ListenerService)
+}
+
+type (
+	// Http2ListenerService the facade of a listener
+	Http2ListenerService struct {
+		listener.BaseListenerService
+		listener net.Listener
+		server   *http.Server
+	}
+)
+
+type handleWrapper struct {
+	fc *filterchain.NetworkFilterChain
+}
+
+type h2cWrapper struct {
+	w *handleWrapper
+	h http.Handler
+}
+
+// ServeHTTP call Handler to handle http request and response.
+func (h *h2cWrapper) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	h.h.ServeHTTP(w, r)
+}
+
+// ServeHTTP call FilterChain to handle http request and response.
+func (h *handleWrapper) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	h.fc.ServeHTTP(w, r)
+}
+
+func newHttp2ListenerService(lc *model.Listener, bs *model.Bootstrap) (listener.ListenerService, error) {
+	fc := filterchain.CreateNetworkFilterChain(lc.FilterChain, bs)
+	return &Http2ListenerService{
+		BaseListenerService: listener.BaseListenerService{
+			Config:      lc,
+			FilterChain: fc,
+		},
+		listener: nil,
+		server:   nil,
+	}, nil
+}
+
+// Start start listen
+func (ls Http2ListenerService) Start() error {
+
+	sa := ls.Config.Address.SocketAddress
+	addr := resolveAddress(sa.Address + ":" + strconv.Itoa(sa.Port))
+
+	l, err := net.Listen("tcp", addr)
+	if err != nil {
+		return err
+	}
+	ls.listener = l
+
+	handlerWrapper := &handleWrapper{ls.FilterChain}
+	h2s := &http2.Server{}
+	h := &h2cWrapper{
+		w: handlerWrapper,
+		h: h2c.NewHandler(handlerWrapper, h2s),
+	}
+
+	ls.server = &http.Server{
+		Addr:    addr,
+		Handler: h,
+	}
+
+	go func() {
+		if err := ls.server.Serve(ls.listener); err != nil {
+			logger.Error("Http2ListenerService Start error %s", err)
+		}
+	}()
+	return nil
+}
+
+func resolveAddress(addr string) string {
+	if addr == "" {
+		logger.Debug("Addr is undefined. Using port :8080 by default")
+		return ":8080"
+	}
+
+	return addr
+}
diff --git a/pkg/listener/listener.go b/pkg/listener/listener.go
new file mode 100644
index 0000000..5b9a76d
--- /dev/null
+++ b/pkg/listener/listener.go
@@ -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 listener
+
+import (
+	"github.com/pkg/errors"
+)
+
+import (
+	"github.com/apache/dubbo-go-pixiu/pkg/filterchain"
+	"github.com/apache/dubbo-go-pixiu/pkg/model"
+)
+
+var factoryMap = make(map[model.ProtocolType]func(lc *model.Listener, bs *model.Bootstrap) (ListenerService, error), 8)
+
+type (
+	ListenerService interface {
+		Start() error
+	}
+
+	BaseListenerService struct {
+		Config      *model.Listener
+		FilterChain *filterchain.NetworkFilterChain
+	}
+)
+
+// SetListenerServiceFactory will store the listenerService factory by name
+func SetListenerServiceFactory(protocol model.ProtocolType, newRegFunc func(lc *model.Listener, bs *model.Bootstrap) (ListenerService, error)) {
+	factoryMap[protocol] = newRegFunc
+}
+
+// CreateListenerService create listener service
+func CreateListenerService(lc *model.Listener, bs *model.Bootstrap) (ListenerService, error) {
+	if registry, ok := factoryMap[lc.Protocol]; ok {
+		reg, err := registry(lc, bs)
+		if err != nil {
+			panic("Initialize ListenerService " + lc.Name + "failed due to: " + err.Error())
+		}
+		return reg, nil
+	}
+	return nil, errors.New("Registry " + lc.ProtocolStr + " does not support yet")
+}
diff --git a/pkg/server/listener_test.go b/pkg/listener/listener_test.go
similarity index 71%
copy from pkg/server/listener_test.go
copy to pkg/listener/listener_test.go
index b3401f7..fe2514d 100644
--- a/pkg/server/listener_test.go
+++ b/pkg/listener/listener_test.go
@@ -15,31 +15,16 @@
  * limitations under the License.
  */
 
-package server
+package listener
 
 import (
 	ctxHttp "github.com/apache/dubbo-go-pixiu/pkg/context/http"
-	"github.com/apache/dubbo-go-pixiu/pkg/model"
 )
 
 func getTestContext() *ctxHttp.HttpContext {
-	l := ListenerService{
-		cfg: &model.Listener{
-			Name: "test",
-			Address: model.Address{
-				SocketAddress: model.SocketAddress{
-					Protocol: model.ProtocolTypeHTTP,
-					Address:  "0.0.0.0",
-					Port:     8888,
-				},
-			},
-			FilterChains: []model.FilterChain{},
-		},
-	}
 
 	hc := &ctxHttp.HttpContext{
-		Listener: l.cfg,
-		Filters:  []ctxHttp.FilterFunc{},
+		Filters: []ctxHttp.FilterFunc{},
 	}
 	hc.Reset()
 	return hc
diff --git a/pkg/model/base.go b/pkg/model/base.go
index 6503f32..ea76b7f 100644
--- a/pkg/model/base.go
+++ b/pkg/model/base.go
@@ -42,20 +42,6 @@ const (
 )
 
 const (
-	ProtocolTypeHTTP ProtocolType = 0 + iota // support for 1.0
-	ProtocolTypeTCP
-	ProtocolTypeUDP
-	ProtocolTypeHTTPS
-	ProtocolTypeGRPC
-)
-
-const (
-	REST_VALUE  = "REST"
-	GRPC_VALUE  = "GRPC"
-	DUBBO_VALUE = "DUBBO"
-)
-
-const (
 	ApiTypeREST api.ApiType = 0 + iota // support for 1.0
 	ApiTypeGRPC
 	ApiTypeDUBBO
@@ -74,24 +60,6 @@ var (
 		"Unknown": 2,
 	}
 
-	// ProtocolTypeName enum seq to protocol type name
-	ProtocolTypeName = map[int32]string{
-		0: "HTTP",
-		1: "TCP",
-		2: "UDP",
-		3: "HTTPS",
-		4: "GRPC",
-	}
-
-	// ProtocolTypeValue protocol type name to enum seq
-	ProtocolTypeValue = map[string]int32{
-		"HTTP":  0,
-		"TCP":   1,
-		"UDP":   2,
-		"HTTPS": 3,
-		"GRPC":  4,
-	}
-
 	ApiTypeName = map[int32]string{
 		0: REST_VALUE,
 		1: GRPC_VALUE,
@@ -106,8 +74,6 @@ var (
 )
 
 type (
-	// ProtocolType protocol type enum
-	ProtocolType int32
 
 	// Address the address
 	Address struct {
@@ -119,13 +85,11 @@ type (
 	// used to tell server where to bind/listen, connect to upstream and find
 	// management servers
 	SocketAddress struct {
-		ProtocolStr  string       `yaml:"protocol_type" json:"protocol_type" mapstructure:"protocol_type"`
-		Protocol     ProtocolType `default:"http" yaml:"omitempty" json:"omitempty"`
-		Address      string       `default:"0.0.0.0" yaml:"address" json:"address" mapstructure:"address"`
-		Port         int          `default:"8881" yaml:"port" json:"port" mapstructure:"port"`
-		ResolverName string       `yaml:"resolver_name" json:"resolver_name" mapstructure:"resolver_name"`
-		Domains      []string     `yaml:"domains" json:"domains" mapstructure:"domains"`
-		CertsDir     string       `yaml:"certs_dir" json:"certs_dir" mapstructure:"certs_dir"`
+		Address      string   `default:"0.0.0.0" yaml:"address" json:"address" mapstructure:"address"`
+		Port         int      `default:"8881" yaml:"port" json:"port" mapstructure:"port"`
+		ResolverName string   `yaml:"resolver_name" json:"resolver_name" mapstructure:"resolver_name"`
+		Domains      []string `yaml:"domains" json:"domains" mapstructure:"domains"`
+		CertsDir     string   `yaml:"certs_dir" json:"certs_dir" mapstructure:"certs_dir"`
 	}
 
 	// ConfigSource
diff --git a/pkg/model/filter.go b/pkg/model/filter.go
index 4214bf6..a03abe4 100644
--- a/pkg/model/filter.go
+++ b/pkg/model/filter.go
@@ -19,12 +19,11 @@ package model
 
 // FilterChain filter chain
 type FilterChain struct {
-	FilterChainMatch FilterChainMatch `yaml:"filter_chain_match" json:"filter_chain_match" mapstructure:"filter_chain_match"`
-	Filters          []Filter         `yaml:"filters" json:"filters" mapstructure:"filters"`
+	Filters []NetworkFilter `yaml:"filters" json:"filters" mapstructure:"filters"`
 }
 
-// Filter core struct, filter is extend by user
-type Filter struct {
+// NetworkFilter core struct, filter is extend by user
+type NetworkFilter struct {
 	Name   string                 `yaml:"name" json:"name" mapstructure:"name"`       // Name filter name unique
 	Config map[string]interface{} `yaml:"config" json:"config" mapstructure:"config"` // Config filter config
 }
diff --git a/pkg/model/http.go b/pkg/model/http.go
index aa944d9..05ba60b 100644
--- a/pkg/model/http.go
+++ b/pkg/model/http.go
@@ -34,6 +34,11 @@ type HttpConnectionManagerConfig struct {
 	GenerateRequestID bool               `yaml:"generate_request_id" json:"generate_request_id" mapstructure:"generate_request_id"`
 }
 
+// GRPCConnectionManagerConfig
+type GRPCConnectionManagerConfig struct {
+	RouteConfig RouteConfiguration `yaml:"route_config" json:"route_config" mapstructure:"route_config"`
+}
+
 // HTTPFilter http filter
 type HTTPFilter struct {
 	Name   string                 `yaml:"name" json:"name" mapstructure:"name"`
diff --git a/pkg/model/listener.go b/pkg/model/listener.go
index 730f00d..73ea0f6 100644
--- a/pkg/model/listener.go
+++ b/pkg/model/listener.go
@@ -17,11 +17,54 @@
 
 package model
 
-// Listener is a server, listener a port
-type Listener struct {
-	Name    string  `yaml:"name" json:"name" mapstructure:"name"`
-	Address Address `yaml:"address" json:"address" mapstructure:"address"`
+const (
+	ProtocolTypeHTTP ProtocolType = 0 + iota // support for 1.0
+	ProtocolTypeTCP
+	ProtocolTypeUDP
+	ProtocolTypeHTTPS
+	ProtocolTypeGRPC
+	ProtocolTypeHTTP2
+)
 
-	FilterChains []FilterChain `yaml:"filter_chains" json:"filter_chains" mapstructure:"filter_chains"`
-	Config       interface{}   `yaml:"config" json:"config" mapstructure:"config"`
-}
+const (
+	REST_VALUE  = "REST"
+	GRPC_VALUE  = "GRPC"
+	DUBBO_VALUE = "DUBBO"
+)
+
+var (
+	// ProtocolTypeName enum seq to protocol type name
+	ProtocolTypeName = map[int32]string{
+		0: "HTTP",
+		1: "TCP",
+		2: "UDP",
+		3: "HTTPS",
+		4: "GRPC",
+		5: "HTTP2",
+	}
+
+	// ProtocolTypeValue protocol type name to enum seq
+	ProtocolTypeValue = map[string]int32{
+		"HTTP":  0,
+		"TCP":   1,
+		"UDP":   2,
+		"HTTPS": 3,
+		"GRPC":  4,
+		"HTTP2": 5,
+	}
+)
+
+type (
+	// ProtocolType protocol type enum
+	ProtocolType int32
+
+	// Listener is a server, listener a port
+	Listener struct {
+		Name        string       `yaml:"name" json:"name" mapstructure:"name"`
+		Address     Address      `yaml:"address" json:"address" mapstructure:"address"`
+		ProtocolStr string       `default:"http" yaml:"protocol_type" json:"protocol_type" mapstructure:"protocol_type"`
+		Protocol    ProtocolType `default:"http" yaml:"omitempty" json:"omitempty"`
+		FilterChain FilterChain  `yaml:"filter_chains" json:"filter_chains" mapstructure:"filter_chains"`
+		Config      interface{}  `yaml:"config" json:"config" mapstructure:"config"`
+	}
+)
diff --git a/pkg/model/router.go b/pkg/model/router.go
index 5314418..af8fc6f 100644
--- a/pkg/model/router.go
+++ b/pkg/model/router.go
@@ -71,14 +71,14 @@ type (
 	}
 )
 
-func (rc *RouteConfiguration) Route(req *stdHttp.Request) (*RouteAction, error) {
+func (rc *RouteConfiguration) RouteByPathAndMethod(path, method string) (*RouteAction, error) {
 	if rc.RouteTrie.IsEmpty() {
 		return nil, errors.Errorf("router configuration is empty")
 	}
 
-	node, _, _ := rc.RouteTrie.Match(stringutil.GetTrieKey(req.Method, req.URL.Path))
+	node, _, _ := rc.RouteTrie.Match(stringutil.GetTrieKey(method, path))
 	if node == nil {
-		return nil, errors.Errorf("route failed for %s,no rules matched.", stringutil.GetTrieKey(req.Method, req.URL.Path))
+		return nil, errors.Errorf("route failed for %s,no rules matched.", stringutil.GetTrieKey(method, path))
 	}
 	if node.GetBizInfo() == nil {
 		return nil, errors.Errorf("info is nil.please check your configuration.")
@@ -86,3 +86,7 @@ func (rc *RouteConfiguration) Route(req *stdHttp.Request) (*RouteAction, error)
 	ret := (node.GetBizInfo()).(RouteAction)
 	return &ret, nil
 }
+
+func (rc *RouteConfiguration) Route(req *stdHttp.Request) (*RouteAction, error) {
+	return rc.RouteByPathAndMethod(req.URL.Path, req.Method)
+}
diff --git a/pkg/pluginregistry/registry.go b/pkg/pluginregistry/registry.go
index 367d394..df9f33e 100644
--- a/pkg/pluginregistry/registry.go
+++ b/pkg/pluginregistry/registry.go
@@ -34,7 +34,10 @@ import (
 	_ "github.com/apache/dubbo-go-pixiu/pkg/filter/http/proxyrewrite"
 	_ "github.com/apache/dubbo-go-pixiu/pkg/filter/http/remote"
 	_ "github.com/apache/dubbo-go-pixiu/pkg/filter/metric"
+	_ "github.com/apache/dubbo-go-pixiu/pkg/filter/network/grpcconnectionmanager"
 	_ "github.com/apache/dubbo-go-pixiu/pkg/filter/network/httpconnectionmanager"
 	_ "github.com/apache/dubbo-go-pixiu/pkg/filter/seata"
 	_ "github.com/apache/dubbo-go-pixiu/pkg/filter/tracing"
+	_ "github.com/apache/dubbo-go-pixiu/pkg/listener/http"
+	_ "github.com/apache/dubbo-go-pixiu/pkg/listener/http2"
 )
diff --git a/pkg/server/listener_manager.go b/pkg/server/listener_manager.go
index 9bee77d..3c433fe 100644
--- a/pkg/server/listener_manager.go
+++ b/pkg/server/listener_manager.go
@@ -18,19 +18,26 @@
 package server
 
 import (
+	"github.com/apache/dubbo-go-pixiu/pkg/listener"
+	"github.com/apache/dubbo-go-pixiu/pkg/logger"
 	"github.com/apache/dubbo-go-pixiu/pkg/model"
 )
 
+// ListenerManager the listener manager
 type ListenerManager struct {
 	activeListener        []*model.Listener
-	activeListenerService []*ListenerService
+	activeListenerService []listener.ListenerService
 }
 
+// CreateDefaultListenerManager create listener manager from config
 func CreateDefaultListenerManager(bs *model.Bootstrap) *ListenerManager {
 	sl := bs.GetStaticListeners()
-	var ls []*ListenerService
+	var ls []listener.ListenerService
 	for _, l := range bs.StaticResources.Listeners {
-		listener := CreateListenerService(l, bs)
+		listener, err := listener.CreateListenerService(l, bs)
+		if err != nil {
+			logger.Error("CreateDefaultListenerManager %s error: %v", l.Name, err)
+		}
 		ls = append(ls, listener)
 	}
 
@@ -44,21 +51,15 @@ func (lm *ListenerManager) addOrUpdateListener(l *model.Listener) {
 	lm.activeListener = append(lm.activeListener, l)
 }
 
+// StartListen make active listener to start listening
 func (lm *ListenerManager) StartListen() {
 	for _, s := range lm.activeListenerService {
-		go s.Start()
-	}
-}
-
-func (lm *ListenerManager) addListenerService(ls *ListenerService) {
-	lm.activeListenerService = append(lm.activeListenerService, ls)
-}
-
-func (lm *ListenerManager) GetListenerService(name string) *ListenerService {
-	for i := range lm.activeListenerService {
-		if lm.activeListenerService[i].cfg.Name == name {
-			return lm.activeListenerService[i]
-		}
+		s := s
+		go func() {
+			err := s.Start()
+			if err != nil {
+				panic(err)
+			}
+		}()
 	}
-	return nil
 }
diff --git a/samples/dubbogo/http/pixiu/conf.yaml b/samples/dubbogo/http/pixiu/conf.yaml
index 24ae301..e7ddc6a 100644
--- a/samples/dubbogo/http/pixiu/conf.yaml
+++ b/samples/dubbogo/http/pixiu/conf.yaml
@@ -20,16 +20,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 8888
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/samples/dubbogo/multi/config/conf.yaml b/samples/dubbogo/multi/config/conf.yaml
index e1f0eb8..bcb21ed 100644
--- a/samples/dubbogo/multi/config/conf.yaml
+++ b/samples/dubbogo/multi/config/conf.yaml
@@ -20,16 +20,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 8882
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/samples/dubbogo/simple/body/pixiu/conf.yaml b/samples/dubbogo/simple/body/pixiu/conf.yaml
index 0aa215d..1d58203 100644
--- a/samples/dubbogo/simple/body/pixiu/conf.yaml
+++ b/samples/dubbogo/simple/body/pixiu/conf.yaml
@@ -21,7 +21,7 @@ static_resources:
   listeners:
     - name: "net/http"
       filter_chains:
-        - filters:
+        filters:
           - name: dgp.filter.httpconnectionmanager
             config:
               route_config:
diff --git a/samples/dubbogo/simple/csrf/pixiu/conf.yaml b/samples/dubbogo/simple/csrf/pixiu/conf.yaml
index ea6eea0..f6b28a5 100644
--- a/samples/dubbogo/simple/csrf/pixiu/conf.yaml
+++ b/samples/dubbogo/simple/csrf/pixiu/conf.yaml
@@ -22,14 +22,9 @@ static_resources:
     - name: "net/http"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 8888
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/samples/dubbogo/simple/jaeger/pixiu/conf.yaml b/samples/dubbogo/simple/jaeger/pixiu/conf.yaml
index 2199759..eb85ee5 100644
--- a/samples/dubbogo/simple/jaeger/pixiu/conf.yaml
+++ b/samples/dubbogo/simple/jaeger/pixiu/conf.yaml
@@ -21,7 +21,7 @@ static_resources:
   listeners:
     - name: "net/http"
       filter_chains:
-        - filters:
+        filters:
           - name: dgp.filter.httpconnectionmanager
             config:
               route_config:
diff --git a/samples/dubbogo/simple/mix/pixiu/conf.yaml b/samples/dubbogo/simple/mix/pixiu/conf.yaml
index d241130..c5cb2ad 100644
--- a/samples/dubbogo/simple/mix/pixiu/conf.yaml
+++ b/samples/dubbogo/simple/mix/pixiu/conf.yaml
@@ -20,16 +20,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 8882
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/samples/dubbogo/simple/proxy/pixiu/conf.yaml b/samples/dubbogo/simple/proxy/pixiu/conf.yaml
index a5c89c5..be9e70d 100644
--- a/samples/dubbogo/simple/proxy/pixiu/conf.yaml
+++ b/samples/dubbogo/simple/proxy/pixiu/conf.yaml
@@ -20,16 +20,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 8883
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/samples/dubbogo/simple/query/pixiu/conf.yaml b/samples/dubbogo/simple/query/pixiu/conf.yaml
index 7f2386c..d300d8c 100644
--- a/samples/dubbogo/simple/query/pixiu/conf.yaml
+++ b/samples/dubbogo/simple/query/pixiu/conf.yaml
@@ -20,16 +20,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 8884
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/samples/dubbogo/simple/registry/pixiu/conf.yaml b/samples/dubbogo/simple/registry/dist/darwin_amd64/pixiuconf/conf.yaml
similarity index 96%
copy from samples/dubbogo/simple/registry/pixiu/conf.yaml
copy to samples/dubbogo/simple/registry/dist/darwin_amd64/pixiuconf/conf.yaml
index 3112742..1c2bdab 100644
--- a/samples/dubbogo/simple/registry/pixiu/conf.yaml
+++ b/samples/dubbogo/simple/registry/dist/darwin_amd64/pixiuconf/conf.yaml
@@ -58,7 +58,8 @@ static_resources:
                         timeout_config:
                           connect_timeout: 5s
                           request_timeout: 5s
-
+                  - name: dgp.filter.http.response
+                    config:
                 server_name: "test_http_dubbo"
                 generate_request_id: false
       config:
@@ -86,4 +87,4 @@ static_resources:
           "zookeeper":
             protocol: zookeeper
             address: "127.0.0.1:2181"
-            timeout: "5s"
\ No newline at end of file
+            timeout: "5s"
diff --git a/samples/dubbogo/simple/uri/conf.yaml b/samples/dubbogo/simple/registry/dist/darwin_amd64/server/log.yml
similarity index 55%
copy from samples/dubbogo/simple/uri/conf.yaml
copy to samples/dubbogo/simple/registry/dist/darwin_amd64/server/log.yml
index af60e20..9330cda 100644
--- a/samples/dubbogo/simple/uri/conf.yaml
+++ b/samples/dubbogo/simple/registry/dist/darwin_amd64/server/log.yml
@@ -16,32 +16,30 @@
 # specific language governing permissions and limitations
 # under the License.
 #
----
-static_resources:
-  listeners:
-    - name: "net/http"
-      address:
-        socket_address:
-          protocol_type: "HTTP"
-          address: "0.0.0.0"
-          port: 8885
-      config:
-        idle_timeout: 5s
-        read_timeout: 5s
-        write_timeout: 5s
-  clusters:
-    - name: "test_dubbo"
-      lb_policy: "RoundRobin"
-      registries:
-        "zookeeper":
-          timeout: "3s"
-          address: "127.0.0.1:2181"
-          username: ""
-          password: ""
-  timeout_config:
-    connect_timeout: "5s"
-    request_timeout: "10s"
-  shutdown_config:
-    timeout: "60s"
-    step_timeout: "10s"
-    reject_policy: "immediacy"
\ No newline at end of file
+level: "debug"
+development: true
+disableCaller: false
+disableStacktrace: false
+sampling:
+encoding: "console"
+
+# encoder
+encoderConfig:
+  messageKey: "message"
+  levelKey: "level"
+  timeKey: "time"
+  nameKey: "logger"
+  callerKey: "caller"
+  stacktraceKey: "stacktrace"
+  lineEnding: ""
+  levelEncoder: "capitalColor"
+  timeEncoder: "iso8601"
+  durationEncoder: "seconds"
+  callerEncoder: "short"
+  nameEncoder: ""
+
+outputPaths:
+  - "stderr"
+errorOutputPaths:
+  - "stderr"
+initialFields:
diff --git a/samples/dubbogo/simple/uri/conf.yaml b/samples/dubbogo/simple/registry/dist/darwin_amd64/server/server.yml
similarity index 55%
copy from samples/dubbogo/simple/uri/conf.yaml
copy to samples/dubbogo/simple/registry/dist/darwin_amd64/server/server.yml
index af60e20..1fbfa46 100644
--- a/samples/dubbogo/simple/uri/conf.yaml
+++ b/samples/dubbogo/simple/registry/dist/darwin_amd64/server/server.yml
@@ -16,32 +16,26 @@
 # specific language governing permissions and limitations
 # under the License.
 #
----
-static_resources:
-  listeners:
-    - name: "net/http"
-      address:
-        socket_address:
-          protocol_type: "HTTP"
-          address: "0.0.0.0"
-          port: 8885
-      config:
-        idle_timeout: 5s
-        read_timeout: 5s
-        write_timeout: 5s
-  clusters:
-    - name: "test_dubbo"
-      lb_policy: "RoundRobin"
-      registries:
-        "zookeeper":
-          timeout: "3s"
-          address: "127.0.0.1:2181"
-          username: ""
-          password: ""
-  timeout_config:
-    connect_timeout: "5s"
-    request_timeout: "10s"
-  shutdown_config:
-    timeout: "60s"
-    step_timeout: "10s"
-    reject_policy: "immediacy"
\ No newline at end of file
+# dubbo server yaml configure file
+# application config
+dubbo:
+  application:
+    name: BDTService
+  registries:
+    zk:
+      protocol: zookeeper
+      timeout: 3s
+      address: 127.0.0.1:2181
+  protocols:
+    dubbo:
+      name: dubbo
+      port: 20000
+  provider:
+    registry-ids: zk
+    services:
+      UserProvider:
+        group: test
+        version: 1.0.0
+        cluster: test_dubbo
+        serialization: hessian2
+        interface: com.dubbogo.pixiu.UserService
diff --git a/samples/dubbogo/simple/registry/pixiu/conf.yaml b/samples/dubbogo/simple/registry/pixiu/conf.yaml
index 3112742..f48327b 100644
--- a/samples/dubbogo/simple/registry/pixiu/conf.yaml
+++ b/samples/dubbogo/simple/registry/pixiu/conf.yaml
@@ -20,16 +20,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 8881
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/samples/dubbogo/simple/triple/pixiu/conf.yaml b/samples/dubbogo/simple/triple/pixiu/conf.yaml
index 652310e..9f52173 100644
--- a/samples/dubbogo/simple/triple/pixiu/conf.yaml
+++ b/samples/dubbogo/simple/triple/pixiu/conf.yaml
@@ -20,13 +20,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 8881
       filter_chains:
-        - filter_chain_match:
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/samples/dubbogo/simple/uri/conf.yaml b/samples/dubbogo/simple/uri/conf.yaml
index af60e20..2e162b8 100644
--- a/samples/dubbogo/simple/uri/conf.yaml
+++ b/samples/dubbogo/simple/uri/conf.yaml
@@ -20,9 +20,9 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 8885
       config:
diff --git a/samples/dubbogo/simple/uri/pixiu/conf.yaml b/samples/dubbogo/simple/uri/pixiu/conf.yaml
index ecab81d..f40bf35 100644
--- a/samples/dubbogo/simple/uri/pixiu/conf.yaml
+++ b/samples/dubbogo/simple/uri/pixiu/conf.yaml
@@ -20,16 +20,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 8885
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/samples/http/grpc/pixiu/conf.yaml b/samples/grpc/pixiu/conf.yaml
similarity index 70%
copy from samples/http/grpc/pixiu/conf.yaml
copy to samples/grpc/pixiu/conf.yaml
index 5b6faab..84fdad5 100644
--- a/samples/http/grpc/pixiu/conf.yaml
+++ b/samples/grpc/pixiu/conf.yaml
@@ -20,33 +20,22 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP2"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 8881
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
-            - name: dgp.filter.httpconnectionmanager
+            - name: dgp.filter.grpcconnectionmanager
               config:
                 route_config:
                   routes:
                     - match:
-                        prefix: "/api/v1"
+                        prefix: "/provider.UserProvider/"
                       route:
                         cluster: "test-grpc"
                         cluster_not_found_response_code: 505
-                http_filters:
-                  - name: dgp.filter.http.grpcproxy
-                    config:
-                      descriptor_source_strategy: auto  # none, auto( invoke: ->reflection->file), local, remote  ## default: auto
-                      path: samples/http/grpc/pixiu/proto
-                server_name: "test-http-grpc"
-                generate_request_id: false
       config:
         idle_timeout: 5s
         read_timeout: 5s
diff --git a/samples/grpc/proto/hello_grpc.pb.go b/samples/grpc/proto/hello_grpc.pb.go
new file mode 100644
index 0000000..7403d6e
--- /dev/null
+++ b/samples/grpc/proto/hello_grpc.pb.go
@@ -0,0 +1,320 @@
+/*
+ * 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.
+ */
+// protoc --proto_path=. --go_out=. --go-grpc_out=. --go_opt=paths=source_relative --go-grpc_opt=paths=source_relative .\hello_grpc.proto
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.27.1
+// 	protoc        v3.15.0--rc2
+// source: hello_grpc.proto
+
+package proto
+
+import (
+	reflect "reflect"
+	sync "sync"
+)
+
+import (
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type GetUserRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	UserId int32 `protobuf:"varint,1,opt,name=userId,proto3" json:"userId,omitempty"`
+}
+
+func (x *GetUserRequest) Reset() {
+	*x = GetUserRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_hello_grpc_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetUserRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetUserRequest) ProtoMessage() {}
+
+func (x *GetUserRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_hello_grpc_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetUserRequest.ProtoReflect.Descriptor instead.
+func (*GetUserRequest) Descriptor() ([]byte, []int) {
+	return file_hello_grpc_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *GetUserRequest) GetUserId() int32 {
+	if x != nil {
+		return x.UserId
+	}
+	return 0
+}
+
+type GetUserResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Message string  `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
+	Users   []*User `protobuf:"bytes,2,rep,name=users,proto3" json:"users,omitempty"`
+}
+
+func (x *GetUserResponse) Reset() {
+	*x = GetUserResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_hello_grpc_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetUserResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetUserResponse) ProtoMessage() {}
+
+func (x *GetUserResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_hello_grpc_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetUserResponse.ProtoReflect.Descriptor instead.
+func (*GetUserResponse) Descriptor() ([]byte, []int) {
+	return file_hello_grpc_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *GetUserResponse) GetMessage() string {
+	if x != nil {
+		return x.Message
+	}
+	return ""
+}
+
+func (x *GetUserResponse) GetUsers() []*User {
+	if x != nil {
+		return x.Users
+	}
+	return nil
+}
+
+type User struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	UserId int32  `protobuf:"varint,1,opt,name=userId,proto3" json:"userId,omitempty"`
+	Name   string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
+}
+
+func (x *User) Reset() {
+	*x = User{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_hello_grpc_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *User) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*User) ProtoMessage() {}
+
+func (x *User) ProtoReflect() protoreflect.Message {
+	mi := &file_hello_grpc_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use User.ProtoReflect.Descriptor instead.
+func (*User) Descriptor() ([]byte, []int) {
+	return file_hello_grpc_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *User) GetUserId() int32 {
+	if x != nil {
+		return x.UserId
+	}
+	return 0
+}
+
+func (x *User) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+var File_hello_grpc_proto protoreflect.FileDescriptor
+
+var file_hello_grpc_proto_rawDesc = []byte{
+	0x0a, 0x10, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x5f, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x12, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x22, 0x28, 0x0a, 0x0e,
+	0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16,
+	0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06,
+	0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0x51, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65,
+	0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73,
+	0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73,
+	0x61, 0x67, 0x65, 0x12, 0x24, 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03,
+	0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x55, 0x73,
+	0x65, 0x72, 0x52, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x22, 0x32, 0x0a, 0x04, 0x55, 0x73, 0x65,
+	0x72, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x05, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
+	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x32, 0x4e, 0x0a,
+	0x0c, 0x55, 0x73, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x3e, 0x0a,
+	0x07, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69,
+	0x64, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x1a, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x47, 0x65,
+	0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x3a, 0x5a,
+	0x38, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x61, 0x63,
+	0x68, 0x65, 0x2f, 0x64, 0x75, 0x62, 0x62, 0x6f, 0x2d, 0x67, 0x6f, 0x2d, 0x70, 0x69, 0x78, 0x69,
+	0x75, 0x2f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x2f, 0x67,
+	0x72, 0x70, 0x63, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x33,
+}
+
+var (
+	file_hello_grpc_proto_rawDescOnce sync.Once
+	file_hello_grpc_proto_rawDescData = file_hello_grpc_proto_rawDesc
+)
+
+func file_hello_grpc_proto_rawDescGZIP() []byte {
+	file_hello_grpc_proto_rawDescOnce.Do(func() {
+		file_hello_grpc_proto_rawDescData = protoimpl.X.CompressGZIP(file_hello_grpc_proto_rawDescData)
+	})
+	return file_hello_grpc_proto_rawDescData
+}
+
+var file_hello_grpc_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
+var file_hello_grpc_proto_goTypes = []interface{}{
+	(*GetUserRequest)(nil),  // 0: provider.GetUserRequest
+	(*GetUserResponse)(nil), // 1: provider.GetUserResponse
+	(*User)(nil),            // 2: provider.User
+}
+var file_hello_grpc_proto_depIdxs = []int32{
+	2, // 0: provider.GetUserResponse.users:type_name -> provider.User
+	0, // 1: provider.UserProvider.GetUser:input_type -> provider.GetUserRequest
+	1, // 2: provider.UserProvider.GetUser:output_type -> provider.GetUserResponse
+	2, // [2:3] is the sub-list for method output_type
+	1, // [1:2] is the sub-list for method input_type
+	1, // [1:1] is the sub-list for extension type_name
+	1, // [1:1] is the sub-list for extension extendee
+	0, // [0:1] is the sub-list for field type_name
+}
+
+func init() { file_hello_grpc_proto_init() }
+func file_hello_grpc_proto_init() {
+	if File_hello_grpc_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_hello_grpc_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetUserRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_hello_grpc_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetUserResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_hello_grpc_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*User); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_hello_grpc_proto_rawDesc,
+			NumEnums:      0,
+			NumMessages:   3,
+			NumExtensions: 0,
+			NumServices:   1,
+		},
+		GoTypes:           file_hello_grpc_proto_goTypes,
+		DependencyIndexes: file_hello_grpc_proto_depIdxs,
+		MessageInfos:      file_hello_grpc_proto_msgTypes,
+	}.Build()
+	File_hello_grpc_proto = out.File
+	file_hello_grpc_proto_rawDesc = nil
+	file_hello_grpc_proto_goTypes = nil
+	file_hello_grpc_proto_depIdxs = nil
+}
diff --git a/samples/grpc/proto/hello_grpc.proto b/samples/grpc/proto/hello_grpc.proto
new file mode 100644
index 0000000..f3d4bcb
--- /dev/null
+++ b/samples/grpc/proto/hello_grpc.proto
@@ -0,0 +1,40 @@
+// 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.
+
+
+// protoc --proto_path=. --go_out=. --go-grpc_out=. --go_opt=paths=source_relative --go-grpc_opt=paths=source_relative .\hello_grpc.proto
+syntax = "proto3";
+
+option go_package = "github.com/apache/dubbo-go-pixiu/samples/http/grpc/proto";
+
+package provider;
+
+service UserProvider {
+    rpc GetUser (GetUserRequest) returns (GetUserResponse);
+}
+
+message GetUserRequest {
+    int32 userId = 1;
+}
+
+message GetUserResponse {
+    string message = 1;
+    repeated User users = 2;
+}
+
+message User {
+    int32 userId = 1;
+    string name = 2;
+}
\ No newline at end of file
diff --git a/samples/grpc/proto/hello_grpc_grpc.pb.go b/samples/grpc/proto/hello_grpc_grpc.pb.go
new file mode 100644
index 0000000..48b5f4c
--- /dev/null
+++ b/samples/grpc/proto/hello_grpc_grpc.pb.go
@@ -0,0 +1,116 @@
+/*
+ * 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.
+ */
+// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+
+package proto
+
+import (
+	context "context"
+)
+
+import (
+	grpc "google.golang.org/grpc"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
+)
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+const _ = grpc.SupportPackageIsVersion7
+
+// UserProviderClient is the client API for UserProvider service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
+type UserProviderClient interface {
+	GetUser(ctx context.Context, in *GetUserRequest, opts ...grpc.CallOption) (*GetUserResponse, error)
+}
+
+type userProviderClient struct {
+	cc grpc.ClientConnInterface
+}
+
+func NewUserProviderClient(cc grpc.ClientConnInterface) UserProviderClient {
+	return &userProviderClient{cc}
+}
+
+func (c *userProviderClient) GetUser(ctx context.Context, in *GetUserRequest, opts ...grpc.CallOption) (*GetUserResponse, error) {
+	out := new(GetUserResponse)
+	err := c.cc.Invoke(ctx, "/provider.UserProvider/GetUser", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// UserProviderServer is the server API for UserProvider service.
+// All implementations must embed UnimplementedUserProviderServer
+// for forward compatibility
+type UserProviderServer interface {
+	GetUser(context.Context, *GetUserRequest) (*GetUserResponse, error)
+	mustEmbedUnimplementedUserProviderServer()
+}
+
+// UnimplementedUserProviderServer must be embedded to have forward compatible implementations.
+type UnimplementedUserProviderServer struct {
+}
+
+func (UnimplementedUserProviderServer) GetUser(context.Context, *GetUserRequest) (*GetUserResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetUser not implemented")
+}
+func (UnimplementedUserProviderServer) mustEmbedUnimplementedUserProviderServer() {}
+
+// UnsafeUserProviderServer may be embedded to opt out of forward compatibility for this service.
+// Use of this interface is not recommended, as added methods to UserProviderServer will
+// result in compilation errors.
+type UnsafeUserProviderServer interface {
+	mustEmbedUnimplementedUserProviderServer()
+}
+
+func RegisterUserProviderServer(s *grpc.Server, srv UserProviderServer) {
+	s.RegisterService(&_UserProvider_serviceDesc, srv)
+}
+
+func _UserProvider_GetUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(GetUserRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(UserProviderServer).GetUser(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/provider.UserProvider/GetUser",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(UserProviderServer).GetUser(ctx, req.(*GetUserRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+var _UserProvider_serviceDesc = grpc.ServiceDesc{
+	ServiceName: "provider.UserProvider",
+	HandlerType: (*UserProviderServer)(nil),
+	Methods: []grpc.MethodDesc{
+		{
+			MethodName: "GetUser",
+			Handler:    _UserProvider_GetUser_Handler,
+		},
+	},
+	Streams:  []grpc.StreamDesc{},
+	Metadata: "hello_grpc.proto",
+}
diff --git a/samples/grpc/server/app/server.go b/samples/grpc/server/app/server.go
new file mode 100644
index 0000000..776d4cc
--- /dev/null
+++ b/samples/grpc/server/app/server.go
@@ -0,0 +1,85 @@
+/*
+ * 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 main
+
+import (
+	"context"
+	"net"
+)
+
+import (
+	"google.golang.org/grpc"
+)
+
+import (
+	"github.com/apache/dubbo-go-pixiu/pkg/logger"
+	"github.com/apache/dubbo-go-pixiu/samples/http/grpc/proto"
+)
+
+const (
+	MsgUserNotFound          = "user not found"
+	MsgUserQuerySuccessfully = "user(s) query successfully"
+)
+
+// Test Cases
+// curl http://127.0.0.1:8881/api/v1/provider.UserProvider/GetUser
+// curl http://127.0.0.1:8881/api/v1/provider.UserProvider/GetUser -X POST -d '{"userId":1}'
+
+type server struct {
+	users map[int32]*proto.User
+	proto.UnimplementedUserProviderServer
+}
+
+func (s *server) GetUser(ctx context.Context, request *proto.GetUserRequest) (*proto.GetUserResponse, error) {
+	us := make([]*proto.User, 0)
+	if request.GetUserId() == 0 {
+		for i := 1; i <= 2; i++ {
+			us = append(us, s.users[int32(i)])
+		}
+	} else {
+		u, ok := s.users[request.GetUserId()]
+		if !ok {
+			return &proto.GetUserResponse{Message: MsgUserNotFound}, nil
+		}
+		us = append(us, u)
+	}
+	return &proto.GetUserResponse{Message: MsgUserQuerySuccessfully, Users: us}, nil
+}
+
+func initUsers(s *server) {
+	s.users[1] = &proto.User{UserId: 1, Name: "Kenway"}
+	s.users[2] = &proto.User{UserId: 2, Name: "Ken"}
+}
+
+func main() {
+	l, err := net.Listen("tcp", ":50001") //nolint:gosec
+	if err != nil {
+		panic(err)
+	}
+
+	s := &server{users: make(map[int32]*proto.User)}
+	initUsers(s)
+
+	gs := grpc.NewServer()
+	proto.RegisterUserProviderServer(gs, s)
+	logger.Info("grpc test server is now running...")
+	err = gs.Serve(l)
+	if err != nil {
+		panic(err)
+	}
+}
diff --git a/pkg/server/listener_test.go b/samples/grpc/test/pixiu_test.go
similarity index 50%
rename from pkg/server/listener_test.go
rename to samples/grpc/test/pixiu_test.go
index b3401f7..250f75e 100644
--- a/pkg/server/listener_test.go
+++ b/samples/grpc/test/pixiu_test.go
@@ -15,32 +15,43 @@
  * limitations under the License.
  */
 
-package server
+package test
 
 import (
-	ctxHttp "github.com/apache/dubbo-go-pixiu/pkg/context/http"
-	"github.com/apache/dubbo-go-pixiu/pkg/model"
+	"context"
+	"flag"
+	"log"
+	"testing"
+	"time"
 )
 
-func getTestContext() *ctxHttp.HttpContext {
-	l := ListenerService{
-		cfg: &model.Listener{
-			Name: "test",
-			Address: model.Address{
-				SocketAddress: model.SocketAddress{
-					Protocol: model.ProtocolTypeHTTP,
-					Address:  "0.0.0.0",
-					Port:     8888,
-				},
-			},
-			FilterChains: []model.FilterChain{},
-		},
-	}
+import (
+	"github.com/stretchr/testify/assert"
+	"google.golang.org/grpc"
+)
 
-	hc := &ctxHttp.HttpContext{
-		Listener: l.cfg,
-		Filters:  []ctxHttp.FilterFunc{},
+import (
+	pb "github.com/apache/dubbo-go-pixiu/samples/http/grpc/proto"
+)
+
+var (
+	addr = flag.String("addr", "localhost:8881", "the address to connect to")
+)
+
+func TestGet(t *testing.T) {
+	flag.Parse()
+	// Set up a connection to the server.
+	conn, err := grpc.Dial(*addr, grpc.WithInsecure())
+	if err != nil {
+		log.Fatalf("did not connect: %v", err)
 	}
-	hc.Reset()
-	return hc
+	defer conn.Close()
+	c := pb.NewUserProviderClient(conn)
+
+	// Contact the server and print out its response.
+	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+	defer cancel()
+	r, err := c.GetUser(ctx, &pb.GetUserRequest{UserId: 1})
+	assert.NoError(t, err)
+	assert.Equal(t, "user(s) query successfully", r.Message)
 }
diff --git a/samples/http/grpc/pixiu/conf.yaml b/samples/http/grpc/pixiu/conf.yaml
index 5b6faab..0489aea 100644
--- a/samples/http/grpc/pixiu/conf.yaml
+++ b/samples/http/grpc/pixiu/conf.yaml
@@ -20,16 +20,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 8881
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/samples/http/simple/pixiu/conf.yaml b/samples/http/simple/pixiu/conf.yaml
index 9eebd84..ad238c1 100644
--- a/samples/http/simple/pixiu/conf.yaml
+++ b/samples/http/simple/pixiu/conf.yaml
@@ -20,16 +20,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 8888
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/samples/https/pixiu/conf.yaml b/samples/https/pixiu/conf.yaml
index 334dc73..2515f5a 100644
--- a/samples/https/pixiu/conf.yaml
+++ b/samples/https/pixiu/conf.yaml
@@ -20,19 +20,15 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTPS"
       address:
         socket_address:
-          protocol_type: "HTTPS"
           domains:
             - "sample.domain.com"
             - "sample.domain-1.com"
             - "sample.domain-2.com"
           certs_dir: $PROJECT_DIR/cert
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/samples/seata/gateway/conf.yaml b/samples/seata/gateway/conf.yaml
index 9fca54c..dea4153 100644
--- a/samples/seata/gateway/conf.yaml
+++ b/samples/seata/gateway/conf.yaml
@@ -20,16 +20,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 2046
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
@@ -62,16 +58,12 @@ static_resources:
         read_timeout: 5s
         write_timeout: 5s
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 2047
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
@@ -105,16 +97,12 @@ static_resources:
         read_timeout: 5s
         write_timeout: 5s
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 2048
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/samples/seata/sidecar/server_a/conf.yaml b/samples/seata/sidecar/server_a/conf.yaml
index dd57eac..fb24d51 100644
--- a/samples/seata/sidecar/server_a/conf.yaml
+++ b/samples/seata/sidecar/server_a/conf.yaml
@@ -20,16 +20,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 2046
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/samples/seata/sidecar/server_b/conf.yaml b/samples/seata/sidecar/server_b/conf.yaml
index 60e75f3..2977ad6 100644
--- a/samples/seata/sidecar/server_b/conf.yaml
+++ b/samples/seata/sidecar/server_b/conf.yaml
@@ -20,16 +20,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 2047
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/samples/seata/sidecar/server_c/conf.yaml b/samples/seata/sidecar/server_c/conf.yaml
index 66cc3d3..81d93ab 100644
--- a/samples/seata/sidecar/server_c/conf.yaml
+++ b/samples/seata/sidecar/server_c/conf.yaml
@@ -20,16 +20,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 2048
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/samples/springcloud/pixiu/conf.yaml b/samples/springcloud/pixiu/conf.yaml
index 897dc9a..f322eac 100644
--- a/samples/springcloud/pixiu/conf.yaml
+++ b/samples/springcloud/pixiu/conf.yaml
@@ -20,16 +20,12 @@
 static_resources:
   listeners:
     - name: "net/http"
+      protocol_type: "HTTP"
       address:
         socket_address:
-          protocol_type: "HTTP"
           address: "0.0.0.0"
           port: 8888
       filter_chains:
-        - filter_chain_match:
-          domains:
-            - api.dubbo.com
-            - api.pixiu.com
           filters:
             - name: dgp.filter.httpconnectionmanager
               config:
diff --git a/start_integrate_test.sh b/start_integrate_test.sh
index f55b57c..2d2cc6b 100755
--- a/start_integrate_test.sh
+++ b/start_integrate_test.sh
@@ -27,6 +27,8 @@ array+=("samples/dubbogo/http")
 ##http
 array+=("samples/http/grpc")
 array+=("samples/http/simple")
+## grpc proxy
+array+=("samples/grpc")
 
 for((i=0;i<${#array[*]};i++))
 do