golang RPC通信读写超时设置
golang RPC通信中,有时候就怕读写hang住。
那是否可以设置读写超时呢?
1.方案一: 设置连接的读写超时
1.1 client
RPC通信基于底层网络通信,可以通过设置connection的读写超时时间,达到RPC读写超时的目的。更多细节可参考golang网络通信超时设置.
下面以client端的读超时为例,介绍设置方法。
server端和client端代码如下。
server
一个简单的json RPC server。
package main
import (
"fmt"
"log"
"net"
"net/rpc"
"net/rpc/jsonrpc"
"time"
)
type Counter struct {
Sum int
}
func (this *Counter) Add(i int, r *int) error {
//sleep
time.Sleep(3*time.Second)
if i < 0 {
return fmt.Errorf("data format incorrect")
}
this.Sum += i
*r = this.Sum
log.Printf("i: %v\n", i)
return nil
}
func NewJsonRpcSocketServer() {
rpc.Register(new(Counter))
l, err := net.Listen("tcp", ":3333")
if err != nil {
log.Printf("Listener tcp err: %s", err)
return
}
for {
log.Println("waiting...")
conn, err := l.Accept()
if err != nil {
log.Printf("accept connection err: %s\n", conn)
continue
}
go jsonrpc.ServeConn(conn)
}
}
func main() {
NewJsonRpcSocketServer()
}
client
json RPC client。
连接建立后,会设置connection的读超时时间。
package main
import (
"log"
"net"
"net/rpc/jsonrpc"
"time"
)
func main() {
NewJsonRpcSocketClient()
}
func NewJsonRpcSocketClient() {
timeout := time.Second*30
conn, err := net.DialTimeout("tcp", "127.0.0.1:3333", timeout)
if err != nil {
log.Printf("create client err:%s\n", err)
return
}
defer conn.Close()
// timeout
readAndWriteTimeout := 2*time.Second
err = conn.SetDeadline(time.Now().Add(readAndWriteTimeout))
if err != nil {
log.Println("SetDeadline failed:", err)
}
client := jsonrpc.NewClient(conn)
var reply int
err = client.Call("Counter.Add", 2, &reply)
if err != nil {
log.Println("error:", err, "reply:", reply)
return
}
log.Printf("reply: %d, err: %v\n", reply, err)
}
client输出:
2019/05/12 22:52:57 error: read tcp 127.0.0.1:55226->127.0.0.1:3333: i/o timeout reply: 0
1.2 server
通常情况下,RPC server端的代码如下:
server := rpc.NewServer()
... ....
for {
conn, err := l.Accept()
if err != nil {
log.Println("listener accept fail:", err)
time.Sleep(time.Duration(100) * time.Millisecond)
continue
}
// timeout
timeout := 10*time.Second
conn.SetDeadline(time.Now().Add(timeout))
go server.ServeCodec(jsonrpc.NewServerCodec(conn))
}
这样,如果设置超时,只有效的影响一次。
对于server来说,都是多次读写。所以,暂时没有方法设置。
2.方案二:定时器
通过定时器的方式,如果RPC调用在指定时间内没有完成,触发定时器,返回超时错误,关闭连接。
2.1 client端
func RpcCall(method string, args interface{}, reply interface{}) error {
... ...
timeout := time.Duration(10 * time.Second)
done := make(chan error, 1)
go func() {
err := rpcClient.Call(method, args, reply)
done <- err
}()
select {
case <-time.After(timeout):
log.Printf("[WARN] rpc call timeout %v => %v", rpcClient, RpcServer)
rpcClient.Close()
return fmt.Errorf("timeout")
case err := <-done:
if err != nil {
rpcClient.Close()
return err
}
}
return nil
}
2.2 server端
无论是gobServerCodec 或者 jsonrpc ,都是实现了ServerCodec接口。
gobServerCodec文件路径:/usr/local/go/src/net/rpc/server.go
jsonrpc文件路径:/usr/local/go/src/net/rpc/server.go
要给server端RPC读写加上超时机制,需要重新定义ServerCodec接口,加上超时的控制。
// A ServerCodec implements reading of RPC requests and writing of
// RPC responses for the server side of an RPC session.
// The server calls ReadRequestHeader and ReadRequestBody in pairs
// to read requests from the connection, and it calls WriteResponse to
// write a response back. The server calls Close when finished with the
// connection. ReadRequestBody may be called with a nil
// argument to force the body of the request to be read and discarded.
type ServerCodec interface {
ReadRequestHeader(*Request) error
ReadRequestBody(interface{}) error
// WriteResponse must be safe for concurrent use by multiple goroutines.
WriteResponse(*Response, interface{}) error
Close() error
}
目前,已经有现成的实现方式,可参考Golang标准库RPC实践及改进
3.参考
Does RPC have a timeout mechanism?
golang RPC通信读写超时设置的更多相关文章
- golang网络通信超时设置
网络通信中,为了防止长时间无响应的情况,经常会用到网络连接超时.读写超时的设置. 本文结合例子简介golang的连接超时和读写超时设置. 1.超时设置 1.1 连接超时 func DialTimeou ...
- RPC通信功能实现
Table of Contents RPC通信功能实现 配置參数 调用方法 RPC通信功能实现 HBase的RPC通信功能主要基于Protobuf和NIO这两个组件来实现.在通信管道上选择的是prot ...
- [转]JDBC如何进行超时设置
文档来源:https://jingyan.baidu.com/article/fc07f98922615a12ffe519ce.html 恰当的JDBC超时设置能够有效地减少服务失效的时间.本文将对数 ...
- RPC通信原理(未完,先睡觉)
一 背景 OpenStack 各组件之间是通过 REST 接口进行相互通信,比如Nova.Cinder.Neutron.Glance直间的通信都是通过keystone获取目标的endpoint,即ap ...
- 深入理解JDBC的超时设置
恰当的JDBC超时设置能够有效地减少服务失效的时间.本文将对数据库的各种超时设置及其设置方法做介绍. 真实案例:应用服务器在遭到DDos攻击后无法响应 在遭到DDos攻击后,整个服务都垮掉了.由于第四 ...
- JDBC超时设置【转】
恰当的JDBC超时设置能够有效地减少服务失效的时间.本文将对数据库的各种超时设置及其设置方法做介绍. 真实案例:应用服务器在遭到DDos攻击后无法响应 在遭到DDos攻击后,整个服务都垮掉了.由于第四 ...
- Spring Cloud 系列之 Dubbo RPC 通信
Dubbo 介绍 官网:http://dubbo.apache.org/zh-cn/ Github:https://github.com/apache/dubbo 2018 年 2 月 15 日,阿里 ...
- Linux串口中的超时设置
在Linux下使用串口通信时,默认的阻塞模式是不实用的.而采用select或epoll机制的非阻塞模式,写代码有比较麻烦.幸好Linux的串口自己就带有超时机制. Linux下使用termios.h中 ...
- PHP与Golang如何通信?
PHP与Golang如何通信? 最近遇到的一个场景:php项目中需要使用一个第三方的功能(结巴分词),而github上面恰好有一个用Golang写好的类库.那么问题就来了,要如何实现不同语言之间的通信 ...
随机推荐
- 多线程编程-- part 4 线程间的通信
线程间的相互作用 线程之间需要一些协调通信,来共同完成一件任务. Object类相关的方法:notify(),notifyAll(),wait().会被所有的类继承,这些方法是final不能被重写.他 ...
- Nginx请求限制配置
Nginx请求限制配置 请求限制可以通过两种方式来配置,分别是 连接频率限制和请求频率限制 首先我们要知道什么是http请求和连接,浏览器和服务端首先通过三次握手完成连接,然后发起请求,传输请求参数 ...
- Nginx编译参数详解
Nginx编译参数 1.当我们安装好nginx后,输入命令 nginx -V 可以看到nginx的编译参数信息,例如 如下图 2. 编译参数如下图 # Nginx安装目的目录或路径 --prefix ...
- Mybatis实际练习
1.mybatis在xml文件中处理大于号小于号的方法 第一种方法: 用了转义字符把>和<替换掉,然后就没有问题了. SELECT * FROM test WHERE 1 = 1 AND ...
- 31、NTP时间服务器
1.NTP简介 NTP服务器顾名思义就是时间同步服务器(Network Time Protocol),Linux下的ntp服务器配置相对来说都比较容易,但在Linux下有一个弊端,不同时区或者说是时间 ...
- Darknet版YOLO安装与配置
Darknet配置和安装 1. 安装显卡驱动 首先查看一下自己的电脑需要怎样的驱动,我们可以先到 http://www.nvidia.com/Download/index.aspx 查询下我们需要的是 ...
- deep_learning_Function_tf.add()、tf.subtract()、tf.multiply()、tf.div()
tf.add().tf.subtract().tf.multiply().tf.div()函数介绍和示例 1. tf.add() 释义:加法操作 示例: x = tf.constant(2, dtyp ...
- 屏蔽iOS升级方法
1.iPhone或者iPad使用safari浏览器打开http://d.updater.i4.cn/i4tools7/temp/tvos.mobileconfig 2.点击[允许] 3.进入[通用]- ...
- libusb读写
https://blog.csdn.net/u012247418/article/details/83684980 https://github.com/crazybaoli/libusb-test ...
- 使用GDI+加载32位的位图或者PNG图片(具有透明通道)
#include <windows.h> #include <gdiplus.h> HBITMAP LoadBitmapFromResource(DWORD ResourceI ...