博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Go实现FastCgi Proxy Client 系列(四) keep-alive实现
阅读量:6266 次
发布时间:2019-06-22

本文共 2378 字,大约阅读时间需要 7 分钟。

hot3.png

先贴几个链接

前三篇

灵感帖

很感谢上面几个文章,让我突然想通了我之前一直没搞懂的问题,虽然问题不是一种,但是也算是旁敲侧击的让我茅塞顿开了,非常感谢!

分析

协议

麻省理工学院的文档上是这么描述的:

The flags component contains a bit that controls connection shutdown:

flags & FCGI_KEEP_CONN: If zero, the application closes the connection after responding to this request. If not zero, the application does not close the connection after responding to this request; the Web server retains responsibility for the connection.

好吧,高大上的描述。各种文档里对fastcgi协议里没怎么讲keep-alive的作用,就只是很简单的说了,如果是开启了,就能让http连接进行复用。然而按照之前的知识(我没跟上时代啊),http协议是无状态的协议,死活我也是想不通如何连接复用。

然而我忘记了,http也是基于tcp协议的,tcp一般而言,如果你不手动进行断开,或者网络原因引起的话,是会保持一个长连接的(通常都会设置超时)。

盗张图:

输入图片说明

可以看出,假如,我们不进行最后的4次挥手操作,在超时范围内,这个tcp连接是不会断开的。

代码

然后我再去看go官方对fastcgi协议的实现,我发现一个很重要的地方(源码位置 net/http/fastcgi/child.go):

当用户发起终止信号的时候,keep-alive起了作用,那就是说,我的proxy层只要不进行断开连接,这个tcp连接就依然还是可用的。

case typeAbortRequest:		//......		if !req.keepConn {			// connection will close upon return			return errCloseConn		}		return nil

然后,我继续阅读源码,此时,我要唱一下,“终于等到你,还好我没忘记”。果然是这样,如果链接不是keep-alive,会即时关闭tcp连接。

func (c *child) serveRequest(req *request, body io.ReadCloser) {	//......	if !req.keepConn {		c.conn.Close()	}}

修改实现

在我们读取数据的位置,我们进行相关操作即可,如果,请求不是keep-alive 自然,返回值会包含终止符 EOF,这时可以直接返回;反之,如果是keep-alive,则会每个请求都获得到一个typeEndRequest(值为3,具体请看)的标识

// recive untill EOF or FCGI_END_REQUEST	for {		err1 = rec.read(cgi.rwc)		//if !keep-alive the end has EOF		if err1 != nil {			if err1 != io.EOF {				err = err1			}			break		}		switch {		case rec.h.Type == typeStdout:			retout = append(retout, rec.content()...)		case rec.h.Type == typeStderr:			reterr = append(reterr, rec.content()...)		case rec.h.Type == typeEndRequest:			//if keep-alive			//It's had return			//But connection Not close			retout = append(retout, rec.content()...)			return		default:			//fallthrough		}	}

总结

个人总结

那,其实很简单不是嘛?我之前只是理解错了typeEndRequest这个类型,我把他当成了错误的时候才会返回,报了一个fallthrough。更简单的一句就是,复用的不是http,不是http,不是!复用的tcp!tcp!tcp!

然后,当遇到一个自己暂时无法理解的问题时候,可能你已经钻入了死胡同。这个时候,你可以放松自己精神,玩玩游戏,运动运动都行(哈哈,这个问题我都忘记一个月了,感谢群友的问题,虽然我没帮他解决,但是他提示了我,我还要没解决的问题)。

下一步

下一步,将会对超时进行设置。

spinx(小玩具)

一个实现对fastcgi协议的转发小玩具。

Quick Start

go get github.com/lwl1989/spinxcd $gopath/src/github.com/lwl1989/spinxgo build -o spinx main.go

Install

sudo ./spinx  -c=config_path install

Remove

sudo ./spinx  remove

Start

sudo ./spinx startor./spinx -d=false -c=config_path

Stop

sudo ./spinx stop

转载于:https://my.oschina.net/lwl1989/blog/1823443

你可能感兴趣的文章
SQL经典面试题集锦
查看>>
View学习(一)-DecorView,measureSpec与LayoutParams
查看>>
色彩力量!21款你应该知道的优秀品牌设计
查看>>
SDUT 3503 有两个正整数,求N!的K进制的位数
查看>>
【.Net】C# 根据绝对路径获取 带后缀文件名、后缀名、文件名、不带文件名的文件路径...
查看>>
Redis常用命令速查 <第二篇>
查看>>
CSS规范
查看>>
使用FastDateFormat来代替JDK自带的DateFormat
查看>>
Python爬虫从入门到放弃(十六)之 Scrapy框架中Item Pipeline用法
查看>>
Android源代码解析之(三)--&gt;异步任务AsyncTask
查看>>
(zhuan) 自然语言处理中的Attention Model:是什么及为什么
查看>>
C#中使用RabbitMQ收发队列消息
查看>>
Hadoop1.2.1 全然分布式集群搭建实操笔记
查看>>
第三百二十七节,web爬虫讲解2—urllib库爬虫—基础使用—超时设置—自动模拟http请求...
查看>>
MVC总结--MVC简单介绍以及和WebForm差别
查看>>
tiny4412 裸机程序 五、控制icache【转】
查看>>
VB.NET多线程入门
查看>>
国外物联网平台初探(二) ——微软Azure IoT
查看>>
findlibrary returned null产生的联想,Android ndk开发打包时我们应该怎样注意平台的兼容(x86,arm,arm-v7a)...
查看>>
Android事件分发机制源代码分析
查看>>