网页客服,欢迎咨询

Go语言项目实践及新特性解读

2025-01-06 11:40:01 36
  • 收藏
  • 管理
    总篇第142篇 2022年第17篇★ 目录 ★01语言介绍02之家项目实践? 2.1 百万级并发状态机 - 818台网互动秒杀项目? 2.2 嵌入式边缘计算网络?- 直播推流窄带高清项目? 2.3 百万级DAU用户产品 - VR全景看车项目03新特性? 3.1 泛型(GENERICS)? 3.2 多模块工作区(WORKSPACE)? 3.3 模糊测试(FUZZING)04总结一语言介绍”Go是Google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的跨平台编程语言,于2009年11月正式宣布推出,成为开放源代码项目,支持Linux、macOS、Windows等不同的操作系统。Go由Robert Griesemer、Rob Pike、Ken Thompson2007年9月开始设计,后Ian Lance Taylor、Russ Cox加入项目。从左到右分别是Robert Griesemer、Rob Pike和Ken ThompsonGo语言本身解决了并发编程和开发效率的痛点,语法十分简洁、丰富的标准库、goroutine和chan原生支持并发(CSP模型)、工具链全面并且在编译、运行上都极高效率、全自动高效的垃圾回收机制、易部署、跨平台等这些特性吸引了越来越多的人开始使用Go。国内有不少企业在使用Go:七牛、阿里、字节、腾讯、百度、小米京东等,在云原生、区块链、游戏、微服务、基础后端许多场景下都有开发应用。许多杀手级开源项目也是基于Go开发:Docker、k8s、Etcd、Cockroach DB、以太坊(区块链)等。近几年之家也基于Go进行了一些开发实践,这些项目也都有着很好的表现。二之家项目实践”近几年之家基于Go在不同的业务场景下(高并发服务、云原生、中间件、机器学习、用户产品、嵌入式等)有着丰富的开发实践,接下来会基于这些场景分享一些典型案例:百万级并发状态机 - 818台网互动秒杀项目818台网互动项目是汽车之家与湖南卫视联合打造的“汽车之家818全球汽车夜”,晚会已经成功举办两届,用户可以通过观看电视并使用汽车之家App实时参与晚会互动,晚会现场和线上活动场景图如下:线下会有大量用户通过观看电视直播,参与线上的秒杀抽奖活动,请求量非常大。在不同的活动场次,App会根据主持人在口播指令下进行活动状态切换,对实时性要求很高。下图是整个活动场次时序图:我们在整个项目架构上增加了状态机,通过webscoket作为长连接向客户端提供实时活动状态信息的服务。状态机底层依赖Redis集群,通过pub/sub来获取状态值的变化向客户端推送最新的状态信息,同时使用HTTP/2轮询作为备用方案,使客户端在websocket连接出问题的情况下也能获取到数据,下图是整个台网互动的架构图:状态机对于高并发负载要求较高,晚会当晚预估量200w连接左右,而Go在并发通讯方面有着天然的优势,所以我们使用了Go语言进行开发。同时我们也用Go http与java常用的spring框架进行了压测对比,在大量并发请求的情况下,Go可以更快的响应,内存增长也少于Java。goroutine&内存优化下面是建立websocket连接的大致流程:客户端发起请求建立连接请求状态机接收到请求后启动一个goroutine进行连接维护,并下发第一次状态信息,同时把对应的指针放入map中状态机在收到对应值改变后,再次向所有的连接进行消息推送广播在建立百万级的websocket连接后,内存暴增21G左右。发现除了socket本身的连接占用外,程序内每条conn占用大概在20k左右:每个连接都产生一个Goroutine来维护连接http读取写入缓存websocket框架内的读写缓存//WS 长链接处理handlerfunc WS(ctx *gin.Context) {//建立websocketconn, err := ws.Upgrade(ctx.Writer, ctx.Request)if err != nil {ctx.AbortWithStatus(400)return}conn.IP = IPconn.C = ctx.Query("_c")conn.UA = CheckUA(ctx.Request)conn.Referer = CheckReferer(ctx.Request)log.Debug().Str("addr", IP).Msg("ws-push new client enter -->") //推送第一次消息if err := conn.WriteMessage(websocket.TextMessage, []byte(ws.StateMsg+cache.State.String())); err != nil {//if err := conn.WriteMessage(websocket.TextMessage, block); err != nil {log.Error().Err(err).Str("addr", conn.RemoteAddr().String()).Msg("ws-push Can't send firstMsg -->")return}monitor.PushEnter 0 {data := make([]byte, nr)copy(data, buf[0:nr])lib.UploadChan /Documents/vr/dal有时候难免疏忽,忘记删除mod文件中replace,提交到git后导致项目编译失败。而在Go1.18上,工作区就可以避免这样的问题发生:go work init //创建工作区, 根目录会生成一个go.work的文件go use ../dal //在go.work中增加dal项目go use . //在go.work中加入当前项目,不添加则会按包名去git上找- go.work内容如下:go 1.18use ( /Documents/vr/dal ./)这样就不需要每次都使用replace来进行mod的替换了,需要注意的是:go.work需要加入.gitignore中,不需要提交到git上!3.模糊测试 (Fuzzing)模糊测试是go在1.18中提供的自动化测试,通过指定类型的语料库进行智能添加测试数据。模糊测试可以覆盖很多人工经常忽略的边缘case,对于程序中漏洞特别有价值。模糊测试方法名以FuzzXxx,且和其他测试用例一样,需要写在xxx_test.go中模糊测试方法需要指定一个随机参数类型,目前只支持基础类型:运行的时候和其他测试用例一样,指定好需要运行的用例名称即可:gotest -fuzz={FuzzTestName}需要注意的是,Fuzzing目前还处于完善阶段:实验性功能,不承诺Go1.x的兼容性不支持结构和非原始类型的结构化模糊模糊测试会消耗大量内存(测试会持续运行),影响机器运行时的性能不支持字典不支持结构和原始类型四总结”Go语言还是一门年轻的语言,1.18的更新是一个非常有意义的里程碑事件,也标志着Go进入泛型时代,随着版本的不断更新,未来Go也会越来越完善。除了上述的一些项目外,我们正在进行Go的微服务实践,通过对业界一些Go微服务框架(go-zero、kitex、dubbo-go、tars-go)的调研使用对比,将目前的一些服务进行模块化,提高项目的可部署性和扩展性。希望未来可以把Go语言应用在更多的业务场景上,同时总结一些实践经验在公司内部进行推广和使用。本页的部分内容是从Google 创建和共享的作品中复制而来,并根据Creative Commons Attribution 3.0 License中描述的条款使用。参考资料https://go.dev/blog/go1.18https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.mdhttps://speakerdeck.com/gopherconil/eran-yanay作者简介汽车之家李广朋用户产品中心-基础产品团队2018年6月加入汽车之家用户产品中心,负责全景看车、图像识别、智能传图的业务开发等相关工作阅读更多使用DDD设计福利中心微服务代码模型代码覆盖率测试实践汽车之家MySQL高可用建设实践 Go语言项目实践及新特性解读
    上一页:H5页面秒开优化与实践 下一页:Freeswitch集群在智能外呼平台中的应用
    全部评论(0)