func (mts *MetadataService) UnsubscribeURL(url *common.URL) error {
	mts.removeURL(mts.subscribedServiceURLs, url)
	return nil
}
UnsubscribeURL can remove the url store in memory
package local
import (
	"sort"
	"sync"
)
import (
	"github.com/Workiva/go-datastructures/slice/skip"
)
import (
	"dubbo.apache.org/dubbo-go/v3/common"
	"dubbo.apache.org/dubbo-go/v3/common/constant"
	"dubbo.apache.org/dubbo-go/v3/common/extension"
	"dubbo.apache.org/dubbo-go/v3/common/logger"
	"dubbo.apache.org/dubbo-go/v3/config"
	"dubbo.apache.org/dubbo-go/v3/metadata/definition"
	"dubbo.apache.org/dubbo-go/v3/metadata/service"
)
func init() {
	extension.SetLocalMetadataService(constant.DEFAULT_KEY, GetLocalMetadataService)
}
const (
	version = "1.0.0"
)
type MetadataService struct {
	service.BaseMetadataService
	exportedServiceURLs   *sync.Map
	subscribedServiceURLs *sync.Map
	serviceDefinitions    *sync.Map
	lock                  *sync.RWMutex
	mOnce                 *sync.Once
	metadataInfo          *common.MetadataInfo
	metadataServiceURL    *common.URL
}
var (
	metadataServiceInstance *MetadataService
	metadataServiceInitOnce sync.Once
)
func GetLocalMetadataService() (service.MetadataService, error) {
	metadataServiceInitOnce.Do(func() {
		metadataServiceInstance = &MetadataService{
			BaseMetadataService:   service.NewBaseMetadataService(config.GetApplicationConfig().Name),
			exportedServiceURLs:   &sync.Map{},
			subscribedServiceURLs: &sync.Map{},
			serviceDefinitions:    &sync.Map{},
			lock:                  &sync.RWMutex{},
			metadataInfo:          nil,
			mOnce:                 &sync.Once{},
		}
	})
	return metadataServiceInstance, nil
}
func (mts *MetadataService) addURL(targetMap *sync.Map, url *common.URL) bool {
	var (
		urlSet interface{}
		loaded bool
	)
	logger.Debug(url.ServiceKey())
	if urlSet, loaded = targetMap.LoadOrStore(url.ServiceKey(), skip.New(uint64(0))); loaded {
		mts.lock.RLock()
		wantedUrl := urlSet.(*skip.SkipList).Get(url)
		if len(wantedUrl) > 0 && wantedUrl[0] != nil {
			mts.lock.RUnlock()
			return false
		}
		mts.lock.RUnlock()
	}
	mts.lock.Lock()
	wantedUrl := urlSet.(*skip.SkipList).Get(url)
	if len(wantedUrl) > 0 && wantedUrl[0] != nil {
		mts.lock.Unlock()
		return false
	}
	urlSet.(*skip.SkipList).Insert(url)
	mts.lock.Unlock()
	return true
}
func (mts *MetadataService) removeURL(targetMap *sync.Map, url *common.URL) {
	if value, loaded := targetMap.Load(url.ServiceKey()); loaded {
		mts.lock.Lock()
		value.(*skip.SkipList).Delete(url)
		mts.lock.Unlock()
		mts.lock.RLock()
		defer mts.lock.RUnlock()
		if value.(*skip.SkipList).Len() == 0 {
			targetMap.Delete(url.ServiceKey())
		}
	}
}
func (mts *MetadataService) getAllService(services *sync.Map) []*common.URL {
	var res []*common.URL
	services.Range(func(key, value interface{}) bool {
		urls := value.(*skip.SkipList)
		for i := uint64(0); i < urls.Len(); i++ {
			url := urls.ByPosition(i).(*common.URL)
			if url.Service() != constant.METADATA_SERVICE_NAME {
				res = append(res, url)
			}
		}
		return true
	})
	sort.Sort(common.URLSlice(res))
	return res
}
func (mts *MetadataService) getSpecifiedService(services *sync.Map, serviceKey string, protocol string) []*common.URL {
	var res []*common.URL
	serviceList, loaded := services.Load(serviceKey)
	if loaded {
		urls := serviceList.(*skip.SkipList)
		for i := uint64(0); i < urls.Len(); i++ {
			url := urls.ByPosition(i).(*common.URL)
			if len(protocol) == 0 || protocol == constant.ANY_VALUE || url.Protocol == protocol || url.GetParam(constant.PROTOCOL_KEY, "") == protocol {
				res = append(res, url)
			}
		}
		sort.Stable(common.URLSlice(res))
	}
	return res
}
func (mts *MetadataService) ExportURL(url *common.URL) (bool, error) {
	if constant.METADATA_SERVICE_NAME == url.GetParam(constant.INTERFACE_KEY, "") {
		mts.metadataServiceURL = url
		return true, nil
	}
	mts.mOnce.Do(func() {
		mts.metadataInfo = common.NewMetadataInfWithApp(config.GetApplicationConfig().Name)
	})
	mts.metadataInfo.AddService(common.NewServiceInfoWithURL(url))
	return mts.addURL(mts.exportedServiceURLs, url), nil
}
func (mts *MetadataService) UnexportURL(url *common.URL) error {
	if constant.METADATA_SERVICE_NAME == url.GetParam(constant.INTERFACE_KEY, "") {
		mts.metadataServiceURL = nil
		return nil
	}
	if mts.metadataInfo != nil {
		mts.metadataInfo.RemoveService(common.NewServiceInfoWithURL(url))
	}
	mts.removeURL(mts.exportedServiceURLs, url)
	return nil
}
func (mts *MetadataService) SubscribeURL(url *common.URL) (bool, error) {
	return mts.addURL(mts.subscribedServiceURLs, url), nil
}