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

网易云信架构升级实践,故障恢复时间缩至8秒

一、项目背景 

网易云信是网易旗下集IM与音视频技术于一体的PaaS服务平台,为全球提供融合通信与视频的核心功能和组件,包括IM即时通讯、短信、信令等通信服务,以及RTC、直播、点播、互动直播、互动白板等音视频服务,此外,网易云信结合网易易盾推出一站式安全通信方案——安全通。由于其广泛的服务场景与多元化的业务需求,网易云信在底层架构上依赖于多元化的数据库系统。以IM通讯系统为例,该系统不仅采用了网易自主研发的关系型数据库DDB,还融合了Redis、HBase及Elasticsearch等重要组件。随着业务需求的持续增长,数据库在性能、成本控制及高可用性方面遭遇了一系列挑战。

本文中,网易云信分享了其IM通讯系统数据库的架构设计优化方案,并阐述了如何利用OceanBase 和 OBKV ,在关系型数据库及KV业务场景中升级并简化现有架构,从而在性能提升、成本节约、运维简化及高可用保障等方面取得的思考与实战经验。

1737543202

目前,网易云信融合通信已接入 220 万企业开发者,全球注册应用数超 75 万,累计覆盖智能终端 SDK 数超 300 亿,月均消息量 3100+ 亿条,居行业首位,日活消息量表现突出。作为专为企业打造的融合通信的品牌,网易云信专注于文娱、社交、教育、医疗等行业,支持公有云、专属云、私有云与混合云四种部署方式。

对于如此体量的服务,数据库作为基石与支柱,扮演着极为重要的角色。随着业务规模的持续增长,我们也正在寻找一套适配网易云信业务场景的升级方案,在简化数据库系统架构、降低运维管理成本的同时,实现降本。本文将分享网易云信数据库实践和运维经验,以及网易云信选型OceanBase背后的实践与思考。

二、网易云信数据库架构现状:需求复杂,种类繁多

在网易云信中,通讯和视频服务都高度依赖数据库,尤其是IM通讯系统。在IM通讯系统中,数据库种类较多。包括关系数据库DDB、缓存数据库Redis,以及HBase和Elasticsearch等。

1、DDB

DDB是网易自研的分库分表中间件,目前在网易内部被广泛应用。不仅网易云信,网易云音乐、有道等众多产品也都深度依赖这套系统。在云信IM系统中,DDB主要用于存储账号、用户关系、群组关系、离线消息等核心的结构化数据。

1737686256

DDB是一个很经典的分库分表架构。接入层我们称为QS服务器,这是一个SQL-proxy,QS服务器的后端则是实际的存储节点,通常是MySQL。客户端连接QS服务器支持两种方式,一种是通过挂载四层负载均衡器,如nlb或阿里云上的slb,来实现对QS的负载均衡和高可用,此外,对于Java程序,DDB还额外提供了lbd-driver驱动,它的优势在于能直连QS服务器,从而在QS上下线管理以及故障转移上更加平滑,此外因为省去了nlb组件,也降低了网络延迟。

DDB是一套完整的解决方案,用于管控的master,元数据存储的sysdb、以及用于高可用切换的ddb-switcher,此外通过ndc这样的数据同步工具以及owl的数据平台,可以统一管理ddb集群,包括表变更、扩缩容等等。 

2、Redis

redis在网易云信IM系统中占有重要角色,支撑着多种业务场景,我这边简单选取几个代表性的场景。

1737686220

1)数据库缓存

第一个场景是数据库缓存,基于自研数据库缓存框架,主要依赖简单的kv读写操作,如set/get/del。

这个场景的特点是读多写少,且读操作的TPS很高。

2)在线状态缓存

第二个场景是在线状态管理,用于记录账号和设备的在线状态,使用redis中的hash结构记录多端登录和实现复杂的多端互踢策略,也是消息分发时的关键组件。简单讲,用户登录时系统会进行在线状态的写入与更新,而发送消息时则需查询在线状态。

这是一个典型的读多写多场景,尤其在处理大群消息或批量消息发送任务时,读操作的TPS会显著上升。

3) 漫游消息

第三个典型场景是漫游消息,从用户角度来看,它主要用于实现最近消息的多端同步功能。为实现这一功能,我们采用了redis中的zset结构实现先进先出的最近逻辑。

该功能的一个显著特点是,由于需要存储最近发送的消息以便进行同步,因此其存储开销相对较大

3、HBase和Elasticsearch

此外,我们还引入了HBase和Elasticsearch数据库,主要用于存储和查询历史消息。

1737686184

HBase的row-key全局有序的特点,非常适合适合根据时间进行历史消息分页查询的场景;而Elasticsearch被用于关键词检索等更复杂的搜索需求,为了降低存储开销,在Elasticsearch中我们并没有直接存储消息的完整内容,最终的搜索结果指向的是HBase中row-key。除了消息之外,用户和关系的检索等也会用到es相关的能力。

四、问题和挑战:业务需求与特定场景带来多样挑战

前面介绍了云信的数据库使用背景及现状,当前我们在使用数据库的过程中也面临一些问题和挑战。

1、DDB

1737685598

首先,在关系数据库方面面临以下几个问题。 

第一,性能瓶颈问题。尽管我们使用的分库分表架构已经相当稳定,并且依赖于内部强大的owl平台,能够自动化完成许多运维工作,如自动扩缩容、在线表变更等,但在某些特定场景下,我们仍然遇到一些瓶颈。为了进一步提升业务的灵活性和应对未来可能的扩展需求,我们希望能够引入原生的分布式数据库。这样不仅可以解决当前的性能瓶颈,还能为业务带来更多的弹性和可扩展性,这是我们最初的诉求。

第二,资源利用率问题。DDB基于MySQL存储作为数据节点,其B+tree结构既有优势也有局限,这是众所周知的。在云环境下,我们期望在某些场景中能提高磁盘利用率,以实现降本增效。

第三,资源隔离功能。DDB已提供一定程度的资源隔离能力,通过配置policy或者schema来实现。这些隔离策略能满足大多数业务场景的需求。然而,在某些特定的业务场景中,我们期望有更精细化的资源控制机制。现有的隔离机制可能是库表级别的,但我们希望它能进一步细化。对于云信这样一个多租户的PaaS系统来说,更细粒度的资源控制是很有必要的。

2、redis

1737685465

最初我们采用了开源的redis-cluster集群部署方案。Redis-cluster本身是多节点且支持水平扩缩容的,在初期单集群即可很好的满足云信的单一业务需求。然而,随着业务的持续增长,由于redis-cluster单集群节点数的上限(我们单集群一般不超过100主100从),我们遇到了单集群下的内存容量瓶颈和QPS容量瓶颈。

为了突破这些瓶颈,我们开发了一个redis代理,以实现更灵活的水平扩展。这个代理服务可以将多个Redis-cluster集群使用分片的方式作为一个整体透明的对外提供服务,从而突破单集群的规模上限。此外,为了更平滑在多个集群之间迁移数据,我们还在redis代理上实现了双写功能。

然而伴随业务规模不断扩大,云信的集群数量也随之增加,这让我们开始思考如何降低成本。特别是针对漫游消息这一业务场景。

漫游消息用于在相同账号的不同设备之间同步最近n天的消息,因此它有一个显著特点,用户通常会频繁读取最近的消息,而几天前的消息则读取较少。针对其特点,我们实现了一个冷热数据分离的存储策略。具体来说,我们将热数据存储在Redis中,以便快速访问;而冷数据则被持久化到HBase中。之所以选择HBase作为冷数据的存储介质,主要是因为当时我们有一套现成的hbase集群,dba也有hbase的运维经验,此外hbase的扩展性也满足了我们业务增长带来的扩容需求。

我们发现冷热数据分离策略的效果相当不错。随即便开始思考如何将其打造得更加通用,不仅仅局限于漫游消息这一场景。为此,我们先将冷热数据分离功能中将redis设置为可选,以适应那些TPS要求不那么高、希望所有数据都直接持久化在磁盘上的场景。

不久我们意识到持久化的KV存储不应局限于HBase这一种方案。因此,我们抽象出了一套通用的接口,使得替换存储方案变得更加简单灵活。这一改动上线后,云信的系统成功接入了更多业务,如在线状态发布订阅、云端会话列表等功能,都逐渐整合到了这套方案中。

值得一提的是,我们还开源了与这些功能相关的代码(开源地址:https://github.com/netease-im/camellia),有兴趣的朋友可以进一步了解。

目前线上我们主要使用hbase作为后端kv存储,然后由于其架构特性,宕机后的恢复时间可能会相对较长,基本要分钟级别。

另外,当我们通过proxy将Redis协议转换为KV协议时,会涉及将单个key的数据映射到多条kv的情况。这种转换过程中,数据不一致的风险是不可避免的,尽管并非所有场景都对数据一致性有严格要求,但这种风险确实存在。

此外,proxy与KV存储之间的映射也会带来proxy和kv-server之间的多次网络I/O,对性能造成一定的损耗。尽管我们做了很多优化工作来减少网络I/O,但显然无法完全覆盖所有场景,性能损耗问题依然存在。

3、hbase

我们以历史消息存储这一核心场景为例。

1737685666

起初,我们选择使用单个HBase集群来存储所有的历史消息数据,考虑到数据规模比较大,为了节约成本,便采用了hdd磁盘作为存储介质。然而,随着数据量的不断增长,HBase也面临了一些挑战,特别是当某个节点出现故障后恢复周期相对较长,可能需要数分钟甚至数十分钟,这对业务的稳定运行造成了不小的影响。

为了应对这些挑战,我们后来决定采用双集群方案。在这个方案中,我们部署了两个HBase集群:一个是基于hdd的全量数据集群,另一个是基于ssd的小规模集群。ssd集群用于存储最近一年内的消息,以提供更快的读写速度;而超过一年的消息则存储在hdd集群中,以节约成本。 

对于写操作,我们采用双写策略,确保数据同时写入两个集群。对于读操作,如果查询的是最近一年的消息,则直接从ssd集群中读取;如果需要查询超过一年的消息,我们会从hdd集群中检索,并在业务层进行合并后返回结果。为了确保双写操作的一致性,我们引入了Kafka作为中间件。当向两个HBase集群写入数据时,如果某个集群写入失败,我们会通过Kafka记录这条失败的写入命令,并触发重试机制,以确保两个集群最终达到一致状态。

双集群方案对提升整个系统的稳定性有非常大的帮助,但并没有解决所有问题。

比如尽管我们已经将热数据迁移到了速度更快的ssd上,但HBase的故障恢复时间依然是一个需要重视的问题。虽然相比使用hdd时,恢复时间已经大大缩短,但分钟级别的恢复时间对于实时性要求极高的业务来说,仍然可能带来不小的风险。

此外,随着业务的不断扩张,ssd上的HBase集群所承受的读流量也在持续攀升。最初的设想中,在一个集群出现问题时,可以迅速切换到另一个节点以维持服务。然而,随着业务量的不断增长,特别是在高峰时段,这种切换策略变得愈发不可行。具体来说,如果ssd节点发生故障时,切换到hdd集群是一个比较艰难的抉择,因为我们不确认hdd集群是否能承担起所有流量,因此更多时候可能我们只能等待故障节点自行恢复,而这段等待时间,对于业务而言,可能就意味着服务的有损。因此数据库恢复时间已经成了制约服务稳定性进一步提升的关键。 

五、技术选型:网易云信需要怎样的数据库?

鉴于上述数据库的这些痛点,我们开始寻找更符合业务需求的数据库。

1737686321

在进行数据库选型的过程中,我们主要从兼容性和稳定性、平台统一性、成本、性能、高可用性、社区方面着重进行考量。

第一,稳定性和兼容性。这是我们着重考虑的因素。首先,稳定性至关重要,特别是对于云信的To B业务来说。鉴于云信拥有庞大的客户群体,任何微小的服务波动都可能迅速引发客户反馈,进而给前向团队和研发团队带来巨大压力。因此,稳定性无疑是数据库选型中的首要考量。其次,兼容性同样不容忽视。我们期望新数据库能够兼容现有mysql协议,以便业务能够顺利迁移,无需进行大规模修改。这样不仅能降低迁移成本,还能确保业务的连续性和稳定性。

第二,平台的统一性。如上文所述,当前许多数据库都具备多模和多功能的特点。我们期望新的数据库平台能够适应云信的多种业务场景,这样,在运维过程中,我们就能因为使用同一套系统而简化工作,进而降低运维成本。

第三,降本增效,特别是在数据存储方面。我们目前线上的数据库现状是,相较于存储需求,CPU资源往往相对闲置。经常出现的情况是,CPU还未充分利用,磁盘空间却已耗尽,且无法再增加磁盘。这时,云信不得不进行扩容。因此,如果能够通过利用CPU资源来换取存储成本的降低,对我们来说将是非常划算的。

第四,性能方面。虽然目前的DDB或HBase在性能上并未出现明显的瓶颈,但如果新数据库能进一步提升性能,那对我们来说无疑是更好的选择。

第五,高可用性的能力。这是我们曾经遇到问题,也是最希望得到改善的方面,特别是HBase。我们期望新数据库具备可控的故障恢复时间,这能显著提升云信服务的整体稳定性。稳定性不仅体现在日常运行的无故障上,更体现在故障发生后的快速恢复上。恢复速度越快,云信的服务中断时间就越短,对于To B业务来说,这直接关联到成本节约。

第六,社区。我们期望使用的数据库,是一个社区活跃、功能持续迭代的现代数据库。这样,未来一旦我们有新的需求,能得到迅速响应和及时满足,这是我们非常看重的一点。

六、网易云信业务场景下 OceanBase 的优势:多场景降本提效

基于上述关于数据库技术选型的考量,OceanBase在网易云业务场景中展现出显著优势。

1、关系数据库

1737686371

首先对于关系数据库来说:

兼容MySQL协议。以关系数据库为例,我们特别欣赏OceanBase社区版对MySQL协议的兼容性,便于业务几乎无需修改即可平滑迁移。同时,我们的使用方式也无需做出特殊调整,大大简化了部署和运维过程。

成本优势,关于这一点,我们有坚实的数据支持,在后文中会详细展示。在采用OceanBase之前,我们曾对MySQL 8.0版本与MySQL 5.7版本进行测试、对比,虽然前者在压缩能力上有所进步,但与OceanBase相比,压缩效率仍显不足。

高可用能力。与DDB相比,OceanBase同样具备出色的高可用性能。然而,DDB的故障恢复时间依赖于DDB-switcher这一高可用切换工具,在最慢的情况下可能需要超过1分钟。相比之下,OceanBase的故障恢复时间可以缩短至8秒,这一优势在我们多次实际测试中得到了验证。 

原生分布式能力。与DDB这类分库分表中间件相比,OceanBase在扩缩容时数据迁移更加高效。虽然DDB也能实现一定程度的自动化,但在资源依赖和操作流程上,OceanBase显然更为便捷。

多租户能力。对于云信这样的PaaS平台,用户众多且使用习惯各异,有时难免出现个别用户行为异常,可能影响到整个系统。此时,OceanBase的多租户资源隔离能力就显得尤为重要。通过OceanBase,我们可以将云信业务中的不同租户数据隔离到各自的数据库实例中,实现资源的独立调度和管理。这样,即使某个租户出现异常行为,也不会波及其他租户或整个系统,从而显著提升服务的稳定性。这一底层逻辑的设计,充分体现了OceanBase在多租户资源隔离方面的独特价值。

性能优势。虽然DDB的性能对我们来说已经相当不错,但在某些特定场景下,由于其底层基于MySQL,因此在单行更新等方面可能会遇到一些性能瓶颈。相比之下,OceanBase在这方面进行了专项优化,表现更为出色。

单机分布式一体化特性,这一特性是OceanBase 4.0版本提出的,它为云信带来了显著价值。因为并非所有业务都需部署如DDB般庞大的数据库,尤其对于发号器、配置中心等轻量级服务,单机版数据库便足以应对。OceanBase 正是满足了这一需求,其一体化架构统一了底层数据库,极大简化了运维流程,对云信而言意义非凡。

2、kv数据库-redis

1737686478

大容量redis场景下,相比于使用hbase作为存储层,obkv的优势包括组件少、运维简单,以及高可用能力增强。此外选用obkv还可以帮助我们统一存储底座,对于减少运维成本还是有很有意义的。

2、kv数据库-hbase

1737686577

历史消息存储这样典型的hbase使用场景下,obkv有以下优势:

成本优势。相比HBase1.x,压缩率显著提升,大大降低了成本。官方数据也证实了这一点。

高可用能力增强,这是我们尤为看重的一点。

接入较简单。官方提供了一个与HBase兼容的客户端SDK,接入简便,因其与HBase客户端高度相似。

运维部署简单。OBKV相比HBase极大的简化了部署,特别适合云信的私有化场景。

在私有化环境中,很多客户的需求并不需要大规模的部署。此时,如果采用HBase来处理历史消息,可能会显得过于庞大和复杂。

如果此时我们改用OBKV,部署将变得非常简单,能够更好地实现公有云与私有化环境的功能一致性。在私有化环境中,由于无法部署HBase,我们往往不得不割舍某些功能或采用其他方式实现,这不仅增加了开发成本,也损害了用户的体验。 

采用OceanBase后,我们在私有化落地方面的挑战得到有效克服,实现了与公有云功能的一致性。OceanBase 相比 HBase 组件少、部署简单、运维方便,解决了私有化过程中的难点。

七、OceanBase与MySQL/Hbase对比实测

1、压缩

在实践中,我们曾将线上数据库同步至OceanBase与MySQL 8.0进行对比测试。测试中,云信特别关注了核心大表,尤其是至关重要且规模庞大的离线消息表。OceanBase 的出色表现再次证明了其在处理这类核心数据上的卓越能力。

以下表为例,OceanBase的压缩比高达4:1左右。相比之下,无论是页压缩还是大字段压缩,SQL 8.0的压缩比都只能达到约1.5或更低,不超过2:1。显然,OceanBase在这方面具有显著优势。高压缩比直接转化为实实在在的成本节约,对云信而言意义重大。

1737686812

2、单行更新 

此次单行更新测试,使用了OceanBase官方文档中的脚本。

1737686844

结果显示,无论是低并发还是高并发场景,OceanBase 4.2.1版本相比MySQL 5.7和8.0都表现出明显优势。尤其在并发增加时,OceanBase的优势更为显著。这对于IM系统中需要单行更新的场景来说,将极大提升系统的稳定性。

3、kv-redis场景

1737686999

对一个简单字符串场景的性能测试,主要对比了HBase、TIKV、OBKV以及原生Redis(通过obkv-4.2.5的POC版本)在get/set方法上的表现。

结果显示,OBKV相较于云信之前使用的HBase,在性能上确实有所提升。特别是在P999上的表现尤为突出。

对于复杂数据结构而言,OBKV同样展现出了优势。这得益于它针对Redis数据结构进行的优化,使得其写入能力相较于Redis-proxy+kv架构更为出色,在读取方面,目前来看各种方案各有优劣。

八、未来展望

第一,逐步上线OceanBase。目前,我们的测试工作正在紧锣密鼓地进行中,测试环境已搭建完毕并投入运行。会按照先部署OBKV,再使用OceanBase替换MySQL的顺序逐步灰度和上线。当前部分业务已经正式上线使用 OceanBase。

第二,异地容灾。由于之前数据库底座的限制,云信的容灾方案相对复杂。在OceanBase的支持下,有望简化整个容灾方案。目前,我们正对此进行深入研究。

第三, 迁移obkv-redis。初期,我们可能会优先上线基于现有redis-proxy+KV的方案,只是将KV从HBase更换为OBKV。我们会先运行这种方案,待其逐渐稳定后,再考虑迁移到obkv-redis。

第四,使用OceanBase的HTAP功能。云信不仅拥有IM系统的核心在线功能,还集成了数据统计能力。当前,我们可能因系统分割,需借助数据平台和CDC来实现数据同步与数仓分析。若OceanBase的HTAP功能符合业务需求,将极大简化整体数据架构,促进系统间的高效集成。

另外,在测试过程中,我们对OceanBase提出了许多需求,都得到了OceanBase的积极反馈。未来也对OceanBase的新特性和新功能充满期待。

相关文章:

网易云信架构升级实践,故障恢复时间缩至8秒

一、项目背景 网易云信是网易旗下集IM与音视频技术于一体的PaaS服务平台,为全球提供融合通信与视频的核心功能和组件,包括IM即时通讯、短信、信令等通信服务,以及RTC、直播、点播、互动直播、互动白板等音视频服务,此外&#xf…...

算法刷题记录——LeetCode篇(3) [第201~300题](持续更新)

(优先整理热门100及面试150,不定期持续更新,欢迎关注) 207. 课程表 你这个学期必须选修 numCourses 门课程,记为 0 到 numCourses - 1 。 在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出,其中 prerequ…...

navicat导出文件密码解密

文章目录 一、概念二、导出文件1、创建的数据库连接信息2、导出带密码的连接信息3、查看导出后的文件 三、Python代码解析四、参考地址 一、概念 Navicat中导出的带密码的文件后缀是.ncx结尾的,里面是xml格式的文件,存储了数据库的连接,方便…...

uniapp vue3项目定义全局变量,切换底部babar时根据条件刷新页面

前言 uniapp项目中,每个tabbar页面来回点时候,不会触发页面更新。但是有时页面上有数据发生改变需要更新模版时,就得能及时的通知到页面。如果在onshow生命周期里每次都调用异步请求更新数据,有些不合理,况且页面有时…...

Linux上的`i2c-tools`工具集的详细介绍;并利用它操作IMX6ULL的I2C控制器进而控制芯片AP3216C读取光照值和距离值

IC-Tools 工具集介绍 i2c-tools 是 Linux 下用于 IC 设备调试 的用户空间工具集(你也可以把它看成是一个库,类似于之前自己用过的触摸屏库tslib库、FreeType矢量字符库),它提供了一系列命令行工具,可以扫描、读取、写入 IC 设备,…...

## DeepSeek写射击手机小游戏

DeepSeek写射击手机小游戏 提问 根据提的要求,让DeepSeek整理的需求,进行提问,内容如下: 请生成一个包含以下功能的可运行移动端射击小游戏H5文件: 要求 可以重新开始游戏 可以暂停游戏 射击位置在底部中间&#xff…...

奇安信全流量(天眼)面试题

一、全流量设备(天眼)的部署架构 天眼系统采用旁路部署模式,通过流量镜像实现非侵入式监测,核心组件包括流量传感器、分析平台和文件威胁鉴定器,具体部署架构如下: 传感器部署 关键节点覆盖:在…...

计算机四级 - 数据库原理(操作系统部分)- 第2章「操作系统运行机制」

系统调用是应用程序请求操作系统核心完成某一特定功能的一种过程调用,与一般调用的最大区别就是调用程序运行在用户态,而被调用程序则运行在系统态寄存器类型: 用户不可见寄存器:程序计数器、指令寄存器、程序状态字(P…...

【css酷炫效果】纯CSS实现虫洞穿越效果

【css酷炫效果】纯CSS实现穿越效果 缘创作背景html结构css样式完整代码基础版进阶版(虫洞穿越) 效果图 想直接拿走的老板,链接放在这里:https://download.csdn.net/download/u011561335/90491973 缘 创作随缘,不定时…...

火山引擎(豆包大模型)(抖音平台)之火山方舟的Prompt的使用测试

前言 在大模型的使用过程当中,Prompt的使用非常的关键。原来,我对Prompt的理解不深,觉得Prompt的产生并不是很有必要。但是,自从使用了火山方舟中的“Prompt优解”之后,感受加深了,觉得Prompt是我们和大模型…...

多线程(四)----线程安全

线程安全问题的万恶之源就是多线程的抢占式执行所带来的随机性. 有了多线程, 此时抢占式执行下, 代码执行的顺序, 会出现更多的变数, 代码执行顺序的可能性就从一种情况变成了无数种情况. 只要有一种情况使得代码结果不正确, 都是视为bug, 线程不安全. 有线程安全的代码 以下…...

跨系统投屏:Realme手机(远程)投屏到Linux系统的简单方法

家里长辈年纪上来了,有点老花眼,平常看手机总是觉得字体不够大,还一个劲儿地将手机拿很远。其实那台手机的字体已经调到最大了。 为了让长辈刷手机的时候可以轻松快乐一点,我们帮他将手机投屏到电脑上。毕竟电脑屏幕比手机大多了&…...

【eNSP基础使用教程-1】

座右铭: 纵有疾风起,人生不言弃。 文章目录 前言一、更改设备名称指令1、双击路由器进入2、 进入系统视图3、更改设备名称为R14、使用同样的办法修改路由器R2、R3 二、配置路由物理接口的IP 地址1、查看R1路由器当前接口IP 地址配置与路由表2、查看路由器上的路由表…...

android开发:组件事件汇总

在 Android 开发中,Java 文件中有许多组件事件可以处理用户交互。以下是一些常见的组件事件及其用途和示例: 1. 点击事件 (Click) 用于处理用户点击控件的操作。 示例代码: Button button findViewById(R.id.button); button.setOnClickL…...

C++|向函数传递对象

在 C 里,对象作为函数的参数和返回值,有值传递、指针传递和引用传递这三种传递方式,下面为你详细介绍。 1.值传递 在值传递时,把实参对象的值复制给形参对象,函数会接收实参的一个副本,而非实参本身。函数…...

网络爬虫【爬虫库urllib】

我叫不三不四,很高兴见到大家,欢迎一起学习交流和进步 今天来讲一讲爬虫 urllib介绍 Urllib是Python自带的标准库,无须安装,直接引用即可。 Urllib是一个收集几个模块来使用URL的软件包,大致具备以下功能。 ● urlli…...

【一起来学kubernetes】17、Configmap使用详解

前言概述核心特性创建 ConfigMap使用 ConfigMap1. **环境变量**2. **Volume 挂载**3. **命令行参数** 更新与热重载Docker容器中Java服务使用Configmap**一、通过环境变量注入****步骤说明****示例配置** **二、通过 Volume 挂载配置文件****步骤说明****示例配置** **三、动态…...

QT程序双击可执行文件运行方法

1、qt编译选择release模式 在pro文件添加:QMAKE_LFLAGS -no-pie 2、cmake编译qt界面程序 在CMakeLists.txt文件中添加: set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -no-pie") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -no-pie")注意 …...

【css酷炫效果】实现鱼群游动动态效果

【css酷炫效果】实现小鱼游动动态效果 缘创作背景css代码创建div容器引入jquery引入鱼群js完整代码效果图成品资源下载链接:点击下载 缘 在开发系统功能的时候,无意间看到了小鱼游动特效,感觉很有意思,就在网上找了相关教程,分享给大家。 创作背景 刚看到csdn出活动了…...

【GNN】GAT

消息传递 层数越多,聚合更多的消息...

Prims region.Views 为null

原因: 导航未完成或异步问题 解决方式:使用回调确认导航完成后再操作视图 _regionManager.RequestNavigate("MonitorRegion", "MonitorView", nps, navigationResult > {if (navigationResult.Result true){var region _regio…...

在windows10系统上安装docker,然后在容器中运行GPU版本的Pytorch,并使用vscode连接该容器

一 . 安装Docker Desktop 首先打开网址https://docs.docker.com/desktop/install/windows-install/ 下载完后,双击下面的exe文件进行安装,默认情况下,Docker Desktop 安装在C:\Program Files\Docker\Docker 出现提示时,请确保…...

WPS 搭配 Zotero 插件使用

安装Zotero后,Word自动引入了插件,但WPS却没有,做为WPS的重度用户,这是不行的。 解决方案: 1.找到 Zotero.dotm 一般在安装目录下, 2.然后复制到WPS的startup下 我的目录是:C:\Users\lianq…...

卷积神经网络 - 卷积层(具体例子)

为了更一步学习卷积神经网络之卷积层,本文我们来通过几个个例子来加深理解。 一、灰度图像和彩色图像的关于特征映射的例子 下面我们通过2个例子来形象说明卷积层中“特征映射”的概念,一个针对灰度图像,一个针对彩色图像。 例子 1&#x…...

新造车不再比拼排名,恰是曲终人散时,剩者为王

据称新能源汽车周销量不再发布,这可能也预示着新造车终于到了给出答案的时候了,新造车企业前三强已基本确立,其余那些落后的车企已很难有突围的机会,而特斯拉无疑是其中的最大赢家。 3月份第一周的数据显示,销量最高的…...

学有所得-Deepin linux操作系统在安装nvidia显卡驱动后的问题修复

目标: 装有deepin V20.9的移动硬盘在系统启动后无法进入图形化界面,修复系统。 背景: 为了方便随时随地开发研究,又不破坏笔记本电脑原装的正版操作系统,在一个朗科(容量50&…...

【QT:网络编程】

网络编程的本质就是在编写应用层代码。需要传输层支持。而传输层的协议有UDP、TCP等 使用QT网络编程的API,需要在.pro文件中添加network模块,而QT中的控件和其他内容都是包含在QtCore模块中的(默认添加) QT为什么要划分模块&…...

基于srpingboot高校智慧校园教学管理服务平台的设计与实现(源码+文档+部署讲解)

技术范围:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论…...

分布式事务3PC解决了2PC哪些问题?

三阶段提交(3PC,Three-Phase Commit) 是对 二阶段提交(2PC,Two-Phase Commit) 的改进,旨在解决 2PC 的一些固有缺陷,特别是在分布式系统中的容错性和性能问题。以下是 3PC 比 2PC 更好的原因及其优势的详细分析: 1. 二阶段提交(2PC)的问题 2PC 是一种经典的分布式事…...

Dify 使用 - 创建 翻译 工作流

文章目录 1、选择 模板2、设置 和 基本使用3、运行应用 1、选择 模板 2、设置 和 基本使用 翻译模板 自带了系统提示词,你也可以修改 3、运行应用 右上角 点击 发布 – 更新,运行应用,就可以在新的对话界面中使用此功能 2025-03-18&#x…...

集成学习(上):Bagging集成方法

一、什么是集成学习? 在机器学习的世界里,没有哪个模型是完美无缺的。就像古希腊神话中的"盲人摸象",单个模型往往只能捕捉到数据特征的某个侧面。但当我们把多个模型的智慧集合起来,就能像拼图一样还原出完整的真相&a…...

c盘清理宝藏小工具

引言 在数字化时代,电脑的存储空间和系统性能直接影响着我们的工作效率和用户体验。C盘作为系统盘,常常因为文件堆积、缓存冗余等问题变得臃肿不堪,导致电脑运行缓慢。为了解决这一问题,我最近试用了一款名为“小番茄C盘清理”的…...

QT多媒体播放器类:QMediaPlayer

QMediaPlayer 是 Qt Multimedia 模块中的核心类,用于播放音频和视频媒体文件。它支持本地文件、网络流媒体以及实时数据源,具备播放控制、状态管理、元数据访问等功能。QMediaPlayer的基本用法可能包括设置媒体源、控制播放(播放、暂停、停止…...

Java动态代理模式深度解析

1. 动态代理基础 1.1 核心组件 Proxy 类:动态生成代理对象的工厂类,核心方法为 newProxyInstance()。 InvocationHandler 接口:代理逻辑的处理器,所有方法调用会转发到其 invoke() 方法。 1.2 实现步骤 定义接口:代…...

【WRF模拟】垂直层设置/与观测数据对比

【WRF模拟】垂直层设置/与观测数据对比 WRF 中 有关垂直层的namelist变量1. 主要垂直层设置参数2. 详细解释3. 典型设置示例WRF 输出的垂直剖面数据与观测数据进行比较WRF 采用 地形跟随坐标(terrain-following coordinate)WRF 输出的垂直剖面数据与观测数据进行比较参考WRF …...

植物知识分享论坛毕设

1.这四个文件直接是什么关系?各自都是什么作用?他们之间是如何联系的? 关系与联系 UserController.java 负责接收外部请求,调用 UserService.java 里的方法来处理业务, 而 UserService.java 又会调用 UserMapper.jav…...

可视化图解算法:链表中倒数(最后)k个结点

1. 题目 描述 输入一个长度为 n 的链表,设链表中的元素的值为ai ,返回该链表中倒数第k个节点。 如果该链表长度小于k,请返回一个长度为 0 的链表。 数据范围:0≤n≤105,0 ≤ai≤109,0 ≤k≤109 要求&am…...

qt下载和安装教程国内源下载地址

qt不断在更新中,目前qt6日渐成熟,先前我们到官方下载或者国内镜像直接可以下载到exe文件安装,但是最近几年qt官方似乎在逐渐关闭旧版本下载通道,列为不推荐下载。但是qt5以其广泛使用和稳定性,以及积累大量代码使得qt5…...

html5表格实战-跨行跨列

效果如图 代码如图...

使用OBS进行webRTC推流参考

参考腾讯云官方文档: 云直播 OBS WebRTC 推流_腾讯云 说明非常详细,分为通过WHIP和OBS插件的形式进行推流。 注意:通过OBS插件的形式进行推流需要使用较低的版本,文档里有说明,需要仔细阅读。...

Rockchip --- 图像时延优化

通过配置wait-line,即图像采集多少行后提前输出buffer给ISP,而无需等待图像全部采集完毕。一般设置为图像采集一半后提前输出buffer给ISP (一)VICAP提前输出 Video Input CAPture是用于图像采集和处理的子系统 1. 通过dts配置 …...

微软 LIDA 库:基于大模型的自动化数据分析与可视化

微软 LIDA 库:基于大模型的自动化数据分析与可视化 一、核心架构与 LLM 交互流程 #mermaid-svg-UzSwZNKPlgrJUpej {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-UzSwZNKPlgrJUpej .error-icon{fill:#5…...

java-正则表达式-集合-泛型

正则表达式 正则表达式到底是什么东西? 在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具。换句话说,正则表达式就是记录文本规则的代码。 http://tool.oschina.net/r…...

力扣刷题994. 腐烂的橘子

994. 腐烂的橘子 - 力扣(LeetCode) 使用bfs,先遍历所有的橘子,统计所有的橘子数量,然后把腐烂的橘子放入队列当中,然后进行bfs遍历,套用bfs的模版,但是每一次出队的橘子&#xff08…...

Kubernetes的Service详解

一、Service介绍 在 kubernetes 中, pod 是应用程序的载体,我们可以通过 pod 的 ip 来访问应用程序,但是 pod 的 ip 地址不是固定的,这也就意味着不方便直接采用pod 的 ip 对服务进行访问。 为了解决这个问题,kuberne…...

Linux目录理解

前言 最近在复习linux,发现有些目录总是忘记内容,发现有些还是得从原义和实际例子去理解会记忆深刻些。以下是个人的一些理解 Linux目录 常见的Linux下的目录如下: 1. 根目录 / (Root Directory) 英文含义:/ 是文件系统的根…...

vue中js简单创建一个事件中心/中间件/eventBus

vue中js简单创建一个事件中心/中间件/eventBus 目录结构如下: eventBus.js class eventBus {constructor() {this.events {};}// 监听事件on(event, callback) {if (!this.events[event]) {this.events[event] [];}this.events[event].push(callback);}// 发射…...

1~2 课程简介+ESP32-IDF环境搭建(虚拟机Linux环境下)

哔站“宸芯IOT”视频链接 一、课程内容介绍 1.什么是ESP32 ESP32是集成2.4GHz Wi-Fi和蓝牙双模的单芯片方案,具有超高的射频性能、稳定性、通用性和可靠性,以及超低的功耗,满足不同的功耗需求,适用于各种应用场景。ESP32是ESP8…...

Linux系统移植篇(十一)Linux 内核启动流程

要分析 Linux 启动流程,同样需要先编译一下 Linux 源码,因为有很多文件是需要编译才 会生成的。首先分析 Linux 内核的连接脚本文件 arch/arm/kernel/vmlinux.lds,通过链接脚本可以 找到 Linux 内核的第一行程序是从哪里执行的。vmlinux.lds …...

React19源码系列之Hooks(useId)

useId的介绍 https://zh-hans.react.dev/reference/react/useId useId 是 React 18 引入的一个新 Hook,主要用于生成全局唯一的 ID。在开发中,我们经常需要为元素(如表单元素、模态框等)生成唯一 ID,以便在 JavaScri…...