刚毕业的时候在迅雷工作了半年,因为一些特殊原因,还是回北京工作了。中间乱七八糟的东西就不说了。

因为只在这个公司待了半年。。所以可能也不算学到了什么东西,只是大概地对这个公司的业务流程有了一些了解,写下来做个记录吧。

对于一般的用户来说,迅雷就只是个简单的下载工具。当年迅雷能干掉网络蚂蚁和快车成为最流行的下载软件,主要还是因为自身做的比较好(其实上市的时候ceo说是因为快车作者沉迷魔兽世界顾不上维护软件我会跟你讲?

作为一个从共享软件年代一路走到互联网时代的工具,迅雷还是有自己的一些创新点的。里面最重要的大概就是用base64加密磁力链接转成thunder链接了(误)。说正经的,其实是自称的p2sp。P2SP(Peer to Server & Peer),看全称,其实就是在p2p里加入了server来参与用户的下载流程。当然有人会说,一般的bt服务也会有tracker服务参与啊,你这个好像不算创新。那还是不一样的。tracker服务器实际上并不会存储具体的文件内容存储。只会存一些torrent的元信息。但是在迅雷的p2sp里,服务器是会深度参与整个下载过程的。当然了,这年头bt下载即使你没有tracker服务器,也可以直接通过DHT网络来获取到资源对应的用户列表。

在后端的服务器大概会有三种角色:

server hub

peer hub

file server  

在说明几种角色服务器功能之前,先来说说迅雷是怎么来进行文件校验吧。

首先,不管什么样的文件,都会按照16kb的大小进行切分,每个16k大小的文件块都可以用sha1算法得到一个哈希值。这个值会拿来做小块的校验,如果客户端从别的地方拖过来的内容校验值和服务端的这个值对得上,那才说明文件是没有问题的,进而落盘。文件整体的校验id则是对所有块的sha1值连接得到的字符串再次进行sha1。这样得到最终的sha1值作为整个文件最终的唯一id。

这里就可以看到了,有了最后的文件唯一id。我们就可以拿着这个key来做一些happy的事情。

server hub

shub扮演的角色比较明确,使用文件key去查询得到所有的服务器资源。因为年代久远,先假设shub返回的都是迅雷自己的server地址。因为要照顾到不同地点的下载,所以这些server地址也一定是返回的cdn的地址。

具体到api的话,其实就是:

key => [server url链接数组]

因为后来迅雷需要你加会员才提供这种服务端级别的服务,所以中间也会有鉴权环节,只是不在shub上做。

如果你要实现这个服务的话是不是也很简单?拿redis的set来做就好~

peer hub

顾名思义,phub会返回:

key => [peer 列表数组]

这些peer信息其实主要还是由客户端自己报上来的,每次启动客户端,就会上报用户下载列表里的文件id和客户端的ip地址。

而因为一般情况下用户上下线操作比较频繁,所以phub的更新和修改对性能也有一定的需求。

看起来拿redis也很好实现对不对?

file server

file server其实就是基本的文件服务器了,这个和一般的分布式存储系统应该差不多(我猜的)。不过用户能拿到的不一定是服务器地址,更应该是cdn节点的地址。

有了上述的三种服务之后,在支持bt/ed2k协议之外,可以通过内部的服务将整个互联网上的二进制资源进行整合。比如你从bt网络下载到的资源,完全可以同步给ed2k网络的用户去(当然前提是他们都用迅雷。

其实使用的技术都不复杂,但是要考虑到迅雷成立的时间,那时候互联网的基础组件并不像现在这么多。开源界也没有现在这么靠谱,所以内部很多轮子还是自己撸的。甚至二进制协议都是自己定义的。这也带来了一些弊端,就是不像现在的rpc一样的有协议描述文件,新人只能通过代码里的各种setbit和老版本的语焉不详的文档去猜各种字段的含义。这么一想的话,现在的互联网公司员工多幸福啊~

对于迅雷的人来说,最难解决的问题其实都是一些乱七八糟的case,比如xx种子解析错误,xx资源下载不了,xx有伪装资源会导致用户下载校验不停出错,xx下到99%就停了之类的诡异情况等等等等。所以实际上解决这些问题也要花费掉不少的开发精力。着实体现出90%的代码都在处理业务以外的异常情况。

因为我们进入迅雷的时期也比较特殊,恰逢整个公司迎接上市,后来还来了国家扫黄打非(关闭快播的风波,实际上公司也多多少少受到了不小的影响。比如进入公司之后,很多工作都是加过滤模块,阉割掉以前的功能,删除资源等等等等。这个公司最终流血上市,一个十年的科技公司认一个后起之秀(小米)做了干爹。也是让人唏嘘不已。