聊聊dubbo-go的DubboInvoker
时间:2022-07-22
本文章向大家介绍聊聊dubbo-go的DubboInvoker,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
序
本文主要研究一下dubbo-go的DubboInvoker
Invoker
dubbo-go-v1.4.2/protocol/invoker.go
// Extension - Invoker
type Invoker interface {
common.Node
Invoke(context.Context, Invocation) Result
}
/////////////////////////////
// base invoker
/////////////////////////////
// BaseInvoker ...
type BaseInvoker struct {
url common.URL
available bool
destroyed bool
}
// NewBaseInvoker ...
func NewBaseInvoker(url common.URL) *BaseInvoker {
return &BaseInvoker{
url: url,
available: true,
destroyed: false,
}
}
// GetUrl ...
func (bi *BaseInvoker) GetUrl() common.URL {
return bi.url
}
// IsAvailable ...
func (bi *BaseInvoker) IsAvailable() bool {
return bi.available
}
// IsDestroyed ...
func (bi *BaseInvoker) IsDestroyed() bool {
return bi.destroyed
}
// Invoke ...
func (bi *BaseInvoker) Invoke(context context.Context, invocation Invocation) Result {
return &RPCResult{}
}
// Destroy ...
func (bi *BaseInvoker) Destroy() {
logger.Infof("Destroy invoker: %s", bi.GetUrl().String())
bi.destroyed = true
bi.available = false
}
- Invoker定义了Invoke方法;BaseInvoker定义了url、available、destroyed属性;NewBaseInvoker方法实例化了BaseInvoker,其available为true,destroyed为false;Destroy方法设置available为false,destroyed为true
DubboInvoker
dubbo-go-v1.4.2/protocol/dubbo/dubbo_invoker.go
var (
// ErrNoReply ...
ErrNoReply = perrors.New("request need @response")
ErrDestroyedInvoker = perrors.New("request Destroyed invoker")
)
var (
attachmentKey = []string{constant.INTERFACE_KEY, constant.GROUP_KEY, constant.TOKEN_KEY, constant.TIMEOUT_KEY}
)
// DubboInvoker ...
type DubboInvoker struct {
protocol.BaseInvoker
client *Client
quitOnce sync.Once
// Used to record the number of requests. -1 represent this DubboInvoker is destroyed
reqNum int64
}
- DubboInvoker定义了client、quitOnce、reqNum属性
NewDubboInvoker
dubbo-go-v1.4.2/protocol/dubbo/dubbo_invoker.go
// NewDubboInvoker ...
func NewDubboInvoker(url common.URL, client *Client) *DubboInvoker {
return &DubboInvoker{
BaseInvoker: *protocol.NewBaseInvoker(url),
client: client,
reqNum: 0,
}
}
- NewDubboInvoker方法实例化DubboInvoker
Invoke
dubbo-go-v1.4.2/protocol/dubbo/dubbo_invoker.go
// Invoke ...
func (di *DubboInvoker) Invoke(ctx context.Context, invocation protocol.Invocation) protocol.Result {
var (
err error
result protocol.RPCResult
)
if di.reqNum < 0 {
// Generally, the case will not happen, because the invoker has been removed
// from the invoker list before destroy,so no new request will enter the destroyed invoker
logger.Warnf("this dubboInvoker is destroyed")
result.Err = ErrDestroyedInvoker
return &result
}
atomic.AddInt64(&(di.reqNum), 1)
defer atomic.AddInt64(&(di.reqNum), -1)
inv := invocation.(*invocation_impl.RPCInvocation)
for _, k := range attachmentKey {
if v := di.GetUrl().GetParam(k, ""); len(v) > 0 {
inv.SetAttachments(k, v)
}
}
// put the ctx into attachment
di.appendCtx(ctx, inv)
url := di.GetUrl()
// async
async, err := strconv.ParseBool(inv.AttachmentsByKey(constant.ASYNC_KEY, "false"))
if err != nil {
logger.Errorf("ParseBool - error: %v", err)
async = false
}
response := NewResponse(inv.Reply(), nil)
if async {
if callBack, ok := inv.CallBack().(func(response common.CallbackResponse)); ok {
result.Err = di.client.AsyncCall(NewRequest(url.Location, url, inv.MethodName(), inv.Arguments(), inv.Attachments()), callBack, response)
} else {
result.Err = di.client.CallOneway(NewRequest(url.Location, url, inv.MethodName(), inv.Arguments(), inv.Attachments()))
}
} else {
if inv.Reply() == nil {
result.Err = ErrNoReply
} else {
result.Err = di.client.Call(NewRequest(url.Location, url, inv.MethodName(), inv.Arguments(), inv.Attachments()), response)
}
}
if result.Err == nil {
result.Rest = inv.Reply()
result.Attrs = response.atta
}
logger.Debugf("result.Err: %v, result.Rest: %v", result.Err, result.Rest)
return &result
}
- Invoke方法先通过atomic.AddInt64递增reqNum,之后遍历attachmentKey设置到invocation;之后读取constant.ASYNC_KEY属性,若async为true,则执行di.client.AsyncCall或di.client.CallOneway;若async为false则执行di.client.Call;最后返回result
Destroy
dubbo-go-v1.4.2/protocol/dubbo/dubbo_invoker.go
// Destroy ...
func (di *DubboInvoker) Destroy() {
di.quitOnce.Do(func() {
for {
if di.reqNum == 0 {
di.reqNum = -1
logger.Infof("dubboInvoker is destroyed,url:{%s}", di.GetUrl().Key())
di.BaseInvoker.Destroy()
if di.client != nil {
di.client.Close()
di.client = nil
}
break
}
logger.Warnf("DubboInvoker is to be destroyed, wait {%v} req end,url:{%s}", di.reqNum, di.GetUrl().Key())
time.Sleep(1 * time.Second)
}
})
}
- Destroy方法在di.reqNum为0时执行di.BaseInvoker.Destroy()及di.client.Close()
小结
Invoker定义了Invoke方法;BaseInvoker定义了url、available、destroyed属性;NewBaseInvoker方法实例化了BaseInvoker,其available为true,destroyed为false;Destroy方法设置available为false,destroyed为true;DubboInvoker的Invoke方法先通过atomic.AddInt64递增reqNum,之后遍历attachmentKey设置到invocation;之后读取constant.ASYNC_KEY属性,若async为true,则执行di.client.AsyncCall或di.client.CallOneway;若async为false则执行di.client.Call;最后返回result
doc
- gitbook安装与使用,并使用docker部署
- 【专业技术】在C/C++程序中打印当前函数调用栈
- 关于定位position的相关知识
- Docker+Jenkins持续集成环境(1)使用Docker搭建Jenkins+Docker持续集成环境
- 段落首字下沉
- 【编程基础】C语言指针、引用和取值
- Docker+Jenkins持续集成环境(2)使用docker+jenkins构建nodejs前端项目
- JavaScript中的this详解
- 使用SpringBoot开发REST服务
- CSS3 -webkit-filter 滤镜
- Docker+Jenkins持续集成环境(3)集成PMD、FindBugs、Checkstyle静态代码检查工具并邮件发送检查结果
- Javascript中的Label语句
- 从编辑距离、BK树到文本纠错
- iframe基本知识及iframe版本Tab切换
- 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 数组属性和方法
- Docker 部署SpringBoot项目不香吗?
- 面试官写了个双冒号::问我这是什么语法?Java中有这玩意?
- 精解四大集合框架:List核心知识总结
- 【深度学习】Keras vs PyTorch vs Caffe:CNN实现对比
- 【深度学习】迁移学习理论与实践
- 使用OpenCV+Tensorflow跟踪排球的轨迹
- 基于OpenCV的手掌检测和手指计数
- 错误诊断:索引数据错误导致ORA-00600 [kdsgrp1]处理
- Python让你成为AI 绘画大师,简直太惊艳了!(附代码))
- PostgreSQL全局临时表插件pgtt的使用
- 首次在手机端不牺牲准确率实现BERT实时推理,比TensorFlow-Lite快近8倍,每帧只需45ms
- 【小白学PyTorch】7.最新版本torchvision.transforms常用API翻译与讲解
- 【SOT】siameseFC论文和代码解析
- 基于OpenCV创建视频会议虚拟背景
- 【算法】图文并茂,一文了解 8 种常见的数据结构