不知道对错,只是想梳理下想法,有错误请指正
微服务已经是一个不再新鲜的概念,但我却依然模糊不清。
微服务,抛开 微 不看,首先是一个面向服务的架构,即 SOA 。系统模块,业务逻辑之间的界限是服务,服务为 服务名+方法名,与 CRUD/REST 不同。服务重在交互,CRUD/REST 重在数据。
SOA 曾经有 SOAP 、Java RMI,现在主流的 gRPC 和常见的 JsonRPC 。这些定义的都是服务交互协议,而微服务更多的关注服务的组合、分布、编排、容错、发现、通信、跟踪等。因此会想到这样的一些主题:
服务之间的通信可类比为网络通信,主要分为点对点,广播和网关:
从服务提供方来说服务的通信也可以区分为主动和被动:
HTTP
目前 HTTP 在快速发展,新的协议提高的主要是性能和对长链接流的支持,如果选择简单实现服务调用,HTTP 请求足以。
使用 HTTP POST 实现 单次请求响应,使用 WebSocket 实现流式请求。使用 HTTP 的好处是能利用现有的基础设施,HTTP 是目前支持最为广泛的协议,也是最受关注的协议。
但选择 HTTP 时,如果自行实现,则最好选择 HTTP 1,避免使用 HTTP 2 等新增特性,HTTP 2+ 能传递 HTTP 1 的所有语义,且性能各方面能得到很好的提升,这样足以。如果要独立使用 HTTP 协议新特性,例如 Trailer,则实现会变得过于复杂。
非 HTTP 语义
当使用非 HTTP 语义语义时,可能是基于 TCP,也可能是对 Payload 进行定义,抽象传输层,但如今想要跨语言,使用非 HTTP 协议阻碍会非常大,因此宁愿选择对 Payload 做自定义也不会选择不使用 HTTP 。
通常点对点是需要直接通信,但现今有提供 Mesh 网络的网关组件,使得原本不互通的网络服务能够互相访问。同时也能实现对应的服务之间的权限管理和监控。
使用 Mesh 网关则可以让客户端的网络层实现更为简单,由网关去维护服务网络的稳定性,对服务网络的变化也能更快的反应。但成本是维护额外的基础设施组件,且注册中心与网关有强关联和交互,每个节点运行一个网关也是额外的资源消耗。
服务总线本来是一种设计模式,比较常见的是基于事件驱动的设计,但在服务场景会有所不同。事件驱动一般有固定的 主题 /Topic,在定义之初已经确定了部分语义。而服务总线则可以理解为只有一个 Topic,通过消息的内容来进行过滤谁处理谁不需要处理。
总线的通信模式解决了服务之间网络隔离的阻碍,不再需要 A 服务 与 B 服务 网络互通,网络的变化也不会阻碍服务的通信。但如果总线本身如果不支持一些 meta 信息的模式匹配,则会导致流量过大,处理能力受限。
选择广播通信,则必然会选择某种形式的 消息队列 /MQ 实现,因此会牵扯到其他的基础设施服务,从部署跟踪上来说,这是扣分的。
网关通信与 Mesh 网关不同,Mesh 的目的在于打通节点,网关的目的在于磨平 /适配不同的环境服务,提供相同的能力。
所有的请求通过网关,由网关进行路由,这是典型的 Nginx 反向代理场景。因为所有请求都加了中间层,因此很多事情都可以在中间层完成:
该模式与实际最底层的服务通信有有一点区别,主要作为适配和耦合存在,如果网关功能越多做的事情越多也越容易造成单点瓶颈。
通信是服务的根本,对于微服务更是如此。通信的模式间接或直接的影响其他组件的选择和设计。但不同的通信模式并不是互斥的,在对于的场景选择对于的方式才是最好的选择。
15s * 3 = 45s
- 不进行主动干预的情况服务发现通常只是一种行为,但实际使用的应该是服务注册中心,主要能力包括:
服务注册中心通常不是,而是一个集群,其中的服务元信息也可被同步到 RDBMS 便于开发人员查看和使用,场景例如:
服务容错包含服务异常、节点异常、网络异常,不同的异常可能采取不同的应对方式,我理解的常见功能包括
容错的实现通常配合监控,网关,注册中心。算是优化服务体验的一部分,可以作为延伸支持考虑。
微服务,微的是除了服务之外的部分,也就是上述的所有内容。微服务的期望是让开发只关心业务逻辑的编写,开发好的业务逻辑能够快速稳定的上线被使用。
如果不在一套完善的体系下谈论开发微服务都是没有意义且难以实现的,而这套体系的搭建不背靠现在的 K8S 之类的体系也是难以成形的。
将最近混乱思绪进行梳理,不一定都是正确,仅作为参考便于理解,引导之后的选择和决定。