本文主要研究一下dubbo-go-proxy的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
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属性
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属性
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
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方法
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
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。