今天小数又漂洋过海给大家运来一篇干货,在今天的文章中,我们将一同了解如何在Docker上规划一套成功的微服务架构。
Docker的人气仍然持续升温,这主要归功于其易于打包且能够在任意环境下实现代码分发的强大能力。而在结合微服务架构的前提下,Docker足以帮助开发者们利用小型模块化组件构建软件,并充分发挥各组件功能以应对各类复杂难题。
不过要真正实现微服务架构,我们需要通过前期规则避免将其误解为分布式整体应用,否则碎片化问题也将随之而来。从服务设计到部署再到监控,利用Docker进行微服务架构部署中存在着多个需要认真考量的关键点。
为每套容器设计一项服务
在创建新的微服务时,在单一容器内部署多项服务似乎是种颇具吸引力的优化方式。然而,存在于同一容器实例中时,各服务将无法独立实现规模伸缩。
规划技巧一: 采取每个容器一项服务的做法能够有效支持微服务的按需规模伸缩,且无需面对由多服务容器带来的内存与CPU过度占用问题。
建立服务发现方案
为了实现规模化与高可用性要求,微服务需要跨越多台Docker主机进行分布。请注意,千万不要在服务当中使用硬编码形式的主机名称或者容器IP地址。相反,大家应当在代码以及负责管理一个或者多个容器实例的Docker基础设施当中建立服务发现机制,即根据名称进行服务定位。
规划技巧二: 选定一项服务发现策略,并确保其能够根据容器实例的规模伸缩进行自动调整。具体选项包括:ZooKeeper、Consul、Etcd、Eureka或者使用内部DNS策略。
通过CDN实现共享资产分发
对于大多数Web应用,其中都会涉及共享资产,例如图片、样式表以及JavaScript库。如果大家使用的是Ruby on Rails之类的框架,那么asset pipeline将成为管理这一流程的有效工具。然而,其在生产环境下的管理工作仍然相当困难。由该pipeline在单一容器内生成的资产无法为其它容器所共享。解决方案分为两种:其一,确保每个容器实例都能够生成并使用资产(不推荐);其二,将资产推送至单一共享位置。
规划技巧三: 利用CDN打理静态及动态生成的资产。通过这种方式,我们能够改进浏览性能,同时帮助专门设计用于处理输入API请求的容器实例减轻负担。其还能简化容器基础设施,意味着我们不再需要为跨容器实例资产共享设计额外的实现方式。
外部化、监控并管理微服务
在一套典型云原生架构当中,进来的的HTTP请求需要跨越各服务器实例进行负载均衡。然而,大多数基于云的负载均衡器都只能将请求路由至服务器,而非单一服务器上的多个容器。通过在基于HTTP的微服务之前安装反向代理,输入的请求可被正确分发至多Docker主机上的任意数量容器实例当中。
除了负载均衡,基于HTTP的微服务可能还需要使用验证、授权以及速率限制等功能。将服务开放给移动或者公众/合作开发者时,我们还需要预防DoS攻击,并将来自单一外部URL结构的负载路由至内部微服务(例如 http://api.example.com/products/ -> http://products.myapp.local/ )。
规划技巧四: 安装反向代理及/或API管理平台。目前市面上存在着多种商用及免费开源的产品供选择,包括:3scale、Apigee、Kong等,也可以通过nginx的定制化调整实现。
将数据库部署在容器之外
与配备有网络块存储设备的传统云服务器不同,容器自身拥有一套独立于主机之外的隔离化文件系统。容器内的数据会在容器本身被销毁后一并消失。另外,我们不可能长时间将容器运行在同一主机当中。因此,在没有做大量的额外工作的情况下,将主机文件系统作为外部卷并不能完全保障生产数据的持久化。我们需要更好的数据库方案,来保障数据的安全和高性能。
规划技巧五: 在容器之外设置并部署数据库。使用数据库即服务方案能够帮助我们摆脱管理自有实例的困扰,当然立足于容器外建立自己的托管数据库方案也是可行的。惟一的例外就是,如果大家的微服务中包含只读数据,则可将其在镜像创建过程中打包在容器之内。