Go语言gin框架实现网关系统①网络基础

    技术2022-07-10  97

    文章目录

    第2章 扫盲网关前置技术:必备网络基础2-1 为什么要学习网络基础2-3 tcpdump抓包分析三次握手和四次挥手2-4 为啥time_wait需要等待2msl_必备网络基础2-5 节流开源 - TCP为啥需要流量控制 网络代理4-3 并发限速的意义漏桶限流令牌桶限流 第9章 项目实战:开发前准备 Vue+Go组合10-1 数据表整理与创建 第10章 项目实战之后台管理后端功能swagger日志10-3 后端开发步骤

    第2章 扫盲网关前置技术:必备网络基础

    2-1 为什么要学习网络基础

    2-3 tcpdump抓包分析三次握手和四次挥手

    双工:双方都是能够发送、接收消息

    2-4 为啥time_wait需要等待2msl_

    必备网络基础

    2-5 节流开源 - TCP为啥需要流量控制

    网络代理

    4-3 并发限速的意义

    漏桶限流

    package main import ( "context" "golang.org/x/time/rate" "log" "testing" "time" ) func Test_RateLimiter(t *testing.T) { l := rate.NewLimiter(1, 5) log.Println(l.Limit(), l.Burst()) for i := 0; i < 100; i++ { //阻塞等待直到,取到一个token log.Println("before Wait") c, _ := context.WithTimeout(context.Background(), time.Second*2) if err := l.Wait(c); err != nil { log.Println("limiter wait err:" + err.Error()) } log.Println("after Wait") //返回需要等待多久才有新的token,这样就可以等待指定时间执行任务 r := l.Reserve() log.Println("reserve Delay:", r.Delay()) //判断当前是否可以取到token a := l.Allow() log.Println("Allow:", a) } }

    令牌桶限流

    package main import ( "fmt" "net" "os" "sync/atomic" "time" ) var ( limiting int32 = 1 // 这就是我的令牌桶 ) func main() { tcpAddr, err := net.ResolveTCPAddr("tcp4", "0.0.0.0:9090") //获取一个tcpAddr checkError(err) listener, err := net.ListenTCP("tcp", tcpAddr) //监听一个端口 checkError(err) defer listener.Close() for { conn, err := listener.Accept() // 在此处阻塞,每次来一个请求才往下运行handle函数 if err != nil { fmt.Println(err) continue } go handle(&conn) // 起一个单独的协程处理,有多少个请求,就起多少个协程,协程之间共享同一个全局变量limiting,对其进行原子操作。 } } func handle(conn *net.Conn) { defer (*conn).Close() n := atomic.AddInt32(&limiting, -1) // dcr 1 by atomic,获取一个令牌,总数减1。这是一个原子性的操作,并发情况下,数据不会写错。 if n < 0 { // 令牌不够用了,限流,抛弃此次请求。 (*conn).Write([]byte("HTTP/1.1 404 NOT FOUND\r\n\r\nError, too many request, please try again.")) } else { // 还有剩余令牌可用 time.Sleep(1 * time.Second) // 假设我们的应用处理业务用了1s的时间 (*conn).Write([]byte("HTTP/1.1 200 OK\r\n\r\nI can change the world!")) // 业务处理结束后,回复200成功。 } atomic.AddInt32(&limiting, 1) // add 1 by atomic,业务处理完毕,放回令牌 } // 异常报错的处理 func checkError(err error) { if err != nil { fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error()) os.Exit(1) } }

    https://www.jianshu.com/p/9032c6f41f1e

    第9章 项目实战:开发前准备 Vue+Go组合

    10-1 数据表整理与创建

    第10章 项目实战之后台管理后端功能

    一键解决 go get golang.org/x 包失败

    export GOPROXY=https://goproxy.io go mod tidy

    swagger日志

    swagger init http://localhost:8880/swagger/index.html

    10-3 后端开发步骤

    Processed: 0.027, SQL: 9