微服务设计原则——高性能:池化

server/2024/9/23 14:41:40/

文章目录

  • 1.池化由来
  • 2.内存池
  • 3.线程池
  • 4.连接池
  • 5.对象池
  • 6.小结
  • 参考文献

1.池化由来

池化(Pooling)是一种优化技术,旨在提高系统性能和资源利用率,特别是在高并发环境中。通过池化,系统可以重用资源,而不是每次都创建和销毁这些资源。

池化的目的是完成资源复用,避免资源重复创建、销毁来提高性能。

常见的池子有内存池、连接池、线程池、对象池…

内存、连接、线程、对象等都是资源,创建和销毁这些资源都有一个特征, 那就是会涉及到很多系统调用或者网络 IO。 每次都在请求中去创建这些资源,会增加处理耗时,但是如果我们用一个 容器(池) 把它们保存起来,下次需要的时候,直接拿出来使用,避免重复创建和销毁浪费的时间。

2.内存池

我们都知道,在 C/C++ 中分别使用 malloc/free 和 new/delete 进行内存的分配,其底层调用系统调用 sbrk/brk。频繁的系统调用分配释放内存不但影响性能还容易造成内存碎片,内存池技术旨在解决这些问题。正是这些原因,C/C++ 中的内存操作并不是直接调用系统调用,而是已经实现了自己的一套内存管理,malloc 主要有三大实现:

  • ptmalloc:glibc 的实现。
  • tcmalloc:Google 的实现。
  • jemalloc:Facebook 的实现。

虽然标准库的实现在操作系统内存管理的基础上再加了一层内存管理,但应用程序通常也会实现自己特定的内存池,如为了引用计数或者专门用于小对象分配。所以看起来内存管理一般分为三个层次。

3.线程池

线程池是一个预先创建并维护一定数量线程的集合。当有任务需要执行时,线程池会从池中取出一个空闲线程来执行任务,而不是每次都创建新线程。

线程创建是需要分配资源的,这存在一定的开销,如果一个任务就创建一个线程去处理,这必然会影响系统的性能。线程池的可以限制线程的创建数量并重复使用,从而提高系统的性能。

线程池可以分类或者分组,不同的任务使用不同的线程组,可以进行隔离以免互相影响。对于分类,可以分为核心和非核心,核心线程池一直存在不会被回收,非核心可能对空闲一段时间后的线程进行回收,从而节省系统资源,等需要时在按需创建放入池子中。

在 Java 中,可以使用 ExecutorService,在 Python 中可以使用 concurrent.futures.ThreadPoolExecutor。其他语言也有类似的线程池实现。

// Java 示例
ExecutorService executor = Executors.newFixedThreadPool(10);
executor.submit(() -> {// 处理任务
});

4.连接池

常用的连接池有数据库连接池、redis连接池、TCP连接池等等,其主要目的是通过复用来减少创建和释放连接的开销。连接池实现通常需要考虑以下几个问题:

  • 初始化:启动即初始化和惰性初始化。启动初始化可以减少一些加锁操作和需要时可直接使用,缺点是可能造成服务启动缓慢或者启动后没有任务处理,造成资源浪费。惰性初始化是真正有需要的时候再去创建,这种方式可能有助于减少资源占用,但是如果面对突发的任务请求,然后瞬间去创建一堆连接,可能会造成系统响应慢或者响应失败,通常我们会采用启动即初始化的方式。

  • 连接数目:权衡所需的连接数,连接数太少则可能造成任务处理缓慢,太多不但使任务处理慢还会过度消耗系统资源。

  • 连接取出:当连接池已经无可用连接时,是一直等待直到有可用连接还是分配一个新的临时连接。

  • 连接放入:当连接使用完毕且连接池未满时,将连接放入连接池(包括连接池已经无可用连接时创建的临时连接),否则关闭。

  • 连接检测:长时间空闲连接和失效连接需要关闭并从连接池移除。常用的检测方法有:使用时检测和定期检测。

5.对象池

严格来说,各种池都是对象池的的具体应用,包括前面介绍的三种池。

对象池跟各种池一样,也是缓存一些对象从而避免大量创建同一个类型的对象,同时限制了实例的个数。如 Redis 中 0-9999 整数对象就通过对象池进行共享。在游戏开发中对象池经常使用,如进入地图时怪物和 NPC 的出现并不是每次都是重新创建,而是从对象池中取出。

微服务中,使用对象池来管理缓存对象(如 Redis 缓存、内存缓存),可以提高缓存的效率。

6.小结

池化技术在微服务架构中通过提高资源的重用率,减少资源创建和销毁的开销,显著提升系统性能。线程池、连接池、对象池等技术可以有效管理并发任务和资源,提高系统的响应速度和吞吐量。通过合理的池化策略和管理,微服务能够更高效地处理高并发负载,优化资源利用率。


参考文献

服务高并发、高性能、高可用实现方案- 杨岂


http://www.ppmy.cn/server/102825.html

相关文章

java并发编程之线程基础

文章目录 线程基础线程状态New(新创建)Runnable(可运行)被阻塞线程和等待线程Terminated(终止) 三种使用线程的方法线程互斥同步Synchronized概念修饰的四种对象 ReentrantLock比较 线程基础 线程状态 线…

网络编程/在哪些场景中不必要进行网络字节序转换? Windows Sockets: Byte Ordering

文章目录 概述字节序必须转换字节序的的情况不必转换字节序的的情况字节序转换的例程字节序转换函数字节序转换可以不生硬字节序和位序 概述 本文主要讲述了在哪些场景下必须要进行大小端字节序转换,在哪些场景下可以不用进行大小端字节序转换,IP和端口…

【ubuntu24.04】k8s 部署6:calico容器正常启动

参考大神 以及 tigera官方的calico 教程:拥有一个带有 Calico 的单主机 Kubernetes 集群 后, 【k8s】配置calico 1: 镜像拉取 【k8s】master节点重新安装docker-ce 本文进一步解决容器启动问题: 非常感谢大神的指点:准备 Kubernetes 集群环境 做好了各种配置以后,kube**的…

encoding with ‘idna‘ codec failed (UnicodeError: label empty or too long)

今天在使用Flask连接mysql的时候,遇到了一个报错:encoding with ‘idna’ codec failed (UnicodeError: label empty or too long) 网上查了一下说是字符集的问题,然后尝试修改了一下字符集,结果还是不行。 最后去翻阅SQLAlchemy…

idea付费插件,这个插件Laravel idea好用吗

以下idea付费插件你们都用过哪些呢? 获取链接:https://web.52shizhan.cn

分类预测|基于白鲸优化混合核极限学习机结合Adaboost的数据分类预测Matlab程序BWO-HKELM-Adaboost

分类预测|基于白鲸优化混合核极限学习机结合Adaboost的数据分类预测Matlab程序BWO-HKELM-Adaboost 文章目录 前言分类预测|基于白鲸优化混合核极限学习机结合Adaboost的数据分类预测Matlab程序BWO-HKELM-Adaboost 一、BWO-HKELM-Adaboost模型1. 模型组成1.1 白鲸优化算法&#…

LeetCode面试题Day12|LC209 长度最小的子数组、LC30 串联所有单词的子串

题目一: 指路: . - 力扣(LeetCode)209 长度最小的子数组 思路与分析: 滑动窗口,目的在于降低算法的时间复杂度,每次只维护一定长度的数组而非原数组的全部元素。那么既然需要长度&#xff0…

xss.pwnfunction-Easy

目录 Ma Spaghet 代码 payload构造 结果 Jefff 代码 payload构造 方法一 方法二 结果 方法一 方法二 Ugandan Knuckles 代码 payload构造 结果 Ricardo Milos 代码 payload构造 结果 Ah Thats Hawt 代码 payload构造 结果 Ligma 代码 payload构造 结果…