当前位置: 首页 > article >正文

浅显易懂——连接池、分布式系统、微服务等概念

文章目录

  • 连接池
    • 比喻
    • 技术层面
    • 关键参数
    • 实际应用示例
  • 分布式系统
    • 概念
    • 实现方式
    • 实际应用场景
    • 关键概念
      • 分布式会话管理
      • 分布式计数器
      • 分布式锁
      • 分布式事务(Distributed Transaction)
      • 分布式追踪
  • 集群环境
    • 比喻
    • 优缺
  • 微服务架构
    • 比喻
    • 优缺
    • 实际场景
    • 服务间通信
  • 负载均衡
  • 服务发现

连接池

比喻

想象你是一家餐厅的顾客,你想点餐。每次点餐时,服务员需要去厨房取一个厨师来为你准备食物。如果每次点餐都重新找一个新厨师,不仅浪费时间,还会让厨房变得混乱不堪。

问题

  • 每次点餐都要重新找厨师(创建新连接),耗时长。
  • 厨师频繁进出厨房(连接频繁创建和销毁),效率低。

解决方案:使用“厨师池”(连接池)

厨师池的概念

  • 预先准备好一批厨师(预创建一定数量的连接)。
  • 当有顾客点餐时,从厨师池中取出一个空闲的厨师(获取一个空闲连接)。
  • 厨师完成任务后,回到厨师池等待下一次任务(归还连接到池中)。

这样做的好处是:

  • 不需要每次都重新找厨师(减少连接创建和销毁的时间开销)。
  • 厨师可以高效地复用(提高性能和资源利用率)。

技术层面

  • 没有连接池的情况:每次应用程序需要访问数据库或Redis时,都会创建一个新的连接,操作完成后关闭连接。这会导致大量的连接创建和销毁操作,消耗时间和资源。

  • 使用连接池的情况

    • 预创建连接:在应用程序启动时,连接池会预先创建一定数量的连接,并将它们保存在池中。
    • 获取连接:当应用程序需要访问数据库或Redis时,它从连接池中获取一个空闲的连接,而不是重新创建新的连接。
    • 归还连接:操作完成后,应用程序将连接归还给连接池,而不是直接关闭连接。这样,连接可以在下次需要时再次被使用。

关键参数

为了更好地管理连接池,通常需要配置一些关键参数:

  • max-active:最大活跃连接数。相当于厨师池中最多能有多少个厨师同时工作。超过这个数量,新的请求需要等待。
  • max-idle:最大空闲连接数。相当于厨师池中最多能有多少个厨师处于空闲状态。过多的空闲连接会浪费资源。
  • min-idle:最小空闲连接数。确保池中始终有一定数量的空闲连接,以应对突发的高并发请求。
  • max-wait:最大等待时间。如果所有连接都在忙,新的请求需要等待多久才能获取到连接。过长的等待时间可能导致请求超时。

实际应用示例

假设你有一个电商网站,用户频繁查询商品信息。每次查询都需要访问Redis缓存。如果没有连接池,每次查询都会创建和销毁连接,导致性能下降。使用连接池后:

  • 初始化时:连接池预先创建了8个Redis连接。
  • 查询时:每次查询从连接池中获取一个空闲连接,查询完成后归还连接。
  • 高并发时:如果有多个用户同时查询,连接池会根据配置的最大活跃连接- 数分配连接,确保系统不会因为连接不足而崩溃。

分布式系统

概念

分布式系统是指由多个独立的计算机或服务组成的系统,这些计算机通过网络相互通信和协作,对外表现为一个整体。每个计算机(或服务)都可以独立运行,但它们协同工作以完成复杂的任务。

实现方式

  • 集群环境(Clustering)
  • 微服务架构(Microservices Architecture)
  • 对等网络(Peer-to-Peer, P2P)
    • 定义:所有节点都是平等的,没有中心化的控制节点,节点之间直接相互通信和协作。
    • 示例:区块链(如比特币网络,节点之间通过共识算法(如PoW、PoS)协同工作,确保数据的一致性和安全性。)、BitTorrent(一个典型的P2P文件共享系统,用户可以直接从其他用户那里下载文件片段。)
  • 客户端-服务器架构(Client-Server Architecture)
    • 定义:由一个或多个服务器提供服务,多个客户端向服务器请求资源或执行操作。
    • 示例:Web应用(浏览器作为客户端,向Web服务器请求页面内容),数据库访问(应用程序作为客户端,向数据库服务器发送查询请求)。
  • 事件驱动架构(Event-Driven Architecture)
    • 定义:系统中的组件通过事件(如消息、通知)进行通信,而不是通过直接调用。
    • 示例:物联网(IoT)平台(设备生成事件(如温度变化),平台根据事件触发相应的处理逻辑。)
  • 混合架构(Hybrid Architecture)
    • 定义:结合多种架构模式的优点,形成一种混合的分布式系统设计。
    • 示例:企业级应用、云计算平台

实际应用场景

  • 单体:早期电商系统可能是一个单体Java应用(如Spring Boot),所有功能(商品管理、订单、支付、库存)集中在一个代码库,部署在一个Tomcat服务器上。
  • 分布式系统:
    • 负载均衡:用Nginx分发请求到多台服务器。
    • 独立数据库:商品库和订单库拆分成MySQL主从集群。
    • 缓存层:Redis缓存热门商品信息,减少数据库压力。
      效果
      • 流量分散到多台服务器,单台故障不影响整体。
      • 数据库读写分离,性能提升。

关键概念

分布式会话管理

  • 问题:在传统系统中,用户的会话信息(如购物车、登录状态)通常存储在服务器的内存中。但在分布式系统中,用户可能会访问不同的服务器节点,因此需要一种机制来确保所有节点都能共享和访问用户的会话信息。
  • 解决方案:使用Redis等缓存系统集中存储会话信息,让所有节点都能读取和更新会话数据。

类比:医院就诊卡
你去医院看病时,不同科室(挂号处、化验科、药房)都需要知道你的病历信息。

  • 单体系统:病历本拿在你自己手里(会话存在浏览器Cookie或服务器内存),每次去科室都要翻开病历本查看。
  • 分布式系统:科室分散在不同楼层(多台服务器),如果病历本只存在某一科室,其他科室无法获取信息。
  • 解决方案:医院给你一张就诊卡(Session ID),所有科室通过读卡器(共享存储如Redis)实时读取同一份电子病历(分布式会话)。

分布式计数器

  • 问题:当多个服务实例同时对某个计数器进行操作时,如何保证计数的准确性?
  • 解决方案:使用Redis的原子操作(如INCR),可以确保即使在高并发情况下,计数也是准确的。

类比:超市排队叫号系统
一家超市有10个收银台(分布式节点),需要统计当日总客流量。

  • 单体系统:一个收银员拿计数器手动统计(单机内存计数),但其他收银台无法同步数据。
  • 分布式系统:每个收银台独立计数,合并总数时可能漏算或重复(并发冲突)。
  • 解决方案
    • 用中央电子屏显示实时客流(Redis原子操作 INCR)。
    • 收银台每服务一个顾客,向电子屏发送+1请求(原子性保证计数准确)。

分布式锁

  • 问题:在分布式系统中,多个服务实例可能同时尝试执行某些关键操作(如库存扣减)。为了防止冲突,我们需要一种机制来确保同一时间只有一个实例能够执行该操作。
  • 解决方案:使用Redis基于Lua脚本的分布式锁实现,确保操作的原子性。

类比:会议室预订系统
公司有多个团队(分布式节点)需要预定同一间会议室(共享资源)。

  • 单体系统:行政部用纸质登记表(单机锁),但多个分公司无法同时访问这张表。
  • 分布式系统:A团队在北京预订成功,B团队在上海同时预订,导致冲突。
  • 解决方案
    • 开发一个在线预订系统(分布式锁如RedisZooKeeper),预订时标记“会议室占用”,释放时清除标记。
    • 类似厕所门锁:门上显示“有人/无人”(锁状态),所有人通过统一标识判断能否进入。

分布式事务(Distributed Transaction)

  1. 原子性问题
    在分布式环境中,多个服务可能分布在不同的节点上。如果其中一个服务失败,如何确保整个事务能够回滚到初始状态?
    类比:你在A银行有一个账户,在B银行也有一个账户。你想从A银行转账1000元到B银行。如果在转账过程中,A银行成功扣款但B银行未能成功入账,怎么办?
  2. 一致性问题
    不同服务之间的数据更新可能存在时间差,尤其是在高并发场景下,可能导致数据不一致。如何确保所有参与事务的服务最终达到一致的状态?
    类比:如果你同时发起两笔转账(如从A银行转到B银行,从B银行转到C银行),并且这两笔转账涉及的资金是同一笔钱。如何确保最终所有账户的余额是一致的?
  3. 隔离性问题
    在分布式系统中,多个事务可能会同时访问和修改相同的数据,导致脏读、不可重复读等问题。如何确保多个事务之间不会相互干扰?
    类比:假设在同一时间段内,有多个用户同时发起从A银行到B银行的转账。如何确保这些转账不会相互干扰,避免脏读、不可重复读等问题?
  4. 持久性问题
    分布式系统中的每个节点都可能出现故障,如何保证事务结果不会丢失?如何确保事务的结果被永久保存,即使在系统崩溃后也能恢复?
    类比:如果在转账过程中,A银行或B银行的服务器突然宕机,如何确保转账的结果被永久保存,即使系统崩溃后也能恢复?

解决方案

  1. 两阶段提交(2PC)
    • 原理类比
      • 准备阶段:A银行向B银行发送“准备转账”消息,询问是否可以接收1000元。B银行检查自身状态并回复“准备就绪”或“拒绝”。
      • 提交阶段:如果B银行准备就绪,A银行正式扣款并将1000元转入B银行;否则,取消整个转账操作。
    • 优:确保原子性和一致性。
    • 缺:性能较低;单点故障。
  2. 三阶段提交(3PC)
    • 原理类比
      • 预准备阶段:A银行向B银行发送“预准备转账”消息,询问是否可以开始准备转账。
      • 准备阶段:B银行回复预准备结果,A银行根据结果决定是否继续。
      • 提交阶段:如果B银行准备就绪,A银行正式扣款并将1000元转入B银行;否则,取消整个转账操作。
    • 优:减少单点故障的风险。
    • 缺:性能进一步降低;存在超时和网络分区问题。
  3. 最终一致性(Eventual Consistency)
    • 原理类比:
      • A银行先扣款,并将转账信息发送给B银行。B银行可能稍后才收到并处理这笔转账。
      • 系统允许短时间内处于不一致状态,但最终会达到一致。
    • 优:提供可用性和性能,适用于实时性要求不高但对吞吐量要求高的场景。
    • 缺:不适合对一致性要求极高的场景
  4. Saga模式
    • 原理类比
      • 将转账拆分为多个子事务:
        • 子事务1:A银行扣款。
        • 子事务2:B银行入账。
      • 如果某个子事务失败(如B银行入账失败),后续的子事务会被回滚,并且之前的子事务会被补偿(如A银行退款)
    • 优:灵活性和可扩展性;适合处理复杂的业务逻辑
    • 缺:实现复杂;不能完全保障强一致性
  5. TCC模式(Try-Confirm-Cancel)
    • 原理类比:
      • Try:A银行尝试扣款,预留1000元。
      • Confirm:确认扣款,正式将1000元转入B银行。
      • Cancel:取消扣款,释放预留的1000元。
    • 优:原子性和一致性;适用于对一致性要求极高的场景。
    • 缺:实现复杂;对开发人员要求高。

工具

  • Seata:阿里巴巴开源的分布式事务解决方案,支持多种模式(如TCC、Saga、AT等)。
  • Atomikos:商业级分布式事务管理器,支持XA协议。
  • Narayana:JBoss提供的分布式事务管理器,支持JTA标准。

分布式追踪

  • 问题:在分布式系统中,一个用户请求可能经过多个服务,每个服务都有自己的日志和监控数据。如何判断这个请求经过了哪些服务?每个服务的处理时间?如何定位性能瓶颈?追踪错误来源?
  • 解决方案:使用Zipkin记录每个服务的处理时间、状态码。

类比:快递包裹的物流轨迹
一个包裹从发货到签收,可能经过多个中转站(服务),我们怎么知道包裹的具体路径和每个中转站的处理时间?

  • 解决方案
    • 全局跟踪编号(Trace ID):为每个快递包裹分配一个全局唯一的跟踪编号,贯穿整个配送流程。
    • 中转站记录(Span):每个中转站在接收到包裹时,记录包裹的到达时间、离开时间、处理状态等信息,并将跟踪编号传递给下一个中转站。
    • 全流程可视化:通过快递公司的追踪系统,可以看到包裹的完整路径、每个中转站的处理时间和状态。

集群环境

比喻

想象你管理一个大型图书馆,有多个书架(服务器)来存放书籍(数据)。为了确保读者能够快速找到自己需要的书,并且图书馆能够高效运作,你可以采用以下几种方式:

  • 单个书架(单体系统):所有书籍都存放在一个巨大的书架上。如果有很多读者同时借阅书籍,这个书架可能会非常拥挤,导致效率低下。
  • 多个书架(集群环境):将书籍分散到多个书架上,每个书架负责一部分书籍。这样,即使有很多读者同时借阅书籍,各个书架可以并行处理,提高效率。

优缺

优点

  • 多节点协作:多个书架(服务器)协同工作,分担读写压力。
  • 高可用性:如果某个书架出现故障,其他书架仍然可以继续提供服务。
  • 扩展性:可以根据需求增加更多的书架(服务器),以应对更多的读者(用户)和书籍(数据)。

缺点

  • 复杂性:管理多个书架需要更多的协调和维护工作。
  • 单点故障风险:如果入口处(如目录系统)出现故障,整个图书馆可能瘫痪。
  • 网络延迟与带宽限制:书架之间的通信可能会受到交通拥堵的影响。
  • 资源浪费与不均衡:某些书架可能非常繁忙,而其他书架相对空闲。

微服务架构

比喻

假设一家餐厅原本是“单体厨房”,所有菜品由一个厨师团队完成。随着菜品增多,厨房变得臃肿,效率下降。于是餐厅转型为模块化厨房

  • 披萨吧台:专做披萨,可快速调整配方。
  • 寿司台:独立处理刺身和寿司,用专用工具。
  • 饮品站:专注调制饮料,随时上新品类。

每个模块(微服务)通过标准化接口(如订单小票)沟通,独立运营、部署和扩展。

优缺

优点:

  • 业务拆分:每个服务专注单一功能(如支付、订单、库存)。
  • 技术自由:披萨吧台用烤箱,寿司台用冰柜,互不影响。
  • 容错性:饮品站故障时,其他模块仍可运作。

缺点

  • 复杂性增加:需要管理多个服务之间的通信和协调。
  • 运维成本高:需要更多的基础设施支持,如负载均衡、服务发现等。

实际场景

  • 单体架构:早期电商系统可能是一个单体Java应用(如Spring Boot),所有功能(商品管理、订单、支付、库存)集中在一个代码库。
  • 微服务架构
    • 商品服务:负责商品CRUD、搜索(用Elasticsearch)。
    • 订单服务:处理下单、支付状态(对接支付宝/微信)。
    • 库存服务:扣减库存,用Redis保证高并发一致性。
    • 用户服务:用户注册、登录(JWT鉴权)。

服务间通信

在微服务架构中,各个服务之间通过轻量级的通信协议进行交互。常见的通信方式包括:

  • HTTP/REST:类似于顾客通过菜单点餐,服务之间通过API接口进行通信。
  • 消息队列(如KafkaRabbitMQ:类似于顾客通过传票下单,服务之间通过消息传递异步通信。

负载均衡

类比:餐厅叫号分配座位
热门餐厅有10张桌子,前台根据顾客人数、桌型空闲情况分配座位。

  • 作用:避免某些服务器过载,其他服务器闲置。
    实际场景
    • Nginx 轮询分发请求到后端服务器,或用 Ribbon 根据响应时间动态调整权重。

服务发现

类比:快递分拣中心的路由表
快递分拣中心需要知道每个城市的配送站地址,否则包裹无法正确送达。

  • 问题:配送站可能动态增加或搬迁(服务实例扩缩容),手动维护地址列表不可靠。
  • 解决方案:所有配送站注册到中央调度系统(如 ZooKeeper/Consul),分拣中心实时查询可用地址。
    实际场景
    • 微服务A需要调用微服务B,但B有多个实例(IP动态变化),通过服务发现组件(如 Nacos)自动获取B的可用地址列表。

http://www.kler.cn/a/584713.html

相关文章:

  • C语言之数据结构:理解什么是数据结构和算法(启航)
  • 【每日学点HarmonyOS Next知识】嵌套组件、装饰器报错、迭代列表刷新、单位换算、tabs组件生命周期
  • 思维链医疗编程方法论框架(Discuss V1版)
  • Android集成:表格、文档文字快速录入-表格识别接口
  • 【C++】initializer_list在实际开发中的应用
  • 101.在 Vue 3 + OpenLayers 使用 declutter 避免文字标签重叠
  • 【C】初阶数据结构9 -- 直接插入排序
  • 集合进阶——数据结构
  • 洛谷P10576 [蓝桥杯 2024 国 A] 儿童节快乐
  • React篇之three渲染
  • WebRTC技术在音视频处理上的难点剖析:EasyRTC嵌入式视频通话SDK的优化策略
  • Appium等待机制--强制等待、隐式等待、显式等待
  • 一次 诡异 的 JVM OOM 事故 原创
  • Vue3:组件通信方式
  • 【工具使用】IDEA社区版如何使用JDK原生命令:从IDEA到命令行的开发技巧
  • 完美解决ElementUI中树形结构table勾选问题
  • 商品管理中的“DeepSeek” AI赋能零售品牌释放利润空间
  • Spring Boot 常用注解的分类及简明解释
  • Spring Boot项目中集成sa-token实现认证授权和OAuth 2.0第三方登录
  • 50.HarmonyOS NEXT 登录模块开发教程(四):状态管理与数据绑定