一,什么是微服务
多微才够微
微服务的 “微” 并不是一个真正可衡量、看得见、摸得着的傲 。这个 “微” 所表达的 , 是一种设计思想和指导方针,是需要团队或者组织共 同努力找到的4个平衡点。
所以,微服务到底有多微 ,是个仁者见仁 ,智者见智的问题 ,最重要的是团队觉得合适。但注意,如果达成“团队觉得合适” 的结论,至少还应该遵循以下两个基本前提 。
1,业务独立性
首先 ,应该保证微服务是具有业务独立性的单元,并不能只是为了微而微。关于如何判断业务 的独立性,也有不同的考量 。譬如 ,可以将某 一领域的模型作为独 立的业务单元,譬如订单、产品、合同等 :也可 以将某业务行为作为独立的业务 单元,譬如发送邮件 、单点登录验证 、不同数据库之间的业务数据同步等 。
2,团队自主性
其次,考虑到团队的沟通 及协作成本 ,一般不建议超过10 个人 。当团队超过10个人 ,在沟通、协作上所耗费的成本会显著增加 ,而这也是大部分敏捷实践里提倡的 。当闭队成员超过10个人的时候,可以考虑继续再划分子团队 ,让不同的 子团队承担独立的工作 ,这也是笔者在实践中通常采用的做法 。除此之外,团队应该由不同技能 、不同角色的成员组成 ,是一个全功能的团队 。
单一职责
“高内聚 、低耦合 ”。所谓高内聚,是一个模块内各个元素彼此结合的紧密程度高 。而低耦合,则是指对于 一个完整的系统 ,模块与模块之间 ,尽可能独立再在 。换句话说,对于每个模块 ,尽可能独立完成某个特定的子功能 。在系统持续发展的过程中 ,高内聚 、低耦合的系统具有更好的重用性 、可维护性和扩展性 ,能够持续支持业务 的发展,而不会成为业务发展的障碍 。
轻量级通信
服务之间应通过轻量级的通信机制 ,实现彼此间的互通互联 ,互相协作 。所谓轻量级 通信机制,通常指语言无关、平台无关的交互方式 。譬如,某些复杂的系统,由Java、Ruby以及 Node 等不同开发语言实现的部分组成 ,不同部分之间能够采用语言无关 、平台无关 的方式进行交互。
对于轻量级通信的格式而言 ,我们熟悉的XML 或者 JSON ,它们的解析和使用基本与语言无关 、平台无关。
独立性
拙立性旨在应用的交付过程中 ,开发、测试以及部署的独立 。
在微服务架构中,每个服务都是一个独立的业务单元 ,当对某个服务进行改变时 ,对且他的服务不会产生影响 。换句话说 ,服务和服务之间是独立的 。
对于每个服务 ,都有独立的代码库 。当对当前服务的代码进行修改后 ,并不会影响其他服务。从代码库的层面而言,服务与服务是隔离的 。
对于每个服务 ,都有独立的测试机制,并不必担心破坏其他功能而需要建立大范围 的 回归测试。也就是说,从测试的角度而言 ,服务和服务之间是松耦合的 。
对于微服务架构中的每个服务而言 ,与其他服务高度解祸 。只改变当前服务本身,就 可以完成独立的测试 、构建以及部署等 。
进程隔离
微服务架构其实是将单一的应用程序划分成一组小的服务 ,每个服务都是具有业务属性的独立单元 ,同时能够被独立开发 、独立运行 、独立测试以及独立部署。
二,微服务不是银弹
优势
1,独立性
每个服务都是独立的业务单元 ,能够被独立地开发 、测试、构建,并且能够被直接部署 。
2,单一职责
每个服务聚焦于某业务功能 ,通过清晰的边界划分 ,更容易被团队理解和维护 。
3,技术多样性
通过服务之间的协作以及轻量级的通信机制 ,组织或者团队能使用适合的语言 、工具 解决业务问题 。
除此之外,微服务的实施也会推动基础设施自动化以 及 DevOps 文化在团队中的发展 , 并有利于构建全功能的团队 。
劣势
实际上,在微服务的实施过程中 ,需要考虑如下因素:
1,分布式系统的复杂度
2,运维成本
3,部署自动化
4,DevOps 与组织架构
5,服务间依赖测试
6,服务问依赖管理
分布式系统的复杂度
微服务架构是一种基于分布式的系统 ,从交付的角度出发 ,构建分布式系统必然会带 来额外的开销 。通常,分布式系统的复杂度主要包括以下几点 。
1,性能
同传统的单块架构相比 ,分布式系统由于组件与组件的调用是跨进程 、跨网络的调用 , 因此必然要考虑、网络延迟以及带宽的影响 。尤其要考虑 ,当某业务场景需要多个服务相互协作时 ,响应时间以及性能对系统的影响 。
2,可靠性
在分布式系统中 ,由于网络、带块、节点自身的可靠性等因素 ,任何一次组件间的远程调用都有可能失败 。而且,随着微服务数量的增多,还会出现更多的潜在故障点 。因此,如何提高系统的可靠性 ,降低由于网络、组件等引起的单点故障率 ,也增加了系统构建的挑战。
3,异步
对于跨网络的调用 ,需要考虑异步的通信机制 。我们知道 ,同步通信的过程一般是发 送请求 ,接收响应并处理 ,整个过程实现简单 ,但会造成阻塞。异步通信的过程则是发送 请求后立即返回 ,不会造成阻塞 ,一般适用于耗时操作的处理 。但异步通信在享受非阻塞 的优势的同时 ,也大大增加了功能实现的复杂度 ,并且当出现缺陷时 ,定位问题、调试问题的难度也更大 。
4,数据一致性
在分布式系统中 ,为了保证数据的一致性 ,通常我们会考虑使用分布式事务管理 。但由于分布式事务管理需要跨多个节点来保证数据的瞬时一致性 ,因此比起传统的单块架构 的事务,成本要高得多 。另外,在分布式系统中,通常也会考虑通过数据的最终一致性来 解决数据瞬时一致带来的系统不可用 。
5,工具
虽然现有的 IDE 以及开发工具对单块架构系统的开发支持较好 ,但并没有为开发分布式系统提供足够的支持 。因此,相比传统的单块架构 ,分布式架构的开发 、调试存在较大的复杂度。
运维成本
通常 ,我们说的运维主要包括以下几个方面 。
1,配置
主要包括应用相关的配置信息,譬如参数、依赖部分 、数据库地址 、缓存地址等 。
2,部署
主要包括将应用部署到指定的环境中 。
3,监控与告警
主要包括对应用的健康状况进行监控 ,并当发现战障时能及时告警 。
4,日志收集
主要包括 日志收集,并提供搜索等方式 ,帮助团队且过日志快速定位问题 。
相比传统的单块架构应用 ,微服务将系统分成多个独立的部分 ,每个部分部是 可以独立部署的业务单元 。这就意味着 ,原来适用于单块架构的集中式的部署 、配置 、监控或日志收集等方式,在微服务架构下 ,随着服务数量的增多 ,每个服务都需要独t的配置 、 部署、监控、日志收集等,因此成本呈指数级增长 。
部署自动化
对于单块架构的系统而言 ,部署包通常只有一个或者很少的几个 ,部署的操作成本较低。同时,在单块架构的时代,通常组织的交付周期都以周 、月为单位 。在这种情况下 ,由手动方式来完成系统的部署 ,是可以满足需求的 。
对于微服务架构而言 ,每个服务都是一个独立可部署的业务单元,每个服务的 修改, 都需要独立部署 。同时,随着互联网时代的快速发展 、用户需求的个性化以及市场雨求不 稳定等因素的出现 ,系统的交付周期越来越短 ,部署的频率越来越高 ,譬如像亚马逊,每 天都要执行数十次 、甚至上百次的部署 ,如果还是依赖手动部署 、人工审查等机制 ,已经 无法适应互联网时代的快速变化 。因此,微服务系统的部署成本较高 。
因此,如何有效地构建自动化部署流水线 ,降低部署成本、提高部署频率,是做服务 架构下需要面临的一个挑战。
DevOps 与组织架构
对下传统单块架构 ,团队通常是按照技能划分 。譬如开发部、测试部 、运维部等 ,并通过项目的方式协作 ,完成系统的交付 。
而在做服务架构的实施过程中 ,除了如上所述的交付 、运维上存在的挑战 ,在组织或者团队层面 ,如何传递 DevOps 文化的价值 ,让团队理解 DevOps 文化的价值 ,并构建全功能用队 ,也是一个不小的挑战 。
实际上 ,微服务不仅表现出一种架构模型 ,同样也表现出一种组织模型 。这种新型的 组织模型意味着开发人员和运维的角色发生了变化 ,开发者将承担起服务整个生命周期的 贡任,包括部署和监控 ,而运维也越来越多地表现出 一种顾问式的角色 ,尽早考虑服务如 何部署。
因此,如何在做服务的实施中,按需调整组织架构 ,构建全功能的团队 ,是一个不小的挑战。
服务间的依赖测试
对于传统的单块架构而言 ,通常使用集成测试验证系统是否和其外部的依赖之间正常 协作。
而对于微服务架构而言 ,由于系统被拆分成多个可独立部署的 、分布式的业务单元 ,因 此,服务之间的交互主要通过接口完成 。在服务数量逐渐增多的情况下,如何有效地保证服 务之间能有效按照接口 的约定正常工作,成为微服务实施过程中,测试面临的主要挑战。
服务间的依赖管理
对 于传统的单块架构而言 ,功能实现比较集中,大部分功能都运行在同一个应用中 , 同其他系统依赖较少 。
对于微服务架构而言 ,当把传统的系统拆分成多个相互协作的独立服务后 ,随着微服 务个数的增多 ,如何清晰有效地展 示服务之间的依赖关系 ,逐渐成为挑战 。这也直接影响 着网队对系统的理解和对其维护的信心 。
综上所述 ,微服务架构的出现 ,解诀了传统的单块架构系统随着业务需求快速变化所 面临的挑战 。但在微服务的实施过程中 ,注定不是一帆风顺的。因此,清楚地了解微服务架构所带来的风险 ,能帮助组织或者团队找到更适合的方式 ,从而有效地实施微服务 。