Living a Simple Life is a Happy Life

有饭吃,自由自在,就非常开心

科技进步是安全行业的最根本保障

| Comments

今天上网的时候突然发现有人邮件问什么是矿震。原来是知乎的注册号职业还是煤矿行业,知乎还是挺智能的~~~

查了一下,辽宁那又有矿难了,矿震引起煤尘爆炸。唉……

什么是矿震呢,矿上有叫岩裂的,有叫岩震的,说法不一。书上的说法是冲击地压。通俗点就是地底下挖空了,巷道两侧岩石受不了压力,就压裂塌陷了。

我是没遇见过,矿上听过一些老师傅讲岩裂的时候,最可怕的是两侧的石子像子弹一样弹出来,人在那个时候是没什么办法的,趴在地上逃过一劫,一般高瓦斯的矿也会引发爆炸之类的事故,这个时候就听老天爷的了。

又胡思乱想了很多事情。

我刚入行,到各个煤矿下过一些井的时候,有很多不明白的事。那时候我一边看书上的一些矿压理论,一边在井下看实际的生产,发现了很多可以改进的地方。比如离层监控,直接顶垮塌预警,还有支护距离、支护强度的选择~~~ 这些事情都是有现有理论支撑的,很多情况下找几位真正懂行的专家来,做好规划和基础建设,后期是能省下很多气力的,生产也能安全的多。

那个时候,我用很幼稚的办法写着一个支护专家系统,想着可以用电脑帮助预测离层压力,该如何选型液压支柱等,还想着要是有个论坛,供全国的煤矿从业者交流经验,提炼知识就好了。

后来,我又下了一段时间的井,有一个很心凉的发现或想法,现在也不能摆脱:

那就是,人命也许不是那么值钱,无论是在他人眼里,或是在自己眼里。

我记得那时候外来人员,像我这样的厂家人员下井,一般会买20几万的地险,我至今也没有去查过之前从业的公司有没有给我买工伤保险,有点可笑是不。可事实就是这样,在山东很多小县城,正规给工人交齐保险的小工厂几乎没有,相比下,富士康其实已经是非常良心的企业了。即使企业按最低标准给你交齐各种保险(这家企业还能正常运转),你换工作,流动到其他地方后,这些钱大部分还是要孝敬当地政府的,而且那点钱再转到外地还不够跑腿的功夫。可能一些工作稳定,长期在一个地方生活的人体会不多。但是当我辗转几个地方后,就发现交类似养老保险这种事无论对企业还是工人都是非常不划算的。

所以在很多地方,工人和工厂心照不宣,在没有保障的前提下尽量活着。

事实上,无论是工厂还是工人自己,对自己的命值多少钱,估量的数字都少得可怜。在非常好的条件下,一个青壮年在井下挂了,能得到的赔偿我估计就在30-40万之间。而且这还是”毛利”,为了得到这笔赔偿你还要杂七杂八的各种打点开销。这个估算就是以山西国有大矿为参照,像甘肃那样年产40万吨的小矿就不说了。

但更令我惊奇的是,甘肃那样的小矿,井下条件反而比山西的大矿好得多,井口的巷道会贴瓷砖,会有很明亮的灯,下井的工人也比大矿的工人心情更宽松。虽然硬件设施比不上人家财大气粗,但软件上的很多小细节都很贴心。

后来我明白了,就是西边的老矿区,一般还是把人当人来看的,说的不好听些,你真的埋在井下了,虽然赔的钱比不上大矿,但一般还有人情世故,给你家其他人安排个矿上清闲活,家里也有矿上的左邻右舍照顾着,这就是我们老派国企的作风。 像山西很多大矿,我觉得是市场化和国有企业的奇怪混合体。工人的价值,管理制度,硬件建设,都市场化了;说白了,就是这个投入下去,要比你的命便宜,就投,你的命贱,就不投。但煤炭销售,利润分配,还是要国家来管。

有很多瞎扯的专家讲这个制度,那个管理。似乎每次事故出来都是管理问题,制度问题……不错,肯定是管理问题,制度问题。但是,我下井的时候,干活很累的时候,不止一次想过:就是现在顶塌了,也无所谓。 人在极累的时候,什么也顾不上的。这是人不可克服的弱点。当工人连自己性命也轻忽的时候,你和他讲这个管理,那个制度,专家们,敢到井下去讲讲吗。

管理当然很重要,后来我觉得,安全行业最根本的保障在于科技进步。只有人远离危险的时候,才有闲情谈管理,谈制度。

听新闻说中国已经成为全世界最大的机器人消费市场,非常高兴。

有人说会有下岗,会有就业萎缩。

我只想问:人命有贵贱吗?人命有价格吗?

如果你不想回答这种无聊的问题,就不要再对更无聊的问题评头论足了。

Pycon2014 in Shanghai

| Comments

今年又去打酱油了。在上海有这点好处,可以很方便的找到各种组织~~~

去年拿了个帽子,今年发了件T恤,明年来条短裤就套装啦。

这次Pycon非常赞,上海的组织者真用心,这次无论是演讲还是气氛都很到位。志愿者们真的辛苦了,十二分的敬礼。

讲的内容有几点让我很惊艳的:

  • 讲协程的时候提到,函数的返回值不必返回给调用者,可以返回给三方,很有启发

  • 黄冬老师讲测试3层设备或者网站性能的最好办法,是把一段时间的DDOS发包抓下来,或者造出一堆SYN,直接用tcpreplay打到目标机上。很好很粗暴,也很有效

  • 关于OpenCL在数据计算领域的应用,让我有点吃惊,已经这么易用了,回头要看看

  • 以前一直听人说postgresql怎么怎么好,这次又被强化了一遍,这个也要研究研究

  • 中间看到有演讲者调试程序用lldb,之前我一直以为它不靠谱,貌似已经很成熟了

  • 机器学习讲的简洁明了,让我这个门外汉也听得津津有味

  • 中间的台湾演讲同五地互动的创举,太有想法了,虽然效果不理想,但我想说太Cool了,未来的大会互动会更多元,更精彩,为这个尝试鼓掌

  • 主持人非常专业,聪敏又风趣,可以直接上央视啦

还有几点不足的:

  • 话筒时好时不好,这个估计让大家有点提心吊胆的。这个是经验啊,以后组织类似的活动话筒要多多益善,还要多备电池。

  • Django和创业的两个议题都有点浅,太多讲Python的ABC了,这方面的内容可以收缩下

另外有点Confuse,会上有人提到用libpcap抓包分析网络流的,黄冬老师说性能没问题。其实我们这测试下来,绑定CPU抓包,libpcap通常的性能就在单网卡400Mbps左右。 如果用Zero Copy的话,可能性能有提升,但也不会太高。目前抓流量效率最好的是Intel的DPDK,可以到10Gbps。

还有魔豆提到用Selenium做自动化测试的事情,我用Selenium觉得,他的适用场景在WEB UI很少变化,并且页面结构简单的企业软件,像传统的路由器管理界面这样的东西,用它的录制测试还是可以的。 但是界面稍微个性化一些,想让测试代码长久,必须手写代码,而且是简单可靠的代码,不能单纯追求覆盖率。Selenium的测试代码虽然好写,但也容易废弃,要想写的简单可靠还是很有难度的。

关于UI测试,我的想法就是,尽量降低编写成本,如果一个UI测试挂了,你不能在5分钟之内修复它,直接丢弃掉!编写UI自动化测试的成本不应该超过5分钟,如果一个测试要频繁维护,那么,是重新写一个的时候了。 要想达到这个目标,我想到的简单解决方案就是图像DIFF,facebook之前出过一个huxley,我很有兴趣的研究过,还PULL过代码,但这个东西还是离我心目中的自动化图像DIFF有距离。后来又自己写了一个能把每天的测试结果保存下来,并能基于时间查看对比的东东,但效果也不好。

我想象中的web UI自动测试是这样的:

  • 支持比较模板点自定义

    对比的截图可以是基于录制时间最早的case的,如果中途重新录制,提供用户自定义机制。

  • 支持时间轴功能

    1、查询时间范围的灵活选择,可以很简洁的查询某段时间、或某个时间点的case.

    2、可以在时间轴上直接修改比较模板的base时间点

    3、以不同颜色标识base时间点、pass的测试、fail的测试以及fail的个数,测试名称等

  • 比较智能的图像DIFF算法:

    1、首先要能忽略指定区域,因为有些区域能够预测到是不断变化的。

    2、能对整张图、或某几个区域提供多个选择,如果符合其中一个我们就认为是OK的

    3、能提供组件级的识别,比如某个button,某个搜索框等等,一张截图里面如果所有指定的组件都OK,我们就认为是OK的。

PS:已经出现了类似的开源项目:

https://github.com/Huddle/PhantomCSS

最后感概下,Pycon一年比一年进步,志愿者们功不可没。对于他们的工作,怎么赞誉都不过分。非常感谢!

用TCP/IP进行网际互连 (笔记)

| Comments

还是要补习基础知识啊。

譬如TCP的状态机转换,我每次都得花很长很长的时间才能反应过来什么时候会进入TIME_WAIT,CLOSE_WAIT….

譬如一个pcap包,看了很长很长时间才发现是个规避糊涂窗口的Nagle算法…

譬如这本书,每次扫一遍好像都能知道怎么回事,过了段时间就又雾里看花了….

这次通读一遍,又发现一些有意思的东西,记一下:

底层网络技术回顾

  • 最初的电话系统是面向连接的电路交换,后期(就是现在)的IP网络是基于分组交换的

    讲起来很简单,实际上为了实现分组交换网上的通信质量达到电路直接交换的效果,还是要付出很大努力,才能克服时延、抖动、通信质量等多个问题

  • 以太网容量

    当前以太网不是为一对计算机之间提供可能的最高吞吐率而优化的,而是为更多网点介入和更多通信总量优化的。当前10G以太网的帧长度和格式还是保持10M网的标准,从这方面看,10G以太网在物理层的协议上还是有优化余地的。

  • POE可以提供48V,不超过15.4W的功率消耗,这个数字还是挺可观的

  • 关于以太网的一些特点

    CSMA/CD 是很简单但有效的手段,值得后来的分布式系统借鉴

    以太网在物理层上只是”尽最大努力交付(best effort delivery)”,但如果碰到问题,错误不会得到通知,数据包会丢弃

    frame帧大小 64B~1518B

    线缆的集合造就集线器,集线器升级为连接任意多的以太网就变成网桥,网桥提供自适应的帧转发,这样任意多的以太网就集合为一个物理网络,他们也遵循CSMA/CD。网桥提供更完善的隔离和配置方案就变成了交换机。

    以太网的地址(MAC)是要向IEEE买的

    以太网基础上升级为WIFI就有了两个很重要的技能: * 可作为接入点基站 * 可作为接入点连接(点对点),也就是WI-MAX

网际互联的模型

  • 路由器的工作,某种情况下和DHT很相似,不过实现的约束更多一些

  • 定向广播地址,主机号都为1

  • 受限广播地址,255.255.255.255 (本地子网广播)

  • 0.0.0.0有时候也用于广播,这是早期BSD实现的一个bug。后来有些软件为了兼容,也这么实现了。

  • 0.0.0.0 表示无路由目标,有些应用把绑定这个的设置,认为是绑定全部本地IP。类似于一些设置中,设为0就相当于该项设置无限制。

  • 127.0.0.1 是本地环回地址, 专供自己访问自己, 速度大( 不用经过整个协议栈 )

  • 地址管理早期是由IANA 管理的,早期的IANA地址维护者仅仅是一个人,Jon Postel,这位传奇人物在1998年过世,后来IANA成长为更完善的组织,ICANN是也,目前由ICANN管理地址相关分配工作。

  • IBM的地址段是9.0.0.0,AT&T的地址段是12.0.0.0

ARP

  • 没什么好讲的了,这个是最熟悉的

无连接网络

* 错误会被丢弃!!!

* IP报文已经包含了源-目的地址

* 分片控制

* 优先级

* 校验和

* 路由信息和时间戳

ICMP

  • 最好和Ping结合起来学习

最后,读这本书后面的应用层也很好玩,能延伸想象很多东西,比如现在Linux下虚拟网卡的实现,Vmware如何虚拟物理网卡的,还有早期浩方上如果实现虚拟局域网的,很多原来看起来Magic的东西,其实原理很简单,平时多想想会很有趣。

从TCP/IP的设计来看,我们的网络应用还是停留在很”初级”的阶段,还没有完全发挥出他的潜力。未来肯定还会出现像P2P软件这样神奇的颠覆者,TCP/IP所承载的流量也会一次次变化,如果把TCP/IP比作海的话,不知道下一位弄潮儿是谁。

Uwsgi部署django程序

| Comments

Python的web世界,部署首选uwsgi,既可独战,又可搭配Nginx等车轮战,实在是居家必备。

但我每次都得搞都得去翻一遍手册,实在烦了,记一下简单粗暴的测试方案。

安装

pip install uwsgi

测试

写一个最简单的test.py:

1
2
3
4
# test.py
def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return "Hello World"

python3的话需要返回一个binary

1
2
3
4
# test.py
def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return [b"Hello World"]

执行shell命令:

uwsgi --http :8000 --wsgi-file test.py

访问:

http://127.0.0.1:8000/

因该能看到Hello World

集成Django

django-admin startproject testuwsgi

这样生成的项目,django版本不同,目录会有微小的差别,找manage.py就对了

如果是>django1.6的话,会自动生成wsgi.py文件,没有的话编辑一个:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/usr/bin/env python
# coding: utf-8

import os
import sys

# 将系统的编码设置为UTF8
reload(sys)
sys.setdefaultencoding('utf8')

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")

from django.core.handlers.wsgi import WSGIHandler
application = WSGIHandler()

执行:

uwsgi --http :8000 --chdir xxxxx/testuwsgi --module testuwsgi.wsgi

访问:

http://127.0.0.1:8000/

因该能看到Django的欢迎页面了

支持Https

uwsgi自1.3版本开始支持https

分两步走:

生成证书

openssl genrsa -out foobar.key 2048
openssl req -new -key foobar.key -out foobar.csr
openssl x509 -req -days 365 -in foobar.csr -signkey foobar.key -out foobar.crt

走起

uwsgi --master --https 0.0.0.0:8443,foobar.crt,foobar.key --chdir xxxxx/testuwsgi --module testuwsgi.wsgi

访问的时候要以:

https://127.0.0.1:8443/

OK了

至于怎么搭配Nginx,写配置文件,搭配Supervisor,还是老老实实翻手册吧,反正这个不是经常做。

How to Auto Gen Css/js by Grunt and Jenkins

| Comments

虽然有grunt-contrib-watch的存在,但多个人编辑同一份css/js代码时,还要操心编译这个事,实在是多余。

想到的最直接的办法就是jenkins上开一个项目,自动编译一把,再自动提交:

虽然是野路子,但效果那是杠杠的。

记一下一些要注意的点:

  • 有时候自动编译会失败,需要标记一下:
1
2
3
4
5
6
7
/usr/local/node-v0.10.20-linux-x64/bin/grunt --force |tee $PWD_DIR/grunt.log
err_count=`grep 'Error' $PWD_DIR/*.log|wc -l`
fail_count=`grep 'failed' *.log|wc -l`
abort_count=`grep 'Aborting' *.log|wc -l`
if [[ $err_count -gt 0 || $fail_count -gt 0 || $abort_count -gt 0 ]]; then
    exit 1
fi

这样jenkins编译失败,就会标红了

  • 还有个坑,有时候新增加了一个js的代码目录,这样编译后也会多一个目录,这就需要svn每次提交的时候,不要忘了强制add一下当前所有目录:
1
svn add static/dist/ --force
  • 最后,极少数的情况编译后会出现冲突,因为编译的时候有人同样编译了一把提交了,这样自动提交会失败,也需要标记一下:
1
2
3
4
5
6
7
svn ci --no-auth-cache --username=xxx --password=xxx static/dist/* -m "jenkins:auto grunt" 2>&1| tee $PWD_DIR/svn.log
err_count=`grep 'Error' $PWD_DIR/*.log|wc -l`
fail_count=`grep 'failed' *.log|wc -l`
abort_count=`grep 'Aborting' *.log|wc -l`
if [[ $err_count -gt 0 || $fail_count -gt 0 || $abort_count -gt 0 ]]; then
    exit 1
fi

这样基本上看看jenkins的状态,或是让jenkins自动发发邮件,就舒心了。

How to Compile by Autotools

| Comments

虽然因为llvm的出现,开源工具链又开始慢慢进化了,但是很多项目还是需要autotools自动gen configure的,但是我每次命令都记不全,还是记一下吧

1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash

echo "Running aclocal..."
aclocal || exit 1
echo "Running autoheader..."
autoheader || exit 1
echo "Running autoconf..."
autoconf || exit 1
echo "Running automake..."
automake --add-missing --copy || exit 1
echo "Finished."

Markdown Raw Format

| Comments

有时候想要在Markdwon里面画ASCII画,会被Format掉,例如:

|——————–+ | | | —— ——- | | | | \ / | | ——-/ | | | +——————–+

这个时候可以用缩进来解决:

|--------------------+
|                    |
|  ------    ------- |
|                    |
|     \        /     |
|      -------/      |
|                    |
+--------------------+

参考: https://meta.stackexchange.com/questions/177133/turn-off-markdown-formatting/177135#177135?newreg=acda653c863843a99d1008c464864262

引发了一点兴趣,meta.stackexchange.com上面有个测试语法专贴,各种乱搞洋洋大观:

http://meta.stackexchange.com/questions/3122/formatting-sandbox/43134#43134

Docker Cheat Sheet

| Comments

container相关

1
2
3
4
$ docker run -it xxx /bin/bash                                      // 启动一个container
$ docker rm -f xxx                                                  // 结束一个container,加-f表示删除掉,这样比较干净
$ docker run -it --add-host host:ip xxx /bin/bash                   // 启动一个container,增加/etc/hosts设定
$ docker run -d -p 127.0.0.1:5000:5000 webapp python app.py         // 启动一个container,映射本地的5000端口

image 相关

1
2
3
4
5
$ docker rmi -f xxx                                                 // 删除一个image,以下情况下不能删除:
                                                                    // * 有其他image依赖于这个image
                                                                    // * 有已创建的container依赖于这个image
                                                                    // build的过程会出现很多<none>的临时image,最好不要去手工清除
$ docker build tag Dockerfile_dir                                   // build一个image

docker service 相关

配置文件位置

  • ubuntu: /etc/default/docker

  • centos: /etc/sysconfig/docker

配置参数

DOCKER_OPTS

增加docker 仓库验证

--insecure-registry own-docker.com

设置storage backend

-s overlay

使用overlay极大提升性能和稳定性,建议开启。但是有两个问题:

  • 编译centos镜像时,调用yum会报checksum错误,所以基本上不能在overlay上面构建redhat系的镜像

  • 不支持 inotify_add_watch 调用,tail -f 类的命令会有问题,具体见:https://github.com/docker/docker/issues/11705

相关工具:

docker镜像瘦身工具

https://github.com/jwilder/docker-squash

nsenter, docker inspect的增强版

https://github.com/jpetazzo/nsenter

dockerfly,自己写的一个构建工具

https://github.com/brain-zhang/dockerfly

shipyard,还算是比较靠谱的监控工具

https://github.com/shipyard/shipyard

一些坑:

  • centos 在4.0.0-1.el6.elrepo.x86_64内核下,启动xfs+overlay,删除文件夹会有问题
  • overlay下,tail命令会有问题
  • overlay下,docker build,yum的checksum会有问题
  • devicemapper效率巨慢无比,不要用

python2.x:Error When Printing an Exception Containing a Unicode String

| Comments

Python2.x中抛出Unicode的异常需要注意:

1
2
3
4
5
>>> try:
...     raise Exception(u'Error when printing 中文异常')
... except Exception, e:
...     print e
...     print str(e)

会报UnicodeEncodeError: ‘ascii’ codec can’t encode character …

同样,如果在log中直接输出,也会报错

1
2
3
4
5
6
7
8
>>> import logging
    logger = logging.getLogger('default')
    try:
...     raise Exception(u'Error when printing 中文异常')
... except Exception, e:
...     logger.error(e)
...     logger.error("%s", e)
...     logger.error("%s", str(e))

简单的解决办法就是用e.message

1
2
3
4
5
>>> try:
...     raise Exception(u'Error when printing 中文异常')
... except Exception, e:
...     print e.message
...     print "%s" % e.message

也可以详细的可以指定encoder

1
2
3
4
>>> try:
...     raise Exception(u'Error when printing 中文异常')
... except Exception, e:
...     print unicode(e.message).encode('utf-8')

Python3就没这个事了,备忘一下。

参考:

http://bugs.python.org/issue2517

C:dynamic Array in Stack

| Comments

以前一直认为C99 只支持const int 定义数组,今天才学到C99里面是支持动态数组的。

1
2
3
4
5
int main()
{
    int x = 12;
    char pz[x];
}

C99是支持的。在gcc4+以上的版本里测试OK。

另外stackoverflow上提到C++不支持动态数组,在g++4.4.7里面试了一下,也是可以的。

不是我不明白,这世界变化快。

Out好多好多年了…….

参考: http://stackoverflow.com/questions/1204521/dynamic-array-in-stack http://stackoverflow.com/questions/737240/c-c-array-size-at-run-time-w-o-dynamic-allocation-is-allowed