docker资源限制之cpu篇

  1. 通过 –cpu-quota 限制容器使用的cpu的配额,如:
    –cpu-quota 50000 : 最多允许使用1个核心的50%
    –cpu-quota 300000: 最多允许用满3个核心,如果只给该容器分配了2个核心,则用满2个核心为止
  2. –cpu-period (默认 50000),和–cpu-quota 一起使用
  3. 通过 –cpuset-cpus 限制容器只运行在指定的几个核心上,如:(留几个核心,避免跑死宿主机)
    –cpuset-cpus 1,2 : 允许使用1、2两个核心
    –cpuset-cpus 0-3:允许使用0、1、2、3 核心
  4. 通过 –cpu-shares 调整容器使用cpu的权重(用于实现偏心)

centos7(或者其他系统也有)上有个kworker的进程,似乎是用来分配系统时间的(可能我理解的不对),参考: http://askubuntu.com/questions/33640/kworker-what-is-it-and-why-is-it-hogging-so-much-cpu

 

参考资料: https://docs.docker.com/engine/reference/run/

timewait high之 debug方法

  1.  ss -s   发现timewait好高
  2. 如果自己的client,可以看看是调用外部的哪个服务太频繁了

  3. 如果自己是server,可以看看是自己的哪个服务导致的:
  4. 或者,只统计外部服务器的IP也可能有助于找到问题的原因
  5. 。。。

解决办法:

  1. 长连接
  2. 不要主动关闭连接,如果走的是http协议,而且是别人的服务,则可以(如果对方支持的话)强制使用HTTP/1.0协议,这样的话,client端不做主动关闭,就不会有timewait;
  3. HTTP/1.1中有个Connection的头,可以设置Connection: close,server端就会主动关闭连接了

效果跟踪:下面是使用HTTP/1.0后的效果:

非主流抓包工具

httpry:

An open-source HTTP packet sniffing tool which captures live HTTP packets with libpcap library, and displays HTTP requests and responses in a human-readable format. It comes with a collection of parsing Perl scripts for mining various information from its standard output.

效果:

安装:

  1. linux下yum可以安装
  2. 其它系统编译安装,源码: https://github.com/jbittel/httpry (从源码来看,虽然是c写的,似乎可以写perl插件)

 

 

mysql sniffer: https://phpor.net/blog/post/9562

haproxy 实现http隧道代理

什么是http隧道代理?(自己搜吧)

haproxy的经典逻辑是:每个请求都分配给所配置的后端(backend)来处理;对于connect请求,原则上不需要添加配置backend的,但是这不符合haproxy的规则;测试+跟踪源代码发现: haproxy根本不能实现http隧道代理,之于option http-tunnel 配置也不过是生命不要解析第一个请求之后的数据而已,connect请求还是要原样转发给backend的

haproxy 健康检查与域名解析

配置:

其中:

  1. check 说明要开启健康检查
  2. fall 100 rise 1: 失败100次才会被自动摘掉,对于被摘掉的机器,成功1次就能挂回来
  3. resolvers dns: 使用指定的dns 进行解析; 如果为开启健康检查(即: check) 则该配置将不生效(这叫什么逻辑?),参考: http://cbonte.github.io/haproxy-dconv/configuration-1.6.html#5.2-resolvers
  4. resolve-prefer ipv4: 参考ipv4地址,这个配置避免解析没有必要的ipv6, 参考: http://cbonte.github.io/haproxy-dconv/configuration-1.6.html#5.3.2

    字面意思来看:DNS总是会解析ipv4和ipv6的,只是Haproxy优先参考哪一个。
    实测的结果是:指定了ipv4后,就不会再去解析ipv6地址了(这样效率更好)
    或许dns类库也可以一下子解析出来ipv4和ipv6的

 

为什么profile中设置的环境变量在crond中取不到?

环境: centos6

分析:

一般来讲,都是因为在某个环节把环境变量给清了:

  1. 要么是应用程序为了安全,自己清理了环境变量;这种情况多半在应用程序的配置中允许设置保留哪些环境变量(如:sudo程序)
  2. 要么是外部脚本启动应用程序时(使用env命令)把环境变量给清了;如: service命令启动服务(如: crond)时就使用env清理了环境变量:

    解决办法: 要么不清环境变量,要么添加自己期望保留的环境变量

根据上面的理论,修改了/sbin/service 添加了自己想保留的环境变量,如下:

(其实,如果直接使用/etc/init.d/crond start 来启动crond是和 /sbin/service 没有一毛钱关系的)

测试发现,在crond中启动的程序,依然获取不到想要的环境变量;根据上面理论,基本是crond把环境变量给清理了,那么这个该怎么办呢?

解决办法1: 给每个cron 任务写一个wrapper,在wrapper中设置自己需要的环境变量,wrapper.sh如下:

这样,只需要在每条cron的前面添加 wrapper.sh 就行了,如下:

cron执行log如下:

看起来还不错:)

但是,我有上百条cron,修改起来好是麻烦;其实通过写脚本来添加,还好;不过每次添加新的cron都要记着先写/tmp/wrapper.sh 有些繁琐,忘记了怎么办?

解决办法2:

据说cron会参考环境变量SHELL,而且可以在crontab中设置这个SHELL,你们crond应该就是用这个东西启动子进程的,否则要这个干啥?如果我在crontab中如下设置:

其不很方便?

测试发现并不如此简单,原因如下:

  1. 如果SHELL设置为/tmp/wrapper.sh 则crond是这么使用的:
    /tmp/wrapper.sh -c “/bin/echo 1 >/tmp/debug.txt”
    显然,我的wrapper.sh中没有处理-c选项; 简单,我也不关心这个,直接shift掉不就完了?wrapper.sh 修改如下:

    测试发现找不到/tmp/debug.txt;但是,在cron的邮件中找到了 “ 1 >/tmp/debug.txt”(这是cron任务的输出); 分析发现,我们的wrapper.sh 似乎并不认识 “>” ,难怪,我的wrapper.sh确实不是一个shell,不能解析 “>”, 但是如果为此写一个认识 “>” 的shell也不值当的呀!还是让bash自己来干吧
  2. 我们上面已经说了,crond使用了bash的-c选项,-c选项就是把字符串当做shell来执行,我何不学下呢?如下:

    嗯,就是这样子的

 

附录: vixiecron 的源码(src/do_command.c)中(函数: static int child_process(entry * e, char **jobenv); )是这么运行任务的:

man execle可以知道:

其中,最后一个参数是要执行的shell的环境变量,没有继承父进程的环境变量(虽然没有专门clear所有的环境变量)

 

其实,完全可以在crontab file的前面定义想要的环境变量的,这里定义的环境变量不会被清空