本文主要研究一下dubbo-go-proxy的Client
dubbo-go-proxy/pkg/client/client.go
// Client represents the interface of http/dubbo clients 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-go-proxy/pkg/client/dubbo/dubbo.go
// Client client to generic invoke dubbo type Client struct { lock sync.RWMutex GenericServicePool map[string]*dg.GenericService }
Client定义了lock、GenericServicePool属性,它实现了Client接口
dubbo-go-proxy/pkg/client/dubbo/dubbo.go
// Init init dubbo, config mapping can do here func (dc *Client) Init() error { dc.GenericServicePool = make(map[string]*dg.GenericService, 4) cls := config.GetBootstrap().StaticResources.Clusters // dubbogo comsumer config dgCfg = dg.ConsumerConfig{ Check: new(bool), Registries: make(map[string]*dg.RegistryConfig, 4), } dgCfg.ApplicationConfig = defaultApplication for i := range cls { c := cls[i] dgCfg.Request_Timeout = c.RequestTimeoutStr dgCfg.Connect_Timeout = c.ConnectTimeoutStr for k, v := range c.Registries { if len(v.Protocol) == 0 { logger.Warnf("can not find registry protocol config, use default type 'zookeeper'") v.Protocol = defaultDubboProtocol } dgCfg.Registries[k] = &dg.RegistryConfig{ Protocol: v.Protocol, Address: v.Address, TimeoutStr: v.Timeout, Username: v.Username, Password: v.Password, } } } initDubbogo() return nil } func initDubbogo() { dg.SetConsumerConfig(dgCfg) dg.Load() }
Init方法主要是构建ConsumerConfig,然后执行initDubbogo
dubbo-go-proxy/pkg/client/dubbo/dubbo.go
// Close clear GenericServicePool. func (dc *Client) Close() error { dc.lock.Lock() defer dc.lock.Unlock() for k := range dc.GenericServicePool { delete(dc.GenericServicePool, k) } return nil }
Close方法通过加锁遍历dc.GenericServicePool执行delete操作
dubbo-go-proxy/pkg/client/dubbo/dubbo.go
// Call invoke service func (dc *Client) Call(req *client.Request) (res interface{}, err error) { types, values, err := dc.genericArgs(req) if err != nil { return nil, err } dm := req.API.Method.IntegrationRequest method := dm.Method logger.Debugf("[dubbo-go-proxy] dubbo invoke, method:%s, types:%s, reqData:%v", method, types, values) gs := dc.Get(dm) rst, err := gs.Invoke(req.Context, []interface{}{method, types, values}) if err != nil { return nil, err } logger.Debugf("[dubbo-go-proxy] dubbo client resp:%v", rst) return rst, nil }
Call方法通过dc.Get(dm)获取GenericService,然后通过GenericService.Invoke进行请求
dubbo-go-proxy/pkg/client/dubbo/dubbo.go
// MapParams params mapping to api. func (dc *Client) MapParams(req *client.Request) (interface{}, error) { r := req.API.Method.IntegrationRequest if len(r.ParamTypes) != len(r.MappingParams) { return nil, errors.New("Numbers of param types and paramMappings are not the same") } var values []interface{} for _, mappingParam := range r.MappingParams { source, _, err := client.ParseMapSource(mappingParam.Name) if err != nil { return nil, err } if mapper, ok := mappers[source]; ok { if err := mapper.Map(mappingParam, req, &values, buildOption(mappingParam)); err != nil { return nil, err } } } return values, nil }
MapParams方法遍历MappingParams,通过client.ParseMapSource获取source,再通过mappers[source]获取mapper,最后通过mapper的Map方法进行转换
dubbo-go-proxy的client.Client接口定义了Init、Close、Call、MapParams方法;其dubbo.Client实现了client.Client接口;其主要是通过mapper进行参数转换,然后通过GenericService.Invoke进行请求。