Ai
1 Star 0 Fork 0

0x43/dubbo-go

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
meshrouter.go 4.11 KB
一键复制 编辑 原始数据 按行查看 历史
0x43 提交于 2024-12-28 17:37 +08:00 . module
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package meshrouter
import (
"math/rand"
)
import (
"gitee.com/git4chen/gost/log/logger"
)
import (
"gitee.com/git4chen/dubbo-go/cluster/router"
"gitee.com/git4chen/dubbo-go/common"
"gitee.com/git4chen/dubbo-go/common/constant"
"gitee.com/git4chen/dubbo-go/config_center"
"gitee.com/git4chen/dubbo-go/protocol"
"gitee.com/git4chen/dubbo-go/remoting/xds"
)
const (
name = "mesh-router"
)
// MeshRouter have
type MeshRouter struct {
client *xds.WrappedClientImpl
}
// NewMeshRouter construct an NewConnCheckRouter via url
func NewMeshRouter() (router.PriorityRouter, error) {
xdsWrappedClient := xds.GetXDSWrappedClient()
if xdsWrappedClient == nil {
logger.Debugf("[Mesh Router] xds wrapped client is not created.")
}
return &MeshRouter{
client: xdsWrappedClient,
}, nil
}
// Route gets a list of routed invoker
func (r *MeshRouter) Route(invokers []protocol.Invoker, url *common.URL, invocation protocol.Invocation) []protocol.Invoker {
if r.client == nil {
return invokers
}
hostAddr, err := r.client.GetHostAddrByServiceUniqueKey(common.GetSubscribeName(url))
if err != nil {
// todo deal with error
return nil
}
rconf := r.client.GetRouterConfig(hostAddr)
clusterInvokerMap := make(map[string][]protocol.Invoker)
for _, v := range invokers {
meshClusterID := v.GetURL().GetParam(constant.MeshClusterIDKey, "")
if _, ok := clusterInvokerMap[meshClusterID]; !ok {
clusterInvokerMap[meshClusterID] = make([]protocol.Invoker, 0)
}
clusterInvokerMap[meshClusterID] = append(clusterInvokerMap[meshClusterID], v)
}
route, err := r.client.MatchRoute(rconf, invocation)
if err != nil {
logger.Errorf("[Mesh Router] not found route,method=%s", invocation.MethodName())
return nil
}
// Loop through routes in order and select first match.
if route == nil || route.WeightedClusters == nil {
logger.Errorf("[Mesh Router] route's WeightedClusters is empty, route: %+v", r)
return invokers
}
invokersWeightPairs := make(invokerWeightPairs, 0)
for clusterID, weight := range route.WeightedClusters {
// cluster -> invokers
targetInvokers := clusterInvokerMap[clusterID]
invokersWeightPairs = append(invokersWeightPairs, invokerWeightPair{
invokers: targetInvokers,
weight: weight.Weight,
})
}
return invokersWeightPairs.GetInvokers()
}
// Process there is no process needs for uniform Router, as it upper struct RouterChain has done it
func (r *MeshRouter) Process(event *config_center.ConfigChangeEvent) {
}
// Name get name of ConnCheckerRouter
func (r *MeshRouter) Name() string {
return name
}
// Priority get Router priority level
func (r *MeshRouter) Priority() int64 {
return 0
}
// URL Return URL in router
func (r *MeshRouter) URL() *common.URL {
return nil
}
// Notify the router the invoker list
func (r *MeshRouter) Notify(invokers []protocol.Invoker) {
}
type invokerWeightPair struct {
invokers []protocol.Invoker
weight uint32
}
type invokerWeightPairs []invokerWeightPair
func (i *invokerWeightPairs) GetInvokers() []protocol.Invoker {
if len(*i) == 0 {
return nil
}
totalWeight := uint32(0)
tempWeight := uint32(0)
for _, v := range *i {
totalWeight += v.weight
}
randFloat := rand.Float64()
for _, v := range *i {
tempWeight += v.weight
tempPercent := float64(tempWeight) / float64(totalWeight)
if tempPercent >= randFloat {
return v.invokers
}
}
return (*i)[0].invokers
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/git4chen/dubbo-go.git
git@gitee.com:git4chen/dubbo-go.git
git4chen
dubbo-go
dubbo-go
v1.0.0

搜索帮助