什么是微服务架构
微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间相互协调、互相配合,为用户提供最终价值。每个服务运行在其独立的进程中,服务和服务之间采用轻量级的通信机制相互沟通(通常是基于HTTP的Restful API)。每个服务都围绕着具体的业务进行构建,并且能够被独立的部署到生产环境、类生产环境等。另外,应尽量避免统一的、集中的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构。"---- Martin
从单体到微服务
微服务架构是一个衍生架构,都是从单体架构演化而来的。
因为微服务架构本身的复杂性,初创系统出于快速开发、快速验证的考虑,很少在一开始就使用微服务架构。加之微服务的概念在这两年才火,大型单体应用也是看到了开发与维护的成本在不断增加,才会有转型微服务的动力。因此,如何从单体到微服务是一个普遍问题。
从单体到微服务的原则:
逐步演进,不要全部重构。
全部重构,带来极大的成本和风险,系统会有很长的不稳定期。而且,最终的效果也不会很好,在设计时很难想到所有问题。微服务架构的演化思路应该是一步步铺基础设施,一点点拆分微服务。
微服务的划分
微服务的划分主要是保证微服务功能内聚,职责单一。一般使用DDD(Domain Drive Design)的思想与方法对微服务进行划分,这种方法有点类似于数据库ER图的划分,不断分解数据,保证关系型数据库符合原子性、冗余性的范式要求。当然,微服务的划分比数据表划分更复杂,也没有微服务范式的概念,但思想是一致的。更多的内容,请参考《领域驱动设计》这本书。
服务的注册与发现
有两种思路,客户端发现(下图),客户端去注册中心查询服务实例列表,自行选择;
另一种是服务端发现(下图),添加LB模块,客户端把请求发向LB,由LB根据负载均衡策略选择服务实例;
服务之间的通信
微服务的拆分一般会带来IPC(inter process communication)通信的问题。通信机制需要完备可靠,服务之间的通信选择应尽量单一,从两个维度对通信的模式进行划分:
第一个维度是一对一还是一对多:
- 一对一:每个客户端请求有一个服务实例来响应。
- 一对多:每个客户端请求有多个服务实例来响应。
第二个维度是这些交互式同步还是异步:
- 同步模式:客户端请求需要服务端即时响应,甚至可能由于等待而阻塞。
- 异步模式:客户端请求不会阻塞进程,服务端的响应可以是非即时的。
现在最通用的有两种方式:
- 同步模式:
①REST(JAX-RS,Spring Boot)
②RPC(Thrift, Dubbo)
- 异步模式(Kafka, Notify, MetaQ)
微服务架构认为,服务间通信应该就只有这几种模式。服务之间的通信要按需选用。
数据隔离问题
微服务之间数据隔离可以保证服务的独立升级与部署,数据隔离有三个维度:
数据表级隔离;数据表之间独立,没有外键关系;
数据库级隔离;不同服务有不同的数据库;
DBMS级隔离;不同服务有不同的数据库管理系统;
一般做到数据库级隔离就可以了,服务之间的数据交换使用服务间接口。
分布式一致性
有两个大的思路:全局的分布式事务;事件驱动;
分布式事务就是现在AC的思路,在设计开发中;
事件驱动,忽略了事务的概念,由每个服务在应用层面保存服务的状态,服务之间的通信使用事件机制通知;此种方法可以保证微服务间的独立性,但把问题交给了服务的设计者;
服务容错
当我们的系统是由一系列的服务调用链组成的时候,我们必须确保任一环节出问题都不至于影响整体链路。相应的手段有很多:
- 重试机制
- 限流
- 熔断机制
- 负载均衡
- 降级(本地缓存)
针对 Java 技术栈,Netflix 的 Hystrix(github 12.4k stars)把熔断、隔离、限流和降级等能力封装成组件,任何依赖调用(数据库,服务,缓存)都可以封装在 Hystrix Command 之内,封装后自动具备容错能力。
单体应用 vs 微服务架构
优点
- 提升开发交流,每个服务足够内聚,足够小,代码容易理解;
- 服务独立测试、部署、升级、发布;
- 按需定制的DFX,资源利用率,每个服务可以各自进行x扩展和z扩展,而且,每个服务可以根据自己的需要部署到合适的硬件服务器上;
- 需要选择HA的模式,选择接受服务的实例个数;
- 容易扩大开发团队,可以针对每个服务(service)组件开发团队;
- 提高容错性(fault isolation),一个服务的内存泄露并不会让整个系统瘫痪;
- 新技术的应用,系统不会被长期限制在某个技术栈上;
缺点
- 微服务提高了系统的复杂度;
- 开发人员要处理分布式系统的复杂性;
- 服务之间的分布式通信问题;
- 服务的注册与发现问题;
- 服务之间的分布式事务问题;
- 数据隔离再来的报表处理问题;
- 服务之间的分布式一致性问题;
- 服务管理的复杂性,服务的编排;
- 不同服务实例的管理。