聊聊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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值