聊聊dubbo-go-proxy的remoteFilter

本文主要研究一下dubbo-go-proxy的remoteFilter

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方法

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执行请求

Client

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执行请求。

doc

相关文章

在网络请求时,总会有各种异常情况出现,我们需要提前处理这...
作者:宇曾背景软件技术的发展历史,从单体的应用,逐渐演进...
hello,大家好呀,我是小楼。最近一个技术群有同学at我,问我...
 一个软件开发人员,工作到了一定的年限(一般是3、4年左右...
当一个服务调用另一个远程服务出现错误时的外观Dubbo提供了多...
最近在看阿里开源RPC框架Dubbo的源码,顺带梳理了一下其中用...