【原创】请避免GO语言中的携程空跑(CPU突然激增)
其实GO语言从1.6版本开始非常不错了,GC性能优化非常到位,并且各种并行设计比从新实现一套C++版本的确是方便不少。
语言包也很多,库也相对稳定,完全可以适用于生产环境。
本文主要是给刚刚入门新手注意一个携程空跑的问题,因为这种问题可能在C++中也遇到过,只是一些代码书写习惯导致。
首先来看一段代码:
func (c *WSConn) processHandler() {
for {
select {
case message, ok := <-c.processMsg: // 处理数据包
if !ok {
break
}
Call(message.MsgHead.Id, c, message.MsgContext, int(message.MsgHead.Msglen))
}
}
}
以上代码是用于处理一个WEBSOCKET的二进制消息后转换为指定处理信息的行为。
但是有没有同学发现有什么问题?但是这段代码的确有问题,因为当连接销毁后会导致processHandler这个携程空跑,CPU完全占满,当你有多个连接出现这种问题后整台服务器就会爆掉。
首先processMsg是一个channel,这里如果连接关闭了会同时关闭掉这个channel,首先我们知道select本身会等待channel,这样是不会消耗CPU的,就像C中的select函数一样,本身是不消耗的(使用不当的略过)。
但是当channel关闭后,整个携程本因直接销毁,但是代码中的break导致select无限循环跑,程序出现空跑现象,这里的break是相对于select而言的,所以看上去没毛病可跑起来毛病很大。
所以如果当出现空跑或GO语言某个携程CPU激增,可以去查看是不是哪个channel和select在无限循环。
所以正确的代码是:
func (c *WSConn) processHandler() {
for {
select {
case message, ok := <-c.processMsg: // 处理数据包
if !ok {
return // 这里必须强制结束携程
}
Call(message.MsgHead.Id, c, message.MsgContext, int(message.MsgHead.Msglen))
}
}
}
我的排错方法是使用http的一种性能分析方式
下面是详细代码:
main.go
package main import (
"log"
"runtime" "net/http" // http包引入
_ "net/http/pprof" // 性能分析包引入 ) func main() {
// 设置并行运行
runtime.GOMAXPROCS(2) logger.SetLogName("testserver.log") go func() {
log.Println(http.ListenAndServe("localhost:6060", nil))
}() // 此处建立http专用的性能分析端口 webSock := knlWebsocket.Create(":88", "null")
webSock.Listen() }
以上代码仅供抛砖引玉,无法通过编译,注意注释内的代码。
看代码很简单,import 2个包:
import (
"net/http" // http包引入
_ "net/http/pprof" // 性能分析包引入 )
然后main函数中加入代码:
go func() {
log.Println(http.ListenAndServe("localhost:6060", nil))
}() // 此处建立http专用的性能分析端口
我在这里加入了一个携程来做性能分析,是因为我本身有自己的主处理逻辑,所以必须使用携程。
完成以上代码添加后,直接编译启动程序,访问地址:http://localhost:6060/debug/pprof/,然后就可以进行愉快的性能分析了
【原创】请避免GO语言中的携程空跑(CPU突然激增)的更多相关文章
- 在Go语言中使用JSON(去掉空字段)
Encode 将一个对象编码成JSON数据,接受一个interface{}对象,返回[]byte和error: func Marshal(v interface{}) ([]byte, error) ...
- 022_go语言中的协程
代码演示 package main import "fmt" func f(from string) { for i := 0; i < 3; i++ { fmt.Print ...
- Golang 入门系列(六)理解Go中的协程(Goroutine)
前面讲的都是一些Go 语言的基础知识,感兴趣的朋友可以先看看之前的文章.https://www.cnblogs.com/zhangweizhong/category/1275863.html. 今天就 ...
- 【 c语言中无符号和有符号的加法运算】【深入理解】--【sky原创】
原文:[ c语言中无符号和有符号的加法运算][深入理解]--[sky原创] 第一题 #include<stdio.h> int main() { unsigned int a=6; i ...
- 2015年4月27日---C语言:输出特殊图案,请在c环境中运行,看一看,Very Beautiful!
---恢复内容开始--- 题目:输出特殊图案,请在c环境中运行,看一看,Very Beautiful! 1.程序分析:字符共有256个.不同字符,图形不一样. 2.程序源代码: [code=c] #i ...
- C语言中->是什么意思啊?比如说 p=p->next 到底表达了什么意思,请说清楚点,还有->这个符号是一个整体吗,什么意思??
->是一个整体,它是用于指向结构体.C++中的class等含有子数据的指针用来取子数据.换种说法,如果我们在C语言中定义了一个结构体,然后申明一个指针指向这个结构体,那么我们要用指针取出结构体中 ...
- 在 Go 语言中使用 Log 包--转自GCTT
Linux 在许多方面相对于 Windows 来说都是独特的,在 Linux 中编写程序也不例外.标准输出,标准 err 和 null devices 的使用不仅是一个好主意,也是一个原则.如果您的程 ...
- C语言中的二级指针(双指针)
原创作品,转载请标明出处http://blog.csdn.net/yming0221/article/details/7220688 C语言更多查看 C语言使用注意事项(一) C语言使用注意事项(二) ...
- 这样子来理解C语言中指针的指针
友情提示:阅读本文前,请先参考我的之前的文章<从四个属性的角度来理解C语言的指针也许会更好理解>,若已阅读,请继续往下看. 我从4个属性的角度来总结了C语言中的指针概念.对于C语言的一个指 ...
随机推荐
- HDU3530 Subsequence(单调队列)
题意是说给出一个序列,现在要求出这个序列的一个最长子区间,要求子区间的最大值与最小值的差在[m, k]范围内,求区间长度 做法是维护两个队列,一个维护到当前位置的最大值,一个维护最小值,然后计算当前节 ...
- timescaledb replication 使用
replication 可以确保系统的ha 以及lb 数据的查询,timesacledb 使用pg 内置的stream replication 进行复制的支持 docker 运行参考 https:// ...
- IT项目管理工具总结
IT项目管理工具总结 俗话说"工欲善其事必先利其器",在一个项目开发流程中,如果搭配一个比较完善的项目管理工具,必将取得事半功倍的效果.本文搜集了目前项目管理界比较有规模的管理工具 ...
- return 0;和exit(0);的区别
首先说一下fork和vfork的差别: fork 是 创建一个子进程,并把父进程的内存数据copy到子进程中. vfork是 创建一个子进程,并和父进程的内存数据share一起用. 这两个的差别是,一 ...
- springboot利用MockMvc测试controller控制器
主要记录一下控制器的测试,service这些类测试相对简单些(可测试性强) API测试需求比较简单: ① 需要返回正确的http状态码 200 ② 需要返回json数据,并且不能返回未经捕获的系统异常 ...
- android单元测试 activity跳转 以及 input 输入后 测试
Android junit实现多个Activity跳转测试 分类: Android Junit测试2011-11-14 16:49 1601人阅读 评论(2) 收藏 举报 androidjunitla ...
- JVM参数之-XX:+HeapDumpOnOutOfMemoryError(导出内存溢出的堆信息(hprof文件))
当出现HeapDumpOnOutOfMemoryError错误时,我们需要分析原因,下面的程序就是模拟这个错误并导出dump文件,好让你分析 GcTest.java package gc; publi ...
- 设置MySQL重做日志大小
什么是InnoDB事务日志 你有没有在文本编辑器中使用过撤消或重做的功能,想像一下编辑器在那种场景下的操作?我确信你应该使用过.你相信吗?事务型数据库有同样的功能.可能不完全一样,但原理是相同的. 就 ...
- 2018 Multi-University Training Contest 4-Problem B. Harvest of Apples
由公式$S(n, m)=S(n - 1, m) + S(n - 1, m - 1) = 2 * S(n - 1, m) - C_{n-1}^{m}$ 莫队思想
- 使用word设置标题级别, 自动生成和大纲对应的多级列表, 自动生成索引目录
作为程序员,只会开发是不够的, 在日常工作中还需要掌握一些办公软件的的操作方法,word excel ppt精通不敢, 暂且入个门吧, 在前后台开发配合过程中,能写的一手好文档将会达到事半功倍的效果, ...