- 博客(114)
- 收藏
- 关注
原创 百万级消息系统中的顶层设计 —— 时序性、ID策略与幂等性保障
在现在的直播平台或聊天系统中,一条消息从发送者手中发出,到出现在其他人屏幕上,中间其实要经过很多环节。对于普通用户来说,只是几秒钟的事情,但对系统来说,背后涉及消息顺序、唯一标识、去重等复杂的问题。如果不提前设计好这些机制,最终会导致用户看到的内容混乱,比如「我刚发的消息居然排在别人后面」、「我发了一个评论竟然出现了两遍」等问题。比如你和朋友同时发送了消息,结果因为网络或服务器调度的问题,你的消息被晚处理了一点,结果显示在他后面。在高并发系统中,消息是“并发”处理的,意味着很多条消息是。
2025-05-28 17:20:09
874
原创 顶层设计——百万直播间推送系统技术方案
为了保证推送效率,我们会把看热门直播的用户,集中分配到几台专门的服务器(WebSocket服务),这样可以更方便地统一管理和发送消息。为了让推送系统既快又省,我们在背后做了几个关键设计,让系统能“聪明地”应对不同直播间的压力。,有的必须马上推送,有的可以稍后再发,甚至可以合并处理。”,像大喇叭广播,一次推送同时送给成千上万人,速度快、效率高。让系统自动判断,自动分配,自动选择最合适的推送方式,既稳又快。
2025-05-28 16:28:51
873
原创 顶层架构 - 消息集群推送方案
上节我们说到,虽然可以通过 Redis 知道用户在哪台服务器,但如果每个路由服务都要和所有 WebSocket 服务器建连接,会导致连接数爆炸,影响性能。消息中间件是负责帮我们传递消息的“邮递员”,但有时候现成的“邮递员”不完全符合我们的需求,所以我们会考虑自己定制或改造它们。和 HTTP 不同,WebSocket 是“长连接”,一旦用户连上了某台服务器,他的这条连接就只属于这一台服务器了。定制中间件能更好地满足这些需求。服务器收到消息后,先看UID,只给对应的用户处理,不用把消息内容全部解析,节省时间。
2025-05-16 21:09:13
858
原创 顶层设计-IM系统架构
整个 IM 系统就像一个团队,每个成员负责不同的工作。下面我们来看看这些“成员”都做些什么。ACK 是英文 Acknowledgement 的缩写,意思是“确认”。举个例子:你给朋友发了一条消息,系统通过 WebSocket 把消息推到了朋友的手机上,这时候朋友的设备会给服务器回一个“我收到了”的信号,这个信号就是 ACK。只有服务器收到这个 ACK,才说明消息真正送达了客户端。服务器把消息推送到客户端客户端收到消息,立刻回 ACK服务器收到 ACK,标记消息为“送达成功”
2025-05-16 20:18:48
891
原创 用户模块-黑名单技术方案博客
把一些不守规矩的用户或者IP地址标记出来,禁止他们继续使用系统功能。在设计上,我们准备了一个专门的黑名单表,里面记录了被拉黑的内容。type(类型):表示是拉黑的用户,还是拉黑的IP地址UID表示用户ID,IP表示某个IP地址。target(目标):具体被拉黑的内容如果是用户,就存用户的ID;如果是IP,就存这个IP地址。为什么不仅要拉黑用户ID,还要拉黑IP呢?因为有些用户可能换小号继续捣乱,但如果他们用的是同一个IP,就能一起拦住,防止继续违规。
2025-05-14 11:24:35
848
原创 用户模块 - IP归属地框架吞吐测试
比如,如果有成千上万的用户同时访问,解析速度慢了,就可能拖慢整个系统。因此,我们需要对这个框架的“吞吐量”进行测试,也就是看看它一秒钟能处理多少请求,有没有异常,能不能稳定运行。每次调用成功后,就打印一句话,比如“成功了”,再打印当前时间。这样,当你关闭程序、按 Ctrl+C 或系统关闭时,就会自动执行这段“善后代码”,确保线程池收得干净、任务不丢失,资源不浪费。简单说,就是用程序不停地调用这个IP解析工具,观察它能不能扛得住压力,速度快不快。如果中间出错,比如框架抛异常了,就捕获下来,并返回。
2025-05-14 10:44:25
751
原创 用户模块 - IP归属地技术方案
当我们使用外部接口(比如淘宝的 IP 归属地接口)进行 IP 解析时,经常会遇到高并发的情况——多个请求同时发起,可能会导致接口被频繁访问,从而触发访问限制。线程池可以提前创建一定数量的线程,当有请求需要处理时,可以直接从线程池中获取线程,而不需要每次都创建新的线程。获取了用户的 IP 地址后,我们常常需要知道这个 IP 地址对应的地理位置,比如用户在哪个城市、国家。也就是说,WebSocket 的建立过程和普通的 HTTP 请求是类似的,你依然可以使用前面提到的方法从请求中获取 IP。
2025-05-05 11:24:22
802
原创 用户模块 - IP归属地功能实现与测试
在开发用户系统时,我们有时需要知道用户的真实 IP 地址,比如为了记录用户的登录地点。我们通常会在拦截器(Interceptor)中处理用户请求,比如过去我们在这里提取 token,现在我们可以在同样的位置提取用户 IP。拿到 IP 后,我们可以把它存到一个临时存储位置(通常叫做“附件”)中,后面的登录逻辑会用到它。,比如登录逻辑专注于验证账号密码,IP 解析等事情可以通过事件异步处理,不影响主流程的速度。为了更方便管理 IP 数据,我们单独封装了一个。来获取 IP,这样得到的是网关地址,不是真实 IP。
2025-05-05 10:06:22
1003
原创 用户模块-SpringEvent观察者模式
RocketMQ 是一个高性能的消息队列系统,主要用来处理大规模的异步消息。简单来说,它就像一个传递信息的中介,能够把消息可靠地传递到接收方。
2025-04-23 20:40:03
1018
原创 用户模块—编程式和注解式的分布式锁
通过自定义注解和切面技术,我们可以在不修改原有代码的情况下,为方法添加分布式锁,极大地提高了代码的可维护性和可复用性。然而,分布式锁的实现相对复杂,需要一些额外的技术支持,例如:如何确保锁的公平性、如何防止死锁、如何处理超时等等。这种方式适合对分布式锁控制有较高需求的场景,例如复杂的业务逻辑或需要精确控制锁的时机。在注解式分布式锁中,我们通过自定义一个注解,标记需要加锁的方法,并指定一些锁的参数。如果你的应用中涉及到复杂的锁策略,或者希望对锁的获取与释放有精细的控制,那么编程式分布式锁更加适合你。
2025-04-23 20:19:48
710
原创 用户模块-物品发放幂等设计
在现代的分布式系统中,物品发放是一个常见的需求,特别是在游戏、电商、社交平台等场景下,用户可能会通过不同的方式获得奖励、道具或徽章。在分布式系统中,每个操作可能会被多个节点处理,而网络的不稳定或系统的故障可能导致请求在不同的节点之间重复执行。例如,物品发放的过程可以在用户请求之后,通过消息队列等方式异步执行,这样用户在请求时就能更快收到响应,而不需要等待物品发放的过程。然而,在复杂的分布式系统中,常常会遇到一些问题。如果某个请求得不到锁,说明它请求的频率过高,此时我们直接返回提示,避免频繁重复的请求。
2025-04-17 11:51:26
732
原创 用户模块——整合 Spring 缓存(Cacheable)
首先,我们需要检查用户是否拥有该徽章,然后判断它是否为有效的徽章,最后更新数据库中的佩戴状态。通过这个接口,用户可以佩戴自己已获得的有效徽章,系统会先检查用户是否拥有该徽章,并确保徽章有效。注解,这样每次调用时,Spring 会自动检查缓存中是否有数据,如果有就直接取缓存,没有的话再去数据库查询,并把查询结果缓存起来。这样,第一次查询会从数据库获取数据并存入缓存,之后的查询会直接从缓存中获取数据,提升性能。这样,后续每次请求徽章数据时,都会直接从缓存中获取,避免了频繁的数据库查询,提高了性能。
2025-03-31 20:41:01
870
原创 用户模块——业务校验工具AssertUtil
统一管理校验逻辑,可以减少重复代码,也能让业务逻辑更清晰。方法,它会从用户的物品里找到**获取时间最早、状态为“未使用”**的改名卡。,去数据库里查询用户的改名卡,并按照时间排序,拿出最早的那一张。提供了一种更简洁的方法,让我们可以用“断言”来进行业务校验。可能不够全面,需要根据需求进行扩展,让校验更灵活、更强大。,要么全部成功,要么全部失败,保证数据的一致性。,当条件不满足时,它会直接抛出异常,让我们不必手动。(比如数据库异常),自动回滚,让数据恢复原样 ❌。这样,每次改名时,我们都能确保使用的是。
2025-03-31 20:26:45
704
原创 用户模块——自定义业务异常
在开发用户系统时,一个最基本的需求就是获取用户的个人信息,比如昵称、头像、改名卡次数等。查询自己的个人信息,返回的数据通常包括用户的基本信息以及一些额外属性(如改名卡次数)。,如果新名字为空或超过 20 个字符,就会抛出异常(下一节介绍如何捕获异常)。这一部分实现了用户基本信息的查询,下一步,我们将开发。),所以我们需要去这个表里查询用户是否拥有可用的改名卡。用户希望修改自己的昵称,但为了防止滥用,我们需要做一些。现在,无论用户输入错误,还是系统出现异常,前端都能收到。,不仅代码冗余,还容易遗漏某些异常。
2025-03-25 15:01:05
771
原创 用户模块——登陆器拦截
在用户登录时,我们不能让前端随意传 UID(用户 ID),因为这可能被篡改,导致安全问题。但如果每个地方都手写。:拦截请求,从 Token 中解析 UID,判断用户是否登录,未登录则返回错误信息。:每次请求时,前端只传 Token,后端解析 Token 获取 UID。根据请求路径,判断接口类型,返回对应的错误信息(比如 "请先登录")。如果 UID 解析成功,说明 Token 有效,用户已登录。如果 UID 解析失败,说明 Token 无效,用户未登录。,进行校验,防止未登录的用户访问需要权限的接口。
2025-03-24 10:08:35
1005
原创 用户模块——背包表设计
在用户系统中,背包表是一个常见的功能,主要用于存储用户拥有的虚拟物品,例如徽章、改名卡等。这些物品通常是用户通过任务、活动、商城购买等方式获得的,需要一个合适的数据结构来管理它们。自动生成数据库模型。物品表存储所有可获得的物品,例如徽章、改名卡等,每种物品有一个唯一的 ID,并包含基本信息,如名称、类型、描述等。自动生成物品表和用户背包表,这不仅提高开发效率,也便于未来的维护。一个用户可以拥有多个物品,一个物品也可以属于多个用户,因此是。,专门用来管理用户与物品的关系,使得数据结构更加清晰、灵活。
2025-03-16 17:37:23
790
原创 用户模块——握手验证
在当前实现中,每次 WebSocket 握手时,服务器都需要解析并验证 Token。服务器在 Netty 中解析 WebSocket 握手请求的 URL,提取 Token 进行身份认证,认证成功后绑定 Token 到用户的 WebSocket 会话中。为了减少 WebSocket 认证的额外开销,我们需要优化传统的认证流程,让用户在刷新页面时不需要额外发送认证请求,而是。(RTT,Round Trip Time),不仅增加了服务器压力,还会影响用户体验,尤其是在网络延迟较高的环境下,认证速度会明显变慢。
2025-03-14 16:17:44
1122
原创 用户模块——项目线程池统一管理
来优化任务执行,提高程序性能。但是,如果项目中到处都在创建线程池,不仅代码冗余,还可能导致资源浪费、线程竞争等问题。,它就像是用户的“通行证”,用户每次访问系统时,都需要带上这个 Token 进行身份验证。—— 如果不加限制,过多的线程可能会把 CPU 占满,导致系统崩溃。,如果过期了,用户就需要重新登录,或者系统在 Token 过期前。在高并发场景下,线程池的队列可能会满,导致新任务无法提交。:某些线程池任务过多,占满 CPU,而其他线程池却很闲。,如果线程池满了,谁提交任务谁自己执行,保证任务不丢失。
2025-03-13 14:22:56
676
原创 用户模块——redis工具类
使用Redisson可以简化分布式锁的实现,它封装了很多底层细节,帮助我们轻松实现分布式环境下的锁机制,确保资源在并发情况下的一致性。Redisson是基于Redis的分布式锁实现,它可以帮助我们确保分布式系统中的不同节点在执行某个操作时能够同步,避免多个线程同时执行某个资源的操作。是基于Redis的客户端,它封装了很多复杂的操作,例如分布式锁、消息队列、分布式集合等。在用户登录成功后,我们生成一个JWT Token,并将其返回给用户,用户后续的每个请求都可以带上这个Token,服务器用它来验证用户身份。
2025-03-12 20:57:52
638
原创 用户模块 - JWT 实现
从最初的项目准备,到核心功能的开发,再到测试与验证,每一步我们都力求通俗易懂,帮助初学者理解整个流程。在完成了项目的基础配置后,接下来我们将进入核心功能的实现阶段,包括 JWT 工具类、登录服务接口设计,以及在 Redis 中实现 Token 的过期与续期逻辑。(Utility 工具包)一般用于存放项目中的工具类,这些工具类通常是一些独立的、通用的方法,方便在项目的各个地方调用,避免重复代码。:例如,始终验证 Token 的有效性,在需要的时候进行续期,避免过期 Token 造成安全隐患。
2025-03-07 13:14:34
1102
原创 用户模块 - Token 认证技术方案
在日常开发中,我们经常会遇到用户登录的问题,比如网站需要登录才能访问某些页面,或者App需要登录才能获取用户的个性化数据。实现实时聊天、推送消息等。如果没有合适的登录验证机制,用户可能需要每次都重新登录,显然这非常不方便。为了解决这个问题,我们需要一种方法,让用户登录后,即使页面刷新或连接重建,仍然能保持登录状态。为了解决这个问题,我们需要一种方法,让服务器能“记住”你,而不需要你每次都输入账号密码,这时。:你还有一张长期有效的会员卡,如果当天的购物券失效了,你可以用会员卡再领一张新的购物券。
2025-03-05 19:14:29
1049
原创 用户模块——扫码登陆代码实现(下)
在扫码登录中,当用户用微信扫码后,我们的系统会接收到微信推送过来的用户信息。好的,接下来是第六章《6. 注意事项》,我会保持通俗易懂的风格,适合小白读者阅读。在扫码登录的流程中,当我们从微信获取到用户信息后,需要对这些信息进行一系列的。绑定在一起,以便在用户授权成功时,能够通知到正确的连接,让用户自动登录。完成后,用户只需用微信扫一扫,即可快速、安全地登录到聊天网站,体验流畅的。就像用户的“通行证”,后续用户的每一个请求都可以通过它来验证身份。在扫码登录的流程中,当用户扫描二维码后,系统会生成一个唯一的。
2025-03-04 20:13:32
862
原创 用户模块——扫码登陆代码实现(中)
在复杂的应用中,循环依赖是一个常见的问题,尤其是在使用依赖注入框架(如 Spring)时,可能会出现多个类相互依赖,导致无法正确加载 Bean。在扫码登录系统中,关注事件是用户与系统互动的重要组成部分,特别是用户扫码登录后,如何根据不同的关注事件类型(扫码登录关注与普通关注)进行不同的处理,确保系统的高效与友好体验。在扫码登录系统中,用户下线处理是一个非常关键的部分,涉及到用户的连接关闭、资源释放以及在线表格的更新。通过定义清晰的接口,使得业务逻辑层不依赖具体的实现细节,从而增强系统的可维护性和灵活性。
2025-02-26 20:35:59
964
原创 用户模块——扫码登陆代码实现(上)
相比传统的 HTTP 请求,WebSocket 更加高效,适合用来处理实时通信的场景。在实现扫码登录的过程中,我们不仅需要关注每个功能模块的实现,还需要考虑如何将这些模块有机地组织起来,使得代码易于维护、扩展,并且符合常见的开发规范。当后端生成带参二维码并成功申请后,需要通过 WebSocket 将二维码的 URL 发送给前端,前端再根据这个 URL 展示二维码。在扫码登录中,WebSocket 被用来在用户的浏览器与服务器之间保持实时连接,确保二维码能够快速推送到前端,并在登录状态变化时及时通知前端。
2025-02-24 13:01:56
1017
原创 用户模块——扫码登陆整合测试
在开发微信公众平台相关功能时,我们需要和微信服务器进行交互,例如获取用户信息、生成带参数二维码、处理消息等。微信官方提供了 API,但直接调用这些 API 需要自己处理 HTTP 请求、参数拼接、签名验证等,非常麻烦。:不同推广渠道(公众号菜单、公众号文章、海报等)扫描的二维码带不同参数,以统计用户来源。在微信公众号开发中,有时候我们需要获取用户的信息,比如。:用户扫描二维码后,公众号可以根据参数确定用户身份,进行绑定操作。在调用微信 API 之前,我们需要注册微信公众号,并获取。
2025-02-23 19:21:23
811
原创 用户模块——扫码登陆方案选型
通常,二维码的生成是由服务器根据用户请求动态生成的,并包含一些重要的文本信息。如果没有合适的防护机制,攻击者可以通过模拟用户输入动态码的方式暴力撞库,从而尝试大量不同的动态码。在实现中,二维码的生成是动态的,生成过程通常是后端通过加密方式生成一个包含上述信息的URL,并将其编码为二维码图片。服务器接收到 WebSocket 连接请求后,会为每个设备分配一个唯一的连接标识符(可以是 sessionId 或者其他唯一 ID),并将此连接与用户的 UID(用户 ID)进行关联。
2025-02-21 13:00:57
862
原创 用户模块——表设计与CRUD开发
这里要替换成你的数据库 IP(可以在 Xshell 里查看)。打开 Navicat Premium,连接到项目对应的数据库。选项中,新建查询窗口,输入以上 SQL 代码,点击。运行测试,成功插入数据,则 CRUD 功能。我们使用 MyBatis-Plus 的。需要修改成你的项目包路径。在数据库中,我们设计一个。:用户状态(如正常、封禁),否则会与代码生成器冲突。,删除多余接口实现。
2025-02-21 12:35:18
429
原创 Websocket——心跳检测
在现代的实时网络应用中,保持客户端和服务端的连接稳定性是非常重要的。尤其是在长时间的网络连接中,存在一些异常情况,导致服务端无法及时感知到客户端的断开,可能造成不必要的资源浪费,甚至是服务端的潜在错误。心跳机制在分布式应用、即时通讯、在线游戏等场景中是非常关键的,它帮助服务端及时发现并处理客户端断开的情况,避免资源的浪费和潜在的服务异常。简单来说,心跳就像人类的心跳一样,不断“跳动”,如果在规定的时间内没有收到心跳信号,服务端就可以判断客户端可能已经断开连接,从而主动释放资源或者做出其他处理。
2025-02-21 12:24:14
1895
1
原创 WebSocket——netty实现websocket编码
在本篇博客中,我们通过一步步搭建和配置 Netty 实现 WebSocket 的服务器端,成功实现了 WebSocket 消息的收发和处理。这里,我将简要总结一下整个过程和实现的关键点。1. WebSocket 和 Netty 的优势WebSocket是一种常用于浏览器和服务器之间的双向通信协议,它通过一个持久的连接,使得数据可以在客户端和服务器之间实时地双向传输。相比于传统的 HTTP 请求,WebSocket 更加高效,适用于实时聊天、在线游戏等需要实时数据交互的场景。Netty。
2025-02-03 21:57:49
1655
1
原创 WebSocket——环境搭建与多环境配置
多环境配置就是将不同环境的设置和配置分开管理,并根据需要切换到对应的环境。这样,我们就能为每个环境定制不同的配置,避免在不同环境中使用相同的配置导致问题。在开发环境中,我们可能会使用本地数据库(比如H2或SQLite),但在生产环境中,我们则需要使用真实的MySQL数据库。在开发环境,我们可以打开详细日志来帮助调试,但在生产环境中,我们通常需要关闭日志或者限制日志的级别,以提高性能。项目结构就是我们如何组织和管理项目中的代码、文件和资源。
2025-02-03 20:28:47
1775
原创 WebSocket——推送方案选型
传统的 HTTP 每个连接都需要占用一个线程来处理,而 WebSocket 通过使用事件驱动的方式,能够用较少的线程处理更多的连接。相比于轮询机制,WebSocket 更节省带宽和服务器资源,能够支持低延迟和高并发的需求,特别适用于即时通讯、在线游戏、实时数据推送等需要频繁交换数据的场景。短轮询和长轮询需要客户端频繁地发起请求,即使没有新数据,服务端也需要响应空数据,而 WebSocket 只需要一次连接,双方可以持续交换数据,避免了重复的 HTTP 请求和响应开销。想象一下你正在使用一个聊天应用。
2025-01-17 16:00:39
952
原创 环境部署——minio部署
通过本次讲解,我们掌握了 MinIO 的部署与配置过程,从挂载目录到配置 Nginx 反向代理,再到 SSL 证书的申请与配置,每一步都为 MinIO 服务的高效、安全运行提供了保障。:MinIO 是一个对象存储系统,数据需要存储在宿主机上,容器的重启不影响数据,因此我们需要为 MinIO 创建一个挂载目录,用于持久化存储数据。为了保证 MinIO 服务的安全性,我们需要为其配置 HTTPS。:完成部署后,我们可以通过 HTTPS 访问 MinIO 服务的控制台,并且能够上传和下载文件,确认一切运行正常。
2025-01-15 21:23:13
2783
原创 Netty中的NioEventloop(1)
例如,Netty的Channel处理了缓冲区的管理、事件的注册与分发、以及数据的编解码等,简化了开发者的使用。轮询通常是通过一个单独的线程来进行,这个线程不断地调用Selector的select方法,它会检查所有注册的事件,查看哪些是“就绪”的,即可以进行处理的。Netty的Channel封装了原生NIO的异步I/O,提供了更加灵活的事件驱动模型,自动处理事件的注册、轮询和分发。在多线程模型中,Reactor通常会将I/O任务和非I/O任务分开,I/O任务由专门的线程来处理,非I/O任务则交给其他线程。
2025-01-15 16:20:07
627
原创 环境搭建——Mysql、Redis、Rocket MQ部署
在实际部署过程中,可能会遇到一些常见问题,如端口冲突、权限不足等,通过日志分析和容器状态检查,我们能够有效定位并解决这些问题,确保服务能够平稳运行。通过本次教程,我们完成了 MySQL、Redis 和 RocketMQ 的部署,并确保它们能在 Docker 环境中稳定运行。在完成 MySQL、Redis 和 RocketMQ 的部署后,确保每个服务都能正常运行是至关重要的。Docker 提供了轻量级虚拟化,用来运行独立的服务容器,而 Docker Compose 则能更方便地管理和编排多个容器。
2025-01-14 20:14:39
878
原创 环境搭建——docker-compose搭建
这一步是项目环境搭建的核心,通过合理的配置文件和命令,将所有服务容器化,形成一个整体的运行环境。简单来说,它就像一个“打包箱”,把程序运行所需的一切打包在一起(包括代码、依赖库、运行环境等),放到任何一台电脑或服务器上都可以直接运行,而不用担心环境不兼容的问题。服务器是项目运行的基础,就像家用电器需要插座一样,我们的程序需要一个稳定的环境来运行。服务器就像是我们项目的“家”,接下来,我们将在这台服务器上配置 Docker 环境,让它具备部署中间件的能力。简单来说,它是你和服务器之间的“遥控器”。
2025-01-13 20:41:58
1192
原创 环境搭建——前后端本地启动
如果是 Vite 或 Webpack 项目,开发服务器会启动在默认端口(如 3000 或 8080)上,但如果你在之前的步骤中更改了端口,则会使用新的端口(例如 8090)。:如果之前的测试账号存在,可能会导致新的测试环境无法正常进行,因此我们先移除旧账号,确保从头开始进行新的测试。点击授权登录后,系统会跳转到微信的授权页面,用户同意授权后,前端会获取用户的基本信息(如昵称、头像等)。:数据交互是前后端系统的核心部分,确保从数据库获取的数据能够正确展示,用户输入的数据能够正确提交并保存。
2025-01-12 20:28:45
1719
原创 高并发编程中ThreadLocal的使用
定义:ThreadLocal是什么?是 Java 提供的一个类,它用于为每个线程提供独立的变量副本。也就是说,每个线程在访问时,都会得到一个属于自己的变量值,而不会与其他线程共享这个值。它的核心作用就是提供线程局部存储(Thread Local Storage,简称 TLS)。在多线程环境中,多个线程通常会访问共享的资源。为了避免线程安全问题,我们通常会使用锁机制来确保在同一时刻只有一个线程能访问共享资源。
2025-01-11 19:48:27
1113
原创 不同类型任务的线程池设置
IO密集型任务是指程序运行时,大量时间花费在与外部设备(磁盘、网络、数据库等)的交互上,而不是在CPU计算上。I/O密集型任务是指任务的大部分时间都在等待 I/O 操作完成(如磁盘读写、网络通信、数据库查询等),而非计算逻辑的执行。线程池的配置需要针对任务的特点进行优化,不同类型的任务对线程数量、资源利用以及运行策略有不同需求。CPU密集型任务指需要大量计算的任务,任务大部分时间花费在逻辑运算上,而非等待资源。钩子函数与线程池结合使用,可适应 I/O密集型、CPU密集型、混合型任务的需求,实现优雅关闭。
2025-01-06 11:23:15
809
原创 线程池的创建规范
线程池的核心理念是将线程的创建、销毁、复用等操作交给线程池来管理,避免了频繁的线程创建与销毁的性能开销。例如,线程池的核心线程数、最大线程数、任务队列的选择、线程空闲时间的设置等,都能影响线程池的性能和响应速度。当线程池中的某个线程完成任务后,它会去“窃取”其他线程的任务来继续执行,从而避免空闲线程浪费。:线程空闲存活时间是指当线程池中的线程数超过核心线程数时,这些线程在空闲时会等待的最长时间。是一种灵活的线程池,它会根据任务的需要动态创建线程,线程池的大小没有固定上限。,并讨论它们的劣势。
2025-01-03 20:37:32
680
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人