Shopify是一个大型的RubyonRails应用,其产品服务器能通过给1700个处理核心和6TB RAM分配任务来完成每秒处理8000多个请求。Shpify为了更加便捷、跨平台跨版本地进行分包任务,采用了时下炙手可热的Docker封装技术。近日,Shopify在其博客上分享了自己的Docker技术使用经验。
关于封装格式的选择,Docker提供很多封装格式,从轻量级的单进程容器到重量级的富应用容器,一应俱全。Shopify的开发者选择“纤薄”路径的容器,并隔绝外部影响,目的就是为了减少CPU和内存的负担。不过虽然运行纤薄容器,但还有一个初始化进程(PID=1)使得监测工具、保密管理和服务能够紧密集成。除了初始化进程,还添加了一个在每个容器内占用PID=2并且简单启动应用进程(PID=3)的ppidshim。有该 ppidshim,应用程序不会直接从(i.e. ppid != 1)继承。除此以外还提供了健康检查,以保证其正常运行。
有一个要特别注意的一点,Shopify称之为“容器的100定律”。在选择将何种服务放入容器中时,假设一台主机中运行100个小容器,评估是需要运行一个给定服务100次,还是共享一台主机的服务更好。用于***效率的选择,这个评判标准在实际中很有用处。100定律的使用需要一定的灵活性。一些情况下,仅仅需要写一下组件的“黏合器”,也可以通过配置来达到目的。最终,你应该获得一个容器,内含你的应用程序运行所需的东西,以及一个提供了Docker托管和共享服务的主机环境。
关于Debug,没有特别需要注意的,容器内运行应用在绝大多数情况下和他们未封装时行为相同,而且,大多数标准的Debug工具和技术在Docker主机上能正常运行。所以开发者只需照常调试。
命名方面。选取容器名称的时候,尽量描述其工作内容(例如:unicorn-1,resque-2),为了便于追溯,还要结合主机名(例如unicorn-1.server2.shopify.com.)。在使用过程中,将Docker的主机名标签也传入容器中,方便问题的追踪。
注册和部署。使用GitHub的提交挂钩触发一个容器生成每一个主推,并提交状态,表明构建是否成功。使用Git的提交SHA来Docker_tag容器,如此可以一目了然容器中的代码是什么版本。还把SHA放入(/app/REVISION)文件夹,容器内的文件夹更容易进行debug和脚本使用。一旦构建成功,希望把容器推到一个中央注册处。开发者选择运行自己数据中心的注册表以加速部署和尽量减少外部依赖。运行Nginx的反向代理,可以缓存GET请求背后的标准Python注册表的多个副本。大型网络接口(10Gbps)和反向代理能有效处理“惊群效应”。代理方式也使我们能够运行多个注册,并在注册中断时提供自动故障切换。