github.com/polarismesh/polaris@v1.17.8/cache/service/l5.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 service 19 20 import ( 21 "container/list" 22 23 types "github.com/polarismesh/polaris/cache/api" 24 "github.com/polarismesh/polaris/common/model" 25 "github.com/polarismesh/polaris/common/utils" 26 "github.com/polarismesh/polaris/store" 27 ) 28 29 // l5Cache L5的cache对象 30 type l5Cache struct { 31 *types.BaseCache 32 33 storage store.Store 34 35 lastRouteFlow uint32 36 lastPolicyFlow uint32 37 lastSectionFlow uint32 38 lastIPConfigFlow uint32 39 40 // <IP, <sidStr, setID> > 41 routeList *utils.SyncMap[uint32, *utils.SyncMap[string, string]] 42 // <modID, Policy> 43 policyList *utils.SyncMap[uint32, *model.Policy] 44 // <modID, []*Section (list)> 45 sectionList *utils.SyncMap[uint32, *list.List] 46 // <IP, IPConfig> 47 ipConfigList *utils.SyncMap[uint32, *model.IPConfig] 48 49 // instances的信息 50 ic *instanceCache 51 sc *serviceCache 52 } 53 54 func NewL5Cache(s store.Store, cacheMgr types.CacheManager) types.L5Cache { 55 return &l5Cache{ 56 BaseCache: types.NewBaseCache(s, cacheMgr), 57 storage: s, 58 } 59 } 60 61 // Initialize 初始化函数 62 func (lc *l5Cache) Initialize(_ map[string]interface{}) error { 63 lc.ic = lc.BaseCache.CacheMgr.GetCacher(types.CacheInstance).(*instanceCache) 64 lc.sc = lc.BaseCache.CacheMgr.GetCacher(types.CacheService).(*serviceCache) 65 lc.routeList = utils.NewSyncMap[uint32, *utils.SyncMap[string, string]]() 66 lc.policyList = utils.NewSyncMap[uint32, *model.Policy]() 67 lc.sectionList = utils.NewSyncMap[uint32, *list.List]() 68 lc.ipConfigList = utils.NewSyncMap[uint32, *model.IPConfig]() 69 return nil 70 } 71 72 func (lc *l5Cache) Update() error { 73 err := lc.updateCL5Route() 74 if err != nil { 75 log.Errorf("[Cache][CL5] update l5 route cache err: %s", err.Error()) 76 } 77 err = lc.updateCL5Policy() 78 if err != nil { 79 log.Errorf("[Cache][CL5] update l5 policy cache err: %s", err.Error()) 80 } 81 err = lc.updateCL5Section() 82 if err != nil { 83 log.Errorf("[Cache][CL5] update l5 section cache err: %s", err.Error()) 84 } 85 return err 86 } 87 88 // Clear 清理内部缓存数据 89 func (lc *l5Cache) Clear() error { 90 lc.routeList = utils.NewSyncMap[uint32, *utils.SyncMap[string, string]]() 91 lc.policyList = utils.NewSyncMap[uint32, *model.Policy]() 92 lc.sectionList = utils.NewSyncMap[uint32, *list.List]() 93 lc.ipConfigList = utils.NewSyncMap[uint32, *model.IPConfig]() 94 lc.lastRouteFlow = 0 95 lc.lastPolicyFlow = 0 96 lc.lastSectionFlow = 0 97 lc.lastIPConfigFlow = 0 98 return nil 99 } 100 101 // Name 获取资源名称 102 func (lc *l5Cache) Name() string { 103 return types.L5Name 104 } 105 106 // GetRouteByIP 根据Ip获取访问关系 107 func (lc *l5Cache) GetRouteByIP(ip uint32) []*model.Route { 108 out := make([]*model.Route, 0, 10) 109 entry, ok := lc.routeList.Load(ip) 110 if !ok { 111 // 该ip不存在访问关系,则返回一个空数组 112 return out 113 } 114 115 entry.Range(func(key string, value string) bool { 116 // sidStr -> setID 117 sid, err := model.UnmarshalSid(key) 118 if err != nil { 119 return true 120 } 121 122 item := &model.Route{ 123 IP: ip, 124 ModID: sid.ModID, 125 CmdID: sid.CmdID, 126 SetID: value, 127 } 128 out = append(out, item) 129 return true 130 }) 131 132 return out 133 } 134 135 // CheckRouteExisted 检查访问关系是否存在 136 func (lc *l5Cache) CheckRouteExisted(ip uint32, modID uint32, cmdID uint32) bool { 137 entry, ok := lc.routeList.Load(ip) 138 if !ok { 139 return false 140 } 141 142 found := false 143 entry.Range(func(key string, value string) bool { 144 sid, err := model.UnmarshalSid(key) 145 if err != nil { 146 // continue range 147 return true 148 } 149 150 if modID == sid.ModID && cmdID == sid.CmdID { 151 found = true 152 // break range 153 return false 154 } 155 return true 156 }) 157 158 return found 159 } 160 161 // GetPolicy 根据modID获取policy信息 162 func (lc *l5Cache) GetPolicy(modID uint32) *model.Policy { 163 value, ok := lc.policyList.Load(modID) 164 if !ok { 165 return nil 166 } 167 168 return value 169 } 170 171 // GetSection 根据modID获取section信息 172 func (lc *l5Cache) GetSection(modeID uint32) []*model.Section { 173 obj, ok := lc.sectionList.Load(modeID) 174 if !ok { 175 return nil 176 } 177 178 out := make([]*model.Section, 0, obj.Len()) 179 for e := obj.Front(); e != nil; e = e.Next() { 180 out = append(out, e.Value.(*model.Section)) 181 } 182 183 return out 184 } 185 186 // GetIPConfig 根据IP获取ipConfig 187 func (lc *l5Cache) GetIPConfig(ip uint32) *model.IPConfig { 188 value, ok := lc.ipConfigList.Load(ip) 189 if !ok { 190 return nil 191 } 192 193 return value 194 } 195 196 // updateCL5Route 更新l5的route缓存数据 197 func (lc *l5Cache) updateCL5Route() error { 198 routes, err := lc.storage.GetMoreL5Routes(lc.lastRouteFlow) 199 if err != nil { 200 log.Errorf("[Cache][CL5] get l5 route from storage err: %s", err.Error()) 201 return err 202 } 203 204 return lc.setCL5Route(routes) 205 } 206 207 // updateCL5Policy更新l5的policy缓存数据 208 func (lc *l5Cache) updateCL5Policy() error { 209 policies, err := lc.storage.GetMoreL5Policies(lc.lastPolicyFlow) 210 if err != nil { 211 log.Errorf("[Cache][CL5] get l5 policy from storage err: %s", err.Error()) 212 return err 213 } 214 215 return lc.setCL5Policy(policies) 216 } 217 218 // updateCL5Section 更新l5的section缓存数据 219 func (lc *l5Cache) updateCL5Section() error { 220 sections, err := lc.storage.GetMoreL5Sections(lc.lastSectionFlow) 221 if err != nil { 222 log.Errorf("[Cache][CL5] get l5 section from storage err: %s", err.Error()) 223 return err 224 } 225 226 return lc.setCL5Section(sections) 227 } 228 229 // updateCL5IPConfig 更新l5的ip config缓存数据 230 func (lc *l5Cache) updateCL5IPConfig() error { 231 ipConfigs, err := lc.storage.GetMoreL5IPConfigs(lc.lastIPConfigFlow) 232 if err != nil { 233 log.Errorf("[Cache][CL5] get l5 ip config from storage err: %s", err.Error()) 234 return err 235 } 236 237 return lc.setCL5IPConfig(ipConfigs) 238 } 239 240 // setCL5Route 更新l5 route的本地缓存 241 func (lc *l5Cache) setCL5Route(routes []*model.Route) error { 242 if len(routes) == 0 { 243 return nil 244 } 245 246 lastRouteFlow := lc.lastRouteFlow 247 for _, item := range routes { 248 if item.Flow > lastRouteFlow { 249 lastRouteFlow = item.Flow 250 } 251 252 sidStr := model.MarshalModCmd(item.ModID, item.CmdID) 253 254 // 待删除的route 255 if !item.Valid { 256 value, ok := lc.routeList.Load(item.IP) 257 if !ok { 258 continue 259 } 260 261 value.Delete(sidStr) 262 continue 263 } 264 265 value, ok := lc.routeList.Load(item.IP) 266 if !ok { 267 value = utils.NewSyncMap[string, string]() 268 lc.routeList.Store(item.IP, value) 269 } 270 value.Store(sidStr, item.SetID) 271 } 272 273 if lc.lastRouteFlow < lastRouteFlow { 274 lc.lastRouteFlow = lastRouteFlow 275 } 276 277 return nil 278 } 279 280 // setCL5Policy 更新l5 policy的本地缓存 281 func (lc *l5Cache) setCL5Policy(policies []*model.Policy) error { 282 if len(policies) == 0 { 283 return nil 284 } 285 286 lastPolicyFlow := lc.lastPolicyFlow 287 for _, item := range policies { 288 if item.Flow > lastPolicyFlow { 289 lastPolicyFlow = item.Flow 290 } 291 292 // 待删除的policy 293 if !item.Valid { 294 lc.policyList.Delete(item.ModID) 295 continue 296 } 297 298 lc.policyList.Store(item.ModID, item) 299 } 300 301 if lc.lastPolicyFlow < lastPolicyFlow { 302 lc.lastPolicyFlow = lastPolicyFlow 303 } 304 305 return nil 306 } 307 308 // setCL5Section 更新l5 section的本地缓存 309 func (lc *l5Cache) setCL5Section(sections []*model.Section) error { 310 if len(sections) == 0 { 311 return nil 312 } 313 314 lastSectionFlow := lc.lastSectionFlow 315 for _, item := range sections { 316 if item.Flow > lastSectionFlow { 317 lastSectionFlow = item.Flow 318 } 319 320 // 无论数据是否要删除,都执行删除老数据操作 321 var listObj *list.List 322 if value, ok := lc.sectionList.Load(item.ModID); ok { 323 listObj = value 324 } else { 325 listObj = list.New() 326 } 327 328 for ele := listObj.Front(); ele != nil; ele = ele.Next() { 329 entry := ele.Value.(*model.Section) 330 if entry.From == item.From && entry.To == item.To { 331 listObj.Remove(ele) 332 break 333 } 334 } 335 // 上面已经删除了,这里直接继续迭代 336 if !item.Valid { 337 continue 338 } 339 340 // 存储有效的数据 341 listObj.PushBack(item) 342 lc.sectionList.Store(item.ModID, listObj) 343 } 344 345 if lc.lastSectionFlow < lastSectionFlow { 346 lc.lastSectionFlow = lastSectionFlow 347 } 348 349 return nil 350 } 351 352 // setCL5IPConfig 更新l5 ipConfig的本地缓存 353 func (lc *l5Cache) setCL5IPConfig(ipConfigs []*model.IPConfig) error { 354 if len(ipConfigs) == 0 { 355 return nil 356 } 357 358 lastIPConfigFlow := lc.lastIPConfigFlow 359 for _, item := range ipConfigs { 360 if item.Flow > lastIPConfigFlow { 361 lastIPConfigFlow = item.Flow 362 } 363 364 // 待删除的ip config 365 if !item.Valid { 366 lc.ipConfigList.Delete(item.IP) 367 continue 368 } 369 370 lc.ipConfigList.Store(item.IP, item) 371 } 372 373 if lc.lastIPConfigFlow < lastIPConfigFlow { 374 lc.lastIPConfigFlow = lastIPConfigFlow 375 } 376 377 return nil 378 }