目录
分布式是个大命题,持续记录对它的理解和梳理其脉络。(持续更新中~)
一、微服务
1、概述
针对单机服务性能瓶颈的问题,一般有两种解决方案,即对原服务进行水平拆解和垂直拆解。水平拆解指将同一服务copy多份,做并行化改造,各服务之间没有关系。垂直拆解指将服务拆成多个小服务,各自通过网络进行通信,与微内核有异曲同工之处。这两种解法优劣显而易见,水平拆解成本一般更低,并且耦合的业务之间都在单机中通信,效率更高,但依然会出现单一服务过于臃肿,维护成本高的问题。垂直拆解成本更高,但是维护成本相对来说更低,更加适合互联网快速迭代的今天。
微服务便是垂直拆解的一套方案,不过它并没有一个标准,更多的是一种思想,Martin Fowler则在Microservices(https://www.martinfowler.com/articles/microservices.html)中对这套架构进行了一些总结,这里做简单摘要:
(1)Componentization via Services
通过服务而不是库来让整个系统组件化,从而让组件的修改给系统的修改带来最小开销。
(2)Organized around Business Capabilities
对团队的划分,不是根据技术类型来的,而是根据业务来的,很有意思,因为同一业务技术间的沟通是频繁的,不同业务间的沟通是稀疏的,所以根据技术类型来对团队划分会带来比较大的沟通成本。
(3)Products not Projects
每个小团队都要对自己的产品的整个生命周期负责,而不是以交付为目标。
(4)Smart endpoints and dumb pipes
微服务架构的其中一个重点是让服务更加内聚与解耦,所以一个服务暴露的接口往往是粗粒度的,适合使用HTTP的RESTful API或轻量级的消息总线做消息传递。
(5)Decentralized Governance
去中心化管理。
(6)Decentralized Data Management
去中心化管理数据,每个服务自行管理自己的数据库。
(7)Infrastructure Automation
CI/CD。
(8)Design for failure
分布式的一个重头戏:容错,高可用。
(9)Evolutionary Design
不断迭代优化设计。
2、服务发现
微服务架构中,多个组件需要交互,那么如何知道对方的IP端口呢,直接保存那是不实际的,因为ip和端口都是可能随着服务的升级变化的,所以需要有一种机制获取服务提供者的网络信息,所以有了服务发现组件consul,它需要有以下功能:
(1)服务注册表:记录各个微服务的信息,如名称(不变的),IP,端口号等,并提供查询服务API,注册服务API,注销服务API。
(2)服务注册与发现:在服务启动时,将自己的信息注册到服务发现组件上。在需要与某一服务交互时,从服务发现组件上查询服务API。
(3)服务检查:定时检查下线服务,从服务注册表中移除该实例。
3、负载均衡
微服务架构中,某一个服务可能存在多个实例,所以需要有负载均衡器,将请求合理分摊到各个实例上去。一般的负载均衡算法有轮询,随机等,首先从服务发现组件获取某服务的实例列表,然后根据负载均衡算法请求相应实例。
4、服务调用容灾
服务崩了或其它原因都会导致某个服务的不可用,所以需要一种方式发现某个服务的不可用,并用恰当的手段来处理。一般使用请求响应时间判断服务是否不可用,使用熔断器处理不可用的服务,它统计一段时间内调用失败的次数,如果失败次数过多,则直接返回错误,不浪费CPU时间。
通常在分布式存储集群中,某个节点不可用了,会通过选举算法选出一个从节点代替主节点,当然这与微服务的场景不太一样,因为微服务的多实例是对等的,大多数分布式存储集群内是分主从节点的,它们并不对等。
5、微服务网关
客户端可能需要调用多个接口才能完成一次业务需求,这就增加了客户端的复杂性,每个服务还都需要独立的认证,未来迭代难以重构。因此,需要有一个门面来封装应用程序的内部结构,客户端只与门面交互即可,这个门面就是微服务网关。
一般来说,微服务网关的核心是一系列的过滤器,用以完成:
(1)身份认证:过滤非法请求
(2)埋点:提供数据统计切面
(3)动态路由:动态地将请求路由到不同后端集群
(4)负载分配