4

聊聊dubbo-go-proxy的DiscoveryService

 3 years ago
source link: https://studygolang.com/articles/33322
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

聊聊dubbo-go-proxy的DiscoveryService

.container .card .information strong · 大约13小时之前 · 25 次点击 · 预计阅读时间 7 分钟 · 不到1分钟之前 开始浏览    

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

DiscoveryService

dubbo-go-proxy/pkg/service/discovery_service.go

// APIDiscoveryService api discovery service interface
type APIDiscoveryService interface {
    AddAPI(router.API) error
    GetAPI(string, config.HTTPVerb) (router.API, error)
}

// DiscoveryService is come from envoy, it can used for admin

// ListenerDiscoveryService
type ListenerDiscoveryService interface {
    AddListeners(request DiscoveryRequest) (DiscoveryResponse, error)
    GetListeners(request DiscoveryRequest) (DiscoveryResponse, error)
}

// RouteDiscoveryService
type RouteDiscoveryService interface {
    AddRoutes(r DiscoveryRequest) (DiscoveryResponse, error)
    GetRoutes(r DiscoveryRequest) (DiscoveryResponse, error)
}

// ClusterDiscoveryService
type ClusterDiscoveryService interface {
    AddClusters(r DiscoveryRequest) (DiscoveryResponse, error)
    GetClusters(r DiscoveryRequest) (DiscoveryResponse, error)
}

// EndpointDiscoveryService
type EndpointDiscoveryService interface {
    AddEndpoints(r DiscoveryRequest) (DiscoveryResponse, error)
    GetEndpoints(r DiscoveryRequest) (DiscoveryResponse, error)
}

discovery_service.go定义了四种DiscoveryService接口,分别是APIDiscoveryService、ListenerDiscoveryService、RouteDiscoveryService、ClusterDiscoveryService、EndpointDiscoveryService

DiscoveryRequest

dubbo-go-proxy/pkg/service/discovery_service.go

// DiscoveryRequest a request for discovery
type DiscoveryRequest struct {
    Body []byte
}

// NewDiscoveryRequest return a DiscoveryRequest with body
func NewDiscoveryRequest(b []byte) *DiscoveryRequest {
    return &DiscoveryRequest{
        Body: b,
    }
}

DiscoveryRequest定义了Body属性

DiscoveryResponse

dubbo-go-proxy/pkg/service/discovery_service.go

// DiscoveryResponse a response for discovery
type DiscoveryResponse struct {
    Success bool
    Data    interface{}
}

// NewDiscoveryResponseWithSuccess return a DiscoveryResponse with success
func NewDiscoveryResponseWithSuccess(b bool) *DiscoveryResponse {
    return &DiscoveryResponse{
        Success: b,
    }
}

// NewDiscoveryResponse return a DiscoveryResponse with Data and success true
func NewDiscoveryResponse(d interface{}) *DiscoveryResponse {
    return &DiscoveryResponse{
        Success: true,
        Data:    d,
    }
}

var EmptyDiscoveryResponse = &DiscoveryResponse{}

DiscoveryResponse定义了Success及Data属性

LocalMemoryAPIDiscoveryService

dubbo-go-proxy/pkg/service/api/discovery_service.go

// Init set api discovery local_memory service.
func Init() {
    extension.SetAPIDiscoveryService(constant.LocalMemoryApiDiscoveryService, NewLocalMemoryAPIDiscoveryService())
}

// LocalMemoryAPIDiscoveryService is the local cached API discovery service
type LocalMemoryAPIDiscoveryService struct {
    router *router.Route
}

// NewLocalMemoryAPIDiscoveryService creates a new LocalMemoryApiDiscoveryService instance
func NewLocalMemoryAPIDiscoveryService() *LocalMemoryAPIDiscoveryService {
    return &LocalMemoryAPIDiscoveryService{
        router: router.NewRoute(),
    }
}

// AddAPI adds a method to the router tree
func (ads *LocalMemoryAPIDiscoveryService) AddAPI(api fr.API) error {
    return ads.router.PutAPI(api)
}

// GetAPI returns the method to the caller
func (ads *LocalMemoryAPIDiscoveryService) GetAPI(url string, httpVerb config.HTTPVerb) (fr.API, error) {
    if api, ok := ads.router.FindAPI(url, httpVerb); ok {
        return *api, nil
    }

    return fr.API{}, errors.New("not found")
}

LocalMemoryAPIDiscoveryService定义了router属性;它实现了APIDiscoveryService的AddAPI及GetAPI方法,均是代理给了router

InitAPIsFromConfig

dubbo-go-proxy/pkg/service/api/discovery_service.go

// InitAPIsFromConfig inits the router from API config and to local cache
func InitAPIsFromConfig(apiConfig config.APIConfig) error {
    localAPIDiscSrv := extension.GetMustAPIDiscoveryService(constant.LocalMemoryApiDiscoveryService)
    if len(apiConfig.Resources) == 0 {
        return nil
    }
    // load pluginsGroup
    plugins.InitPluginsGroup(apiConfig.PluginsGroup, apiConfig.PluginFilePath)
    // init plugins from resource
    plugins.InitAPIURLWithFilterChain(apiConfig.Resources)
    return loadAPIFromResource("", apiConfig.Resources, nil, localAPIDiscSrv)
}

InitAPIsFromConfig根据config.APIConfig的配置来加载plugin对应的filter方法

loadAPIFromResource

dubbo-go-proxy/pkg/service/api/discovery_service.go

func loadAPIFromResource(parrentPath string, resources []config.Resource, parentHeaders map[string]string, localSrv service.APIDiscoveryService) error {
    errStack := []string{}
    if len(resources) == 0 {
        return nil
    }
    groupPath := parrentPath
    if parrentPath == constant.PathSlash {
        groupPath = ""
    }
    fullHeaders := parentHeaders
    if fullHeaders == nil {
        fullHeaders = make(map[string]string, 9)
    }
    for _, resource := range resources {
        fullPath := groupPath + resource.Path
        if !strings.HasPrefix(resource.Path, constant.PathSlash) {
            errStack = append(errStack, fmt.Sprintf("Path %s in %s doesn't start with /", resource.Path, parrentPath))
            continue
        }
        for headerName, headerValue := range resource.Headers {
            fullHeaders[headerName] = headerValue
        }
        if len(resource.Resources) > 0 {
            if err := loadAPIFromResource(resource.Path, resource.Resources, fullHeaders, localSrv); err != nil {
                errStack = append(errStack, err.Error())
            }
        }

        if err := loadAPIFromMethods(fullPath, resource.Methods, fullHeaders, localSrv); err != nil {
            errStack = append(errStack, err.Error())
        }
    }
    if len(errStack) > 0 {
        return errors.New(strings.Join(errStack, "; "))
    }
    return nil
}

loadAPIFromResource用于加载指定resources的api,它借用了loadAPIFromMethods

loadAPIFromMethods

dubbo-go-proxy/pkg/service/api/discovery_service.go

func loadAPIFromMethods(fullPath string, methods []config.Method, headers map[string]string, localSrv service.APIDiscoveryService) error {
    errStack := []string{}
    for _, method := range methods {
        api := fr.API{
            URLPattern: fullPath,
            Method:     method,
            Headers:    headers,
        }
        if err := localSrv.AddAPI(api); err != nil {
            errStack = append(errStack, fmt.Sprintf("Path: %s, Method: %s, error: %s", fullPath, method.HTTPVerb, err.Error()))
        }
    }
    if len(errStack) > 0 {
        return errors.New(strings.Join(errStack, "\n"))
    }
    return nil
}

loadAPIFromMethods遍历methods创建fr.API,并执行localSrv.AddAPI(api)

discovery_service.go定义了四种DiscoveryService接口,分别是APIDiscoveryService、ListenerDiscoveryService、RouteDiscoveryService、ClusterDiscoveryService、EndpointDiscoveryService;LocalMemoryAPIDiscoveryService定义了router属性;它实现了APIDiscoveryService的AddAPI及GetAPI方法,均是代理给了router。


有疑问加站长微信联系(非本文作者)

280

本文来自:Segmentfault

感谢作者:.container .card .information strong

查看原文:聊聊dubbo-go-proxy的DiscoveryService

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:1006366459


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK