我们在后台架构设计中经常会将较大的系统进行微服务化。这种架构的优势是显而易见的:模块化的开发和维护相对要简单很多,每个服务可以采用不同的技术去构建,团队的分工协作能力也能够得到最大的发挥。然而微服务架构同样也带来了一些麻烦,比如运维的复杂度较高,数据的一致性等问题。我们认为实施高质量的微服务架构至少需要解决以下三个问题。
定义微服务的边界
- 首先我们需要考虑如何对服务进行拆分,可以按照业务逻辑或是技术层面进行分割。
不管是哪种方式,我们期望最终的效果是每一块服务都应该提供单一的服务,并且能够实现自治,即不需要过度依赖外部接口,出现问题后也不至于拖垮整个系统。
- 其次我们需要选择一种高效的服务间通信方式,我们经常会用到thrift或protobuf等RPC框架,以及各种消息队列的灵活应用也能帮助优化我们的通信机制。
通过使用RPC,服务之间的相互依赖都会被集中在接口上,比如我们将多个服务都会用到的语义全部封装在thrift IDL中,这样也避免服务内部的硬编码导致难以化解的耦合。
微服务的部署
- 当我们完成了子服务的拆分之后,需要考虑如何去部署他们。当然我们会想到把服务部署在弹性十足的云上,通过划分不同的硬件资源来承载不同服务的运行,力求达到资源的合理性利用。
然而在缺少高效运维平台的支撑下,传统云服务还是很难提供最佳的外部资源环境,部署和迁移的成本还是较高。
- 这时候我们想到了用时下很流行的Docker对我们的系统进行Dockerize。通过这种方式,我们可以在一台物理机器上虚拟出上百个container,这种计算粒度足够的小,加上操作系统级别的虚拟机制,整个服务构建起来也很方便快捷。而且可以考虑将不同的服务进程封装在不同的Docker Container,这样各个服务的动态伸缩和迁移都能够得到保证。
微服务架构的自我构建
- 微服务由于网状的架构,它的负载均衡及自我构建也比传统的单一后端服务要复杂很多。
所谓的自我构建就是,微服务架构中的任何一块服务都能够同步感知到其他关联服务的变化。
比如依赖的后端服务进行了扩容或者迁移,前端的服务是否能够及时的发现。又或者,后端某个微服务进行了节点扩容,前端的代理服务是否能够做到无缝感知。
- 这里我们推荐一种轻量级的基于Docker的高可用web基础架构,通过Etcd和Confd来做到负载均衡的自动发现。
- 其中Docker Container中部署的是我们的后端服务,比如Python的Uwsgi进程或者PHP的Fast CGI等。
- 负载均衡我们通过Nginx来实现,当然也可以采用Haproxy等其它代理服务。
- Etcd作为一个高可用的K/V存储系统,我们用它来存储后端服务的信息,对于负载均衡而言,只需要知道host:port即可。
- 采用Confd作为配置管理工具,可以定时检测Etcd节点的变化并获取最新配置,然后结合模板引擎生成最新的Nginx配置文件,并自动执行service nginx reload。
- Docker run shell是我们编写的用于启动Docker Container的脚本,同时兼顾在启动时向etcd注册最新的后端服务信息。
- 上述架构中,每次启动或是停止Container时,Etcd中的value都会发生变化,Confd也能较及时的感知到这一变化,从而实现了自动负载均衡。
原文地址:http://mtydev.net/?p=171 from 猫头鹰团队