聊聊dubbo-go-proxy的DiscoveryService
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。
有疑问加站长微信联系(非本文作者)
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:1006366459
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK