【Java分布式】基本概念

分布式

基本概念

1、微服务

微服务是由单一应用程序构成的小服务,拥有自己的进程与轻量化处理,服务依业务功能设计,以全自动的方式部署,与其他服务使用HTTP API通讯。同时,服务会使用最小规模的集中管理 (例如Docker)技术,服务可以用不同的编程语言与数据库等。

2、分布式、集群、节点

集群是个物理状态,分布式是个工作方式

  • 分布式:指根据不同的业务分布在不同的地方
  • 集群:指的是将几台服务器集中在一起,实现同一业务
  • 节点:分布式系统中的一个业务

《分布式系统原理与范型》定义:分布式系统是若干独立计算机的集合,这些计算机对于用户来说像单个系统。

分布式系统 (distributed system) 是建立网络之上的软件系统

分布式系统中的每一个节点,都可以做集群,而集群并不一定就是分布式的

3、远程调用

在分布式系统中,各个服务可能处于不同主机,但是服务之间不可避免的需要互相调用,我们称之为远程调用

天然具备跨平台性

SpringCloud中使用HTTP+JSON的方式来完成远程调用

4、负载均衡

分布式系统中,A 服务需要调用B服务,B服务在多台机器中都存在, A调用任意一个服务器均可完成功能

为了使每一个服务器都不要太或者太闲,我们可以负载均衡调用每一个服务器,提升网站的健壮性

常见的负载均衡算法:

  • 轮询:为第一个请求选择健康池中的每一个后端服务器,然后按顺序往后依次选择,直到最后一个,然后循环
  • 最小连接:优先选择链接数最少,也就是压力最小的后端服务器,在会话较长的情况下可以考虑采取这种方式
  • 散列:根据请求源的 IP 的散列(hash)来选择要转发的服务器。这种方式可以一定程 度上保证特定用户能连接到相同的服务器。如果你的应用需要处理状态而要求用户能连接到和之前相同的服务器,可以考虑采取这种方式。

5、服务注册中心

A 服务调用 B 服务,A 服务并不知道 B 服务当前在哪几台服务器有,哪些正常的,哪些服务 已经下线。解决这个问题可以引入注册中心,如果某些服务下线,我们其他人可以实时的感知到其他服务的状态,从而避免调用不可用的 服务

6、配置中心

每一个服务最终都有大量的配置,并且每个服务都可能部署在多台机器上。我们经常需要变 更配置,我们可以让每个服务在配置中心获取自己的配置,即配置中心用来集中管理微服务的配置信息

7、服务熔断、降级

在微服务架构中,微服务之间通过网络进行通信,存在相互依赖,当其中一个服务不可用时,有可能会造成雪崩效应。要防止这样的情况,必须要有容错机制来保护服务。

1)服务熔断

设置服务的超时,当被调用的服务经常失败到达某个阈值,可以开启断路保护机制,后来的请求不再去调用这个服务,本地直接返回默认 的数据

2)服务降级

在运维期间,当系统处于高峰期,系统资源紧张,我们可以让非核心业 务降级运行。

降级:某些服务不处理,或者简单处理【抛异常、返回 NULL、 调用 Mock 数据、调用 Fallback 处理逻辑】。

情景:

订单服务 --> 商品服务 --> 库存服务

库存服务出现故障导致响应慢,导致商品服务需要等待,可能等到10s后库存服务才能响应。库存服务的不可用导致商品服务阻塞,商品服务等的期间,订单服务也处于阻塞。一个服务不可用导致整个服务链都阻塞。如果是高并发,第一个请求调用后阻塞10s得不到结果,第二个请求直接阻塞10s。更多的请求进来导致请求积压,全部阻塞,最终服务器的资源耗尽。导致雪崩

8、API网关

在微服务架构中,API Gateway 作为整体架构的重要组件,抽象服务中需要的公共功能,同时它提供了客户端负载均衡,服务自动熔断,灰度发布,统一认证,限流监控,日志统计等丰富功能,帮助我们解决很多API管理的难题

架构

由单体架构演变成SOA架构,然后再演变为微服务架构的,如图:

单体架构

以MVC架构为例,业务通常是通过部署一个WAR包到Tomcat中,然后启动Tomcat,监听某个端口即可对外提供服务。早期在业务规模不大、开发团队人员规模较小的时候,采用单体应用架构,团队的开发和运维成本都可控。

然而随着业务规模的不断扩大,团队开发人员的不断扩张,单体应用架构就会开始出现问题。大致有以下几个方面:

  • 部署效率低下
  • 团队协作开发成本高
  • 系统高可用性差、可靠性低
  • 线上发布变慢
  • 程序复杂性高

面向服务(SOA)

面向服务就是把传统的单机应用中通过JAR包依赖产生的本地方法调用,改造成通过RPC接口产生的远程方法调用。

微服务

微服务架构风格,就是把一个单独的应用程序开发为一套小服务,每个小服务运行在自己的进程中,并使用轻量级机制通信,通常是 HTTP API。这些服务围绕业务能力来构建, 并通过完全自动化部署机制来独立部署。这些服务可以使用不同的编程语言书写,以及不同数据存储技术,并保持最低限度的集中式管理。

简而言之:拒绝大型单体应用,基于业务边界进行服务微化拆分,一个服务通常实现一组不同的功能或特性,各个服务独立部署运行。

优点:

  • 解决了单体架构下应用在后期会变得复杂的问题,采用类似SOA的方式,将单体应用程序分解成一套服务。
    • 应用程序被分解成可管理的块或服务,每个服务都有一个明确定义边界的方式,如远程过程调用(RPC)驱动、消息驱动的API
    • 微服务架构模式强制一定程度的模块化
  • 每个服务都可以由一个团队独立专注开发,个体服务能被更快地开发, 并更容易理解与维护。
    • 可以自由选择 任何符合服务 API 契约的技术
    • 由于服务较小,使用当前技术重写旧服务将变得更加可行
  • 微服务架构模式可以实现每一个微服务独立部署
    • 开发人员根本不需要去协调部署本地变更到服务,变更一经测试即可立即部署
    • 微服务架构模式使得持续部署成为可能
    • 微服务架构模式使得每个服务能够独立扩展
    • 可以仅部署满足每个服务的容量和可用性约束的实例数目。
    • 可以使用与服务资源要求最匹配的硬件

缺点:

  • 重点过多偏向于服务规模
  • 由于微服务是一个分布式系统,其使得系统整体变得复杂。(模块间通过RPC进行调用)
  • 分区数据库架构
  • 测试复杂
  • 跨越多服务变更
  • 部署复杂(大量服务,配置,监控,发现)

比较:

从表面上看,微服务架构模式类似于 SOA,微服务是由一组服务组成 。然而,换另一 种方式去思考微服务架构模式,它是没有商业化的 SOA没有集成 Web 服务规范(WS- )和企业服务总线(Enterprise Service Bus,ESB)基于微服务的应用支持更简单、 轻量级的协议 ,例如,REST,而不是 WS-。他们也尽量避免使用 ESB,而是实现微服 务本身具有类似 ESB 的功能 。微服务架构也拒绝了 SOA 的其他部分,例如,数据访 问规范模式概念。

在SOA的基础上,微服务主要有了以下的发展:

  • 服务拆分粒度更细。微服务可以说是更细维度的服务化,小到一个子模块,只要该模块依赖的资源与其他模块都没有关系,那么就可以拆分为一个微服务。
  • 服务独立部署。每个微服务都严格遵循独立打包部署的准则,互不影响。比如一台物理机上可以部署多个Docker实例,每个Docker实例可以部署一个微服务的代码。
  • 服务独立维护。每个微服务都可以交由一个小团队甚至个人来开发、测试、发布和运维,并对整个生命周期负责。
  • 服务治理能力要求高。因为拆分为微服务之后,服务的数量变多,因此需要有统一的服务治理平台,来对各个服务进行管理。

微服务架构也是有成本的,架构复杂度提升,也会带来一些新的问题,这些微服务架构必须要解决的问题:

  • 服务定义。对于单体应用来说,不同功能模块之前相互交互时,通常是以类库的方式来提供各个模块的功能。对于微服务来说,每个服务都运行在各自的进程之中,应该以接口的形式向外界传达自己的信息,无论采用哪种通讯协议,是HTTP还是RPC,服务之间的调用都通过接口描述来约定,约定内容包括接口名、接口参数以及接口返回值。
  • 发布订阅。单体应用由于部署在同一个WAR包里,接口之间的调用属于进程内的调用。而拆分为微服务独立部署后,服务提供者该如何对外暴露自己的地址,服务调用者该如何查询所需要调用的服务的地址呢?这个时候你就需要一个类似登记处的地方,能够记录每个服务提供者的地址以供服务调用者查询,在微服务架构里,这个地方就是注册中心。
  • 服务监控。通常对于一个服务,我们最关心的是QPS(调用量)、AvgTime(平均耗时)以及P999(99.9%的请求性能在多少毫秒以内)这些指标。这时候你就需要一种通用的监控方案,能够覆盖业务埋点、数据收集、数据处理,最后到数据展示的全链路功能。
  • 服务治理。可以想象,拆分为微服务架构后,服务的数量变多了,依赖关系也变复杂了。比如一个服务的性能有问题时,依赖的服务都势必会受到影响。可以设定一个调用性能阈值,如果一段时间内一直超过这个值,那么依赖服务的调用可以直接返回,这就是熔断,也是服务治理最常用的手段之一。
  • 链路追踪。在单体应用拆分为微服务之后,一次用户调用可能依赖多个服务,每个服务又部署在不同的节点上,如果用户调用出现问题,你需要有一种解决方案能够将一次用户请求进行标记,并在多个依赖的服务系统中继续传递,以便串联所有路径,从而进行故障定位。

总结来说,微服务架构是将复杂臃肿的单体应用进行细粒度的服务化拆分,每个拆分出来的服务各自独立打包部署,并交由小团队进行开发和运维,从而极大地提高了应用交付的效率,并被各大互联网公司所普遍采用。

服务拆分

任何分布式架构都离不开服务的拆分,微服务也是一样。微服务的拆分原则:

  • 不同微服务,不要重复开发相同业务
  • 微服务数据独立,不要访问其它微服务的数据库
  • 微服务可以将自己的业务暴露为接口,供其它微服务调用

纵向拆分

从业务维度进行拆分。标准是按照业务的关联程度来决定,关联比较密切的业务适合拆分为一个微服务,而功能相对比较独立的业务适合单独拆分为一个微服务。

一个最有效的手段就是将不同的功能模块服务化,独立部署和运维。

例子:社交App

可以认为首页信息流是一个服务,评论是一个服务,消息通知是一个服务,个人主页也是一个服务。

横向拆分

从公共且独立功能维度拆分。标准是按照是否有公共的被多个其他服务调用,且依赖的资源独立不与其他业务耦合。

例子:社交App

无论是首页信息流、评论、消息箱还是个人主页,都需要显示用户的昵称。假如用户的昵称功能有产品需求的变更,你需要上线几乎所有的服务,这个成本就有点高了。显而易见,如果我把用户的昵称功能单独部署成一个独立的服务,那么有什么变更我只需要上线这个服务即可,其他服务不受影响,开发和上线成本就大大降低了。

技术选型

对于大部分公司而言,自研来解决微服务架构的一些问题,成本是很难接受的。不过,幸运的是,有不少业界开源方案可供选择。

  • 前几年比较火的是阿里的Dubbo,后来一度停止维护,最近两年又起死回生,重新焕发生机。
  • 后来又出现了Spring体系下的微服务方案Spring Cloud,并迅速流行起来。

Dubbo

Spring Cloud

Spring Cloud本身不是新的框架,它是一系列框架的有机组合,利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发。并非所有组件都由Spring提供,Netflix扮演了重要的角色。注册中心Eureka、熔断器Hystrix、负载均衡组件Ribbon、网关Zuul等重要组件均由Netflix提供。

因为上面提到的SpringCloud官方版,或者说SpringCloud Netflix版一些重要组件如注册中心Euraka、Ribbon已经不再迭代更新了。所以采用 Spring Cloud Alibaba。

​ Spring Cloud Alibaba是阿里开源的一套Sping Cloud规范的实现。

SpringCloud Alibaba

Spring Cloud 本身是一套微服务规范,并不是一个拿来即可用的框架,而 Spring Cloud Alibaba 的开源为开发者们提供了这套规范的实现方式。同时,Spring Cloud Alibaba 提供的完整的微服务组件、中文文档和本地化的开源服务提高了开发者们接入微服务的速率,并降低了后续的运维难度。

和SpringCloud Netflix的主要区别:

Spring Cloud Alibaba 各版本兼容表:

网关

应用不能直接访问后端服务,它们之间的通信是由一个称为 API 网关(API Gateway)的中介负责。

API 网关负责负载均衡、缓存、访问控制、API 计量和监控

可以通过使用 NGINX 来实现。

负载均衡

运行着服务的多个实例,每个服务配合负载均衡器以满足吞吐量和可用性

为了实现高可用,容器是在多个云虚拟机上运行的。服务实例的之前是一个类似 NGINX 的负载均衡器,用于跨实例分发请求。负载均衡器也可以处理其他问题,如 缓存、访问控制、API 度量和监控。

数据库

微服务架构模式明显影响到了应用程序与数据库之间的关系。与其他共享单个数据库 模式(schema)服务有所不同,其每一个服务都有自己的数据库模式。一方面,这种 做法与企业级数据库数据模型的想法相背,此外,它经常导致部分数据冗余。

然而, 如果您想从微服务中受益,每一个服务都应该有自己的数据库模式。因为它能实现松耦合。

参考

SpingCloud Alibaba实战(1:微服务与SpringCloud Alibaba) - 三分恶 - 博客园 (cnblogs.com)

(323条消息) SpringCloud五大核心组件_springcloud五大组件_Hei哈的博客-CSDN博客

(323条消息) 一看就会的SpringCloud五大组件_画出springcloud重要组件图!_三金同志的博客-CSDN博客

相关推荐
赶路人儿18 小时前
UTC时间和时间戳介绍
java·开发语言
dreamread18 小时前
【SpringBoot整合系列】SpringBoot3.x整合Swagger
java·spring boot·后端
6+h18 小时前
【java】基本数据类型与包装类:拆箱装箱机制
java·开发语言·python
一直都在57218 小时前
Spring面经
java·后端·spring
xiaoye370818 小时前
如何在Spring中使用注解配置Bean的生命周期回调方法?
java·spring
日更嵌入式的打工仔18 小时前
个人笔记3
笔记
闻哥18 小时前
深入Redis的RDB和AOF两种持久化方式以及AOF重写机制的分析
java·数据库·spring boot·redis·spring·缓存·面试
jgyzl19 小时前
2026.3.12 常见的缓存读写策略
java·后端·spring
ruanyongjing19 小时前
Spring TransactionTemplate 深入解析与高级用法
java·数据库·spring
fengxin_rou19 小时前
[Redis从零到精通|第六篇]:Redis的主从同步
java·数据库·redis·缓存