广告
返回顶部
首页 > 资讯 > 数据库 >Go语言中怎么开启TCPkeepalive
  • 274
分享到

Go语言中怎么开启TCPkeepalive

2024-04-02 19:04:59 274人浏览 独家记忆
摘要

这篇文章将为大家详细讲解有关Go语言中怎么开启tcpkeepalive,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。TCP-keepalive — 一个轻量

这篇文章将为大家详细讲解有关Go语言中怎么开启tcpkeepalive,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

TCP-keepalive — 一个轻量级的 ping

TCP keepalive发送没有(或者几乎没有)包体负载的 TCP 报文给对端,并且对端会回复 keepaliveACK确认包。它不是 TCP 标准的一部分(尽管在RFC1122

在它的大部分实现中,简单来说,有三个主要参数:

Idle time(空闲时间) - 接收一个包后,等待多长时间发出一个 ping 包。Retry interval(重试间隔时间) - 如果发送了一个 ping,但是没有收到对端回复的ACK,在重试间隔时间之后重新发送 ping。Ping amount(重试次数) - 重试次数(没有收到对端ACK)达到多少次后,我们认为这个连接不存活了。

举个例子,空闲时间是 30 秒,重试间隔时间是 5 秒,重试次数为 3。以下是它的工作方式:

服务端收到客户端的一包应用层数据。然后客户端不再发送任何数据。服务端等待 30 秒。然后发送一个 ping 给客户端。如果服务端收到了ACK,则服务端等待另一个 30 秒,再次发送 ping;如果在这 30 秒内服务端收到了数据,则 30 秒的定时器被重置。

如果服务端没有收到ACK,等待 5 秒后再次发送 ping。如果再过 5 秒还是没有收到回复?发送最后一个 ping 并等待最后一个 5 秒(是的,在最后一个 ping 也需要等待重试间隔时间)。然后我们认为这个连接超时了并且在服务端断开它。

默认值

据说 Window 系统在发送 keepalive ping 之前默认等待 2 小时。linux 下获取默认值十分简单,就像此处 3.1.1 节

# Idle timecat /proc/sys/net/ipv4/tcp_keepalive_time# Retry intervalcat /proc/sys/net/ipv4/tcp_keepalive_intvl# Ping amountcat /proc/sys/net/ipv4/tcp_keepalive_probes

在 Go 语言中如何设置?

由于我最近使用 Go 语言比较多,我需要在 Go 语言中运用 TCP keepalive。

讨论开始之前需要说明,以下内容适用于 Linux。我不是百分百确定它是否适用于 OSX,但我几乎可以肯定它不适用于 windows

连接的特殊类型

首先,我注意到我在服务端程序中只使用了net.Conn

这意味着,我们需要使用ListenTCP

Go 语言提供的方法

如果你翻看文档可能会注意到这两个相关的方法:SeTKEepAlive

但是接下来的func (c *TCPConn) SetKeepAlivePeriod(d time.Duration) error就有些令人困惑了。我们用它究竟设置的是什么?答案可以在这篇文章和重试间隔时间。而重试间隔次数则使用系统的默认值。所以如果我设置5 * time.Second。那么它可能是等待 5 秒钟,发送 ping 并等待另一个 5 秒。并且 8 次重试(取决于系统设置)。而我需要更大的灵活性,设置得更精准。

进入系统层面

可以通过直接操作 Socket 参数来实现。我没有关注里面太多的细节,这纯粹是我的个人解释。以下是我们如何设置空闲时间为 30 秒(我们可以通过SetKeepAlivePeriod设置,因为其他参数我们再另外设置),重试时间间隔设置为 5 秒,重试次数设置为 3。我偷了(啊呸,是参考了)上面所引用的文章中的一些代码,多谢。

conn.SetKeepAlive(true)conn.SetKeepAlivePeriod(time.Second * 30) // Getting the file handle of the socket sockFile, sockErr := conn.File() if sockErr == nil { // got socket file handle. Getting descriptor. fd := int(sockFile.Fd()) // Ping amount err := syscall.SetsockoptInt(fd, syscall.IPPROTO_TCP, syscall.TCP_KEEPCNT, 3) if err != nil {        Warning("on setting keepalive probe count", err.Error())    } // Retry interval err = syscall.SetsockoptInt(fd, syscall.IPPROTO_TCP, syscall.TCP_KEEPINTVL, 5) if err != nil {        Warning("on setting keepalive retry interval", err.Error())    } // don't forget to close the file. No worries, it will *not* cause the connection to close. sockFile.Close()} else {    Warning("on setting socket keepalive", sockErr.Error())}

在这段代码之后的某一行我会写上dataLength, err := conn.Read(readBuf),这行代码会阻塞直到收到数据或者发生错误。如果是 keepalive 引起的错误,err.Error()将会包含连接超时信息。

关于文件描述符的坑

上面的代码只有在你不频繁调用的前提下才运行良好。在写完这篇文章之后,我以困难模式学习到了一个关于它的小问题。。。

问题就隐藏在Fd

func (f *File) Fd() uintptr { if f == nil { return ^(uintptr(0))    } // If we put the file descriptor into nonblocking mode, // then set it to blocking mode before we return it, // because historically we have always returned a descriptor // opened in blocking mode. The File will continue to work, // but any blocking operation will tie up a thread. if f.nonblock {        f.pfd.SetBlocking()    } return uintptr(f.pfd.Sysfd)}

如果文件描述符处于非阻塞模式,会将它修改为阻塞模式。根据stackoverflow 的这个回答的所属系统线程从调度池中移出。如果调度池中的系统线程数小于GOMAXPROCS,则会创建新的系统线程。鉴于我的每一个连接都使用一个独立协程,你可以想象一下这个爆炸速度。将很快到达 10000 线程的限制然后 panic。

将它放入独立协程并不好使。

但是有一个方法是可行的。注意,前提是 Go 版本高于 1.11。看以下代码。

//Sets additional keepalive parameters. //Uses new interfaces introduced in Go1.11, which let us get connection's file descriptor, //without blocking, and therefore without uncontrolled spawning of threads (not goroutines, actual threads). func setKeepaliveParameters(conn devconn) {    rawConn, err := conn.SyscallConn() if err != nil {        Warning("on getting raw connection object for keepalive parameter setting", err.Error())    }    rawConn.Control( func(fdPtr uintptr) { // got socket file descriptor. Setting parameters. fd := int(fdPtr) //Number of probes. err := syscall.SetsockoptInt(fd, syscall.IPPROTO_TCP, syscall.TCP_KEEPCNT, 3) if err != nil {                Warning("on setting keepalive probe count", err.Error())            } //Wait time after an unsuccessful probe. err = syscall.SetsockoptInt(fd, syscall.IPPROTO_TCP, syscall.TCP_KEEPINTVL, 3) if err != nil {                Warning("on setting keepalive retry interval", err.Error())            }        })} func deviceProcessor(conn devconn) { //............ conn.SetKeepAlive(true)    conn.SetKeepAlivePeriod(time.Second * 30)    setKeepaliveParameters(conn) //............ dataLen, err := conn.Read(readBuf) //............ }

最新版本的 Go 提供了一些新接口,net.TCPConn实现了SyscallConn

关于Go语言中怎么开启TCPkeepalive就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

您可能感兴趣的文档:

--结束END--

本文标题: Go语言中怎么开启TCPkeepalive

本文链接: https://www.lsjlt.com/news/56715.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Go语言中怎么开启TCPkeepalive
    这篇文章将为大家详细讲解有关Go语言中怎么开启TCPkeepalive,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。TCP-keepalive — 一个轻量...
    99+
    2022-10-18
  • go语言怎么启动web服务
    这篇文章主要介绍“go语言怎么启动web服务”,在日常操作中,相信很多人在go语言怎么启动web服务问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”go语言怎么启动web服务”的疑惑有所帮助!接下来,请跟着小编...
    99+
    2023-07-04
  • go语言怎么进行web开发
    Go语言的Web开发流程为:1、选择Web框架;2、设计路由,指定URL如何映射到处理程序;3、处理请求和响应,包括解析请求参数、处理表单数据、设置Cookie等;4、数据库操作,将数据存储在数据库中;5、模板渲染,将数据呈现给用户使用模板...
    99+
    2023-12-13
    go语言web开发 go语言 Golang
  • go语言微服务怎么开发
    go语言微服务开发步骤:1、定义微服务接口;2、创建项目结构来组织微服务代码;3、使用HTTP或RPC进行通信;4、实现业务逻辑,包括处理请求、访问数据库、调用其他微服务等;5、数据库访问,使用数据库驱动程序来连接和操作数据库;6、利用错误...
    99+
    2023-12-12
    go语言 Golang
  • go语言怎么进行爬虫开发
    go语言进行爬虫开发步骤如下:1、选择合适的库,如GoQuery、Colly、PuerkitoBio和Gocolly等;2、选择合适的库,并获取到返回的响应数据;3、解析HTML,从网页中提取所需的信息;4、并发处理,极大地提高爬取效率;5...
    99+
    2023-12-13
    golang爬虫 go语言 Golang
  • Go语言中的:=怎么用
    这篇文章主要为大家展示了“Go语言中的:=怎么用”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Go语言中的:=怎么用”这篇文章吧。1. 单变量 :=Go 语言中新增了一个特殊的运算符:=,这个运...
    99+
    2023-06-22
  • go语言中goto怎么用
    本教程操作环境:windows7系统、GO 1.18版本、Dell G3电脑。go语言中的goto语句goto 顾言思义,是跳转的意思。Go 语言的 goto 语句可以无条件地转移到程序中指定的行,通过标签进行代码间的无条件跳转,同时 go...
    99+
    2022-11-23
    goto go语言
  • go语言中if怎么用
    在go语言中,关键字if用于测试某个条件(布尔型 或逻辑型)是否成立,如果该条件成立,则会执行if后由大括号“{}”括起来的代码块,否则就忽略该代码块继续执行后续的代码,语法“if condition {...}”。if语句用于选择单分支,...
    99+
    2023-05-14
    Golang go语言
  • go语言怎么调用c语言
    Go语言可以通过使用cgo工具以及一些特定的语法来调用C语言代码。 以下是调用C语言的Go代码示例: 创建一个名为 `callc....
    99+
    2023-10-27
    go语言 c语言
  • Go语言中go fmt命令怎么用
    这篇文章主要为大家展示了“Go语言中go fmt命令怎么用”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Go语言中go fmt命令怎么用”这篇文章吧。go fmt命令主要是用来帮你格式化所写好的...
    99+
    2023-06-25
  • Go语言中go build命令怎么用
    这篇文章主要介绍了Go语言中go build命令怎么用,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。go build 用于测试编译多个包或一个main包2. build命令编...
    99+
    2023-06-25
  • Go语言中go install命令怎么用
    小编给大家分享一下Go语言中go install命令怎么用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!go install编译并安装代码包,对于库,会生成目标库...
    99+
    2023-06-25
  • go语言怎么样
    Go语言是一种简洁、高效、可靠的编程语言,适用于构建高性能、高并发和可扩展的软件系统。在并发编程、网络编程和大型项目开发方面具有显著优势,并且具有跨平台部署的能力。详细介绍:1、简洁易读,用了清晰的语法结构和简洁的关键字,使得代码易于编写、...
    99+
    2023-12-12
    go语言 Golang
  • Go语言中defer语句怎么使用
    今天小编给大家分享一下Go语言中defer语句怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。1.在一个函数内的def...
    99+
    2023-07-02
  • go语言代码怎么转c语言
    go语言代码转c语言方法:1、将Go代码转换为LLVM IR;2、使用LLVM提供的工具将LLVM IR转换为C语言代码;3、使用C语言编译器(如GCC)将生成的C代码编译成可执行文件。本教程操作环境:windows10系统、golang1...
    99+
    2023-07-10
  • 开发go语言用什么ide
    go语言的ide有Visual Studio Code、GoLand、LiteIDE、Atom、Sublime Text、Emacs等等。详细介绍:1、VSCode,轻量级且功能强大的开源代码编辑器,支持Go语言的语法高亮、代码自动完成、调...
    99+
    2023-12-12
    go语言 Golang
  • go语言可以开发什么
    go语言可以开发后端服务、分布式系统、数据库系统、命令行工具、云原生应用、网络编程和机器学习和人工智能。详细介绍:1、后端服务,可以帮助开发人员快速构建可扩展的Web应用程序和API服务;2、分布式系统,提供了丰富的网络库和并发原语,使得开...
    99+
    2023-12-12
    go语言 Golang
  • CentOS6.8中怎么安装GO语言
    这篇文章主要讲解了“CentOS6.8中怎么安装GO语言”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“CentOS6.8中怎么安装GO语言”吧!Go 语言被设计成一门应用于搭载 Web 服务...
    99+
    2023-06-27
  • go语言中mysql怎么使用
    本篇内容介绍了“go语言中mysql怎么使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!golang支持多种数据库MySQLMySQL是一...
    99+
    2023-07-04
  • Go语言中goroutine怎么创建
    这篇“Go语言中goroutine怎么创建”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Go语言中goroutine怎么创建...
    99+
    2023-07-04
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作