早些年,如果你知道有个 strace 命令,就很牛了,而现在大家基本都知道 strace 了,如果你遇到性能问题求助别人,十有八九会建议你用 strace 挂上去看看,不过当你挂上去了,看着满屏翻滚的字符,却十有八九看不出个所以然。本文通过一个简单的案例,向你展示一下在用 strace 诊断问题时的一些套路。如下真实案例,如有雷同,实属必然!让我们看一台高负载服务器的 top 结果:
认识自己很重要!
No results found
早些年,如果你知道有个 strace 命令,就很牛了,而现在大家基本都知道 strace 了,如果你遇到性能问题求助别人,十有八九会建议你用 strace 挂上去看看,不过当你挂上去了,看着满屏翻滚的字符,却十有八九看不出个所以然。本文通过一个简单的案例,向你展示一下在用 strace 诊断问题时的一些套路。如下真实案例,如有雷同,实属必然!让我们看一台高负载服务器的 top 结果:
不要被经验主义羁绊;生产环境的进程管理工具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
truss和strace都是用来跟踪一个进程的系统调用或信号产生的情况,而 ltrace用来 跟踪进程调用库函数的情况。
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 ...]]
Transfer-ncoding
,是一个 HTTP 头部字段,字面意思是「传输编码」。实际上,HTTP 协议中还有另外一个头部与编码有关:Content-Encoding(内容编码)。Content-Encoding 通常用于对实体内容进行压缩编码,目的是优化传输,例如用 gzip 压缩文本文件,能大幅减小体积。内容编码通常是选择性的,例如 jpg / png 这类文件一般不开启,因为图片格式已经是高度压缩过的,再压一遍没什么效果不说还浪费 CPU。而Transfer-Encoding
则是用来改变报文格式,它不但不会减少实体内容传输大小,甚至还会使传输变大,那它的作用是什么呢?本文接下来主要就是讲这个。我们先记住一点,Content-Encoding 和 Transfer-Encoding 二者是相辅相成的,对于一个 HTTP 报文,很可能同时进行了内容编码和传输编码。
lombok 提供了简单的注解的形式来帮助我们简化消除一些必须有但显得很臃肿的 java 代码。特别是相对于 POJO。官方网站lombook。它由2部分构成。一部分是idea插件,主要实现编译增强。另一部分是它的API。
总有人说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调试了
两个可以分开使用
实际项目中不建议做这些处理,没啥必要。