如何构建微服务架构

【编者的话】“微服务”的概念兴起于四五年前,近几年尤为火热,各大厂都在进行微服务化改造和微服务建设。最近一年来咱们也参与了微服务化的改造大军,这里写下一些作微服务系统设计和开发时的切身感觉。html

【3 天烧脑式基于Docker的CI/CD实战训练营 | 北京站】本次培训围绕基于Docker的CI/CD实战展开,具体内容包括:持续集成与持续交付(CI/CD)概览;持续集成系统介绍;客户端与服务端的 CI/CD 实践;开发流程中引入 CI、CD;Gitlab 和 CI、CD 工具;Gitlab CI、Drone 的使用以及实践经验分享等。java

微服务架构

提及微服务,不得不提那篇经典的文章,来自Martin Flower的《Microservices》,建议多读几遍。Martin Flower是敏捷开发方法创始人之一,《重构》《企业应用架构模式》做者,ThoughtWorks公司的首席科学家。微服务虽然不是在这篇文章中首次提出,可是它将发展多年的微服务架构进行了重要性总结,推进了微服务的流行。数据库

Martin在文章中从多个方面详细阐述了微服务的概念,首先做者对比单体应用的架构,一个单体应用处理请求的全部逻辑都运行在一个单独的进程中,这种状况下,你能够在笔记本上开发、测试、部署都很简单,还能够经过负载均衡进行横向扩展,最后交付给运维团队。单体应用很是成功,可是愈来愈多的人感受不妥,尤为是在云中部署的时候,任何微小的变动都要总体从新构建和部署,扩展的时候也须要总体扩展,不能进行部分扩展。这时候微服务架构风格就出现了,它提出将应用程序构建为一套服务,每一个服务均可以独立部署和扩展,运行在独立的进程中,服务之间经过RPC调用进行通讯。微服务的应用致力于松耦合和高内聚:采用单独的业务逻辑封装,接受请求、处理业务逻辑、返回响应,并且喜欢简单的REST风格,而不喜欢复杂的协议,最终实现敏捷开发。 后端

单体架构和微服务架构图

微服务不是什么框架,也不是什么系统,只是一种架构风格。咱们所使用的DSF(华为)、DUBBO(阿里)、Spring Clould(Pivotal)等框架,在介绍中都称是分布式服务框架。这些分布式服务框架都是微服务架构必不可少的基础能力,微服务必定是分布式的。分布式服务的概念比较模糊,只是解决了网站的高并发问题,不少细节问题是微服务帮其明确的。微服务更增强调敏捷和健壮,强调服务的粒度,一个服务只需完成一个单一的、独立的功能,多个微服务组合完成相对复杂的业务系统,以知足需求。并且微服务注重借助于各类中间件进行业务解耦和提升性能,以及提升服务的容错性。服务器

从上面的介绍中咱们能够看出,微服务架构有不少优势。例如,服务的拆分将复杂问题简单化;每一个服务由专门的团队开发,开发者能够自由选择实现技术,提供API服务;每一个微服务均可独立部署,加快了部署速度;每一个服务可独立扩展以知足需求。微服务不是免费的午饭,微服务架构也有缺点。微服务概念强调了服务的大小,可是服务变小不是最终目的,微服务的目的是有效地拆分应用,实现敏捷开发和部署;微服务应用都是分布式系统,须要经过RPC进程间通讯完成服务调用,这样大大增长了系统的复杂性,所以必须写代码处理因为网络或者服务不可用等致使的调用失败问题,虽然通常框架都支持相关配置,可是在这种状况下微服务显得相对复杂些;在微服务架构的应用中,建议不一样的服务使用不一样的数据库,这种状况下,一个交易通常会调用多个服务,同时须要修改多个数据库,因为CAP理论和其它的一些因素,并不能实时地保证数据的一致性,所以不得不使用最终一致性的方法,从而对开发者提出了更高的要求和挑战;测试一个微服务架构的应用也是很复杂的任务,首先须要启动和它相关的全部服务(至少须要这些服务的stubs)。最后仍是要强调一下,不要低估了微服务架构带来的复杂性,下面介绍一下咱们如何应对这样的复杂性。网络

微服务架构给咱们带来方便的同时,也引入必定的系统复杂性,最近几年随着基础设施自动化技术的发展,好比云平台、容器技术,再加上自动化测试与持续集成,减小了构建、发布、运维微服务的复杂性。所以咱们的微服务团队应该依赖基础设施自动化技术构建软件,下图说明这种构建的流程: 架构

基本的构建流程

在构建微服务软件时使用的分布式服务框架也拥有不少特性,这些特性提供了不少复杂问题的解决方案,好比异步调用、超时失败策略、故障隔离、健康检查、流量控制以及自定义路由等,这些特性大大减轻了开发者处理逻辑的负担,还有一些高性能、高可用的保障都增长了咱们构建微服务的信心。并且通过多年的微服务实践者的摸索,也总结出了不少辅助运维系统,好比统一日志收集(ELK)、服务管理、服务监控和服务治理等,大大减轻了运维的工做,并且能让咱们对复杂的微服务系统作到心中有数。并发

总之,微服务架构入坑容易,坑了呆得舒服难。各类基础设施和配套系统必须跟得上,还得有一个具备微服务特性的团队,才能真正驾驭得了微服务。负载均衡

两个值得深刻的话题:框架

  1. 微服务与持续集成
  2. 微服务与测试

微服务团队

上一节中说到更适合构建微服务应用的微服务团队,什么时微服务团队?说一个比较现实的问题,当咱们作服务拆分的时候,一般管理都会集中在技术层面,涉及到UI团队、服务端业务逻辑团队、数据库团队、测试团队和运维团队。当采用这种标准对团队进行划分时,即便时小小的变动都将致使跨团队项目协做,从而消耗时间和预算审批。这就是 Conway's Law :

设计一个系统的任何组织(广义上)都会产生这样一种设计,其结构是组织交流结构的复制。 ——Melvyn Conway, 1967

Melvyn Conway 的意思是设计一个系统的团队结构将决定了一个软件系统的结构,将人员划分为 UI 团队,中间件团队,DBA 团队,那么相应地,软件系统也就会天然地被划分为 UI 界面,中间件系统,数据库。而一个高效的微服务团队会针对这种状况进行改善,微服务团队须要是一个全栈的团队,跨职能的团队,应该包含整个项目周期的全部技能,先后端开发、UI设计、测试、构建部署、上线与运维都是必须技能。

微服务团队除了熟练的业务逻辑开发以外,还须要有DevOps能力、服务的快速构建、良好的团队文化:

  • 首先DevOps能力是保证持续交付和应对复杂运维问题的动力之源,运维人员不懂开发人员的服务设计和调用流程,开发人员不懂产品环境和总体配置结构,开发和运维的融合才能更好的应对微服务架构。正以下面这句话所说的,“你构建,你运维”。

You build it, you own it. – Amazon CTO

所以,须要打造DevOps文化,将运维做为需求提早注入到开发流程中。

DevOps流程

  • 其次保持服务的持续演进,使服务可以快速、低成本地被拆分和合并,以快速响应业务的变化。

  • 同时要保持团队和架构的对齐,微服务看似是技术层面的变革,但它对团队结构和组织文化有很强的要求和影响,识别和构建匹配架构的团队是解决问题的加速器。微服务团队的另外一个关键点是持续改进、持续学习和反馈,只有保持这样一个文化氛围,微服务架构才能持续发展下去,保持新鲜的生命力,进而实现咱们的初衷。

专业的微服务团队,为微服务保驾护航。

项目的微服务设计实践

咱们在各类基础设施不健全的状况下,匆忙进入了微服务改造的深渊。原来的单体应用按照功能拆分红了下面的结构:

微服务下的系统分层

拆分以后,模块忽然变多了。将内部业务逻辑和原子功能拆分出来,实现了部分功能的复用,而且对外的接口按类型区分到不一样的模块中去了,方便了使用,可是增长了管理的难度。

从上面咱们对微服务架构的了解,一个微服务系统会有大量的服务组成,服务之间的层次关系依然是存在的,可是调用顺序上的要求会有所下降,只要知足严格的上层调用下层便可,在某些简单的业务功能上容许跨层调用。

架构对比图

上图是三种架构(集中式、分布式、微服务架构)的形象化展现。能够看到微服务的一个状态,乍看起来有些混乱,若是还按照之前的管理方式维护项目的话,工做量会成指数级增加,人力所没法胜任的工做。

这时候就须要依赖一些分布式服务框架,并创建一些辅助运维系统:

  1. 首先服务之间远程调用,服务的注册和发现机制必须有好的分布式服务框架(相似dubbo)支持,方便作服务之间的调用配置管理。
  2. 部署的服务进程增长之后,对应的日志文件也会增多,这时再使用ssh到服务器上查看日志,这个工做量也是可想而知的。咱们对业务日志作了规范化约束,而后使用ELK技术栈搭建了日志集中化管理系统。
  3. 为了可以对线上的全部服务有个全局的把控,咱们根据注册中心的数据搭建了服务的管理系统,展现各个维度的统计数据,例如,每一个主机上多少个应用,每一个应用提供了多少个服务,同时又消费了多少个服务等等。还有一些针对服务的约束规则的告警信息,例如某个应用消费的服务,却没有服务提供者等。还有一个总体的应用之间的依赖关系图。
  4. 为了优化系统结构和排查问题,搭建了服务的监控系统,这个是依赖分布式服务框架打印的预统计日志的,经过这些日志分析获得一个总体的服务监控功能,例如每一个服务的响应时间、错误率等。还有调用链跟踪功能,排查问题时使用它来跟踪请求信息。
  5. 服务治理功能用来及时地对线上项目作一些调整,例如限流、降级、负载均衡、超时、路由、隔离容错等。

有了以上这些系统辅助,咱们的微服务化改造之路平坦了许多。

在进行微服务化改造的时候,接口的设计上遇到了一个问题,服务之间的调用是经过私有协议进行的RPC调用,这种调用中如何描述服务响应成功以外的其余异常状况?

  1. 采用Exception类,定义各类异常类来描述异常状况。
  2. 采用错误码+错误描述。

其中方案1采用的Exception类,是咱们平时java中定义进程内部接口最多见的方法,这种方法的优势是,可以使调用接口的一方的代码更简洁,经过try...catch来处理,若是不须要处理的话,在方法上声明直接向上抛出便可。缺点是跨语言开发解析难度大增,并且日志中异常堆栈不少。方案2采用错误码的形式偏偏相反,缺点就是每次调用都要判读是否调用成功,增长代码中的if语句。

针对这个问题,但愿各位实践分布式服务或者微服务的大神给出大家的实践方案,疯狂讨论起来。

结束语

上述三节中讲述了咱们在构建微服务的经历和一些感想,给其余准备实施微服务和正在实施微服务的团队以参考,写这篇文章的另外一个目的就是但愿能起到抛砖引玉的做用,但愿能和其余团队进一步交流。

搞微服务

原文连接:如何构建微服务架构(做者:rabbitGYK)

相关文章
相关标签/搜索