记录salt的一个问题

现象:

cpu使用 接近100%

strace 跟踪结果

 

进程调用栈:

 

从调用栈来看,就算有bug也是libzmq的bug

 

关于redis短连接问题

场景:

PHP通过phpredis(https://github.com/phpredis/phpredis)循环执行如下操作:

 

 

发现connect会出现大量超过1s的情况,甚至超过3s;但是,如下图抓包所示:两次请求之间间隔了3s才发送syn请求,并且没有失败,也就是说,并非syn丢包所致,而是因为某种原因导致根本没有发送syn包;但是外部表现却是connect花费了很多时间(3s);

所以,从此推断,连接超时未必就一定是网络的问题,你们究竟会是什么原因导致client端3s后才发送syn的呢?

 

阅读源码发现: redis的connect用的是php提供的connect方法:php_stream_xport_create

其实,fsockopen用的也是该方法,如此的话,不放通过如下脚本直接测试connect:

结果如下:

  1. connect超过1s的还挺不少的
  2. 前面300多次的时候连续出了好几次超过1s的,你们怎么会从374到13489一直没出错呢?而且,运行程序的时候也能感觉到,从第374到第13489花费时间很短的,难道这个区间根本没有发生真正的连接? strace 跟踪统计发现,确实connect了,就是说,一般情况下,connect是很快的
  3. 该问题可能发生在PHP中,也可能发生在glibc中,也可能发生在系统层面,排查办法:
    1. 写一个C的,如果不出现问题,那么就是PHP的问题;如果依然如此,很可能是系统问题

让go get 支持gitlab

参考文章: https://baokun.li/archives/go-get-proxy/

在你的nginx中添加配置:

注意:修改你自己的域名

另:

  1. 可能你自己的gitlab没有配置https,那么可以给go get 添加 -insecure 选项即可
  2. 可能你的gitlab仓库需要输入用户名和密码,那么你可以改成public的就好了

 

关于docker

  1. docker create -it 其中 -it选项,如果没有的话,docker exec 进去,top时会报 TERM environment variable not set. 错误 ; 其实没有关系,手动 export TERM=xterm-256color 就可以了;其实, -it 选项和1号进程为 /bin/bash 是密切相关的; 如果1号进程不是 /bin/bash 的话,-it选项没有屁用
  2. docker 的CMD 其实是1号进程,一定不能立即就会退出的进程,如: service sshd start 就不行,如下脚本就可以:

     
  3. 容器可以自杀: 容器内进程使用root kill -9 1 默认是杀不死1号进程的,但是:
    当strace -p  1 的时候,kill -9 1 是可以杀死1号进程的 (难道说这是个bug?)
    因为docker stop时是先给1号进程发送sigterm,是在不行才kill -9 ; 所以,1号进程最好能合理处理sigterm信号,最后退出;然而,容器内的root进程是有权限给1号进程发送sigterm信号的,所以,容器自杀其实是很方便的
  4. 改进版的1号进程
    myinit.c

    gcc -o myinit myinit.c
    myinit.sh

  5. 其实还不够
    你会慢慢发现,ssh连接失败,因为:sshd接到连接请求之后,检查是否session太多了(默认最大10个),超过了就不伺候了,直接断开; 为什么会太多了?sshd每次接到连接请求,会fork => fork (两次fork)出来一个子进程处理请求,就因为是两次fork,这个新的sshd进程便“过继”给了1号进程;但是上面的1号进程还不够成熟,不会带孩子,当这个新的sshd进程退出的时候,就需要1号进程来做一些处理(如:清理进程表项),但是1号进程还不会,于是新的sshd进程会处于 <defunct>状态;而sshd的祖先还以为该session还没结束,就不再接受新的请求了,解决办法:添加信号处理,如下:

    参考资料:
    https://blog.phusion.nl/2015/01/20/docker-and-the-pid-1-zombie-reaping-problem/
    https://github.com/phusion/baseimage-docker/blob/rel-0.9.16/image/bin/my_init
    dockerd 提供了init 和init-path的选项,允许配置是否启动一个指定的(默认的)init进程, 该进程就是为了转发信号和收割僵尸进程 的
  6. 上面sshd对于连接请求是两次fork的说法不太对,见下图:

    99、134进程并没有立即退出(不过,一旦意外退出,则 101、136将会被1号进程收养)
    还有一种情况为:sshd被restart了,这时候30号进程退出,99、134被1号进程收养,如下:

    由于我重启了sshd,再次连接就会失败,如下:

    为什么呢?
    稍后再查,至少可以确定的是,启动容器时候启动的sshd是可以正常服务的,登录进去重启的sshd是不能正常服务的

 

see also : https://docs.docker.com/engine/examples/running_ssh_service/

 

关于docker的内存限制:

  1. 如果每个docker容器限制最大使用4G,则可能会使用超过4G,(似乎是使用了交换分区了)
  2. 如果宿主机有64G内存,则允许docker容器内存总和大于64G,(这个不会也和交换分区有关吧)
  3. 文档说–memory-swap=-1 就禁止使用交换分区了,但是测试发现还是使用了1倍内存的交换分区

缅怀一下阿里云云引擎

 

学习一下人家下线产品是咋写的: