netstat -s统计输出的所有字段详细解释

今天工作上碰到一个问题需要知道udp的丢包数据。实际上我不相信能简单地得到udp的丢包精确数据。理由是,网卡负载太高时有些包连网卡都没收到,根本不可能来得及汇报给内核。另外,如果是路由器把udp丢了,那udp的目的端机器当然更不可能感知到有丢包了。 这时,同事说netstat -us (–statistic)可以看到udp的丢包。这里的u选项指的是只展示udp相关的统计,s选项自然表示的是统计了。如果不用u选项,则出显示所有统计数据。下面是我的机器上的输出。 Ip: 203440255187 total packets received 0 forwarded 0 incoming packets discarded 201612429535 incoming packets delivered 1064529177 requests sent out 15 fragments dropped after timeout 3058122492 reassemblies required 1230296840 packets reassembled ok 15 packet reassembles failed Icmp: 14869220 ICMP messages received 3965512 input ICMP message failed. ICMP input histogram: destination unreachable: 6054246 timeout in transit: 687 echo requests: 8570532 echo replies: 243755 12913011 ICMP messages sent 0 ICMP messages failed ICMP output histogram: destination unreachable: 4097869 time exceeded: 5 echo request: 244605 echo replies: 8570532 IcmpMsg: InType0: 243755 InType3: 6054246 InType8: 8570532 InType11: 687 OutType0: 8570532 OutType3: 4097869 OutType8: 244605 OutType11: 5 Tcp: 111681768 active connections openings 4186820 passive connection openings 24951865 failed connection attempts 55064041 connection resets received 275 connections established 1033901799 segments received 1776166765 segments send out 12156205 segments retransmited 6705 bad segments received. 106348033 resets sent Udp: 198894689917 packets received 472986510 packets to unknown port received. 1146976531 packet receive errors 116750744 packets sent 110301286 receive buffer errors 0 send buffer errors UdpLite: TcpExt: 423 invalid SYN cookies received 693 packets pruned from receive queue because of socket buffer overrun 19 packets pruned from receive queue 11309370 TCP sockets finished time wait in fast timer 106 packets rejects in established connections because of timestamp 10210477 delayed acks sent 20811 delayed acks further delayed because of locked socket Quick ack mode was activated 8856 times 17118697 packets directly queued to recvmsg prequeue. 301717551 bytes directly in process context from backlog 152118951904 bytes directly received in process context from prequeue 104771733 packet headers predicted 15179703 packets header predicted and directly queued to user 218747377 acknowledgments not containing data payload received 102637644 predicted acknowledgments 7293 times recovered from packet loss by selective acknowledgements Detected reordering 40 times using FACK Detected reordering 27 times using SACK Detected reordering 1088 times using time stamp 476 congestion windows fully recovered without slow start 5287 congestion windows partially recovered using Hoe heuristic 236 congestion windows recovered without slow start by DSACK 151673 congestion windows recovered without slow start after partial ack 1 timeouts after reno fast retransmit 4 timeouts after SACK recovery 10540 timeouts in loss state 7232 fast retransmits 649 forward retransmits 1871 retransmits in slow start 11612658 other TCP timeouts TCPLossProbes: 93185 TCPLossProbeRecovery: 14667 2431 packets collapsed in receive queue due to low socket buffer 8814 DSACKs sent for old packets 3350 DSACKs received 1 DSACKs for out of order packets received 90851 connections reset due to unexpected data 214 connections reset due to early user close 352 connections aborted due to timeout TCPDSACKIgnoredNoUndo: 1571 TCPSpuriousRTOs: 7 TCPSackShifted: 94 TCPSackMerged: 131 TCPSackShiftFallback: 21183 TCPTimeWaitOverflow: 1876775 TCPRcvCoalesce: 15711184 TCPOFOQueue: 3194 TCPChallengeACK: 2337394 TCPSYNChallenge: 13608 TCPSpuriousRtxHostQueues: 1982796 IpExt: InBcastPkts: 46443933 InOctets: 44312451521655 OutOctets: 1915626725817 InBcastOctets: 6827280595 喂,要是转载文章。麻烦贴一下出处 ykyi.net 采集爬虫把链接也抓走 ...

November 23, 2018 · 3 min · kamus

如何定制一个python的logging Handler

上个月用python的gevent协程库写了一个tcp服务。日志库使用python标准日志库logging。一个月后,发现一个偶发的bug。这个bug发生时,用python的标准日志库自带的FileHandler写的日志会发往socket占用的文件描述符fd。结果就是,客户端收到了本要打印到磁盘上的日志。花了不少时间定位排查这个bug,仍然没有结果。我开始怀疑是gevent协程库和python的标准日志库logging有冲突。协程库会错误的把logging打开的文件描述符fd关闭并分配给新创建的socket,于是日志就打印到socket占用的fd了。 后来,写了一个检测脚本用来监控这个情况发生的概率。该脚本每分钟会检查进程占用的所有fd,一但发现用来打印本地日志的文件fd不见了,就重启服务进程。核心代码如下: lsof -p $pid | grep -q ${log_file_name} if [ $? != 0 ] then # 报警代码 ... fi 发现bug发生的频率大概是一个星期一次。但这毕竟根本上解决不了问题啊,又找不到bug的原因,怎么办? 那就自定义一个File Handler吧! 决定自定义一个File Handler,这个File Handler工作在另外一个单独的进程,这样无论如何日志用的fd都不会跟主进程的各种socket用的fd冲突了吧。 代码如下,主要用到的技术进程通讯和用python的__getattribute__魔法把截获类实例的方法调用。这样,只需要把旧的代码中的File Handler(我用了TimedRotatingFileHandler)换成自定义的Handler Class,所有其他旧代码都无需改动。 #!/usr/bin/env python3 ''' created by kamuszhou*AT*tencent.com, zausiu*AT*gmail.com http://ykyi.net Nov 20, 2018 ''' import logging import logging.handlers from functools import partial from multiprocessing import Process, Queue class MySpecialHandler(logging.StreamHandler): def __init__(self, *args, **kargs): self._q = Queue() self._p = Process(target=MySpecialHandler.__run, args=(self._q,)) self._p.start() self._q.put(('__init__', args, kargs)) def join(self): self._p.join() def __run(q): handler = None while True: # op, params = q.get() method, args, kwargs = q.get() if method == '__init__': handler = logging.handlers.TimedRotatingFileHandler(*args, **kwargs) else: # 主进程的日志调用实际上被转到这里 getattr(handler, method)(*args, **kwargs) def __proxy(self, name, *args, **kwargs): # 把调用的方法名和方法参数通过Queue传到专门的日志进程。 self._q.put((name, args, kwargs)) fun = logging.StreamHandler.__getattribute__(self, name) # print('call method: ', name, args, kwargs) # 如果是setLevel函数,再调用一次父类的方法 if name in {'setLevel'}: return fun(*args, **kwargs) def __getattribute__(self, name): ''' Hook大法!截获所有方法 ''' attr = logging.StreamHandler.__getattribute__(self, name) if hasattr(attr, '__call__') and name not in {'join', 'emit'}: return partial(MySpecialHandler.__proxy, self, name) else: return attr if __name__ == '__main__': handler = MySpecialHandler('/data/tmp/ttt.log', when='D', interval=1, backupCount=90) handler.setLevel(logging.DEBUG) formatter = logging.Formatter('%(asctime)s: %(levelname)s %(message)s') handler.setFormatter(formatter) logger = logging.getLogger(__name__) logger.propagate = False # Don't propagate the logging to ROOT logger.setLevel(logging.DEBUG) logger.addHandler(handler) logger.debug('debug testtttttttt') logger.info('info testtttttttttt') logger.warn('warn testtttttttttt') logger.error('error testtttttttt') logger.critical('critical testttttt') handler.join() 这里自定义的日志进程类只是一个很粗糙的实现,一但跑起来,只能手动杀进程。反正我的使用场景是一个服务。所以,我也懒得加‘优雅的退出代码’。 ...

November 20, 2018 · 2 min · kamus

伯努利(Binomial)分布和伯努利试验的区别,负伯努利分布及几何分布,超几何分布

[mathjax]我又重新把概率,统计书拿起来了。这次是真的,要把机器学习(统计学习)学好。显然,学好机器学习并不是一件容易的事情。需要要扎实的数学基础。好在我的数学储备还勉强可以,但远算不上“基础扎实”。所以,我有了一个长期远景规划,重新开始学习吧! 今天看了伯努力分布,负伯努利分布,超几何分布,几何分布这几个知识点。下面我一边写回顾今天学到的,一边写文章。 伯努利分布和伯努利试验的区别 伯努利试验(Binomial Experiment)指的仅仅是”一次试验”,或者成功,或者失败。伯奴利分布是一个常用分布,这是完全不同的两个概念。 每次伯努利试验的成功概率记为p,又把重复很多次伯努利试验称为伯努利过程(Binomial Process)。一个重复了n次伯努利试验的伯努利过程中,成功的试验次数记为X,这个X则是伯努利随机变量。X的概率分布被称为伯努利分布。 伯努利分布: $$b(x;n,p) = {n \choose x} p^k (1-p)^{ n-k}$$ 其中,n表示试验次数,p表示每次独立试验成功的概率,x表示成功次数。 什么是负伯努利分布(Negative Binomial Distribution) 伯努利分布和负伯努利分布的大多数设定都是一样的,都不断重复伯努利试验,要么成功要么失败。 不同点是:伯努利分布的随机变量X,表示的是在前n次伯努利试验中成功了x次;而负伯努利的随机变量x,表示的是要达成k次成功试验,需要试验x次(即第x次试验成功,前x-1次试验成功了k-1次)。伯努利分布限定了试验次数记为n,负伯努利限定了成功次数记为k。 负伯努利分布: $$b^*(x;k, p) = {{x-1} \choose {k-1}}p^kq^x-k$$ 几何分布和超几何分布 再以伯努利分布为讨论的基础,仅更改一处,即把伯努利过程中的放回抽样(with replacement)改成不放回抽样(without replacement),即可得到超几何分布。 以负伯努利分布为讨论的基础,仅更改一处,即k设为1,表示成功一次。即不断重复伯努利试验,直到第一次成功就结束,得到了几何分布。 伯努利分布,负伯努利分布的命名 为什么叫伯努利分布 因为伯努利展开式$$(q+p)^n$$的n+1个项对应伯努利分布取各个值时的情况。 为什么叫负伯努利分布 因为展开式$$p^k(1-p)^(-k)$$中的每个项对应$$b^*(x;k,p)$$取x=k, k+1, k+2, …时的情况。

November 13, 2018 · 1 min · kamus

安装MathJax-LaTeX插件,让wordpress显示数学公式

最近看统计学,涉及很多数学公式。于是,想找到一款wordpress的插件可以显示数学公司。 当然,于是就找到了 MathJax-LaTex这个插件。虽然插件名字中有LaTex,但实际上不仅仅可以用LaTex语法描述数学公式,亦可用AsciiMath,以及MathML。 本以为像其它所有wordpress插件一样,安装很简单,很容易就能上手使用。没想到还是花了一些时间。 MathJax-LaTex插件依赖MathJax这个javascript开源工程。原因貌似是MathJax默认用的CDN在大陆被墙了,还是因为浏览器的同源策略被浏览器禁了??我懒得重现排查真正原因了。总之,我用MathJax-LaTex默认配置没有成功,于是我自己手动下载并安装到自己的服务器,运行OK。 首先到 https://github.com/mathjax/MathJax{.wp-editor-md-post-content-link} 下载源代码。熟悉git的同学可以用git下载,亦可用右边的 Clone or Dowload 按钮下载zip包。 把zip包上传到自己的服务器,找一个目录解压缩。 打开MathJax-LaTex的配置web页面,如下图如示,去掉Use MathJax CDN Service 的勾,不要用MathJax自己的CDN;然后,在Custom MathJax location选项中填上自己的路径。假如刚才zip包MathJax解压缩到的目录是/tools,那么就填上 /tools/MathJax-2.7.5/MathJax.js 。 {.wp-editor-md-post-content-link} 然后创建一篇新博文,现在可以录入数学公式啦。装逼必备!比如下面的伯努利分布的公式: [mathjax] $$b(x;n,p) = {n \choose x} p^k (1-p)^{ n-x}$$ 要输入上述方程式,在文章开头输入**[mathJax]** ,这个标志让MathJax-LaTex插件加载显示数学公式相关的javascript代码。然后敲两个美元号 $$,敲入公式 b(x;n,p) = {n \choose k} p^k (1-p)^{ n-k},再敲入两个美元号结尾。即用双美元号$$把公式围起来。亦可用[latex][/latex]这对标签把公式围起来。这对标签这里的公式描述用了 asciiMath语法. n choose k即一个组合。在网上搜索相关语法参考。 在这个页面可以看到更多用MathJax显示的数学公式的例子,用浏览器的查看源代码功能(ctrl-u)查看使用的语法: 使用LaTex语法: http://ykyi.net/zausiu/MathJax-2.7.5/test/sample.html{.wp-editor-md-post-content-link} 使用AsciiMath语法: http://ykyi.net/zausiu/MathJax-2.7.5/test/sample-asciimath.html{.wp-editor-md-post-content-link} 使用MathML语法:http://ykyi.net/zausiu/MathJax-2.7.5/test/sample-mml.html{.wp-editor-md-post-content-link}

November 13, 2018 · 1 min · kamus

C/C++用万恶的libcurl透过HTTPS发POST+JSON请求

相比python, nodejs这样的脚本开发语言已有非常好用的RESTful开发库,很多C/C++程序在调用RESTful接口时,还在使用非常难使用的libcurl纯C接口。下面是用libcurl透过HTTPS发POST请求的代码代段,http body是json字符串: #include <curl/curl.h> CURL* curl; struct curl_slist* headers; curl = curl_easy_init(); headers_ = curl_slist_append(headers, "Content-Type: application/json"); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, "PEM"); curl_easy_setopt(curl, CURLOPT_SSLCERT, cert_file_path.c_str()); curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, "PEM"); curl_easy_setopt(curl, CURLOPT_SSLKEY, key_file_path.c_str()); curl_easy_setopt(curl, CURLOPT_CAINFO, ca_file_path.c_str()); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L); curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, -1L); // jv_text存了json字符串 curl_easy_setopt(curl_, CURLOPT_POSTFIELDS, jv_text.c_str()); curl_easy_setopt(curl_, CURLOPT_URL, path.c_str()); CURLcode res = curl_easy_perform(curl_); if (res != CURLE_OK) // 没有成功 { LG_ERR("curl_easy_perform() failed: %s", curl_easy_strerror(res)); } else // 成功了 { } curl_easy_cleanup(curl);

June 21, 2018 · 1 min · kamus

openssl签发证书肘后备急方(cheatsheet)

生成一对新的RSA非对称密钥,2048bits长。 generate an RSA private key openssl genrsa -out private.key 2048 从私钥中提出公钥。 extract the public key openssl rsa -in mykey.pem -pubout > my_pubkey.pub 创建自签名证书。create a self-singned certificate openssl req -config openssl.conf -x509 -sha256 -days 3650 -newkey rsa:4096 -keyout ca.key -out ca.crt 签署CSR。sign the CSR openssl ca -config openssl.conf -days 375 -notext -in test.csr -out test.crt 检验签书。verify the certificate openssl verify -CAfile ca.crt test.crt 生成一个CSR。Generate a new private key and CSR(Certificate Signing Request) openssl req -config openssl.conf -out CSR.csr -nodes -new -newkey rsa:2048 -nodes -keyout private.key ...

June 20, 2018 · 2 min · kamus

nginx架设HTTP服务器接受PUT方法上传文件

最近用nginx架了个http服务器,通过http上传文件。 nginx的配置如下: location ~ ^/wraith { root /data/tmp; dav_methods PUT; dav_access user:r group:r all:r; create_full_put_path on; limit_except GET { } } 如上,子目录/wraith将接受PUT方法。 $curl -XPUT --data-binary @${TAR_PATH} --noproxy '*' http://xxx.xxx.xxx.xxx/wraith/${TAR_FILE} 如上用curl通过http上传文件到服务器的/data/tmp目录下,文件命名为${TAR_FILE}

March 27, 2018 · 1 min · kamus

utf8中文字符串的多模式匹配算法的优化

utf8中文字符串的多模式匹配算法的优化 信息安全部接口组 kamuszhou@tencent.com 效果 本节仅展示优化效果,对一些业务逻辑和背景未做解释,读者可直接跳至下一节。 上个月接触到了我组的一个关于在海量文本中匹配字符串业务。读源代码时发现一些问题,并针对这些问题做了优化工作,效果非常明显。 测试的硬件环境是只用一颗主频2.4G的Intel至强处理器核心。OS是tlinux2。该业务目前载入11万3千条规则。优化前后的效果如下: |载入 | 旧算法 |旧算法简版| 新算法 | 提升效果 | |:—:|:——:|:——–:|:——-:|:——-:| |速度 | 26分钟 | 3分钟 | 3秒 |60倍或250倍| |内存 | 4327M | 4327M | 不到200M| 20倍 | 表中的“旧算法简版”指去掉了一个繁琐的预计算步骤 |处理速度 | 旧算法 | 新算法 | 提升效果 | |:—:|:——:|:——–:|:——-:| |用11万3千条规则作为待检测文本|52秒|2秒|26倍| |10倍四大名著共88M,平均每行143个汉字|59秒|10秒|近6倍| |文字选自四大名著共87M,平均每行10个汉字|161秒|5秒|32倍| 用11万3千条规则作为待检测文本使得新旧算法都会密集地走到“命中逻辑”,旨在比较“命中逻辑”的性能。 用四大名著作为待检测文本,使得新旧算法几乎不会走到“命中逻辑”,旨在比较算法处理正常文本时的性能。而每次处理文本的长度亦可能影响到性能表现。如表所示,处理短文本(10个汉字)时,新算法的优势有所降低,可解释为旧算法为启动每一次处理消耗较大的资源,而如果处理的文本较长时,这个资源消耗分摊到每个待处理字符就相对不那么明显了。 在一台24核的M2机器上,理论估计新算法一天可以处理36,495,360M文本,36个T~ 业务简述 该业务的核心问题简单地近似概括为: 有几十万甚至更多的模式(短字符串)集合P={P1, P2, …, Pn},输入一个utf8编码的字符串string,输出有哪些模式Px在string中出现。 实际问题比上面的描述稍微复杂一点点。业务需要通过找到的模式判断是否命中预定的规则。一个模式串或多个模式都可以组成规则。比如,单独的一个Px组成一条规则,多个不同的模式则会组合成一个 与 关系的规则(目前业务只支持与关系,支持更复杂的匹配规则是将来需要增强的地方)。比如,有下面几条规则: 铁王座 雪诺 & 提利昂 雪诺 & 艾莉亚 & 2 雪诺 & 龙母 & 床 雪诺 & 夜王 & 异鬼军团 & 守夜人 下文的讨论将继续引用这个规则列表。 ...

November 20, 2017 · 2 min · kamus

用lftp为ftp服务器做镜像

用lftp为ftp服务器做镜像 命令是这样的: $ lftp -d -u user_name,password ftp_server_host -e "mirror -c -e --parallel=5 / /path/to/mirror" 解释一下这里的选项: -d 调试模试,看到详细的输出 -u 用户名和密码,用,隔开 -e 让lftp执行lftp自有的一些命令 mirror 执行做镜像命令 -c continue a mirror job if possible 继续做镜像,如果可能的话。难道不用这个选项,做镜像的过程有可能被中断? -e 如果一个文件在ftp站点上没有,但在本机上有,则删除这个文件 –parallel 并发数 http://ykyi.net mirror 命令还有一个 -R 参数,这样的话,会put文件到ftp服务器,效果和上例相反。

September 27, 2017 · 1 min · kamus

访问ES最简单示例

这些天架了一个ES集群,用来分析积累了海量日志数据。我用sphinx写了一个简单文档,发布在内网。下面是复制过来的部分内容,不幸的是很多格式信息都丢失了。做了点简单修改,去掉了敏感信息。 /////////////////////////////////////////////////////////// 本示例仅示范最为基础的应用,协助读者调通最简单的查询。 详细灵活的使用方法非本文档能够覆盖,需参见官方详细文档或咨询你常用的搜索引擎。 使用curl命令行工具 使用es官方python库 RESTful接口 官方python库 使用curl命令行工具 NOTICE: <div class="line"> [*略去较为敏感的鉴权部分*] </div> 在访问日志中检索一个keyword,无论keyword出现在哪个字段中。 如下示例:所有文档,superuser出现在其中任意字段中都会被召回。注意酌情更换URI中的参数。 实际上,把_all替换成user_name,则只在user_name字段中检索。这里使用的是lucene语法, 参见:https://lucene.apache.org/core/2_9_4/queryparsersyntax.html 1 curl https://endpoint/_search?q=_all:superuser 使用ES的DSL语法,在访问日志中检索出现在指定字段中的keyword。 如下示例:superuser出现在user_name字段中。 1 2 3 4 5 6 7 8 9 10 curl https://endpoint/_search?pretty -H "Content-Type: application/json" -X POST -d ' { "query":{ "bool":{ "filter":[ { "term":{ "user_name": "superuser" } } ] } } }' 上述检索方法使用了ES中的filter语法,filter是较快的一种查询方式。如果需要检索的字段需要分词,则只能使用 match语法,如下: 1 2 3 4 5 6 7 8 curl ./kamus.key https://endpoint/_search?pretty -H "Content-Type: application/json" -X POST -d ' { "query":{ "match":{ {"user_name": "superuser"} } } }' 为检索增加时间限制 如需要指定时间区间: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 curl "https://endpoint/_search?pretty" -d ' { "query":{ "bool":{ "must":{ "match":{ "user_name":"superuser" } }, "filter":{ "range":{ "req_time":{ "gte":"2017-01-01 00:00:00", "lt":"2017-08-08 00:00:00" } } } } } } ' 分页 ES的分页使用”from”和”size”参数。例如,每页10条,返回第1页。 1 2 3 4 5 6 7 8 9 10 11 curl "https://endpoint/_search?pretty" -d ' { "from": 0, "size": 10, "query": { "term": { "user_name": "superuser" } } } ' 由于ES的实现机制,ES并不鼓励使用分页,在size较大且from的页码也较大时,ES可能无法及时响应。 如果需要返回所有命中文档 如果命中文档超过一千,用上述方法不容易拿到所有结果。需要使用 scroll and scan 方法。 参见 https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-scroll.html 其他高级应用 如bool操作,以及复杂灵活的查询条件组合请参加官网文档。 ...

August 25, 2017 · 1 min · kamus