fasthttp client解析--Golang更快的http组件

1. test中调用Get方法

2. 调用clientGetURL方法

3. 首先调用AcquireRequest()方法得到一个复用的request
AcquireRequest():
1. 从requestPool中选择一个request,从pool中删掉
2. 对pool操作要加锁。
3. 若pool中没有request,那么New一个
4. pool.pin()函数:
1. 对pool进行操作前,先调用 runtime_procPin
2. 原子操作:读入localSize的值
3.返回p.poolLocal
4. 设定request的Header的参数,若为post请求,需要将参数写入到request的Body
5. 调用doRequestFollowRedirects方法处理请求,处理完之后调用ReleaseRequest(request)回收request, 减少GC压力
doRequestFollowRedirects()方法:
1. 调用AcquireResponse从responsePool中得到一个复用的response
2. 将空的byte[]写入response以清空response;
3. 设定request的Header的url参数
4. 调用client.Do方法,此处有5个Client对其重写

以Client为例: client是继承的HttpClient,并发安全
1. 解析request的参数,拿到host目标主机字符串
2. 校验协议,http/https,https置isTLS为true
3. 对client加锁
4. 得到Client的map:key为string,value为HostClient的地址
5. 从map中查找到host对应的HostClient,若map中没有那么新建一个HostClient,并设置HostClient参数,并加入map
6. 如果map中只有刚刚新建的这一条记录,那么开启一个新协程,mCleaner
mCleaner: 遍历map中的主机Client,如果1min内没有使用,那么从map中删除。直至map为空
每10s执行协程一次
7. 对该 HostClient 调用hc.Do处理请求
1. 重试次数为5
2. 调用HostClient.do函数真正处理请求
1. 如果传入的resp为空,那么调用AcquireResponse 重新? 获取一个复用的response,且结束后回收resp
2. 调用HostClient的doNonNilReqRsp处理请求
1.校验req和resp不为空
2. resp的header和body重置
3. 调用HostClient.acquireConn()函数,获取一个属于该host的connection
对Host的conn操作需要加锁
acquireConn():
1. 如果该Host的可用conn为空,且该HostClient的总conn尚未达到max限制,那么需要调用dialHostHard()新建
dialHostHard()函数:
1. 遍历 每一个Addr? ,调用dialAddr,建立一个connection
dialAddr函数:新建tcp连接
1. 地址拼上协议的端口号(80、443)
2. dial(addr)是和host建立tcp连接
3. 返回新建的connection
2. 调用 acquireClientConn 从clientConnPool中得到一个clientConn(没有则新建),对connection包装成ClientConn
2. 不为空,那么可用conn计数--,返回最后一个conn。
4. 如果 lastWriteDeadlineTime 超过writeTimeout的25%,更新
5. 如果超过包活时间,那么关掉这个connection
6. 从writerPool中得到一个writer,写入request,使用完后将writer回收
从writerpool中获取一个writer:
7. 从readerPool中得到一个reader,读取响应并回收writer
8. 关闭connection
3. 若1中传入的resp为空那么调用ReleaseResponse将resp回收


代码调用流程图:



猜你喜欢

转载自blog.csdn.net/nnnora/article/details/80983008