网站首页 > 文章中心 > 其它

关于go语言发起http请求的信息

作者:小编 更新时间:2023-08-26 11:48:11 浏览量:53人看过

【golang】context上下文与http请求妙用

①在后端服务开发中,如过一个HTTP请求,请求一致占用,将会带来大的性能影响,所以需要为每个请求加上超时设置

golang中http请求体多次读取的坑

报错信息如下:

原因:

关于go语言发起http请求的信息-图1

在请求体为json的请求中,调用了parsePostForm方法,方法大致内容如下:

在这个方法中,会读取http的请求体.

今天这一节被读取的时候,后面又重新读取一次,之后解json

后面读到的请求体是空的,解json的时候就会报错EOF

总结:golang中http请求报错eof,多半是因为多次读取了请求体

go语言实现一个简单的简单网关

网关=反向代理+负载均衡+各种策略,技术实现也有多种多样,有基于 nginx 使用 lua 的实现,比如 openresty、kong;也有基于 zuul 的通用网关;还有就是 golang 的网关,比如 tyk.

这篇文章主要是讲如何基于 golang 实现一个简单的网关.

转自: troy.wang/docs/golang/posts/golang-gateway/

关于go语言发起http请求的信息-图2

整理:go语言钟文文档:

启动两个后端 web 服务(代码)

这里使用命令行工具进行测试

具体代码

直接使用基础库 httputil 提供的NewSingleHostReverseProxy即可,返回的reverseProxy对象实现了serveHttp方法,所以呢可以直接作为 handler.

director中定义回调函数,入参为*http.Request,决定如何构造向后端的请求,比如 host 是否向后传递,是否进行 url 重写,对于 header 的处理,后端 target 的选择等,都可以今天这一节完成.

director今天这一节具体做了:

modifyResponse中定义回调函数,入参为*http.Response,用于修改响应的信息,比如响应的 Body,响应的 Header 等信息.

最终依旧是返回一个ReverseProxy,然后将这个对象作为 handler 传入即可.

随便 random 一个整数作为索引,然后取对应的地址即可,实现比较简单.

使用curIndex进行累加计数,一旦超过 rss 数组的长度,则重置.

后端真实节点包含三个权重:

操作步骤:

一致性 hash 算法,主要是用于分布式 cache 热点/命中问题;这里用于基于某 key 的 hash 值,路由到固定后端,但是只能是基本满足流量绑定,一旦后端目标节点故障,会自动平移到环上最近的那么个节点.

实现:

每一种不同的负载均衡算法,只需要实现添加以及获取的接口即可.

然后使用工厂方法,根据传入的参数,决定使用哪种负载均衡策略.

作为网关,中间件必不可少,这类包括请求响应的模式,一般称作洋葱模式,每一层都是中间件,一层层进去,然后一层层出来.

中间件的实现一般有两种,一种是使用数组,然后配合 index 计数;一种是链式调用.

Go语言HTTPServer开发的六种实现

相比于Java的HTTPServer开发基本上都是使用Spring或者Springboot框架,总是要配置各种配置类,各种 handle 对象.Golang的Server开发显得非常简单,就是因为特别简单,或者说没有形成特别统一的规范或者框架,我发现了很多实现方式,HTTP协议基于还是 net/http 和 fasthttp ,但是 handle 语法就多种多样了.

在Golang语言方面,实现某个功能的库可能会比较多,有机会还是要多跟同行交流,指不定就发现了更好用的库.下面我分享我学到的六种Server开发的实现Demo.

基于 net/http 实现,这是一种比较基础的,对于接口和 handle 映射关系处理并不优雅,不推荐使用.

第二种也是基于 net/http ,这种编写语法可以很好地解决第一种的问题,handle和path有了类似配置的语法,可读性提高了很多.

第三个基于 net/http 和 github.com/labstack/echo ,后者主要提供了 Echo 对象用来处理各类配置包括接口和handle映射,功能很丰富,可读性最佳.

第四种依然基于 net/http 实现,引入了 github.com/gin-gonic/gin 的路由,看起来接口和 handle 映射关系比较明晰了.

第五种基于 fasthttp 开发,使用都是 fasthttp 提供的API,可读性尚可,handle配置倒是更像Java了.

第六种依然基于 fasthttp ,用到了 github.com/buaazp/fasthttprouter ,有点奇怪两个居然不在一个GitHub仓库里.使用语法跟第三种方式有点类似,比较有条理,有利于阅读.

golang net/http包 http请求的字节码读取与解析.

先构建newTextprotoReader,由于缓冲区是对象复用的,用完后要defer put.共完以以下解析任务:

TextprotoReader数据结构,将字节码Reader转成文本Reader.

第一步,从第一行解析出method uri prototype.

第二步解析URL.url.URL数据结构:

解析Scheme,协议前缀(小写).有查询参数?,则配置url.ForceQuery url.RawQuery.有认证信息///...//,则解析url.User url.Host.最后配置url.Path和url.RawPath,如果Path==RawPath,则RawPath="".

第三步解析MIMEHeader.

第四步readTransfer.重新配置如下参数:RequestMethod ProtoMajor ProtoMinor Header Trailer ContentLength Close.对于Body,如果encodings支持chunked,读取流用chunkedReader包裹.默认情况用LimitedReader,无body赋空的struct{}.

以下情况返回非空err,示得到正确的请求:

最后配置req.ctx req.RemoteAddr req.TLS body.doEarlyClose = true.

构建Response:

关于go语言发起http请求的信息-图3

其中closeNotifyCh必须在构建时初始化,没有content所以先置contentLength为-1.

获取Request可能出现如下错误:

先上响应数据结构:

response字段可以分类为:大对象、缓冲、KV对或bool型的状态参数.

大对象有:

状态字段:

chunkWriter数据结构:

chunkWriter包裹了Response,功能之一是完成Header设置,包括Content-Type Content-Length chunk-header.bufio.Writer是chunkWriter是缓冲包裹.

handler将响应写入到response.w.

调用w.w.Flush()将w写入到cw,注意到Flush()操作,如果未刷空缓存并报错,触发拷贝操作.报错不会退回已写出的数据.

进而调用cw.Write(),根据cw.chunking参数.

putBufioWriter(w.w)清空resp.w缓冲,如果池化放回sync.pool.

根据chunkWriter的定义,w.cw.close()负责cw的结束工作:写入换行符和resp.trailers数据.

最后刷新TCP缓冲w.conn.bufw.Flush(),完成响应包发送.并正确关闭request.

以上就是土嘎嘎小编为大家整理的关于go语言发起http请求的信息相关主题介绍,如果您觉得小编更新的文章只要能对粉丝们有用,就是我们最大的鼓励和动力,不要忘记讲本站分享给您身边的朋友哦!!

版权声明:倡导尊重与保护知识产权。未经许可,任何人不得复制、转载、或以其他方式使用本站《原创》内容,违者将追究其法律责任。本站文章内容,部分图片来源于网络,如有侵权,请联系我们修改或者删除处理。

编辑推荐

热门文章