赞
踩
采用 go 的协程完成 gin多服务
什么多服务?就是启动服务器后,可以同时访问多个资源,比如router01、router02
ReadTimeout 读取请求超时时间,一般防止客户端慢请求,导致长时间占用服务器资源
WriteTimeout 写入响应超时时间,一般是防止客户端读取响应慢,导致长时间占用服务器资源可以这么理解,就是服务器这边的效率是特别高的,出现的问题都是从客户端那边冒出来的
然后,服务器要读取来自客户端的请求 所有叫ReadTimeout 读取请求超时时间,这个是从客户端从开始发起请求到结束发起请求结束的时间,如果一个请求数据,一直慢吞吞的发送,这个时间段服务器其实是中断来处理这个业务的,这个时间段的资源全部用来等待请求数据,是不是占用了很多资源?
WriteTimeout 叫写入响应超时时间,就是服务器要响应客户端的请求,如果客户端读取服务器的响应很慢,水管那头(客户端)一直减速,水管这头(服务器)的写入速度是不是也响应的被减缓了?
package main import ( "log" "net/http" "time" "github.com/gin-gonic/gin" "golang.org/x/sync/errgroup" ) var ( g errgroup.Group ) func route01() http.Handler { e := gin.New() e.Use(gin.Recovery()) e.GET("/", func(c *gin.Context) { c.JSON( http.StatusOK, gin.H{ "code": http.StatusOK, "error": "wellcome server 01", }, ) }) return e } func router02() http.Handler { // 创建一个新的Gin引擎 e := gin.New() // 为这个引擎添加一个中间件,它可以捕获处理请求过程中的任何panic并将错误写入日志 e.Use(gin.Recovery()) // 为这个引擎添加一个GET 路由,当收到这个请求时,调用处理函数 e.GET("/", func(c *gin.Context) { // c.JSON 是一个方法,生成JSON格式的HTTP响应 c.JSON( http.StatusOK, gin.H{ "code": http.StatusOK, "error": "wellcome server02", }, ) }) return e } /* go run example_14_runservers.go example_14_runservers.go:9:2: no required module provides package golang.org/x/sync/errgroup; to add it: go get golang.org/x/sync/errgroup [root@localhost gin_test]# go get golang.org/x/sync/errgroup */ func main() { server01 := &http.Server{ Addr: ":8080", // Handler 接收所有的HTTP请求 Handler: route01(), // ReadTimeout 读取请求的超时时间 防止慢速攻击(客户端故意以非常慢的速度发送请求,导致服务器资源被长时间占用) ReadTimeout: 5 * time.Second, //WriteTimeout 写入响应的超时时间 防止客户端读取响应过慢,导致服务器资源被长时间占用 WriteTimeout: 10 * time.Second, } server02 := &http.Server{ Addr: ":8081", Handler: router02(), ReadTimeout: 5 * time.Second, WriteTimeout: 10 * time.Second, } // 会在新的goroutine中启动服务器 //server02.ListenAndServe() 是 Go 语言 net/http 包中 Server 结构体的一个方法。 //这个方法会启动一个 HTTP 服务器,使其开始监听其 Addr 字段指定的网络地址,并等待并处理接收到的 HTTP 请求。 //当我们说 server02.ListenAndServe() 会阻塞 goroutine,意思是这个方法会一直运行, //直到服务器停止。在这个方法运行期间,它所在的 goroutine 不会执行其他代码,也就是说,这个 goroutine 被 "阻塞" 了。 g.Go(func() error { return server01.ListenAndServe() }) g.Go(func() error { return server02.ListenAndServe() }) /* 等待由group启动的所有goroutine结束 收集gorountine 出现的错误 调用 g.wait的goroutine会阻塞,等待所有的g.Go启动后的goroutine结束。 只有所有的g.Go启动的goroutine结束之后,才执行g.wait收集错误 */ if err := g.Wait(); err != nil { log.Fatal("the err is ", err) } }
轻量级:goroutine 是非常轻量级的,它的创建和切换的开销都非常小。一个 Go 程序可以同时运行数十万甚至数百万个 goroutine,而在大多数操作系统上,同时运行这么多的线程是不可能的。
内存占用:每个 goroutine 的堆栈大小开始时非常小(只有几 KB),并且可以根据需要增长和缩小,而线程的堆栈大小通常是固定的,通常为几 MB。
调度:goroutine 的调度是由 Go 运行时进行的,而不是由操作系统进行的。这意味着 Go 运行时可以更精细地控制 goroutine 的执行,例如,当一个 goroutine 在等待 I/O 操作时,Go 运行时可以运行其他 goroutine。
并发编程模型:Go 语言提供了 channel 和 select 语句,使得在 goroutine 之间进行通信和同步变得非常简单。这是一种不同于传统的共享内存并发模型的并发编程模型,它更易于理解和使用。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。