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

DubboProtocol

dubbo-go-v1.4.2/protocol/dubbo/dubbo_protocol.go

// dubbo protocol constant
const (
    // DUBBO ...
    DUBBO = "dubbo"
)

func init() {
    extension.SetProtocol(DUBBO, GetProtocol)
}

var (
    dubboProtocol *DubboProtocol
)

// DubboProtocol ...
type DubboProtocol struct {
    protocol.BaseProtocol
    serverMap  map[string]*Server
    serverLock sync.Mutex
}
  • DubboProtocol嵌套了protocol.BaseProtocol,定义了serverMap、serverLock属性

GetProtocol

dubbo-go-v1.4.2/protocol/dubbo/dubbo_protocol.go

// GetProtocol ...
func GetProtocol() protocol.Protocol {
    if dubboProtocol == nil {
        dubboProtocol = NewDubboProtocol()
    }
    return dubboProtocol
}
  • GetProtocol方法通过NewDubboProtocol创建dubboProtocol

NewDubboProtocol

dubbo-go-v1.4.2/protocol/dubbo/dubbo_protocol.go

// NewDubboProtocol ...
func NewDubboProtocol() *DubboProtocol {
    return &DubboProtocol{
        BaseProtocol: protocol.NewBaseProtocol(),
        serverMap:    make(map[string]*Server),
    }
}
  • NewDubboProtocol方法实例化了DubboProtocol

Export

dubbo-go-v1.4.2/protocol/dubbo/dubbo_protocol.go

// Export ...
func (dp *DubboProtocol) Export(invoker protocol.Invoker) protocol.Exporter {
    url := invoker.GetUrl()
    serviceKey := url.ServiceKey()
    exporter := NewDubboExporter(serviceKey, invoker, dp.ExporterMap())
    dp.SetExporterMap(serviceKey, exporter)
    logger.Infof("Export service: %s", url.String())

    // start server
    dp.openServer(url)
    return exporter
}
  • Export方法通过NewDubboExporter创建exporter,然后更新到DubboProtocol的exporterMap中,之后执行DubboProtocol的openServer

openServer

dubbo-go-v1.4.2/protocol/dubbo/dubbo_protocol.go

func (dp *DubboProtocol) openServer(url common.URL) {
    _, ok := dp.serverMap[url.Location]
    if !ok {
        _, ok := dp.ExporterMap().Load(url.ServiceKey())
        if !ok {
            panic("[DubboProtocol]" + url.Key() + "is not existing")
        }

        dp.serverLock.Lock()
        _, ok = dp.serverMap[url.Location]
        if !ok {
            srv := NewServer()
            dp.serverMap[url.Location] = srv
            srv.Start(url)
        }
        dp.serverLock.Unlock()
    }
}
  • openServer方法先根据url.Location从serverMap获取Server,获取不到则执行dp.ExporterMap().Load(url.ServiceKey()),之后再次使用dp.serverMap[url.Location]获取,获取不到则执行NewServer,放到dp.serverMap中,然后执行srv.Start(url)

Refer

dubbo-go-v1.4.2/protocol/dubbo/dubbo_protocol.go

// Refer ...
func (dp *DubboProtocol) Refer(url common.URL) protocol.Invoker {
    //default requestTimeout
    var requestTimeout = config.GetConsumerConfig().RequestTimeout

    requestTimeoutStr := url.GetParam(constant.TIMEOUT_KEY, config.GetConsumerConfig().Request_Timeout)
    if t, err := time.ParseDuration(requestTimeoutStr); err == nil {
        requestTimeout = t
    }

    invoker := NewDubboInvoker(url, NewClient(Options{
        ConnectTimeout: config.GetConsumerConfig().ConnectTimeout,
        RequestTimeout: requestTimeout,
    }))
    dp.SetInvokers(invoker)
    logger.Infof("Refer service: %s", url.String())
    return invoker
}
  • Refer方法先获取requestTimeout,之后通过NewDubboInvoker创建invoker,然后执行dp.SetInvokers(invoker)

Destroy

dubbo-go-v1.4.2/protocol/dubbo/dubbo_protocol.go

// Destroy ...
func (dp *DubboProtocol) Destroy() {
    logger.Infof("DubboProtocol destroy.")

    dp.BaseProtocol.Destroy()

    // stop server
    for key, server := range dp.serverMap {
        delete(dp.serverMap, key)
        server.Stop()
    }
}
  • Destroy方法先执行dp.BaseProtocol.Destroy(),之后遍历dp.serverMap,执行delete(dp.serverMap, key)及server.Stop()

小结

DubboProtocol嵌套了protocol.BaseProtocol,定义了serverMap、serverLock属性;Export方法通过NewDubboExporter创建exporter,然后更新到DubboProtocol的exporterMap中,之后执行DubboProtocol的openServer;Refer方法先获取requestTimeout,之后通过NewDubboInvoker创建invoker,然后执行dp.SetInvokers(invoker);Destroy方法先执行dp.BaseProtocol.Destroy(),之后遍历dp.serverMap,执行delete(dp.serverMap, key)及server.Stop()

doc


codecraft
11.9k 声望2k 粉丝

当一个代码的工匠回首往事时,不因虚度年华而悔恨,也不因碌碌无为而羞愧,这样,当他老的时候,可以很自豪告诉世人,我曾经将代码注入生命去打造互联网的浪潮之巅,那是个很疯狂的时代,我在一波波的浪潮上留下...


引用和评论

0 条评论