golang-gin-mgo高并发服务器搭建教程
来源:脚本之家
时间:2023-01-28 18:24:19 178浏览 收藏
本篇文章主要是结合我之前面试的各种经历和实战开发中遇到的问题解决经验整理的,希望这篇《golang-gin-mgo高并发服务器搭建教程》对你有很大帮助!欢迎收藏,分享给更多的需要的朋友学习~
gin-mgo服务器搭建
该服务器实现简单接收请求并将请求参数封装存储在mongodb数据库中,本文将讲述gin-mgo的使用方法。
项目完整代码地址: https://github.com/wayne-yhp/golang-gin-mgo
gin web框架使用介绍
首先获取gin框架依赖
go get gopkg.in/gin-gonic/gin.v1
func main() { server = gin.Default() app.server.GET("/do", IndexRouter)//创造一个GET请求的路由地址,并指定处理函数为IndexRouter函数 app.server.Run(":8080") } func IndexRouter(c *gin.Context) { if c.Request.Form == nil { //获取所有请求参数名和值的预处理 c.Request.ParseMultipartForm(32mgo 持久层框架使用介绍
前提条件mongodb环境已经搭建好了,首先安装mgo框架依赖
go get labix.org/v2/mgo
type User struct{ username string pwd string } func main() { mgo_session, err = mgo.Dial("127.0.0.1") //获取连接对象session if err != nil { panic(err) } defer session.Close() //方法执行完后关闭连接 mgo_db = oper.mgo_session.DB("test") //获取数据库对象,数据库名为test //如果没有mongodb没有开启权限认证,则跳过这一步 mgo_db.Login("test1", "test1") //用户认证,用户名账户和密码都是test1 mgo_c = oper.mgo_db.C("coll") //获取数据库某个集合对象 //插入操作 mgo_c.insert(&User{ username: "xxx", pwd: "xxx", }) }提高服务器高并发性能讲解(针对文章开头地址中的项目)
该项目主要实现接收请求,解析封装参数,插入数据库的简单操作,这里只涉及插入操作,故不涉及数据缓存的知识,整个服务处于单机下,故不涉及分布式服务架构,集群的知识。
注意以下
1、开启一个协程独自监听访问数量,进行插入操作
2、实现批量插入
3、实现定时插入
4、加锁解决并发资源竞争
开启一个协程独自监听访问数量,进行插入操作
如果将插入操作放在主线程,那么接收http请求和逻辑处理,数据库插入操作都必须要顺序执行,大大降低了插入效率,因此要开启一个协程,独自监听访问数量,进行数据库插入。
实现批量插入
假想一下如果每次有人访问你的数据库你就进行一次插入操作,那么你的数据库将会是一个什么样的情况?我们都知道数据库操作相对服务器其他操作是一件相对很耗时的事情,所以每次访问就操作一次数据库,会大大降低服务器性能,更别说有几千上万的人同时访问你的服务器了。
实现定时插入
在实现了批量插入的基础上,如果没有达到一定的访问量,那么就不会执行插入操作,刚好在两个访问请求中间隔了很长时间,那么前面的请求就会等待很久才会更新到数据库中,为了防止这种情况,我们必须要设定一个时间,定时插入。
加锁解决并发资源竞争
在并发量几千上万的情况下,可能一秒可以执行很多次数据库的插入操作,这个时候很有可能上一个插入还没执行完,第二个就已经执行了,这时候可能出现数据冗余,服务器瘫痪等问题,因此要给批量插入操作加上一个读写锁。
具体实现细节可以去上述地址中查看。
补充:Golang号称高并发,但高并发时性能不高
1.管道chan吞吐极限10,000,000,单次Put,Get耗时大约100ns/op,无论是采用单Go程,还是多Go程并发(并发数:100, 10000, 100000),耗时均没有变化,Go内核这对chan进行优化。
解决之道:
在系统设计时,避免使用管道chan传递主业务数据,避免将业务流程处理流程分割到对个Go程中执行,这样做减少chan传输耗时,和Go程调度耗时,性能会有很大的提升。
案例分析:nsq和nats都是实时消息队列,nsq在客户端端和服务端大量使用chan转发消息,导致性能不佳,只有100,000/s;而nats服务端在分发消息流程中,没有使用chan,只在客户端接收时使用chan,性能可达到1,000,000/s。
2.互斥锁Mutex在单Go程时Lock,Unlock耗时大约20ns/op,但是采用多Go程时,性能急剧下降,并发越大耗时越长,在Go1.5并发数达到1024耗时900ns/op,Go1.6优化到300ns/op,究其原因,是构建在CPU的原子操作之上,抢占过于频繁将导致,消耗大量CPU时钟,进而CPU多核无法并行。
解决之道:
采用分区,将需要互斥保护的数据,分成多个固定分区(建议是2的整数倍,如256),访问时先定位分区(不互斥),这样就可降低多个Go程竞争1个数据分区的概率。
案例分析:Golang的Go程调度模块,在管理大量的Go程,使用的就是数据分区。
3.select异步操作在单管道时耗时120ns/op,但是随着管道数增加,性能线性下降,每增加1个管道增加100ns/op,究其原因,slelect时当chan数超过1后,Go内部是创建一个Go程,有它每1ms轮训的方式检查每个chan是否可用,而不是采用事件触发。
解决之道:
在select中避免使用过多的管道chan分支,或者把无法用到的chan置为nil;解决select超时,避免使用单独的超时管道,应与数据返回管道共享。
案例分析:nsq和nats都是实时消息队列,由于nsq大量使用chan,这就必然导致大量使用select对多chan操作,结果是性能不高。
4.Go调度性能低下,当出现1,000,000Go程时,Go的调度器的性能急剧下降。
解决之道:
避免动态创建Go程,服务端收到数据并处理的流程中,避免使用chan传递业务数据,这样会引起Go程调度。
案例分析:nsq和nats都是实时消息队列,由于nsq大量使用chan,这就必然导致在服务过程中,引起Go调度,结果是性能不高。
5.defer性能不高,每次defer耗时100ns,,在一个func内连续出现多次,性能消耗是100ns*n,累计出来浪费的cpu资源很大的。
解决之道:
除了需要异常捕获时,必须使用defer;其它资源回收类defer,可以判断失败后,使用goto跳转到资源回收的代码区。
6.内存管理器性能低下,申请16字节的内存,单次消耗30ns,64字节单次消耗70ns,随着申请内存尺寸的增长,耗时会迅速增长。加上GC的性能在1.4, 1.5是都不高,直到1.6, 1.7才得到改善。
解决之道:
建议使用pool,单次Put,Get的耗时大约在28ns,在并发情况下可达到18ns,比起每次创建,会节省很多的CPU时钟。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持golang学习网。如有错误或未考虑完全的地方,望不吝赐教。
本篇关于《golang-gin-mgo高并发服务器搭建教程》的介绍就到此结束啦,但是学无止境,想要了解学习更多关于Golang的相关知识,请关注golang学习网公众号!
-
102 收藏
-
347 收藏
-
245 收藏
-
456 收藏
-
420 收藏
-
155 收藏
-
457 收藏
-
309 收藏
-
225 收藏
-
485 收藏
-
233 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 507次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 484次学习
-
- 迷路的彩虹
- 这篇技术文章真是及时雨啊,作者加油!
- 2023-05-10 20:14:43
-
- 威武的鸵鸟
- 很有用,一直没懂这个问题,但其实工作中常常有遇到...不过今天到这,帮助很大,总算是懂了,感谢作者大大分享技术贴!
- 2023-04-06 15:45:50
-
- 受伤的秋天
- 太全面了,收藏了,感谢师傅的这篇博文,我会继续支持!
- 2023-03-04 08:51:34
-
- 甜美的睫毛膏
- 好细啊,码住,感谢up主的这篇文章内容,我会继续支持!
- 2023-02-11 19:42:47
-
- 谦让的板凳
- 这篇文章真及时,好细啊,很有用,码起来,关注作者大大了!希望作者大大能多写Golang相关的文章。
- 2023-02-10 13:18:47
-
- 辛勤的菠萝
- 这篇文章内容真是及时雨啊,细节满满,很棒,已收藏,关注作者大大了!希望作者大大能多写Golang相关的文章。
- 2023-02-06 22:00:21
-
- 如意的蜗牛
- 感谢大佬分享,一直没懂这个问题,但其实工作中常常有遇到...不过今天到这,看完之后很有帮助,总算是懂了,感谢楼主分享技术贴!
- 2023-02-06 09:02:47