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  }