记一次排查ES FGC导致的集群宕机异常
有一个私有云环境的运维同事反应项目中的ES集群无法查询, 由于是私有云环境, 没有直接运维权限, 所以没有接收到一线报警, 远程登录上去后发现ES集群已经宕机了, 这次的排查过程也发现了几个比较容易忽视的细节, 在此记录一下,比较有意思.
有一个私有云环境的运维同事反应项目中的ES集群无法查询, 由于是私有云环境, 没有直接运维权限, 所以没有接收到一线报警, 远程登录上去后发现ES集群已经宕机了, 这次的排查过程也发现了几个比较容易忽视的细节, 在此记录一下,比较有意思.
之前学习了prometheus的架构及一些基本术语, 今天学习一下Prometheus的服务发现机制,这块的内容占据比较大的份额, 主要学习下基于kubernetes做服务发现.
字符串在所有语言中可以说是用的最频繁的一种数据结构, 在golang中当然也存在.虽然字符串往往被看做一个整体,但是实际上字符串是一片连续的内存空间,我们也可以将它理解成一个由字符组成的数组
生产中由于历史遗留问题,有些程序还是二进制部署, 对于这类程序需要使用守护进程进行托管,常用的能实现对程序进行守护的用的多的有如systemd, supervisor,monit等工具, monit其实更好用一些,拓展性也很强,但是因为线上已经有一些使用了supervisor,为了工具统一化,就都使用了supervisor了,这次讲一讲supervisor使用自定义邮件模板实现报警的实现
Kubernetes集群中的容器监控数据已经通过Prometheus采集上来,在Grafana上配置可视化的时候,发现了个很有意思的需求,即:按物理机展示各种状态下的容器占比情况
如果使用Prometheus做监控系统的话, node-exporter一定是不能绕过的采集工具, 开箱即用的实用性让运维同学节省很多时间, 最近也是发现了一个比较有意思的功能, NodeExporter可以采集额外的Metrics到Prometheus中
组成一个package的多个文件,编译后实际上和一个文件类似,组成包的不同文件相互之间可以直接引用变量和函数,不论是否导出
go中对于变量(函数也是如此)使用首字母大小写来区别是否可引用. 首字母大写则能被其它包引用(不完全正常, 目前先这么理解).
1 | // cat main.go |
1 | // cat other.go |
在命令行下运行go run .
输出很正常
1 | 0 |
var比较直接, 使用没有限制
1 | package main |
####:=
:=个人觉得是个比较好的设计, 干练简短, 虽然在开开始学的时候常常会用错
:=用于声明变量并初始化, 且只能用在函数中, 如果你在函数外使用:=会提示
non-declaration statement outside function body
1 | func main() { |
上面的错误提示,说没有一个新的变量, 原因就在于xx之前已经被定义了, 不能重复定义. 所以这里只能使用赋值
a := 100
这句话是声明了变量a, 且给a赋值100
1 | // make slice、map和channel,并且返回一个有初始值(非零)的类型 |
1 | // new 用于分配了零值填充的T类型的内存空间, 它返回了一个指针,指向新分配的类型T的零值 |
make跟new是两个用的比较多, 在这里只是简单介绍下, 后面会单独学习它们的区别
const跟其它语言的用法一样, 都是声明常量, 常量就是不能被改变的变量(当然通过常量指针还是可以修改的)
const 可以在任何地方使用
1 | package main |
iota在const中比较特别, 因此特意提出来说一下
1 | const ( |
首先,iota是可以参与运算的, iota带表达式的都将应用到下面的常量
比如上面的1<< iota,此时等于0, 整个表达式的值为1
每二行, iota的值等于1了, 1 << 1, 整个表达式的值2
以此类推.
iota在const关键字出现时将被重置为0(const内部的第一行之前),从第一行开始, 每新增一行常量声明(不包括空行及注释)将使iota计数一次(iota可理解为const语句块中的行索引)。使用iota能简化定义,主要用于定义枚举,而且很有用
1 | const ( // iota在const内部的第一行之前就被初始化为0 |
const及iota可参考这里
1 | // 常见的基本类型零值 |
有个比较特殊的零值nil
, 这个必须要单独说.
如果把一个包分成多个文件,在IDE如vscode中run时,可提示如下错误
最开始的时候一脸茫然, 很明显是因为在ide运行的时候,执行的命令是go run main.go
, 只传入了一个main.go,而没有传递others.go, 因此找不到mainxx(), 在命令行下执行也会报同样的错误. 需要运行go run .
或者go run *.go
,另外, 最好不要形成循环引用, 如果两个文件需要相互引用的话, 引用第三方是个推荐的办法.
Prometheus做为CNCF的第二个项目,被给予厚望, 现已然成为监控系统设计的标杆. 特别是对于Kubernetes的支持,可谓天衣无缝. 使用kubernetes,很难跳过prometheus不说.
golang到现在还没出现一款类似log4j这么强大的日志打印工具, 在调研了一番之后发现,现在用的最多的是logrus跟zap, github上的star也比较多, logrus使用起来比较简单, 不需要做过多的设置, 导入就能使用, 非常方便, 而zap则侧重在高性能方面, 基本所有的参数都可配置,不过需要的代码比logrus多.
golang中经常会用到make来初始化变量, 另外还有new也可以用来定义及初始化变量,这两者有啥区别呢?