一般来说会推荐采用 qiniu 或者 upyun,又或者是 amazon 之类大公司的 cdn 服务,不过当需要一些自己实现的场景,比如企业内部软件的加速,就需要一个私有的 CDN 了。
极简内容分发系统是我在公司里面的一个项目,最近把他开源出来了。可能其他企业或者组织也需要一个类似的东西。
通常来说 CDN 分为 push 和 pull 两种方式,push 比较适合大文件,pull 适合小一些的文件,但是使用起来比 push 要简单的多。
MiniCDN 采用的就是 pull 这种方式,目前的实现方式是所有缓存的文件存储在内存中,使用 LRU 算法淘汰掉就的文件,镜像的文件受限于缓冲区的大小(目前的缓冲区是512M),如果超过了这个缓冲器大小,就没有加速的效果了。
没有所有的智能 DNS,直接用的是最简单的 http redirect。 还没写负载均衡,所以 redirect 的时候,就是随机返回一个节点(简单粗暴)
MiniCDN 分为 manager 和 peer。都是写在一个程序里。
我平常用的时候,就只开一个 minicdn 的 Manager 来加速我的后端服务器。如果没有节点的话,manager 就会把自己当成一个节点。然后当有特别大的下载即将要冲击我的服务器的时候。我就会找很多的同事,将 minicdn 部署到他们平常用的电脑上(window系列, 因为是golang语言写的,什么平台的程序都能编译的出来)。这样我在短时间内就拥有了一个性能不错的 cdn 集群(充分利用同事的资源)。当下载冲击结束的时候,在把这些节点撤掉就可以了。相当省事
MiniCDN 使用了谷歌开源出来的 groupcache 框架,目前dl.google.com后台就用到了groupcache,性能而言远超那些squid或者nginx-proxy-cache.
groupcache 的数据获取过程很有意思,我把他翻译了过来
groupcache 的运行过程
查找foo.txt的过程(节点#5 是N个节点中的一个,每个节点的代码都是一样的)
判断foo.txt是否内存中,并且很热门(super hot),如果在就直接使用它
判断foo.txt是否在内存中,并且当前节点拥有它(译者注:一致性hash查到该文件属于节点#5),如果是就使用它
在所有的节点中, 如果foo.txt的拥有者是节点#5,就加载这个文件。如果其他请求(通过直接的,或者rpc请求),节点#5会阻塞该请求,直接加载完毕,然后给所有请求返回同样的结果。否则使用rpc请求到拥有者的节点,如果请求失败,就本地加载(译者注:这种方式比较慢)
groupcache 是2013年写出来的,软件也不怎么更新了。里面的 HTTPPool 还有两个问题一直没有修复,这两个问题直接影响到节点之间不能交换数据。因为官方不用 groupcache 的这部分,所以连用户提的 issue 都不修(真是蛋疼)
https://github.com/codeskyblue/groupcache 是我fork的,把这两个问题修复了,虽然提了pr,不过感觉他们一时半会不会merge的。
受 python-celery 的启发,我实现了 peer 退出时候的两种状态(Warm close and Code close)。 Warn close可以保证党节点不在服务的时候才退出。Code close就是强制退出,下载者可能会发现下载中断的问题。
M: Manager
负责维护Peer的列表,每个peer会去Manager同步这个列表。
所有的请求会先请求到manager, 然后由manager重定向到不同的peer
P: Peer
提供文件的下载服务
Peer之间会根据从manager拿到的peer列表,同步文件
Manager 与 Peer 是一对多的关系
[M] |`------+--------+---...... | | |[P] [P] [P] ....
命令行启动
./minicdn -mirror http://localhost:5000 -addr :11000 -log cdn.log
对网站http://localhost:5000进行镜像加速
监听11000端口
日志存储在cdn.log中
源站的所有下载地址,最好都改成这个http://localhost:5000/something
命令行启动
./minicdn -upstream http://localhost:11000 -addr :8001
指定Server地址http://localhost:11000
监听8001端口
MiniCDN 使用了谷歌开源出来的 groupcache 框架,目前dl.google.com后台就用到了groupcache,性能而言远超那些squid或者nginx-proxy-cache. groupcache 的数据获取过程很有意思,我把他翻译了过来 groupcache 的运行过程 原文地址 查找foo.txt的过程(节点#5 是N个节点中的一个,每个节点的代码都是一样的) 判断foo
我试图创建一个正弦和余弦的计算器,技术上只在0-pi/2的范围内运行。现在这可能看起来很傻,但以后它将被使用,这样我就可以使用泰勒级数。 我有一个大部分工作的实现,但是当θ是x*(PI/2)的形式时,我有一个严重的问题,其中x是一个任意的整数。看起来,在这些值上,有时它们被推入附近的象限,它们不属于。也有一些偶尔的彻头彻尾的错误,我无法解释。 下面是这样做的代码。
关于元组,上一讲中涉及到了这个名词。本讲完整地讲述它。 先看一个例子: >>>#变量引用str >>> s = "abc" >>> s 'abc' >>>#如果这样写,就会是... >>> t = 123,'abc',["come","here"] >>> t (123, 'abc', ['come', 'here']) 上面例子中看到的变量t,并没有报错,也没有“最后一个有效”,而是将对象做
开发人员可以选择三种语言来编写智能合约: 1.solidity,以太坊的旗舰语言,也是开发智能合约最流行的语言。 2.Serpent,一个用于编写智能合约的Python语言。 3.类LISP语言(LLL),低级语言,Serpent提供了LLL的超集。使用LLL的信息不多,这个博客/var/log/syrinx和github相关的库lll-resurrected GitHub不错,可以参考参考。 为
问题内容: 有很多不错的json libs lika GSon。但是对于XML,我只知道Xerces / JDOM,并且都具有乏味的API。我不喜欢使用不必要的对象,例如DocumentFactory,XpathExpressionFactory,NodeList等。因此,鉴于对诸如groovy / scala之类的语言的本机xml支持,我有一个问题。是否有简约的Java XML IO框架? PS
我有一个对象列表,如下所示: 在<范围内,每天都有一个元素。 我希望能够根据和之间的间隔将这些元素减少到不同的时态分组中。如果和之间的差异大于4年,我希望将它们分组为年。如果差异小于四年,但大于一年,我想把它们分成几个月。如果小于一年,但大于一个月,我想分成几周。任何少于一个月的,不需要分组。 当我说“group”时,我的意思是我想总结属于特定年份的所有东西的元素(使用上面的第一个示例),并为每个
出自何乐源码,简单的易语言写的markdown编辑器,Markdown NOTEPAD pro使用了著名的开源项目Editor.md,感谢Editor.md的作者,本程序使用了一些来自互联网的免费,开源作品及其资源,其版权归其作者所有。本软件是一个免费软件,感谢大家的支持和使用。软件UI设计主要配色是白黑,突出简约的风格,给使用者更美观的感觉,欢迎fork/star。 版本:Editor.md v