序
本文次要钻研一下 dubbo-go-proxy 的 Client
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 办法
Client
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 接口
Init
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
Close
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 操作
Call
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 进行申请
MapParams
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; ok {if err := mapper.Map(mappingParam, req, &values, buildOption(mappingParam)); err != nil {return nil, err}
}
}
return values, nil
}
MapParams 办法遍历 MappingParams,通过 client.ParseMapSource 获取 source,再通过 mappers 获取 mapper,最初通过 mapper 的 Map 办法进行转换
小结
dubbo-go-proxy 的 client.Client 接口定义了 Init、Close、Call、MapParams 办法;其 dubbo.Client 实现了 client.Client 接口;其次要是通过 mapper 进行参数转换,而后通过 GenericService.Invoke 进行申请。
doc
- dubbo-go-proxy