聊聊dubbo-go的failfastCluster
时间:2022-07-23
本文章向大家介绍聊聊dubbo-go的failfastCluster,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
序
本文主要研究一下dubbo-go的failfastCluster
failfastCluster
dubbo-go-v1.4.2/cluster/cluster_impl/failfast_cluster.go
type failfastCluster struct{}
const failfast = "failfast"
func init() {
extension.SetCluster(failfast, NewFailFastCluster)
}
// NewFailFastCluster ...
func NewFailFastCluster() cluster.Cluster {
return &failfastCluster{}
}
func (cluster *failfastCluster) Join(directory cluster.Directory) protocol.Invoker {
return newFailFastClusterInvoker(directory)
}
- failfastCluster的Join方法执行newFailFastClusterInvoker(directory)
newFailFastClusterInvoker
dubbo-go-v1.4.2/cluster/cluster_impl/failfast_cluster_invoker.go
type failfastClusterInvoker struct {
baseClusterInvoker
}
func newFailFastClusterInvoker(directory cluster.Directory) protocol.Invoker {
return &failfastClusterInvoker{
baseClusterInvoker: newBaseClusterInvoker(directory),
}
}
- newFailFastClusterInvoker方法创建了failfastClusterInvoker
Invoke
dubbo-go-v1.4.2/cluster/cluster_impl/failfast_cluster_invoker.go
func (invoker *failfastClusterInvoker) Invoke(ctx context.Context, invocation protocol.Invocation) protocol.Result {
invokers := invoker.directory.List(invocation)
err := invoker.checkInvokers(invokers, invocation)
if err != nil {
return &protocol.RPCResult{Err: err}
}
loadbalance := getLoadBalance(invokers[0], invocation)
err = invoker.checkWhetherDestroyed()
if err != nil {
return &protocol.RPCResult{Err: err}
}
ivk := invoker.doSelect(loadbalance, invocation, invokers, nil)
return ivk.Invoke(ctx, invocation)
}
- Invoke方法先通过invoker.directory.List(invocation)获取invokers,之后通过getLoadBalance(invokers[0], invocation)获取loadbalance,再通过invoker.doSelect(loadbalance, invocation, invokers, nil)选择ivk,最后执行ivk.Invoke(ctx, invocation)
getLoadBalance
dubbo-go-v1.4.2/cluster/cluster_impl/base_cluster_invoker.go
func getLoadBalance(invoker protocol.Invoker, invocation protocol.Invocation) cluster.LoadBalance {
url := invoker.GetUrl()
methodName := invocation.MethodName()
//Get the service loadbalance config
lb := url.GetParam(constant.LOADBALANCE_KEY, constant.DEFAULT_LOADBALANCE)
//Get the service method loadbalance config if have
if v := url.GetMethodParam(methodName, constant.LOADBALANCE_KEY, ""); len(v) > 0 {
lb = v
}
return extension.GetLoadbalance(lb)
}
- getLoadBalance方法通过url获取constant.LOADBALANCE_KEY,然后通过extension.GetLoadbalance(lb)获取cluster.LoadBalance
doSelect
dubbo-go-v1.4.2/cluster/cluster_impl/base_cluster_invoker.go
func (invoker *baseClusterInvoker) doSelect(lb cluster.LoadBalance, invocation protocol.Invocation, invokers []protocol.Invoker, invoked []protocol.Invoker) protocol.Invoker {
var selectedInvoker protocol.Invoker
url := invokers[0].GetUrl()
sticky := url.GetParamBool(constant.STICKY_KEY, false)
//Get the service method sticky config if have
sticky = url.GetMethodParamBool(invocation.MethodName(), constant.STICKY_KEY, sticky)
if invoker.stickyInvoker != nil && !isInvoked(invoker.stickyInvoker, invokers) {
invoker.stickyInvoker = nil
}
if sticky && invoker.stickyInvoker != nil && (invoked == nil || !isInvoked(invoker.stickyInvoker, invoked)) {
if invoker.availablecheck && invoker.stickyInvoker.IsAvailable() {
return invoker.stickyInvoker
}
}
selectedInvoker = invoker.doSelectInvoker(lb, invocation, invokers, invoked)
if sticky {
invoker.stickyInvoker = selectedInvoker
}
return selectedInvoker
}
- doSelect方法先判断是否sticky,是的话且invoker.stickyInvoker不为nil且available,则返回stickyInvoker,否则通过invoker.doSelectInvoker(lb, invocation, invokers, invoked)获取selectedInvoker
doSelectInvoker
dubbo-go-v1.4.2/cluster/cluster_impl/base_cluster_invoker.go
func (invoker *baseClusterInvoker) doSelectInvoker(lb cluster.LoadBalance, invocation protocol.Invocation, invokers []protocol.Invoker, invoked []protocol.Invoker) protocol.Invoker {
if len(invokers) == 1 {
return invokers[0]
}
selectedInvoker := lb.Select(invokers, invocation)
//judge to if the selectedInvoker is invoked
if (!selectedInvoker.IsAvailable() && invoker.availablecheck) || isInvoked(selectedInvoker, invoked) {
// do reselect
var reslectInvokers []protocol.Invoker
for _, invoker := range invokers {
if !invoker.IsAvailable() {
continue
}
if !isInvoked(invoker, invoked) {
reslectInvokers = append(reslectInvokers, invoker)
}
}
if len(reslectInvokers) > 0 {
selectedInvoker = lb.Select(reslectInvokers, invocation)
} else {
return nil
}
}
return selectedInvoker
}
- doSelectInvoker方法通过lb.Select(invokers, invocation)选择selectedInvoker,如果selectedInvoker已经invoked或者非available,则遍历invokers重新构造reslectInvokers,再通过lb.Select(reslectInvokers, invocation)选择selectedInvoker
小结
failfastCluster的Join方法执行newFailFastClusterInvoker(directory);failfastClusterInvoker的Invoke方法先通过invoker.directory.List(invocation)获取invokers,之后通过getLoadBalance(invokers[0], invocation)获取loadbalance,再通过invoker.doSelect(loadbalance, invocation, invokers, nil)选择ivk,最后执行ivk.Invoke(ctx, invocation)
doc
- failfast_cluster
- 设计模式学习(三): 装饰者模式 (附C#实现)
- 浅谈非PE的攻击技巧
- hbase源码系列(十)HLog与日志恢复
- hbase源码系列(六)HMaster启动过程
- 如何写好一篇漏洞报告(国外篇)
- hbase源码系列(八)从Snapshot恢复表
- hbase源码系列(七)Snapshot的过程
- CVE-2017-3085:Adobe Flash泄漏Windows用户凭证
- hbase源码系列(九)StoreFile存储格式
- 如何确定恶意软件是否在自己的电脑中执行过?
- Carbondata源码系列(二)文件格式详解
- 挖洞经验 | 记一次针对Twitter(Periscope)API 的有趣挖洞经历
- 设计模式学习(二): 观察者模式 (C#)
- Carbondata源码系列(一)文件生成过程
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 以OpenResty搭建RTB竞价引擎接入层
- 优化Linux bootloader速度的究极之路:从GRUB到EFI Stub
- Linux--nc命令
- Netty之美--I/O模型
- 023.基于IT论坛案例学习Elasticsearch(二):Query高级知识(一)
- 打卡群刷题总结0807——验证二叉搜索树
- 打卡群刷题总结0808——二叉树的层序遍历
- Mybatis高级查询(四):延迟加载
- I/O多路复用器之隐秘的角落
- 打卡群刷题总结0809——二叉树的锯齿形层次遍历
- 简单的ssm整合练手项目:汽车项目
- 在spring-boot中使用pageHelper插件
- 要深入 JavaScript,你需要掌握这 36 个概念
- mybatis-plus实现增删改查
- mybatis-plus代码生成器