当单块架构被划分成微服务之后,随着微服务数量的增多,毫无疑问,将会面临比单块架构更复杂的问题。
部署微服务将会面临以下问题。
1.运维负担
对传统的单块架构系统来说,产品通常只有一个发布包,升级、部署系统往往只需要部署这个发布包即可。现在,面临着这么多的微服务,显然运维的负担要比之前更重了。对于运维工程师来说,部署的服务呈指数上升,传统的手工部署方式往往已经不能适应日益增长的服务运维需求。
⒉服务间的依赖
在一个微服务结构中,你更容易遇到的错误是来自依赖的问题。在微服务架构系统中,某些业务功能需要几个微服务协同才能完成,这些服务之间难免存在一定的依赖关系。特别是以某种方式更新某个服务的API时,同时也会影响其他服务,造成某些服务的不可用。例如,在天气预报系统中,天气预报微服务是依赖于天气数据API微服务及城市数据API微服务的,只要这两个数据API微服务其中一个不可用,则会导致整个天气预报微服务不可用。所以在更新服务时,需要先确定哪些服务需要更新,而后评估更新对其他服务的影响是什么。
3.更多的监控
每个微服务往往需要设置单独的监控,这意味着更多的监控。而且每个微服务可能使用不同的技术或语言,依靠不同的机器或容器,使用其特有的版本控制,这也大大增加了监控的复杂性。
4.更频繁的发布
每个微服务都需要单独部署,这就意味着需要更多的服务发布。微服务的颗粒度相对较小,修改和发布也较为容易,所以发布也会相对更加频繁。这是微服务的优点,但同时也是实施微服务所要解决的难题。
5.更复杂的测试
微服务化之后,服务可以独立开发和测试,团队或成员之间可以并行快跑,这极大提高了系统的研发效率,但也给测试工作带来了挑战。除了验证各个独立微服务之外,我们还需要考虑通过具有分布式特性的微服务架构检查全部关键性事务的执行路径。由于微服务的目标之一在于实现快速变更,因此我们必须更加关注服务的依赖性,以及性能、可访问性、可靠性和弹性等非功能性要求。
针对上面的部署和发布的问题,一般采取如下的解决思路。
1.自动化运维
微服务显著增加了开发团队的运维和工具负担。每个服务都需要一个部署管道、一个监控系统、自动报警、轮流电话值班等。在这种情况下,采用自动化运维手段,可以有效提升运维的效率。
微服务需要大量的基础设施用于开发和部署,因此要使用一个自动化运维平台。Kubernetes ,Swarm、Mesos、Docker及其他类似产品可以提供很大的帮助。
2.处理服务间的依赖关系
服务越多,服务间的依赖关系就越复杂。其中解决其复杂关系的一个基本原则是:永远只有不同层级的单向依赖,即上层依赖下层,高层服务可以依赖低层服务,同层服务间不互相依赖。这样就能让系统有一个清晰的依赖关系,而且这样的话,单向依赖就永远不可能形成环状。如果出现了同层服务间依赖,就说明服务分层出现了问题,此时需要抽象出一个更高层次的服务或者提升其中一个服务的层次。
3.日志收集
由于微服务的数量众多,每个服务都有自己的日志,那么通过这些散落的日志来查看服务的状态将会变成一个难题。针对微服务的日志,我们倾向于将所有的微服务的日志进行收集,尽量统一到一个平台中,这样就能在同一个平台中监控所有微服务的状态。
日志收集方式也尽量做到统一。由于很多设计里对于业务日志、容器日志、宿主机日志等采用不同的agent,这是一个不好的设计方式,因为agent也是需要管理的,引入太多agent只会给自己增加不必要的管理成本。
在日志收集方面的方案有Splunk、Logstash、Flume、Fluentd等。本书后续章节也会对微服务的日志管理展开详细的讨论。
4.监控和告警
从功能上来说,服务的监控可以分为两种类型,一种是对主机的监控,另一种是对服务的监控。
对于服务的监控,是指在不知道服务具体运行的情况下去检查这个服务本身是否可用,以及在它出了故障以后如何进行故障的恢复。这种监控方式在容器和非容器上差异性比较小,但是与具体使用的技术栈或平台会有比较大的关联性。例如,如果使用JConsole工具来监控程序的性能,显然这里的程序只能是Java程序。对于主机的监控,是指我们需要去了解这个服务器内部的运行状态,如CPU使用率是否爆满,磁盘占用一段时间是否出现异常。对于主机监控主要作用有两点,一种是出现严重故障的时候,我们要对发生故障的现场进行回溯,另一种是我们通过监控数据能够去预测—些可能发生的问题。
当监控到异常时,监控软件最好能自动做出一些处置机制。例如,在集成服务器中,当检测到提交的代码有问题时,集成服务器会自动将部署的版本回溯到上一个可用的版本,以保证现场部署的服务始终可用。
当监控软件检测到系统超过阈值时,应该要发送告警信息给运维人员。常见的告警方式有短信、邮件、闪光灯、音响喇叭等。
5.微服务的发布
由于同一个微服务可能会被发布到多个主机上进行水平扩展,这就要求不同的主机之间部署的是相同的软件。同时,微服务能够独立于其他微服务发布或者取消发布,在部署时,微服务之间的功能不会产生相互影响。
一种比较好的方式是把微服务打包成镜像,这样就保证了不同主机之间能够使用相同的镜像。
同时,由于镜像中包含了服务的配置文件和环境,这样,就可以尽可能地避免主机环境对软件部署产生的影响。
考虑使用Docker容器,这将会使构建、发布、启动微服务变得十分快捷。
通过Kubernetes能够进一步扩展Docker 的能力,能够从单个Linux主机扩展到Linux集群,支持多主机,管理容器的位置,提供服务发现等功能,这些都是微服务需求的重要特性。因此,利用Kubernetes管理微服务和容器的发布,是一个非常有力的方案。
6.API版本控制
版本控制应当适用于任何API,对微服务也一样。如果有某些改动打破了API的格式,那么就应当针对该改动单独发布另外一个版本。无论是公共接口还是其他内部服务使用的接口,在我们不清楚谁在使用这些接口的前提下,必须要保证向下兼容,或者至少要给用户足够的时间去适应。
一种比较好的实践是,在部署新的接口时,保持老的接口暂时不变。新老接口并存的好处是,我们可以尽快地发布新的服务,其中包含了新的接口,同时,我们也给老的接口用户迁移到新接口的时间。当所有的用户都迁到了新接口后,就能将老的接口及相关代码进行移除。这种部署方式,我们也称为“蓝―绿部署(Blue-Green Deployment) ”。
本篇内容篇理论知识,比较枯燥一些,也希望大家仔细阅读。
本文就是愿天堂没有BUG给大家分享的内容,大家有收获的话可以分享下,想学习更多的话可以到微信公众号里找我,我等你哦。