github.com/polarismesh/polaris@v1.17.8/cache/api/types.go (about) 1 /** 2 * Tencent is pleased to support the open source community by making Polaris available. 3 * 4 * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. 5 * 6 * Licensed under the BSD 3-Clause License (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * https://opensource.org/licenses/BSD-3-Clause 11 * 12 * Unless required by applicable law or agreed to in writing, software distributed 13 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 14 * CONDITIONS OF ANY KIND, either express or implied. See the License for the 15 * specific language governing permissions and limitations under the License. 16 */ 17 18 package api 19 20 import ( 21 "runtime" 22 "sync" 23 "time" 24 25 apisecurity "github.com/polarismesh/specification/source/go/api/v1/security" 26 apiservice "github.com/polarismesh/specification/source/go/api/v1/service_manage" 27 apitraffic "github.com/polarismesh/specification/source/go/api/v1/traffic_manage" 28 29 "github.com/polarismesh/polaris/common/metrics" 30 "github.com/polarismesh/polaris/common/model" 31 "github.com/polarismesh/polaris/store" 32 ) 33 34 const ( 35 // NamespaceName cache name 36 NamespaceName = "namespace" 37 // ServiceName 38 ServiceName = "service" 39 // InstanceName instance name 40 InstanceName = "instance" 41 // L5Name l5 name 42 L5Name = "l5" 43 // RoutingConfigName router config name 44 RoutingConfigName = "routingConfig" 45 // RateLimitConfigName rate limit config name 46 RateLimitConfigName = "rateLimitConfig" 47 // CircuitBreakerName circuit breaker config name 48 CircuitBreakerName = "circuitBreakerConfig" 49 // FaultDetectRuleName fault detect config name 50 FaultDetectRuleName = "faultDetectRule" 51 // ConfigGroupCacheName config group config name 52 ConfigGroupCacheName = "configGroup" 53 // ConfigFileCacheName config file config name 54 ConfigFileCacheName = "configFile" 55 // ClientName client cache name 56 ClientName = "client" 57 // UsersName user data config name 58 UsersName = "users" 59 // StrategyRuleName strategy rule config name 60 StrategyRuleName = "strategyRule" 61 ) 62 63 type CacheIndex int 64 65 const ( 66 // CacheNamespace int = iota 67 // CacheBusiness 68 CacheService CacheIndex = iota 69 CacheInstance 70 CacheRoutingConfig 71 CacheCL5 72 CacheRateLimit 73 CacheCircuitBreaker 74 CacheUser 75 CacheAuthStrategy 76 CacheNamespace 77 CacheClient 78 CacheConfigFile 79 CacheFaultDetector 80 CacheConfigGroup 81 82 CacheLast 83 ) 84 85 // Cache 缓存接口 86 type Cache interface { 87 // Initialize 88 Initialize(c map[string]interface{}) error 89 // AddListener 添加 90 AddListener(listeners []Listener) 91 // Update . 92 Update() error 93 // Clear . 94 Clear() error 95 // Name . 96 Name() string 97 // Close . 98 Close() error 99 } 100 101 // CacheManager 102 type CacheManager interface { 103 // GetCacher 104 GetCacher(cacheIndex CacheIndex) Cache 105 // RegisterCacher 106 RegisterCacher(cacheIndex CacheIndex, item Cache) 107 } 108 109 type ( 110 // NamespaceCache 命名空间的 Cache 接口 111 NamespaceCache interface { 112 Cache 113 // GetNamespace 114 GetNamespace(id string) *model.Namespace 115 // GetNamespacesByName 116 GetNamespacesByName(names []string) []*model.Namespace 117 // GetNamespaceList 118 GetNamespaceList() []*model.Namespace 119 } 120 ) 121 122 type ( 123 // ServiceIterProc 迭代回调函数 124 ServiceIterProc func(key string, value *model.Service) (bool, error) 125 126 // ServiceArgs 服务查询条件 127 ServiceArgs struct { 128 // Filter 普通服务字段条件 129 Filter map[string]string 130 // Metadata 元数据条件 131 Metadata map[string]string 132 // SvcIds 是否按照服务的ID进行等值查询 133 SvcIds map[string]struct{} 134 // WildName 是否进行名字的模糊匹配 135 WildName bool 136 // WildBusiness 是否进行业务的模糊匹配 137 WildBusiness bool 138 // WildNamespace 是否进行命名空间的模糊匹配 139 WildNamespace bool 140 // Namespace 条件中的命名空间 141 Namespace string 142 // Name 条件中的服务名 143 Name string 144 // EmptyCondition 是否是空条件,即只需要从所有服务或者某个命名空间下面的服务,进行不需要匹配的遍历,返回前面的服务即可 145 EmptyCondition bool 146 } 147 148 // ServiceCache 服务数据缓存接口 149 ServiceCache interface { 150 Cache 151 // GetNamespaceCntInfo Return to the service statistics according to the namespace, 152 // the count statistics and health instance statistics 153 GetNamespaceCntInfo(namespace string) model.NamespaceServiceCount 154 // GetAllNamespaces Return all namespaces 155 GetAllNamespaces() []string 156 // GetServiceByID According to ID query service information 157 GetServiceByID(id string) *model.Service 158 // GetServiceByName Inquiry service information according to service name 159 GetServiceByName(name string, namespace string) *model.Service 160 // IteratorServices Iterative Cache Service Information 161 IteratorServices(iterProc ServiceIterProc) error 162 // CleanNamespace Clear the cache of NameSpace 163 CleanNamespace(namespace string) 164 // GetServicesCount Get the number of services in the cache 165 GetServicesCount() int 166 // GetServiceByCl5Name Get the corresponding SID according to CL5name 167 GetServiceByCl5Name(cl5Name string) *model.Service 168 // GetServicesByFilter Serving the service filtering in the cache through Filter 169 GetServicesByFilter(serviceFilters *ServiceArgs, 170 instanceFilters *store.InstanceArgs, offset, limit uint32) (uint32, []*model.EnhancedService, error) 171 // ListServices get service list and revision by namespace 172 ListServices(ns string) (string, []*model.Service) 173 // ListAllServices get all service and revision 174 ListAllServices() (string, []*model.Service) 175 // ListServiceAlias list service link alias list 176 ListServiceAlias(namespace, name string) []*model.Service 177 // GetAliasFor get alias reference service info 178 GetAliasFor(name string, namespace string) *model.Service 179 // GetRevisionWorker . 180 GetRevisionWorker() ServiceRevisionWorker 181 } 182 183 // ServiceRevisionWorker 184 ServiceRevisionWorker interface { 185 // Notify 186 Notify(serviceID string, valid bool) 187 // GetServiceRevisionCount 188 GetServiceRevisionCount() int 189 // GetServiceInstanceRevision 190 GetServiceInstanceRevision(serviceID string) string 191 } 192 ) 193 194 type ( 195 // InstanceIterProc instance iter proc func 196 InstanceIterProc func(key string, value *model.Instance) (bool, error) 197 198 // InstanceCache 实例相关的缓存接口 199 InstanceCache interface { 200 // Cache 公共缓存接口 201 Cache 202 // GetInstance 根据实例ID获取实例数据 203 GetInstance(instanceID string) *model.Instance 204 // GetInstancesByServiceID 根据服务名获取实例,先查找服务名对应的服务ID,再找实例列表 205 GetInstancesByServiceID(serviceID string) []*model.Instance 206 // IteratorInstances 迭代 207 IteratorInstances(iterProc InstanceIterProc) error 208 // IteratorInstancesWithService 根据服务ID进行迭代 209 IteratorInstancesWithService(serviceID string, iterProc InstanceIterProc) error 210 // GetInstancesCount 获取instance的个数 211 GetInstancesCount() int 212 // GetInstancesCountByServiceID 根据服务ID获取实例数 213 GetInstancesCountByServiceID(serviceID string) model.InstanceCount 214 // GetServicePorts 根据服务ID获取端口号 215 GetServicePorts(serviceID string) []*model.ServicePort 216 // GetInstanceLabels Get the label of all instances under a service 217 GetInstanceLabels(serviceID string) *apiservice.InstanceLabels 218 // QueryInstances query instance for OSS 219 QueryInstances(filter, metaFilter map[string]string, offset, limit uint32) (uint32, []*model.Instance, error) 220 } 221 ) 222 223 type ( 224 // FaultDetectCache fault detect rule cache service 225 FaultDetectCache interface { 226 Cache 227 // GetFaultDetectConfig 根据ServiceID获取探测配置 228 GetFaultDetectConfig(svcName string, namespace string) *model.ServiceWithFaultDetectRules 229 } 230 ) 231 232 type ( 233 // RoutingArgs Routing rules query parameters 234 RoutingArgs struct { 235 // Filter extend filter params 236 Filter map[string]string 237 // ID route rule id 238 ID string 239 // Name route rule name 240 Name string 241 // Service service name 242 Service string 243 // Namespace namesapce 244 Namespace string 245 // SourceService source service name 246 SourceService string 247 // SourceNamespace source service namespace 248 SourceNamespace string 249 // DestinationService destination service name 250 DestinationService string 251 // DestinationNamespace destination service namespace 252 DestinationNamespace string 253 // Enable 254 Enable *bool 255 // Offset 256 Offset uint32 257 // Limit 258 Limit uint32 259 // OrderField Sort field 260 OrderField string 261 // OrderType Sorting rules 262 OrderType string 263 } 264 265 // RouterRuleIterProc Method definition of routing rules 266 RouterRuleIterProc func(key string, value *model.ExtendRouterConfig) 267 268 // RoutingConfigCache Cache interface configured by routing 269 RoutingConfigCache interface { 270 Cache 271 // GetRouterConfig Obtain routing configuration based on serviceid 272 GetRouterConfig(id, service, namespace string) (*apitraffic.Routing, error) 273 // GetRouterConfig Obtain routing configuration based on serviceid 274 GetRouterConfigV2(id, service, namespace string) (*apitraffic.Routing, error) 275 // GetRoutingConfigCount Get the total number of routing configuration cache 276 GetRoutingConfigCount() int 277 // QueryRoutingConfigsV2 Query Route Configuration List 278 QueryRoutingConfigsV2(args *RoutingArgs) (uint32, []*model.ExtendRouterConfig, error) 279 // ListRouterRule list all router rule 280 ListRouterRule(service, namespace string) []*model.ExtendRouterConfig 281 // IsConvertFromV1 Whether the current routing rules are converted from the V1 rule 282 IsConvertFromV1(id string) (string, bool) 283 // IteratorRouterRule iterator router rule 284 IteratorRouterRule(iterProc RouterRuleIterProc) 285 } 286 ) 287 288 type ( 289 // RateLimitRuleArgs ratelimit rules query parameters 290 RateLimitRuleArgs struct { 291 // Filter extend filter params 292 Filter map[string]string 293 // ID route rule id 294 ID string 295 // Name route rule name 296 Name string 297 // Service service name 298 Service string 299 // Namespace namesapce 300 Namespace string 301 // Disable *bool 302 Disable *bool 303 // Offset 304 Offset uint32 305 // Limit 306 Limit uint32 307 // OrderField Sort field 308 OrderField string 309 // OrderType Sorting rules 310 OrderType string 311 } 312 313 // RateLimitIterProc rate limit iter func 314 RateLimitIterProc func(rateLimit *model.RateLimit) 315 316 // RateLimitCache rateLimit的cache接口 317 RateLimitCache interface { 318 Cache 319 // GetRateLimit 根据serviceID进行迭代回调 320 IteratorRateLimit(rateLimitIterProc RateLimitIterProc) 321 // GetRateLimitRules 根据serviceID获取限流数据 322 GetRateLimitRules(serviceKey model.ServiceKey) ([]*model.RateLimit, string) 323 // QueryRateLimitRules 324 QueryRateLimitRules(args RateLimitRuleArgs) (uint32, []*model.RateLimit, error) 325 // GetRateLimitsCount 获取限流规则总数 326 GetRateLimitsCount() int 327 } 328 ) 329 330 type ( 331 // L5Cache L5的cache接口 332 L5Cache interface { 333 Cache 334 // GetRouteByIP 根据IP获取访问关系 335 GetRouteByIP(ip uint32) []*model.Route 336 // CheckRouteExisted 检查IP对应的SID是否存在访问关系 337 CheckRouteExisted(ip uint32, modID uint32, cmdID uint32) bool 338 // GetPolicy 获取有状态路由信息policy 339 GetPolicy(modID uint32) *model.Policy 340 // GetSection 获取有状态路由信息policy 341 GetSection(modeID uint32) []*model.Section 342 // GetIPConfig 获取IpConfig 343 GetIPConfig(ip uint32) *model.IPConfig 344 } 345 ) 346 347 type ( 348 // CircuitBreakerCache circuitBreaker配置的cache接口 349 CircuitBreakerCache interface { 350 Cache 351 // GetCircuitBreakerConfig 根据ServiceID获取熔断配置 352 GetCircuitBreakerConfig(svcName string, namespace string) *model.ServiceWithCircuitBreakerRules 353 } 354 ) 355 356 type ( 357 BaseConfigArgs struct { 358 // Namespace 359 Namespace string 360 // Group 361 Group string 362 // Offset 363 Offset uint32 364 // Limit 365 Limit uint32 366 // OrderField Sort field 367 OrderField string 368 // OrderType Sorting rules 369 OrderType string 370 } 371 372 ConfigFileArgs struct { 373 BaseConfigArgs 374 FileName string 375 Metadata map[string]string 376 } 377 378 ConfigReleaseArgs struct { 379 BaseConfigArgs 380 // FileName 381 FileName string 382 // ReleaseName 383 ReleaseName string 384 // OnlyActive 385 OnlyActive bool 386 // Metadata 387 Metadata map[string]string 388 // NoPage 389 NoPage bool 390 } 391 392 // ConfigGroupArgs 393 ConfigGroupArgs struct { 394 Namespace string 395 Name string 396 Business string 397 Department string 398 Metadata map[string]string 399 Offset uint32 400 Limit uint32 401 // OrderField Sort field 402 OrderField string 403 // OrderType Sorting rules 404 OrderType string 405 } 406 407 // ConfigGroupCache file cache 408 ConfigGroupCache interface { 409 Cache 410 // GetGroupByName 411 GetGroupByName(namespace, name string) *model.ConfigFileGroup 412 // GetGroupByID 413 GetGroupByID(id uint64) *model.ConfigFileGroup 414 // Query 415 Query(args *ConfigGroupArgs) (uint32, []*model.ConfigFileGroup, error) 416 } 417 418 // ConfigFileCache file cache 419 ConfigFileCache interface { 420 Cache 421 // GetActiveRelease 422 GetGroupActiveReleases(namespace, group string) ([]*model.ConfigFileRelease, string) 423 // GetActiveRelease 424 GetActiveRelease(namespace, group, fileName string) *model.ConfigFileRelease 425 // GetRelease 426 GetRelease(key model.ConfigFileReleaseKey) *model.ConfigFileRelease 427 // QueryReleases 428 QueryReleases(args *ConfigReleaseArgs) (uint32, []*model.SimpleConfigFileRelease, error) 429 } 430 ) 431 432 type ( 433 // UserCache User information cache 434 UserCache interface { 435 Cache 436 // GetAdmin 获取管理员信息 437 GetAdmin() *model.User 438 // GetUserByID 439 GetUserByID(id string) *model.User 440 // GetUserByName 441 GetUserByName(name, ownerName string) *model.User 442 // GetUserGroup 443 GetGroup(id string) *model.UserGroupDetail 444 // IsUserInGroup 判断 userid 是否在对应的 group 中 445 IsUserInGroup(userId, groupId string) bool 446 // IsOwner 447 IsOwner(id string) bool 448 // GetUserLinkGroupIds 449 GetUserLinkGroupIds(id string) []string 450 } 451 452 // StrategyCache is a cache for strategy rules. 453 StrategyCache interface { 454 Cache 455 // GetStrategyDetailsByUID 456 GetStrategyDetailsByUID(uid string) []*model.StrategyDetail 457 // GetStrategyDetailsByGroupID returns all strategy details of a group. 458 GetStrategyDetailsByGroupID(groupId string) []*model.StrategyDetail 459 // IsResourceLinkStrategy 该资源是否关联了鉴权策略 460 IsResourceLinkStrategy(resType apisecurity.ResourceType, resId string) bool 461 // IsResourceEditable 判断该资源是否可以操作 462 IsResourceEditable(principal model.Principal, resType apisecurity.ResourceType, resId string) bool 463 // ForceSync 强制同步鉴权策略到cache (串行) 464 ForceSync() error 465 } 466 ) 467 468 type ( 469 470 // ClientIterProc client iter proc func 471 ClientIterProc func(key string, value *model.Client) bool 472 473 // ClientCache 客户端的 Cache 接口 474 ClientCache interface { 475 Cache 476 // GetClient get client 477 GetClient(id string) *model.Client 478 // IteratorClients 迭代 479 IteratorClients(iterProc ClientIterProc) 480 // GetClientsByFilter Query client information 481 GetClientsByFilter(filters map[string]string, offset, limit uint32) (uint32, []*model.Client, error) 482 } 483 ) 484 485 var ( 486 // DefaultTimeDiff default time diff 487 DefaultTimeDiff = -5 * time.Second 488 ) 489 490 // BaseCache 对于 Cache 中的一些 func 做统一实现,避免重复逻辑 491 type BaseCache struct { 492 lock sync.RWMutex 493 // firtstUpdate Whether the cache is loaded for the first time 494 // this field can only make value on exec initialize/clean, and set it to false on exec update 495 firtstUpdate bool 496 s store.Store 497 lastFetchTime int64 498 lastMtimes map[string]time.Time 499 Manager *ListenerManager 500 CacheMgr CacheManager 501 } 502 503 func NewBaseCache(s store.Store, cacheMgr CacheManager) *BaseCache { 504 c := &BaseCache{ 505 s: s, 506 CacheMgr: cacheMgr, 507 } 508 509 c.initialize() 510 return c 511 } 512 513 func (bc *BaseCache) initialize() { 514 bc.lock.Lock() 515 defer bc.lock.Unlock() 516 517 bc.lastFetchTime = 1 518 bc.firtstUpdate = true 519 bc.Manager = NewListenerManager() 520 bc.lastMtimes = map[string]time.Time{} 521 } 522 523 var ( 524 zeroTime = time.Unix(0, 0) 525 ) 526 527 func (bc *BaseCache) ResetLastMtime(label string) { 528 bc.lock.Lock() 529 defer bc.lock.Unlock() 530 bc.lastMtimes[label] = time.Unix(0, 0) 531 } 532 533 func (bc *BaseCache) ResetLastFetchTime() { 534 bc.lock.Lock() 535 defer bc.lock.Unlock() 536 bc.lastFetchTime = 1 537 } 538 539 func (bc *BaseCache) LastMtime(label string) time.Time { 540 bc.lock.RLock() 541 defer bc.lock.RUnlock() 542 v, ok := bc.lastMtimes[label] 543 if ok { 544 return v 545 } 546 547 return time.Unix(0, 0) 548 } 549 550 func (bc *BaseCache) LastFetchTime() time.Time { 551 lastTime := time.Unix(bc.lastFetchTime, 0) 552 tmp := lastTime.Add(DefaultTimeDiff) 553 if zeroTime.After(tmp) { 554 return lastTime 555 } 556 lastTime = tmp 557 return lastTime 558 } 559 560 // OriginLastFetchTime only for test 561 func (bc *BaseCache) OriginLastFetchTime() time.Time { 562 lastTime := time.Unix(bc.lastFetchTime, 0) 563 return lastTime 564 } 565 566 func (bc *BaseCache) IsFirstUpdate() bool { 567 return bc.firtstUpdate 568 } 569 570 // update 571 func (bc *BaseCache) DoCacheUpdate(name string, executor func() (map[string]time.Time, int64, error)) error { 572 if bc.IsFirstUpdate() { 573 log.Infof("[Cache][%s] begin run cache update work", name) 574 } 575 576 curStoreTime, err := bc.s.GetUnixSecond(0) 577 if err != nil { 578 curStoreTime = bc.lastFetchTime 579 log.Warnf("[Cache][%s] get store timestamp fail, skip update lastMtime, err : %v", name, err) 580 } 581 defer func() { 582 if err := recover(); err != nil { 583 var buf [4086]byte 584 n := runtime.Stack(buf[:], false) 585 log.Errorf("[Cache][%s] run cache update panic: %+v, stack\n%s\n", name, err, string(buf[:n])) 586 } else { 587 bc.lastFetchTime = curStoreTime 588 } 589 }() 590 591 start := time.Now() 592 lastMtimes, total, err := executor() 593 if err != nil { 594 return err 595 } 596 597 bc.lock.Lock() 598 defer bc.lock.Unlock() 599 if len(lastMtimes) != 0 { 600 if len(bc.lastMtimes) != 0 { 601 for label, lastMtime := range lastMtimes { 602 preLastMtime := bc.lastMtimes[label] 603 log.Infof("[Cache][%s] lastFetchTime %s, lastMtime update from %s to %s", 604 label, time.Unix(bc.lastFetchTime, 0), preLastMtime, lastMtime) 605 } 606 } 607 bc.lastMtimes = lastMtimes 608 } 609 610 if total >= 0 { 611 metrics.RecordCacheUpdateCost(time.Since(start), name, total) 612 } 613 bc.firtstUpdate = false 614 return nil 615 } 616 617 func (bc *BaseCache) Clear() { 618 bc.lock.Lock() 619 defer bc.lock.Unlock() 620 bc.lastMtimes = make(map[string]time.Time) 621 bc.lastFetchTime = 1 622 bc.firtstUpdate = true 623 } 624 625 // AddListener 添加 626 func (bc *BaseCache) AddListener(listeners []Listener) { 627 bc.lock.Lock() 628 defer bc.lock.Unlock() 629 bc.Manager.Append(listeners...) 630 } 631 632 func (bc *BaseCache) Close() error { 633 return nil 634 }