本文主要研究一下dubbo-go-proxy的remoteFilter
dubbo-go-proxy/pkg/filter/remote/call.go
func Init() { extension.SetFilterFunc(constant.RemoteCallFilter, remoteFilterFunc()) } func remoteFilterFunc() fc.FilterFunc { return New(defaultNewParams()).Do() } func defaultNewParams() mockLevel { mock := 1 mockStr := os.Getenv(constant.EnvMock) if len(mockStr) > 0 { i, err := strconv.Atoi(mockStr) if err == nil { mock = i } } return mockLevel(mock) } type mockLevel int8 const ( open = iota close all ) // clientFilter is a filter for recover. type clientFilter struct { level mockLevel } // New create timeout filter. func New(level mockLevel) filter.Filter { if level < 0 || level > 2 { level = close } return &clientFilter{ level: level, } }
clientFilter往extension注册了名为dgp.filters.remote_call
的filter func;该func执行的是Do方法
dubbo-go-proxy/pkg/filter/remote/call.go
func (f clientFilter) Do() fc.FilterFunc { return func(c fc.Context) { f.doRemoteCall(c.(*contexthttp.HttpContext)) } } func (f clientFilter) doRemoteCall(c *contexthttp.HttpContext) { api := c.GetAPI() if (f.level == open && api.Mock) || (f.level == all) { c.SourceResp = &filter.ErrResponse{ Message: "mock success", } c.Next() return } typ := api.Method.IntegrationRequest.RequestType cli, err := matchClient(typ) if err != nil { c.Err = err return } resp, err := cli.Call(client.NewReq(c.Ctx, c.Request, *api)) if err != nil { logger.Errorf("[dubbo-go-proxy] client call err:%v!", err) c.Err = err return } logger.Debugf("[dubbo-go-proxy] client call resp:%v", resp) c.SourceResp = resp // response write in response filter. c.Next() } func matchClient(typ config.RequestType) (client.Client, error) { switch strings.ToLower(string(typ)) { case string(config.DubboRequest): return dubbo.SingletonDubboClient(), nil case string(config.HTTPRequest): return clienthttp.SingletonHTTPClient(), nil default: return nil, errors.New("not support") } }
Do方法执行的是doRemoteCall,该方法辉县判断是否是mock,如果是则返回mock success;之后根据RequestType判断是否支持该请求类型并返回对应的client,最后通过cli.Call执行请求
dubbo-go-proxy/pkg/client/client.go
type Client interface { Init() error Close() error // Call invoke the downstream service. Call(req *Request) (res interface{}, err error) // MapParams mapping param, uri, query, body ... MapParams(req *Request) (reqData interface{}, err error) }
Client接口定义了Init、Close、Call、MapParams方法,它有两个实现类,分别是dubbo.Client及http.Client
dubbo-go-proxy的clientFilter往extension注册了名为dgp.filters.remote_call
的filter func;该func执行的是Do方法,该方法根据RequestType判断是否支持该请求类型并返回对应的client,最后通过cli.Call执行请求。