anchor.diff:  
   按流处理之后，无论源文件或打包产出文件都无需存在硬盘上了，剩下硬盘资源，剩下I/O时间。
   
  +[[golang_for_concurrency]]
   === 并发考虑：Golang实现web服务
   
   打包下载服务仍是请求响应模型的web服务。如何提高并发下载数？在资源紧张的情况下
  
positive.code: - IE和现代浏览器对UTF8文件名的对待是有区分的，我们在服务端都满足它们。
  - 不同浏览器对特殊字符的转换也是有差异的，我们在服务里直接统一改好名，同时做到区别重名。
  
  === 别拼接源文件地址进 URL
  提出打包下载请求肯定要带着若干源文件的地址，发一个 POST ajax 请求比较理想。因为若选 GET 请求只能拼 URL，源文件地址的URL长度和数目未知，存在超过 URL 长度限制的可能（IE有2084个字节的限制）。
  
  POST 请求带回一个固定长度的存根，在回调方法里再组装一个下载打包文件的 URL，直接打开它就可以启动下载了。这两个请求的衔接是一个用户无法干预的连贯动作，所以时间很快，所以把存根存放在内存数据库如 Redis 中可以设一个很快的过期时间。
  
  image:zipper/request_sequence_diagram.png[]
  
  === 高可用、高并发：集群方案
  看了前文，你该知道这个服务被设计成独立无状态的。和其他集群一样，一个负载均衡器就可实现。
  
  但是前文我说过是用 docker 部署的，我推荐在几个VM之间建 docker swarm，直接利用 docker 的 ingress 网络特性来做负载均衡，通过横向扩展 docker swarm 中节点数目和container数目来支持更高并发。
  
  存根依赖的内存数据库如 Redis 自然也需要做集群，负载很小，只为高可用。
  
  == 实现
  你很走运，我已实现好了，拿去吧~
  
  
negative.code: 
  结果 Golang 语言胜出，采用 Golang 内置的 http 库由 goroutine 支持并发。
  
  [[token_auth]]
  === 安全考虑：secure-token auth
  
  打包下载服务授予 key pair 给服务使用者，并约定共同的hash算法，由服务使用者发出请求前做签名生成 token，之后由打包下载服务验证签名，并进一步验证是否过期以反盗链。
  
  在打包下载服务这里实际只做了验证（authentication），而没有做授权（authorization）。没错，任何签名正确且未过期的请求都可以被放行。你应该注意到了，签名请求的是服务使用者，那是你的某个使用此服务的产品，不是最终用户，对最终用户做授权是各产品自己的事，这也是为独立性的考虑。
  
  [[stateless]]
  === 独立可复用考虑：独立无状态服务
  服务中必须把独立做到极致，才易复用
  
  