手把手教你用Strace诊断问题

早些年,如果你知道有个 strace 命令,就很牛了,而现在大家基本都知道 strace 了,如果你遇到性能问题求助别人,十有八九会建议你用 strace 挂上去看看,不过当你挂上去了,看着满屏翻滚的字符,却十有八九看不出个所以然。本文通过一个简单的案例,向你展示一下在用 strace 诊断问题时的一些套路。如下真实案例,如有雷同,实属必然!让我们看一台高负载服务器的 top 结果:

too-many-open-files

故障总结:

不要被经验主义羁绊;生产环境的进程管理工具Supervisor等的原理和限制需要理解清楚。

昨天,项目的 ElasticSearch 服务挂了,我说的挂可不是进程没了,因为有 Supervisor 保护,而是服务不可用了。以前曾经出现过一次因为 ES_HEAP_SIZE 设置不当导致的服务不可用故障,于是我惯性的判断应该还是 ES_HEAP_SIZE 的问题,不过登录服务器后发现日志里显示大量的「Too many open files」错误信息。那么 ElasticSearch 设置的最大文件数到底是多少呢?可以通过 proc 确认:

shell> cat /proc/<PID>/limits

结果是「4096」,我们还可以进一步看看 ElasticSearch 打开的都是什么东西:

shell> ls /proc/<PID>/fd

linux工具-strace

truss和strace都是用来跟踪一个进程的系统调用或信号产生的情况,而 ltrace用来 跟踪进程调用库函数的情况。

strace用法

usage: strace [-dDffhiqrtttTvVxx] [-a column] [-e expr] ... [-o file]
          [-p pid] ... [-s strsize] [-u username] [-E var=val] ...
          [command [arg ...]]
   or: strace -c [-D] [-e expr] ... [-O overhead] [-S sortby] [-E var=val] ...
          [command [arg ...]]                        

HTTP 协议中的 Transfer-Encoding

Transfer-ncoding,是一个 HTTP 头部字段,字面意思是「传输编码」。实际上,HTTP 协议中还有另外一个头部与编码有关:Content-Encoding(内容编码)。Content-Encoding 通常用于对实体内容进行压缩编码,目的是优化传输,例如用 gzip 压缩文本文件,能大幅减小体积。内容编码通常是选择性的,例如 jpg / png 这类文件一般不开启,因为图片格式已经是高度压缩过的,再压一遍没什么效果不说还浪费 CPU。而 Transfer-Encoding 则是用来改变报文格式,它不但不会减少实体内容传输大小,甚至还会使传输变大,那它的作用是什么呢?本文接下来主要就是讲这个。我们先记住一点,Content-Encoding 和 Transfer-Encoding 二者是相辅相成的,对于一个 HTTP 报文,很可能同时进行了内容编码和传输编码。

lombook工具包简介

介绍

lombok 提供了简单的注解的形式来帮助我们简化消除一些必须有但显得很臃肿的 java 代码。特别是相对于 POJO。官方网站lombook。它由2部分构成。一部分是idea插件,主要实现编译增强。另一部分是它的API。

golang编译后文件编写的技巧

总有人说Go程序“好大”,一个Hello World都1M多。其实,随着程序源码越来越大,编译后的文件并非那么快速的增长,这点大小真心没必要那么在乎,又不是软盘时代。但总有一些人非得想要小点。

首先我们看一下为什么会比其他语言大些:

Go 编译的可执行文件都包含了一个运行时(runtime),和我们习惯的Java/.NET VM有些类似。运行时负责内存分配(Stack Handing、    GC Heap)、垃圾回收(Garbage Collection)、Goroutine调度(Schedule)、引用类型(slice、map、channel)管理,以及反射(Reflection)等工作。Go程序进程启动后会自动创建两个goroutine,分别用于执行main入口函数和GC Heap管理。也正是因为编译文件中嵌入了运行时,使得其可执行文件相较其他语言更大一些。但Go的二进制可执行文件都是静态编译的,无需其他任何链接库等文件,更利于分发。                        

我们可以通过下面的方法将其变小点:

采用:go build -ldflags “-s -w” 这种方式编译。

解释一下参数的意思:

-ldflags: 表示将后面的参数传给连接器(5/6/8l)
-s:去掉符号信息
-w:去掉DWARF调试信息
注意:

-s 去掉符号表(这样panic时,stack trace就没有任何文件名/行号信息了,这等价于普通C/C+=程序被strip的效果)

-w 去掉DWARF调试信息,得到的程序就不能用gdb调试了

两个可以分开使用

实际项目中不建议做这些处理,没啥必要。

原文转自 http://studygolang.com/topics/98

Go性能优化技巧-string

概述

字符串(string)作为一种不可变类型,在与字节数组(slice, [ ]byte)转换时需付出 “沉重” 代价,根本原因是对底层字节数组的复制。这种代价会在以万为单位的高并发压力下迅速放大,所以对它的优化常变成 “必须” 行为。

首先,须了解 string 和 [ ]byte 数据结构,并确认默认方式的复制行为。

Go性能优化技巧-array

前言

对于一些初学者,自知道 Go 里面的 array 以 pass-by-value 方式传递后,就莫名地引起“恐慌”。外加诸多文章未作说明,就建议用 slice 代替 array,企图避免数据拷贝,提升性能。实际上,此做法有待商榷。某些时候怕会适得其反,倒造成不必要的性能损失。

Go性能优化技巧-map

前言

golang内置 map类型是必须的。首先,该类型使用频率很高;其次,可借助 runtime 实现深层次优化(比如说字符串转换,以及 GC 扫描等)。可尽管如此,也不意味着万事大吉,依旧有很多需特别注意的地方。

|