【原创】请避免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语言的一个指 ...
随机推荐
- Html页面Dom对象之Event
HTML DOM Event 对象 实例 哪个鼠标按钮被点击? 光标的坐标是? 被按的按键的 unicode 是? 相对于屏幕,光标的坐标是? shift 键被按了吗? 哪个元素被点击了? 哪个事件类 ...
- Fiddler显示响应时间 显示服务器IP
在主界面菜单上 Rules->CustomRules 在class Handlers{}里添加class 如: 显示响应时间 class Handlers { …… ) function Tim ...
- 在Chrome调试器中引入jQuery
在Console中输入以下代码并回车,Console显示"function (a,b){return new m.fn.init(a,b)}"说明导入成功,就可以在Console中 ...
- There is no Action mapped for namespace / and action name login. - [unknown location]
(自己在浏览器中,直接进入项目的根目录,即 http://localhost:8080/ssh/ 时便报错,web.xml文件已经配置了 欢迎页面 <welcome-file-list> ...
- <meta name="viewport" content="width=device-width, initial-scale=1.0">的说明
今天在做适配手机版时,chrome调到手机版,但是还是显示PC端的样式,无法展现出手机端的样式: 开始的时候还以为是chrome版本的问题,最新版本的chrome62.0是有很多变化的,而之前工作中使 ...
- jmeter录制https请求时,浏览器每一个请求都 跳 不安全访问页面的解决方法
1.关闭所有浏览器 2,使用终端 输入 : /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --ignore-certif ...
- 常见的加密和解密算法—BASE64
一.BASE64加密和解密概述 Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一,Base64编码可用于在HTTP环境下传递较长的标识信息.例如,在Java Persistence系 ...
- 1.1_C语言概述
C语言概述 1.1 什么是C语言 一提到语言这个词语,自然会想到的是像英语.汉语等这样的自然语言,因为它是人和人交换信息不可缺少的工具. 而今天计算机遍布了我们生活的每一个角落,除了人和人的相互交流之 ...
- django之模型
ORM简介 MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库 ORM是“对象-关系-映射”的简称 ...
- Mysql总结(一)
数据库命令:创建create database 数据库名 charset=utf8;删除drop database 数据库名;查看所有数据库:show databases;使用数据库:use 数据库名 ...