微服务核心
微服务架构
什么是微服务架构
微服务架构被认为是一种架构风格,具有以下六个特点:
- 一组小的服务
- 每个服务运行在独立的进程上
- 轻量级通信的通信机制
- 基于业务能力
- 独立部署
- 无集中式管理
如何理解 “一组小的服务” 中的 “小” ,其实被没有明确的定义,如果一个服务能够容易的被人理解,在运行过程中可以方便的基于自身的数据完成该服务要完成的功能即可。
权衡微服务的利弊
微服务虽然是目前系统的热点,但我们还是要清晰的了解微服务的利益和挑战。
微服务的好处
- 强模块化边界(类 -> 模块 -> 组件 -> 服务)
- 可独立部署,每个团队可以独立开发和部署
- 技术多样性,每个团队可以根据业务情况选择最优的技术栈来实现
微服务的挑战
- 分布式复杂性(需要有人理解整个系统的工作)
- 最终一致性(数据分散治理,如何保证不同服务间的数据一致性)
- 运维复杂性(容量规划、监控)
- 测试复杂性
康威法则
具体的介绍可以参考这篇文章:微服务架构的理论基础 - 康威定律
如果 n 个人互相之间可以沟通,那么沟通渠道就是 n * ( n-1) / 2,也就是 O(N^2),组织的沟通和系统设计之间的紧密联系,对于复杂的系统,聊设计就离不开聊人与人的沟通,解决好人与人的沟通问题,才能有一个好的系统设计。
Organizations which design systems are constrained to produce designs which are copies of the communication structures of these organizations. - Melvin Conway(1967)
中文直译大概的意思就是:设计系统的组织,其产生的设计等同于组织之内、组织之间的沟通结构。
更加通俗的说法是:组织形式等同系统设计。
系统的设计不只需要考虑技术架构,也要了解组织架构。
微服务的引入时机
有人认为架构是设计出来的,也有人认为架构是演化出来的。
微服务的引入是需要考虑基础设施和成本的。
一般在系统的应用初期,功能较少,不使用微服务开发的生产力反而更高;
随着应用的用户和功能增加,系统变得复杂,单块应用开发效率会随着应用复杂性的升高而降低
在上图的交叉点就是适合引入微服务的时机,而这个点的把控需要对业务、发展综合考虑后决定
除非对系统的用户量和功能有充分的考量,否则推荐单块优先,因为在前期开发中对服务的边界划分并不是很清晰,采用微服务很容易导致服务划分不清晰;如果对用户量高估,采用微服务开发部署会增加不必要的成本。
微服务中台战略
如何理解中台战略?"中台"到底是什么
中台战略将公司可复用的服务抽象出来,提供给上层的业务复用,使得业务层能够不用担心基础却又至关重要的技术支撑问题。
中台战略的达成一般需要一些条件:
- 公司拥有多个业务板块
- 这些业务板块之间有可共同整合的部分
系统的功能很少有稳定到常年不变的,从这个角度讲,抽象出可复用的功能是较为虚幻的;但是对于一些专用服务,例如支付,可能在公司的多个业务场景中使用,订单,报名缴费等。
中台的发展是需要时间和业务的沉淀,打造企业级服务复用平台。
微服务总体技术架构体系
对于一些成型的互联网公司来说,内部一般都会有一套完善的类似下图的微服务架构体系。
接入层主要是我们的负载均衡,负责把外部的流量接入到内部的平台上。
网关层在流量接入进来后做反向路由、限流熔断、安全认证等等的一些跨横切面的功能,在微服务体系当中,处于比较核心的层次。网关包括内部网关、H5网关、无线网关、第三方网关、开放平台网关等
业务服务层分为聚合层和基础层。
- 聚合层主要承接一个适配角色:将内部复杂的微服务,适配成对各种不同用户体验(无线/Web/H5/第三方等)友好和统一的API。聚合裁剪适配是聚合层的主要职责。
服务支持体系涉及的内容包括注册发现、集中配置、限流容错、认证授权、日志聚合、监控告警、后台服务(MQ、Cache、DB、JOB)等。
平台服务对于现代比较新的技术引入一些发布体系,支撑我们上层技术体系,平台服务层一般包括发布系统、集群资源调度、镜像治理、资源治理、IAM(权限管控)
基础设施层主要是由运维团队来处理,涉及的内容包括计算、网络、存储、NOC监控、安全、IDC管理等。
这两个层次主要涉及基础设施,一般由运维团队进行负责。
在整个微服务管理体系当中,有些纵向的能力包括微服务的开发框架、持续交付流水线、端到端的工具链、工程实践与规范等这些也是微服务技术体系重要的方面。
微服务架构中的服务发现机制
独立 LB
服务消费方访问后台服务的时候,需要使用域名,进行域名解析,解析到LB负载均衡上,通过负载均衡访问后台的服务。这种做法是最普遍做法,也是最简单的做法,消费者接入的成本比较低。服务的配置和负载均衡的配置需要运维的介入。它的不足之处就是它需要一个集中的LB,这个集中的LB可能是一个单点,如果集中的LB挂了可能会影响整个服务的访问。还有一点在性能方面,当消费者在调用服务端的时候,必须穿透LB,这个过程中可能会有一定的性能开销。
用户使用域名访问,经过解析后利用 Nginx 进行负载均衡,服务发现就属于此类。
进程内 LB
服务提供方通过注册的方式,将服务注册到服务注册表中,并且定期的发送心跳。服务消费者通过集成的客户端,客户端中集成了服务发现和负载均衡的功能,它通过LB直接调用后台的服务,客户端会定期的同步注册表中的服务信息。
这种方式的优点它没有集中的 LB,不存在性能问题,也不存在单点问题。缺点是在多语言当中,必须为每个语言的消费者研发相应的客户端,多语言的升级成本会比较高。例如 Netflix 之前的 Eureka+Ribbon,Ribbon 就是客户端,目前只支持 Java。
主机独立进程 LB
这是前面两种方式的折中,LB 独立进程的方式部署在主机上。这种方式跟第二种有点类似,服务生产者会自动注册到我们的服务注册表中,并且定期的发送心跳。消费者端的 LB 也会定期的去同步主机服务。当消费者去调用后台服务的时候,直接调用本机的 LB 进程,这个本机的 LB 会负责负载均衡和远程的调用。
优点是既没有集中LB性能问题,也没有多语言的问题,它可以通过服务调用方式,不需要为每种语言开发客户端。但是它的运维成本比较高,它需要在每台主机上部署 LB 进程。
微服务架构中的配置中心
如果没有配置中心,一般我们会把配置打包至程序文件中,这样对于配置的调整非常不友好,改动配置项需要重新启动项目,而如果有了配置中心,开发人员可以近乎实时的调整系统运行过程中的一些配置项。
至于配置如何更新到服务中,有配置中心主动 push 到服务中,也可以由服务主动来配置中心 pull。
配置中心主动 push:优点是实时性好,能够及时更新到客户端,为了避免异常情况,需要配置中心保证推送的可靠性
服务端主动 pull:会通过不断重试保证拉取成功
携程的 Apollo 的设计权衡了两种方式
微服务的通讯方式
一般来讲就是 RPC 或者 REST
REST 采用 JSON 序列化,已读性更好,但会增加请求体空间占用,性能相比 RPC 会差
RPC 采用更加优异的序列化方式,Protocol Buffer、Hessian2 等,性能更好,但由于是二进制序列化方式,不可读
感兴趣可以看另一篇文章:RPC发展史
这篇文章有点理论了,甚至有点像正确的废话,微服务中的注册中心,服务发现等都是可以详细解释出一篇文章的~