其实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突然激增)的更多相关文章

  1. 在Go语言中使用JSON(去掉空字段)

    Encode 将一个对象编码成JSON数据,接受一个interface{}对象,返回[]byte和error: func Marshal(v interface{}) ([]byte, error) ...

  2. 022_go语言中的协程

    代码演示 package main import "fmt" func f(from string) { for i := 0; i < 3; i++ { fmt.Print ...

  3. Golang 入门系列(六)理解Go中的协程(Goroutine)

    前面讲的都是一些Go 语言的基础知识,感兴趣的朋友可以先看看之前的文章.https://www.cnblogs.com/zhangweizhong/category/1275863.html. 今天就 ...

  4. 【 c语言中无符号和有符号的加法运算】【深入理解】--【sky原创】

    原文:[ c语言中无符号和有符号的加法运算][深入理解]--[sky原创]   第一题 #include<stdio.h> int main() { unsigned int a=6; i ...

  5. 2015年4月27日---C语言:输出特殊图案,请在c环境中运行,看一看,Very Beautiful!

    ---恢复内容开始--- 题目:输出特殊图案,请在c环境中运行,看一看,Very Beautiful! 1.程序分析:字符共有256个.不同字符,图形不一样. 2.程序源代码: [code=c] #i ...

  6. C语言中->是什么意思啊?比如说 p=p->next 到底表达了什么意思,请说清楚点,还有->这个符号是一个整体吗,什么意思??

    ->是一个整体,它是用于指向结构体.C++中的class等含有子数据的指针用来取子数据.换种说法,如果我们在C语言中定义了一个结构体,然后申明一个指针指向这个结构体,那么我们要用指针取出结构体中 ...

  7. 在 Go 语言中使用 Log 包--转自GCTT

    Linux 在许多方面相对于 Windows 来说都是独特的,在 Linux 中编写程序也不例外.标准输出,标准 err 和 null devices 的使用不仅是一个好主意,也是一个原则.如果您的程 ...

  8. C语言中的二级指针(双指针)

    原创作品,转载请标明出处http://blog.csdn.net/yming0221/article/details/7220688 C语言更多查看 C语言使用注意事项(一) C语言使用注意事项(二) ...

  9. 这样子来理解C语言中指针的指针

    友情提示:阅读本文前,请先参考我的之前的文章<从四个属性的角度来理解C语言的指针也许会更好理解>,若已阅读,请继续往下看. 我从4个属性的角度来总结了C语言中的指针概念.对于C语言的一个指 ...

随机推荐

  1. test20181016 B君的第三题

    题意 B 君的第三题(haskell) 题目描述 大学四年,我为什么,为什么不好好读书,没找到和你一样的工作. B 君某天看到了这样一个题,勾起了无穷的回忆. 输入\(n, k\) 和一棵\(n\) ...

  2. Windows 7 x64 安装 Oracle 11g Express

    1. 下载    在这里下载文件: Oracle Database Express Edition 11g Release 2 for Windows x32    Oracle 不提供 window ...

  3. SEO -- WP如何建立SiteMap

    站点地图对网站的seo优化有着相当重要的作用,而WordPress的优势就是插件特别的多,也特别符合蜘蛛的口味,在wp上建立站点地图是相当简单的事情,只需要一款插件和几步简单的配置 Google XM ...

  4. pfsense openvpn上网终于通了

    先看配置,等会在说过程中遇到的问题: 1.openvpn配置: /var/etc/openvpn/server2.conf下: port 1195 proto tcp dev tap writepid ...

  5. charles手机抓包配置-1

    1.下载和安装Charles 下载和安装Charles软件.安装前要先安装Java运行环境,因为Charles是Java写的. 自己百度云上有破解版 2.安装电脑的Charles证书,对证书进行信任设 ...

  6. Train-Alypay-Cloud:蚂蚁大数据平台培训开课通知(第三次)

    ylbtech-Train-Alypay-Cloud:蚂蚁大数据平台培训开课通知(第三次) 1.返回顶部 1. 您好! 很高兴通知您,您已经成功报名将于蚂蚁金服计划在2018年2月28日- 2018年 ...

  7. Jenkins构建Python项目提示:'python' 不是内部或外部命令,也不是可运行的程序

    问题描述: jenkin集成python项目,立即构建后,发现未执行成功,查看Console Output 提示:'Python' 不是内部或外部命令,也不是可运行的程序,如下图: 1.在 Windo ...

  8. 第八章 Mixer 适配器的应用

    概述: Mixer “知晓”每一次服务间的调用过程,这些调用过程会为Mixer提供丰富的相关信息,Mixer通过接入的适配器对这些信息进行处理,能够在调用的预检(执行前)和报告(执行后)阶段执行多种任 ...

  9. 6.9-JDBC

    一.JDBC 步骤: 1.加载驱动 2.创建连接 3.创建Statement或PreparedStatement 4.遍历结果集 5.释放资源 二.PrepareStatement sql注入: Pr ...

  10. 在window的IIS中搭配Php的简单方法

    在window的IIS中搭配Php的简单方法.搭配php的时候找到的一个超级简单方法 关键的核心是 PHP Manager for IIS 这是微软开发的一个项目,使用它可以在window下最方便简单 ...