软路由http连接超时问题排查
Tag openwrt, 连接超时, on by view 219

用软路由有一段时间的,最近家人经常跟我吐槽,家里网络差。后来我发现确实存在网络差的问题,有时候刷抖音视频加载不出来,刷微博图片加载不出来。一开始以为是天威宽带运营商的问题,后面发现同一时间直接链接运营商的光猫路由无线网络不会有问题。这么说来,问题是出在软路由上了。 一开始我以为富强网的问题,因为访问国外没问题,访问国内有问题,各种找解决方案,有人说需要设置这条防火墙规则就可以了

iptables -t nat -I POSTROUTING -o eth0 -j MASQUERADE

但是,我测试了没有效果。而且还比较符合别人的描述,重启防火墙就恢复正常了,然后在不确定长度的一段时间后,又会出现这个问题。这里肯定是防火墙的问题了。但是想尽一切办法都没法解决,于是我关闭了富强网。

第二天,我发现访问csdn的资源链接依然会有问题,通常会卡个1分钟以上,才有响应。这很不正常。看样子跟富强网没关系。我先后确认了DNS解析正常,关闭了“Turbo ACC网络加速”,设置调小了lan口MTU,但是都没有结果。头发都要薅光了。

先dig一下域名

➜  ttt dig csdnimg.cn

; <<>> DiG 9.11.5-P4-5.1+deb10u7-Debian <<>> csdnimg.cn
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 63181
;; flags: qr rd ra; QUERY: 1, ANSWER: 9, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;csdnimg.cn.                    IN      A

;; ANSWER SECTION:
csdnimg.cn.             57      IN      CNAME   csdnimg.cn.trpcdn.net.
csdnimg.cn.trpcdn.net.  1717    IN      CNAME   uz95.v.trpcdn.net.
uz95.v.trpcdn.net.      95      IN      A       116.77.73.215
uz95.v.trpcdn.net.      95      IN      A       116.77.73.214
uz95.v.trpcdn.net.      95      IN      A       116.77.73.211
uz95.v.trpcdn.net.      95      IN      A       116.77.73.213
uz95.v.trpcdn.net.      95      IN      A       116.77.73.218
uz95.v.trpcdn.net.      95      IN      A       116.77.73.217
uz95.v.trpcdn.net.      95      IN      A       116.77.73.212

;; Query time: 20 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: 一 9月 05 13:45:27 CST 2022
;; MSG SIZE  rcvd: 217

解析出来的是cname到网宿CDN,A记录为天威宽带的节点。从openwrt的ptty终端访问正常,说明ip是通的没问题, 但是在路由下我的电脑上访问,也是偶现超时卡顿。

然后想办法稳定重现,写个shell脚本,用curl循环访问问题链接

#!/bin/bash

for ((i=1;i<=100;i++)); do
  curl --no-tcp-nodelay 'https://csdnimg.cn/release/blogv2/dist/pc/img/pay-time-out.png'$i -w "@fmt" -o /dev/null -s;
done

其中fmt耗时输出格式文件

time_namelookup:  %{time_namelookup}\n
       time_connect:  %{time_connect}\n
    time_appconnect:  %{time_appconnect}\n
      time_redirect:  %{time_redirect}\n
   time_pretransfer:  %{time_pretransfer}\n
 time_starttransfer:  %{time_starttransfer}\n
                    ----------\n
         time_total:  %{time_total}\n

调用shell文件,结果中间卡了很久

vjgy55fs

可以看到中间有个异常耗时

time_namelookup:  0.031654
       time_connect:  129.203610
    time_appconnect:  129.222947
      time_redirect:  0.000000
   time_pretransfer:  129.223397
 time_starttransfer:  129.359648
                    ----------
         time_total:  129.359827

可以看到,dns解析耗时0.031654,没问题,问题主要在time_connect,说明是到该ip的链接超时。众所周知,tcp连接需要握手,其中会传输ACK,SYN这些数据包,用于确认握手状态。会不会是这些包存在被路由器防火墙丢弃的情况?打开openwrt“状态->防火墙”,搜索DROP,有这么一条规则被我看到了

75ura4is

查了一下223.252.199.10,是网易云的,这让我突然想起来,openwrt上有个“解锁网易云灰色歌曲”的功能,曾经被我打开了。

91tw7d76

关闭。网络恢复正常了

最终结论:这次网络故障是由“解锁网易云灰色歌曲”这个功能导致的故障,其原理是劫持所有到网易云的流量到腾讯云,从而实现网易云音乐被封禁的音乐从腾讯云下载。中间的规则应该是出了什么问题,影响到正常链路了。 关闭之后就正常了,openwrt上各种功能的确丰富,但是坑也多,很多功能都需要基于防火墙实现流量劫持与转发,一旦出现问题,就可能影响正常上网。


万兆网卡台湾货的一个有趣现象
Tag 万兆, on by view 69

最近入手了威联通的雷电3万兆光纤网卡。淘宝京东官方店一直缺货,好不容易等来了,赶紧分期买了。今天终于到货了。晒图

s2kfhdfz 赶紧用了一下,挺不错的。我NAS也是万兆网卡,在NAS上运行iperf3服务端,然后macbook pro上用这个雷电万兆网卡,iperf3客户端连接测速。基本跑满万兆。

gpo9z4dx

测速结果 9.4Gbit/sec 左右,符合万兆。然后测试了一下NAS上的samba服务读写速度

ue981e7l

测速结果显示,读速度1033MB/s,能达到万兆;但是写速度只有360MB/s,这可能是因为我NAS上用了3块4T日立硬盘,硬盘比较廉价,读写速度也比较差;另外我猜也可能与我使用了RAIDZ有关,毕竟RAIDZ奇偶校验比较损耗性能。

网卡到手第一时间,发现了一个有趣的事情,网卡上看起来有一行字被人刻意的用黑色油性笔划掉了,凑近隐约能看到 made in taiwan 字样。结合国际时事,威联通以及淘宝京东官方店这款网卡最近一直缺货没补上的情况,一瞬间了解是什么情况。

z63r8f6j

最后呢,我想说,胳膊拧不过大腿;台湾省无脑的井底之蛙太多;希望台湾省早日回归中国大陆。这样对大家都好。


大文件下载的一些经验
Tag 下载, cdn, on by view 69

数年之前,我在一家CDN公司上班。在CDN项目主要工作是负责对客户视频数据搬运到云存储,中间也涉及到下载转码上传之类的工作。其中踩过一些坑,也吸取了一些经验。下面简单讲一下我遇到的几个问题。

下载没网速了

首先是下载没网速的情况。在处理大量的下载任务过程中,发现了一些特殊情况,客户通知我的服务回源,我的下载服务从源站下载一些大文件的时候,开始网络一切正常,可是逐渐的网速越来越低,甚至没网速,这回导致下载一直卡主。可能你会说,设置一个下载超时不就好了,但是,由于客户的文件大多是影视原片,体积巨大,有些甚至达到了几十G,如果简单的设置超时,以处理时间判断下载成败,那么这些大文件基本上不可能成功,都会以超时失败。当然,也可以分片下载来解决文件大的问题,但是对于0网速或者只有几B/s的网速,你的分片就显得无力了。其实,这个状况产生的原因大多是因为源站故障导致的,比如负载高之类的。只要断开连接重新下载就有机会恢复正常速度的连接,而且一般源站是有多个的,重新连接到新的节点就好了。所以,这里“断开连接重新发起下载”这个能力就非常重要了。我原本使用的是github.com/nareix/curl这个库进行文件下载,它的优点是创建异步下载任务后,可以监控当前下载的速度。这样,我可以对每个下载任务的网速进行监控,当网速低于一个阈值的时候,就放弃下载并重试。最初的时候只是简单的调用它的Close()方法,关闭了下载。后面却发现,经常发生fd用完的情况,一查才知道Close()方法并不能释放连接。最后只好自己修改了这个库,给它添加了强制关闭连接的能力。于是就完美的解决了这一问题。记得当时有一次,源站故障了,客户反馈说,它们接入的多家CDN厂商都上报,文件下载失败了,只有我们公司文件下载成功了,听到这消息,我嘴角不由得上翘,漏出了得意的笑容。

并行写同文件

遇到另一个印象深刻的问题就是某客户反馈文件错误的问题。客户反馈说他们在我们CDN上的文件播到一半卡死了,查了文件之后,发现文件大小正常,但是文件只有前半截有数据,后半截全是0,空的。当时,老板CTO领导全站在我工位后面,讨论这个问题,我也是第一时间加回了MD5校验,因为之前在我同事的要求下(同事是老员工、他负责任务调度、我负责几个agent,相当于他为主),去掉了上传前MD5校验,以节省任务时间。当时非常紧张,但是一时间也查不出原因,只能先加MD5校验,然后开发专用校验程序,将半年前开始的所有上传文件重新拉下来做MD5校验,查出异常文件重新上传。后来在一个偶然的机会下,发现了故障的原因,居然是调度测下发任务之后,等待N分钟之后agent还没上报成功,于是又重新下发了这个任务,然后刚好是同一个节点的agent收到该任务,这样一来,同一个节点上2个相同的任务在处理,文件路径一致,也就是说,有2个线程在从源站拉文件写到本地磁盘的同一个路径,一先一后,先处理完的线程开始上传了,后处理的还在写文件,后处理的写文件之后就会将该文件后半截变为空(这里与文件打开模式有关),这样前一个线程在上传的时候,文件其实变成半截了,再加上没有MD5校验,所以,故障就此发生了。

所以之后我就给每个任务的本地路径前加了一个uuid目录,这样一来,不管任务是否同一个文件路径,都不会相互干扰。每个任务都有自己的独立路径了。原程序是我接手别人的,虽说这问题不是我引入,但是,平心而论换做当时的我,也是想不到这一点的。不过,吃一堑长一智,现在只要涉及到本地资源存储,我基本上都会给路径前添加uuid前缀。


最近关于家庭网络我做了这些事
Tag 网络, on by view 86

软路由

我使用软路由已经有几年了,从最早的4网口工控小主机,到现在的r4s,一直是在用openwrt软路由作为家里的主路由。具体为啥要用软路由,相信懂的都懂。

vfxfwh7n

r4s相较于我之前用过的4网卡工控小主机,只有2个千兆网口,要小很多,很容易放进弱电箱。另外,由于我原来的工控机是英特尔J1900处理器,相较于使用arm处理器的r4s,r4s要节能得多,而且发热量也更小。

无线网络

无线网络,从最初的单路由器,到家里部署两个路由器,再到现在基于ap+ac部署的分布式无线网络。最初在老家县城的时候,由于WiFi普及率不高,基本无信号干扰,所以一个最基础的普通WiFi路由器就可以覆盖整个房子,网速也还行;后来老家农村重新建房了,3层楼房,用了2个路由器设置了两个接入点,但是从二楼到一楼切换的时候会有较长时间中断,或者是没有能切换,连接的是信号较差的二楼接入点;这种情况比较影响网络连接。所以,上次回农村老家后,将网络改为了ac+ap的部署模式,设备可以在ap间漫游,几乎不会中断网络。顺便整理了一下弱电箱,理线过程中发现光猫经常发生光信号中断的情况,最后发现是盘纤问题,光纤的尾纤弯折程度太大就会导致光信号中断,于是用绑线带重新绑了一下光纤,以免出现折纤的情况。

rdz4f7a1

同时,这一波处理也将预埋的网线接入到路由设备,每个预埋网线的房间都有有线网络了。

展望未来

未来家庭万兆迟早会普及,但是按现在的标准,万兆网线要使用八类线,八类线最大的缺点就是太粗太硬,不便于穿管,而且成本不菲,并且万兆电口网卡目前也是非常昂贵。不过如果是光纤就不一样了,单模双芯光纤在某宝上就有售卖,非常便宜,而且万兆光口网卡相较于万兆电口网卡便宜很多,但是这里面有一个额外的成本,那就是光模块,如果是全新万兆单模双lc光模块,价格也不菲,不过呢,某鱼上的二手模块却是很便宜,24块钱一个,我直接卖了一盒10个,据说是从服务器上退役下来的,都是卖家测试过没问题发货,并且收到后,我自己测试过没问题。另一个设备就是光交换机,万兆光交换机的价格与万兆电口价格差别也很大。因此,全屋万兆方案我更看好全屋万兆光纤的方案。假如以后我有机会装修自己的房子的话,我肯定会要求装修师傅给我单独埋一根光纤管线,然后预埋光纤,进入万兆网络时代,这样我的nas也能发挥他的最大性能。


不更新你可能以为我已经挂了
Tag 琐碎, 博客, on by view 90

上一篇是2019年。为什么这么久没更新?两方面原因:第一是自从加入现在的公司后,近几年更加忙碌了,没那么多时间;第二是博客的发布后台被我改版了,没时间完善,所以发文章的功能还不够完善。

是的,我和我的博客都没挂。并且,最近比较流行暗黑模式,无论是app还是网站,但凡不支持暗黑模式,就显得特别碍眼,所以我就索性更新了一下样式,支持了暗黑模式;亮白主题与暗黑主题根据读者计算机系统上的主体模式自动变化。你系统是亮白主题,那么你浏览我博客页面也是亮白主题;你系统是暗黑主题,那么你浏览我博客页面也是暗黑主题。另外,还给博客添加了一个搜索功能,基于bleve的搜索。

这几年,除了疫情,其实也没什么特别的。和之前一样生活、上班,如果非得说有所不同,只能说无论是生活还是工作都比之前更忙了。


糖糖发烧了,好担心
Tag 琐碎, on by view 1048

糖糖昨天下午开始就发烧了,晚上喝了布洛芬退烧了,半夜2点又发烧了,爸爸妈妈外婆起来给糖糖吃退烧药和物理降温,今天一早又发烧了,温度高的时候有39度。一早妈妈请假,外婆和妈妈带糖糖去儿童医院看病,爸爸去公司上班。

爸爸现在完全无心工作,看病回来下午这会儿糖糖又发烧了。再加上公司的事情,昨天凌晨手欠在公司某系统评论了某事,一早被领导diss了,心情真是糟糟的,烦烦的,真是手欠,半夜两点还关心公司的事情,更欠的事情是还顺手评论了某事。

希望糖糖能够早日康复,健康快乐成长。公司的事情该忙的还是要继续忙,吃一堑长一智,谨行慎言。


矛盾
Tag 情感, on by view 1314

已经结婚快要2年了,娃也已经开始整天“babababa”的咿呀学语了。

休完产假刚上班,工作上的事情并不太多,挺闲的。所以就上网刷知乎玩儿。最近刷到几个问题,“爸爸能爱女儿到什么程度?”,大概就是这样的问题,主题在表现爸爸对女儿的爱。刷了挺多答案的,看到了各种各样爸爸疼女儿的回答。每个回答都是满满的爱,虽然都各有各的可爱,每个故事都可爱的与别人不同。

想到了娃爸,似乎没有网上那样,难道这就是说的别人家的爸爸?难道我糖以后也只能看着别人家的爸爸然后满满羡慕?每次想到这里都很替我糖抱不平,会找娃爸抱怨几句。

但是回头想一想,其实娃爸也很爱臭糖,从来都想要把最好的给她,从来都愿意惯着她的小脾气(别看小小一个人,还穿纸尿裤,甚至还不会爬,但是小脾气绝对是足足的)。比如臭糖要吃奶睡觉觉,比如臭糖要抱抱不肯自己做着玩,比如臭糖要人陪着不肯自己呆着,比如臭糖睡觉觉的时候要把腿放在我身上,比如臭糖吃奶睡觉觉的时候大脚丫子使劲在我身上蹬,等等等等这些时候。她爸都会说,哎呀你糖喜欢这样就让她这样嘛。嗯,反正折腾的都是麻麻,不是爸爸!手动白眼。

这么说来,似乎糖爸对糖的爱也很假,都不是需要他付出的他就很慷慨,是不是这样?老实说,心里有时候也是这样觉得的。可是看着糖爸的眼睛,又知道他其实是真的很爱糖。

其实糖爸很信任我,他只是将我当成了他最放心的人,将他心里最重要的部分交给了我,并认为我一定能照顾好他最爱的人。

所以,我想他是爱我的,很爱我。不然,如何敢将自己最脆弱的部分完全依靠在我身上。虽然有时候又会突然怀疑他是不是像别人口中的渣男一样,并没有我想的那么伟大,只是单纯的不在乎我和糖。不过静下心来,我还是选择相信我的男人。

即便心里偶尔很矛盾。偶尔不平衡。



对gin应用基于TCP窗口的流量控制
Tag gin, tcp, 窗口, 流量控制, on by view 3332

TCP可以基于滑动窗口进行流量控制,使用setsockopt系统调用实现,可以限定客户端或者服务端连接的入网或出网流量,http是基于TCP协议的,因此http也可以基于TCP滑动窗口实现流量控制。golang自有的net包不支持server端TCP窗口设置,因此无法直接实现基于TCP窗口的流量控制。今天我们要对一个基于gin实现的微服务进行流量限制。

首先,gin自带的r.Run()启动的http肯定是不行的,然后http包中的http.ListenAndServer()也是不行的,那么我们就基于TCP来实现,但是golang得net包中的net.Listen()也是不行的。这时候我们只有调用底层的系统调用了(不是cgo),我们可以使用syscall包来实现系统调用。我们分为五步:创建socket,设置socket选项,绑定端口地址,转换为golang的listener,listen。

  • 创建原生的socket

s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_STREAM|syscall.SOCK_NONBLOCK|syscall.SOCK_CLOEXEC, 0)
if err != nil {
    log.Println("create socket failed, err:", err.Error())
    return
}
  • 设置socket选项

// set receive buffer here
err = syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_RCVBUF, 2350)
if err != nil {
    log.Println("set socket option receive buffer failed, err:", err.Error())
    return
}

// set send buffer here
err = syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_SNDBUF, 2450)
if err != nil {
    log.Println("set socket option send buffer failed, err:", err.Error())
    return
}
  • 绑定端口地址

err = syscall.Bind(s, &syscall.SockaddrInet4{Port: 8099, Addr: inetAddr("192.168.31.11")})
if err != nil {
    log.Println("bind socket failed, err:", err.Error())
    return
}
  • 转换为golang的listener

f := os.NewFile(uintptr(s), "")
ln, err := net.FileListener(f)
if err != nil {
    log.Println("create listener failed, err:", err.Error())
    return
}
  • listen

err = syscall.Listen(s, 0)
if err != nil {
    log.Println("listen failed, err:", err.Error())
    return
}

最后我们把我们自定义的支持限流的listener应用于gin上

r := gin.Default()

r.GET("/", func(context *gin.Context) {
    context.File("socket")
})

err = http.Serve(ln, r)
if err != nil {
    log.Println("create http server failed, err:", err.Error())
    return
}

一个支持限流的http server就此实现。


将caffemodel编译为movidius的graph模型
Tag caffe, model, movidius, on by view 3020

首先需要安装ncsdk, 去movidius官网下载 https://developer.movidius.com/start 

mkdir -p ~/workspace
cd ~/workspace
wget https://ncs-forum-uploads.s3.amazonaws.com/ncsdk/ncsdk-01_12_00_01-full/ncsdk-1.12.00.01.tar.gz
tar xvf ncsdk-1.12.00.01.tar.gz
cd ncsdk-1.12.00.01
make install

安装完毕后可以调用mvNCCompile进行编译

mvNCCompile ./deploy.prototxt -w ./resnet_50_1by2_nsfw.caffemodel -s 12 -0 ./nsfw.graph

若是遇到编译失败

mvNCCompile v02.00, Copyright @ Movidius Ltd 2016

Error importing caffe

请设定环境变量后重试

export PYTHONPATH=/opt/movidius/caffe/python:$PYTHONPATH

编译成功后会生成 msfw.graph 文件,接下来可以使用 movidius 和 graph 模型进行推导了。


幸福的孤独者
Tag 散文, on by view 2755

人,一旦进入天命之年后就意味着进入了孤独期。尤其是独生子女家庭。记得二十几年前,父亲常常喊:“兵伢,来,来坐哈?”那时无知的我面对老父的招呼,显出明显的不耐烦,甚至冷漠,无动于衷。那时我是多么的冷酷自私呀!为什么那时我心中就没有一丝的对老人的怜悯或同情呢?其实我内心是非常悲悯老父老母的,只是自己不愿表露而已。我不想因为自己的“行孝而招来弟兄之间更深的仇隙”。这就是事实的症结,别人的不孝姑且不论,人在做天在看!我心底的内疚从没有消失过,时至今天他还让自己难安。就让自已在时间中慢慢讦悔吧!那时,而且那时父亲已经身患重病:老血栓。父亲在喊叫几遍无应后,他就孤独地喃喃自语地拖着垂暮之年的病弱之躯慢慢地走入他那低矮的老房子……

当时我为什么心中有恁大的抵触情绪呢?根源还是因为弟兄之间的不和。这不和的根源多是由老人的厚此薄彼引起的,当时自己为什么就过不了自己心魔那道坎呢?归根结底还是自已太自私了。现在父亲走了十一年,母亲也走了三年,我们也进入了天命之年还多五的光景,幸运的是我们还在工作还能工作!虽然如此,空闲时就感觉日子中似乎少了点什么?那就是孩子不在身边的空虚!这时自已就常常于寂寞中感受到“孤独的可怕”!是的,父辈们的“今天就是我们的明天。”“我的今天就是父亲的昨天”啊!我这不孝之子,现在终于体味到当年父亲为什么老是喊我陪他坐坐……?啊!往事堪追忆?可是这后悔能改变一切吗?能回到当年吗?能让自己重新“行孝”吗?俱往矣!现在我终于懂得了父亲当年常对我唠叨的“养儿方知父母恩”是什么意思!“寂寞使人孤独,孤独使人易老”。我现在感受到“寂寞的可怕”,或者这是“上天对自己的警告吧”!我有个和协美满的家,可是一家几囗常年在外工作,儿子儿媳他们就是把全年的假期算在内,在家住的时间也没有一个月?我现在能要求他在家陪陪我们吗?笑话!这是不可能的。当年父亲不就是这样要求我吗?可是当年父亲求孩子在身边陪坐几十分钟的愿望就变成了奢侈?唉!现在我们的孩子他为了自己的发展跑到天涯海角去打拼,如果想孩子就默默地盯住天空飞来飞去的银色机冀吧!说不定那架飞机内就坐着自己的小子呢!