详解架构模式的六种事件驱动

6 种事件驱动的架构模式 在过去一年里,我一直是数据流团队的一员,负责Wix事件驱动的消息传递基础设施(基于 Kafka)。有超过 1400 个微服务使用这个基础设施。在此期间,我实现或目睹了事件驱动消息传递设计的几个关键模式,这些模式有助于创建一个健壮的分布式系统,该系统可以轻松地处理不断增长的流量和存储需求。 1.消费与投影 针对那些使用非常广泛、已经成为瓶颈的服务 当有遗留服务存储着大型域对象的数据,这些数据使用又非常广泛,使得该遗留服务成为瓶颈时,此模式可以提供帮助。 在 Wix,我们的 MetaSite 阅读详情

在过去一段时间里,一直是数据流团队的一员,负责 Wix 事件驱动的消息传递基础设施(基于 Kafka)。有超过 1400 个微服务使用这个基础设施。在此期间,我实现或目睹了事件驱动消息传递设计的几个关键模式,这些模式有助于创建一个健壮的分布式系统,该系统可以轻松地处理不断增长的流量和存储需求。

1、消费与投影

针对那些使用非常广泛、已经成为瓶颈的服务

当有遗留服务存储着大型域对象的数据,这些数据使用又非常广泛,使得该遗留服务成为瓶颈时,此模式可以提供帮助。

在 Wix,我们的 MetaSite 服务就面临着这样的情况,它为 Wix 用户创建的每个站点保存了大量的元数据,比如站点版本、站点所有者以及站点上安装了哪些应用程序——已安装应用上下文(The Installed Apps Context.)。

这些信息对于 Wix 的许多其他微服务(团队)很有价值,比如 Wix Stores、Wix booking、Wix Restaurants 等等。这个服务被超过 100 万 RPM 的请求轰炸,它们需要获取站点元数据的不同部分。

从服务的各种 API 可以明显看出,它处理了客户端服务的太多不同的关注点。

​MetaSite 服务处理大约 1M RPM 的各类请求

我们想要回答的问题是,如何以最终一致的方式将读请求从该服务转移出来?

使用 Kafka 创建“物化视图”

负责这项服务的团队决定另外创建一个服务,只处理 MetaSite 的一个关注点——来自客户端服务的“已安装应用上下文”请求。

  • 首先,他们将所有数据库的站点元数据对象以流的方式传输到 Kafka 主题中,包括新站点创建和站点更新。一致性可以通过在 Kafka Consumer 中进行 DB 插入来实现,或者通过使用 CDC 产品(如 Debezium)来实现。

  • 其次,他们创建了一个有自己数据库的“只写”服务(反向查找写入器),该服务使用站点元数据对象,但只获取已安装应用上下文并写入数据库。即将站点元数据的某个“视图”(已安装的应用程序)投影到数据库中。

​已安装应用上下文消费与投影

  • 第三,他们创建了一个“只读”服务,只接受与已安装应用上下文相关的请求,通过查询存储着“已安装应用程序”视图的数据库来满足请求。

​读写分离

效果

  • 通过将数据以流的方式传输到 Kafka,MetaSite 服务完全同数据消费者解耦,这大大降低了服务和 DB 的负载。

  • 通过消费来自 Kafka 的数据,并为特定的上下文创建一个“物化视图”,反向查找写入器服务能够创建一个最终一致的数据投影,大幅优化了客户端服务的查询需求。

  • 将读服务与写服务分开,可以方便地扩展只读 DB 副本和服务实例的数量,这些实例可以处理来自全球多个数据中心的不断增长的查询负载。

2、端到端事件驱动

针对简单业务流程的状态更新

请求 - 应答模型在浏览器 - 服务器交互中特别常见。借助 Kafka 和 WebSocket,我们就有了一个完整的事件流驱动,包括浏览器 - 服务器交互。

这使得交互过程容错性更好,因为消息在 Kafka 中被持久化,并且可以在服务重启时重新处理。该架构还具有更高的可伸缩性和解耦性,因为状态管理完全从服务中移除,并且不需要对查询进行数据聚合和维护。

考虑一下这种情况,将所有 Wix 用户的联系方式导入 Wix 平台。

这个过程涉及到两个服务:Contacts Jobs 服务处理导入请求并创建导入批处理作业,Contacts Importer 执行实际的格式化并存储联系人(有时借助第三方服务)。

传统的请求 - 应答方法需要浏览器不断轮询导入状态,前端服务需要将状态更新情况保存到数据库表中,并轮询下游服务以获得状态更新。

而使用 Kafka 和 WebSocket 管理者服务,我们可以实现一个完全分布式的事件驱动过程,其中每个服务都是完全独立工作的。

​使用 Kafka 和 WebSocket 的 E2E 事件驱动

首先,浏览器会根据开始导入请求订阅 WebSocket 服务。

它需要提供一个 channel-Id,以便 WebSocket 服务能够将通知路由回正确的浏览器:

​打开 WebSocket 通知“通道”

第二,浏览器需要向 Jobs 服务发送一个 HTTP 请求,联系人信息使用 CSV 格式,并附加 channel-Id,这样 Jobs 服务(和下游服务)就能够向 WebSocket 服务发送通知。注意,HTTP 响应将立即返回,没有任何内容。

第三,Jobs 服务在处理完请求后,会生成并向 Kafka 主题发送作业请求。

​HTTP Import 请求和生成的 Import Job 消息

第四,Contacts Importer** 服务消费来自 Kafka 的作业请求,并执行实际的导入任务。当它完成时,它可以通知 WebSocket 服务作业已经完成,而 WebSocket 服务又通知浏览器。

​工作已消费、已处理和已完成状态通知

效果

  • 使用这种设计,在导入过程的各个阶段通知浏览器变得很简单,而且不需要保持任何状态,也不需要任何轮询。

  • Kafka 的使用使得导入过程更具弹性和可扩展性,因为多个服务可以处理来自同一个原始导入 http 请求的作业。

  • 使用 Kafka 复制,很容易将每个阶段放在最合适的数据中心和地理位置。也许导入器服务需要在谷歌 DC 上,以便可以更快地导入谷歌联系人。

  • WebSocket 服务的传入通知请求也可以生成到 Kafka,然后复制到 WebSocket 服务所在的数据中心。

3、内存 KV 存储

针对 0 延迟数据访问

有时,我们需要动态对应用程序进行持久化配置,但我们不想为它创建一个全面的关系数据库表。

一个选择是用 HBase/Cassandra/DynamoDB 为所有应用创建一个大的宽列存储表,其主键包含标识应用域的前缀(例如“store_taxes_”)。

​这个解决方案效果很好,但是通过网络取值存在无法避免的延迟。它更适合于更大的数据集,而不仅仅是配置数据。

另一种方法是有一个位于内存但同样具有持久性的键 / 值缓存——Redis AOF 提供了这种能力。

Kafka 以压缩主题的形式为键 / 值存储提供了类似的解决方案(保留模型确保键的最新值不会被删除)。

在 Wix,我们将这些压缩主题用作内存中的 kv-store,我们在应用程序启动时加载(消费)来自主题的数据。这有一个 Redis 没有提供的好处,这个主题还可以被其他想要获得更新的用户使用。

订阅和查询

考虑以下用例——两个微服务使用压缩主题来做数据维护:Wix Business Manager(帮助 Wix 网站所有者管理他们的业务)使用一个压缩主题存放支持的国家列表,Wix Bookings(允许安排预约和课程)维护了一个“(Time Zones)”压缩主题。从这些内存 KV 存储中检索值的延迟为 0。

​

各内存 KV 存储以及相应的 Kafka 压缩主题

Wix Bookings 监听“国家(Countries)”主题的更新:

Bookings 消费来自压缩主题 Countries 的更新

当 Wix Business Manager 将另一个国家添加到“国家”主题时,Wix Bookings 会消费此更新,并自动为“时区”主题添加一个新的时区。现在,内存 KV 存储中的“时区”也通过更新增加了新的时区:

​South Sudan 的时区被加入压缩主题

我们没有在这里停下来。Wix Events(供 Wix Users 管理事件传票和 RSVP)也可以使用 Bookings 的时区主题,并在一个国家因为夏令时更改时区时自动更新其内存 kv-store。

​两个内存 KV 存储消费同一个压缩主题

4、调度并遗忘

当存在需要确保计划事件最终被处理的需求时

在许多情况下,需要 Wix 微服务根据某个计划执行作业。

Wix Payments Subscriptions 服务就是一个例子,它管理基于订阅的支付(例如瑜伽课程的订阅)。

对于每个月度或年度订阅用户,必须通过支付提供程序完成续订过程。

为此,Wix 自定义的 Job Scheduler 服务调用由 Payments Subscription 服务预先配置好的 REST 端点。

订阅续期过程在后台进行,不需要(人类)用户参与。这就是为什么最终可以成功续订很重要,即使临时有错误——例如第三支付提供程序不可用。

要确保这一过程是完全弹性的,一种方法是由作业调度器重复请求 Payment Subscriptions 服务(续订的当前状态保存在数据库中),对每个到期但尚未续期的订阅进行轮询。这将需要数据库上的悲观 / 乐观锁定,因为同一用户同一时间可能有多个订阅续期请求(来自两个单独的正在进行的请求)。

更好的方法是首先生成 Kafka 请求。为什么?因为请求的处理将由 Kafka 的消费者顺序完成(对于每个特定的用户),所以不需要并行工作的同步机制。

​此外,一旦消息生成并发送到 Kafka,我们就可以通过引入消费者重试来确保它最终会被成功处理。由于有这些重试,请求调度的频率可能就会低很多。

在这种情况下,我们希望可以保持处理顺序,这样重试逻辑可以在两次尝试之间(以“指数退避”间隔进行)简单地休眠。

​Wix 开发人员使用我们自定义的 Greyhound 消费者,因此,他们只需指定一个 BlockingPolicy,并根据需要指定适当的重试间隔。

在某些情况下,消费者和生产者之间可能会产生延迟,如长时间持续出错。在这些情况下,有一个特殊的仪表板用于解除阻塞,并跳过开发人员可以使用的消息。

如果消息处理顺序不是强制性的,那么 Greyhound 中还有一个使用“重试主题”的非阻塞重试策略。

​当配置重试策略时,Greyhound 消费者将创建与用户定义的重试间隔一样多的重试主题。内置的重试生成器将在出错时生成一条下一个重试主题的消息,该消息带有一个自定义头,指定在下一次调用处理程序代码之前应该延迟多少时间。

还有一个死信队列,用于重试次数耗尽的情况。在这种情况下,消息被放在死信队列中,由开发人员手动审查。

这种重试机制是受 Uber 这篇文章的启发。

https://eng.uber.com/reliable-reprocessing/

Wix 最近开放了 Greyhound 的源代码,不久将提供给测试用户。要了解更多信息,可以阅读 GitHub 上的自述文件。

https://github.com/wix/greyhound#greyhound

总结:

  • Kafka 允许按顺序处理每个键的请求(例如使用 userId 进行续订),简化工作进程逻辑;

  • 由于 Kafka 重试策略的实现大大提高了容错能力,续期请求的作业调度频率大大降低。

5、事务中的事件

当幂等性很难实现时

考虑下面这个典型的电子商务流程。

Payments 服务生成一个 Order Purchase Completed 事件到 Kafka。现在,Checkout 服务将消费此消息,并生成自己的 Order Checkout Completed 消息,其中包含购物车中的所有商品。

然后,所有下游服务(Delivery、Inventory 和 Invoices)将消费该消息并继续处理(分别准备发货、更新库存和创建发票)。

​如果下游服务可以假设 Order Checkout Completed 事件只由 Checkout 服务生成一次,则此事件驱动流的实现会简单很多。

为什么?因为多次处理相同的 Checkout Completed 事件可能导致多次发货或库存错误。为了防止下游服务出现这种情况,它们将需要存储去重后的状态,例如,轮询一些存储以确保它们以前没有处理过这个 Order Id。

通常,这是通过常见的数据库一致性策略实现的,如悲观锁定和乐观锁定。

幸运的是,Kafka 为这种流水线事件流提供了一个解决方案,每个事件只处理一次,即使当一个服务有一个消费者 - 生产者对(例如 Checkout),它消费一条消息,并产生一条新消息。

简而言之,当 Checkout 服务处理传入的 Payment Completed 事件时,它需要将 Checkout Completed 事件的发送过程封装在一个生产者事务中,它还需要发送消息偏移量(使 Kafka 代理能够跟踪重复的消息)。

事务期间生成的任何消息将仅在事务完成后才对下游消费者(Inventory Service)可见。

​此外,位于 Kafka 流开始位置的 Payment Service Producer 必须转变为幂等(Idempotent)生产者——这意味着代理将丢弃它生成的任何重复消息。

​

要了解更多信息,请观看视频“Kafka 中的恰好一次语义”。

https://www.youtube.com/watch?v=7O_UC_i1XY0

6、事件聚合

当你想知道整个批次的事件已经被消费时

在上半部分,我描述了在 Wix 将联系人导入到 Wix CRM 平台的业务流程。后端包括两个服务。一个是作业服务,我们提供一个 CSV 文件,它会生成作业事件到 Kafka。还有一个联系人导入服务,它会消费并执行导入作业。

​假设 CSV 文件有时非常大,将工作负载分割成更小的作业,每个作业中需要导入的联系人就会更少,这个过程就会更高效。通过这种方式,这项工作可以在 Contacts Importer 服务的多个实例中并行。但是,当导入工作被拆分为许多较小的作业时,该如何知道何时通知最终用户所有的联系人都已导入?

​显然,已完成作业的当前状态需要持久化,否则,内存中哪些作业已完成的记录可能会因为随机的 Kubernetes pod 重启而丢失。

一种在 Kafka 中进行持久化的方法是使用 Kafka 压缩主题。这类主题可以看成是一种流式 KV 存储。

在我们的示例中,Contacts Importer 服务(在多个实例中)通过索引消费作业。每当它处理完一些作业,就需要用一个 Job Completed 事件更新 KV 存储。这些更新可以同时发生,因此,可能会出现竞态条件并导致作业完成计数器失效。

原子 KV 存储

为了避免竞态条件,Contacts Importer 服务将完成事件写到原子 KV 存储类型的 Jobs-Completed-Store 中。

原子存储确保所有作业完成事件将按顺序处理。它通过创建一个“Commands”主题和一个“Store”压缩主题来实现。

顺序处理

从下图可以看出,原子存储如何生成每一条新的 Import-job-completed“更新”消息,并以 [Import Request Id]+[total job count] 作为键。借助键,我们就可以总是依赖 Kafka 将特定 requestId 的“更新”放在特定的分区中。

接下来,作为原子存储的一部分,消费者 - 生产者对将首先侦听每个新的更新,然后执行 atomicStore 用户请求的“命令”——在本例中,将已完成作业数量的值加 1。

​端到端更新流示例

让我们回到 Contacts Importer 服务流。一旦这个服务实例完成了某些作业的处理,它将更新 Job-Completed KVAtomicStore(例如,请求 Id 为 YYY 的导入作业 3 已经完成):

Atomic Store 将生成一条新消息到 job-completed-commands 主题,键为 YYY-6,值为 Job 3 Completed。

接下来,Atomic Store 的消费者 - 生产者对将消费此消息,并增加 KV Store 主题中键 YYY-6 的已完成作业计数。

​恰好一次处理

注意,“命令”请求处理必须只发生一次,否则完成计数器可能不正确(错误增量)。为消费者 - 生产者对创建一个 Kafka 事务(如上文的模式 4 所述)对于确保统计准确至关重要。

AtomicKVStore 值更新回调

最后,一旦 KV 最新生成的已完成作业计数的值与总数匹配(例如 YYY 导入请求有 6 个已完成作业),就可以通知用户(通过 WebSocket,参见本系列文章第一部分的模式 3)导入完成。通知可以作为 KV-store 主题生成动作的副作用,即调用用户提供给 KV 原子存储的回调。

​注意事项:

  • 完成通知逻辑不一定要在 Contacts Importer 服务中,它可以在任何微服务中,因为这个逻辑完全独立于这个过程的其他部分,只依赖于 Kafka 主题。

  • 不需要进行定期轮询。整个过程都是事件驱动的,即以管道方式处理事件。

  • 通过使用基于键的排序和恰好一次的 Kafka 事务,避免作业完成通知或重复更新之间的竞态条件。

  • Kafka Streams API 非常适合这样的聚合需求,其特性包括 groupBy(按 Import Request Id 分组), reduce 或 count(已完成作业计数)和 filter (count 等于总作业数),然后是副作用 Webhook 通知。对于 Wix 来说,使用现有的生产者 / 消费者基础设施更有意义,这对我们的微服务拓扑影响更小。

7、总结

这里的一些模式比其他的模式更为常见,但它们都有相同的原则。通过使用事件驱动的模式,可以减少样板代码(以及轮询和锁定原语),增加弹性(减少级联失败,处理更多的错误和边缘情况)。此外,微服务之间的耦合要小得多(生产者不需要知道谁消费了它的数据),扩展也更容易,向主题添加更多分区(和更多服务实例)即可。

架构范式一 - 事件驱动架构(EDA) EDA 是一种基于发布/订阅模式的消息异步通信的架构,你可以把它理解为架构层面的观察者模式,它主要分为以下7个核心对象。 大致流程为:第一,因为它是异步的,因此特别适合以下:第二,如果业务模式的整个主流程不强调强一致性且流程变化很快的,则可以适当的考虑这种架构。第三、因为它是通过管道进行异步通信,如果你的系统是那些对交易实时性要求较高的或者是跟2C端页面交互强关联的,则不太建议使用该异步架构。... 阅读详情

相关推荐

谈谈基于Kafka的六种微服务架构事件驱动模式

在过去的一年里,我一直是负责Wix的事件驱动消息基础设施(基于Kafka之上)的数据流团队的一员。该基础设施被 1400 多个微服务使用。 在此期间,我已经实现或目睹了事件驱动消息传递设计的几个关键模式的实现,这些模式有助于创建一个健壮的分布式系统,可以轻松处理不断增长的流量和存储需求。

Java_LingFeng的博客 495

事件驱动架构

事件驱动的微服务架构是一种现代架构模式,它将微服务架构和事件驱动架构结合在一起,提供了异步通信、完全解耦和灵活性、可靠性和可扩展性等优势。使用事件驱动的微服务架构,可以轻松创建对任何系统事件做出反应的服务,并创建包括一些手动操作的半自动管道。随着实时事件数据和云服务使用的需求增加,许多现代应用程序,如Netflix和Lyft,已经转向了事件驱动的微服务方法。微服务架构将应用程序进程分组为单独的服务,使用轻量级协议进行交互,提供了改进的模块化和更好的应用程序可维护性和弹性。使用事件驱动的微服务。

Baron_ND的博客 1885

Spring循环依赖原理与六种解决方案详解

循环依赖是软件开发中常见的架构问题,指两个或多个组件相互直接依赖形成的闭环。在Spring框架中,这种问题会破坏IoC容器的正常初始化流程,导致BeanCurrentlyInCreationException等运行时异常。通过三级缓存机制,Spring可以处理setter注入的循环依赖,但构造器注入场景仍需开发者主动规避。从技术价值看,解决循环依赖能提升系统稳定性,避免NPE等隐蔽错误。典型应用场景包括电商系统中的订单-库存服务交互、支付-通知服务联动等。本文重点解析的@Lazy注解和接口抽离方案,配合JM

weixin_32576389的博客 196

事件驱动

事件驱动的理解: 1.要理解事件驱动和程序,就需要与非事件驱动的程序进行比较。实际上,现代的程序大多是事件驱动的,比如多线程的程序,肯定是事件驱动的。早期则存在许多非事件驱动的程序,这样的程序,在需要等待某个条件触发时,会不断地检查这个条件,直到条件满足,这是很浪费cpu时间的。而事件驱动的程序,则有机会释放cpu从而进入睡眠态(注意是有机会,当然程序也可自行决定不释放cpu),当事件触发时被操作系统唤醒,这样就能更加有效地使用cpu. 2.再说什么是事件驱动的程序。一个典型的事件驱动的程序,就是一个死循环

qq_20034655的博客 4891

六种重要的软件架构模式总结

六种重要的软件架构模式总结

LifeIsGood 289

LabWindows/CVI调用外部程序六种方法详解与实战

在Windows平台上,进程创建与通信是系统编程的基础技术,涉及CreateProcess、管道重定向等核心机制。通过匿名管道实现标准输入输出的重定向,能够有效捕获子进程输出并实现双向交互,这是构建自动化工具链的关键。在工业测控领域,LabWindows/CVI上位机常需集成外部可执行文件,如数据采集程序或算法模块。针对这一需求,六种调用方法从简单的system()到复杂的CreateProcess加管道,提供了不同粒度的控制力,涵盖隐藏窗口、超时等待和输出捕获等场景,帮助开发者高效实现进程间通信与集成。

weixin_29179311的博客 146

事件驱动设计模式

是一种常见的设计模式,其核心思想是:系统中发生的事件会触发相应的事件处理器或监听器,从而实现特定的业务逻辑或功能事件驱动架构是一种常见的软件设计架构,它包括多个组件之间的事件交互。在事件驱动的架构中,事件是所有通信的中心点,组件通过订阅和发布事件来进行通信。下面是几种常见的事件驱动设计模式:观察者模式(Observer Pattern):观察者模式是一种经典的事件驱动设计模式。在这个模式中,一个被观察者对象(也称为主题)会维护一组观察者对象,当主题发生变化时,会通知所有观察者对象进行更新。

loserbai的博客 3182

【Aseprite】制作Unity2D瓦片地图素材(平台游戏)

本文章用于记录用Aseprite软件制作2D平台游戏的瓦片地图的方法。

凡心所向,素履以往 5549

基于Kafka的六种事件驱动的微服务架构模式

在过去的一年里,我一直是负责Wix的事件驱动消息基础设施(基于Kafka之上)的数据流团队的一员。该基础设施被 1400 多个微服务使用。在此期间,我已经实现或目睹了事件驱动消息传递设计的几个关键模式的实现,这些模式有助于创建一个健壮的分布式系统,可以轻松处理不断增长的流量和存储需求。一、消费与投射…那些非常受欢迎的服务会成为瓶颈当您遇到存储大型领域对象的“流行”数据的瓶颈时,此模式可以提供帮助。...

大数据星球-浪尖 476

别再手动续期SSL证书了!用acme.sh配合阿里云DNS API,实现全自动HTTPS证书管理

本文详细介绍了如何使用acme.sh配合阿里云DNS API实现SSL/TLS证书的全自动管理,彻底解决手动续期带来的风险与不便。通过自动化部署流程,包括环境准备、API集成、多域名证书申请等关键步骤,帮助运维人员构建高效、可靠的HTTPS证书管理体系,显著提升安全性和运维效率。

weixin_29200485的博客 271

静态与动态LACP链路聚合:原理、配置与排错实战指南

链路聚合技术是提升网络带宽与可靠性的核心方案,通过将多个物理端口逻辑捆绑,实现带宽叠加与链路冗余。其原理基于IEEE 802.3ad标准,通过负载均衡算法将数据流分布到不同物理链路,既避免了数据包乱序,又提升了整体吞吐量。该技术的核心价值在于消除单端口瓶颈、提供毫秒级故障切换,并能简化网络拓扑管理。在企业服务器接入、数据中心互联及虚拟化平台等场景中,链路聚合已成为构建高可用网络的基础。实践中,动态LACP模式通过协议报文协商,能主动检测链路故障并防止配置错误导致的网络环路,相比静态聚合更为可靠。本文将深入解

weixin_31412781的博客 270

常用架构模式

常见架构模式

YZJincsdn的博客 1029

EMC测试案例分析——晶振对辐射发射的影响

本文分析了某产品350MHz辐射发射超标问题,发现源头是50MHz晶振的7次谐波通过连接器泄漏。主要原因是:1)防水非导电垫圈形成屏蔽缝隙;2)晶振下方地平面不完整且信号线穿过;3)晶振离接口过近。改进措施包括:完善晶振下方地平面、增大晶振与接口距离、使用导电密封圈等。最终辐射降低10dB以上达标。文章总结了晶振EMC设计要点:保持地平面完整、远离接口、外壳接地、合理布局滤波电路等,并强调防水与屏蔽的协调统一。

u012526819的博客 670

解锁软件构建的艺术:六种架构模式的解析

本教程提供了对六种主要软件架构的深入理解,包括它们的特点、优势、选择条件、应用场景以及相应的开发框架、设计模式和算法。通过实际案例,展示了每种架构在现实世界中的应用,帮助您根据项目需求选择最合适的架构和技术栈。• 优势:允许团队专注于特定功能层,易于维护和扩展。• 用途:适用于企业级应用,通过分层(表现层、业务层、持久层)提高代码的可读性和可维护性。• 优势:核心功能保持不变,通过插件添加新功能,适应不断变化的开发需求。• 优势:服务独立部署和扩展,如独立扩展消息推送服务,不影响其他服务。

进击的Blazor 1258

鸿蒙OS开机动画背后的秘密:从代码到视觉的完整解析(附源码分析)

本文深入解析了鸿蒙OS开机动画的系统级实现原理。从bootanimation服务的启动配置、与Render Service的协同,到基于VSync信号的帧率同步与绘制流水线,结合OpenHarmony源码进行了逐行解读。文章揭示了其事件驱动的优雅退出机制,并探讨了视频支持、多屏适配等高级特性与定制化可能,为开发者理解鸿蒙图形子系统提供了硬核技术视角。

sony5的博客 976

PHP项目实战:易宝支付SDK对接全流程(含回调处理与常见问题排查)

本文详细介绍了PHP项目中易宝支付SDK的对接全流程,包括环境准备、SDK配置、支付请求构建与发起、回调处理实战以及常见问题排查。特别针对回调处理环节的常见问题提供了解决方案,帮助开发者快速完成支付对接并优化性能。

weixin_29007809的博客 388

六种最关键的架构模式

有许多广泛使用的架构模式。然而,其中六种非常常见且关键,这并非偶然。以下是这些模式,为什么你应该使用它们,以及何时使用它们。1.模型-视图-控制器(MVC)。这是最早采用并广泛使用的架构模式之一。其主要目标是将应用程序的数据、用户界面和控制逻辑分离为三个相互连接的组件。模型管理数据和逻辑,视图显示信息,控制器连接模型和视图,处理用户输入。使用场景:适用于具有明确数据处理和UI分离的Web应用程序...

小技术君 473

通达信+大智慧数据同步存调DLL

数据同步存调DLL(通达信版+大智慧版)

guleba的博客 2062

微服务架构的六种常用设计模式

服务拆分模式:解决单体应用的复杂性。API网关模式:统一管理服务入口和横切关注点。服务发现模式:支持动态服务调用。熔断器模式:提高系统的容错能力。事件驱动模式:实现服务间的异步通信。数据管理模式:确保数据的独立性和一致性。在实际应用中,通常需要结合多种设计模式来构建健壮、可扩展的微服务系统。同时,选择合适的技术栈和工具(如Spring Cloud、Kubernetes)也是成功实施微服务架构的关键。

LiuYuHao_的博客 1220

当C#遇见声音魔法:从麦克风到文字的0.1秒奇幻漂流

为什么选300Hz?因为人声基频通常在85-255Hz,但清脆的“啊”可能到2kHz,所以300Hz是安全区!(参考知识库[1])

墨夶的博客 366

贝叶斯统计 [韦来生编]

贝叶斯(Bayes)统计是近几十年来迅速发展起来的数理统计的一个重要分支。贝叶斯方法与经典统计方法的主要不同之处是进行统计推断时除了利用样本信息外,还要利用参数的先验信息,因此可以提高统计推断或统计决策的效果。它在经济、金融、生物、医学、自然科学和社会科学等许多领域具有广泛的应用。贝叶斯方法的研究已渗透到了统计学的几乎所有领域。作者在给中国科学技术大学概率论与数理统计专业本科生开设的“数理统计”课程中有一章专门讲授“贝叶斯方法和统计决策理论”,近十年来也给中国科学技术大学概率统计专业研究生开设过几次“贝叶斯分析”课。本书是在对过去讲稿的内容作了适当的增减和调整的基础上完成的。  本书共分六章。第1章是绪论,介绍了贝叶斯统计的若干基本概念,同时对必要的数理统计的基础知识有重点地作了回顾。第二章介绍了确定先验分布的若干可供选择的方法。第三章介绍了几类常见统计模型参数的后验分布的主要结果和计算方法。第四章和第五章分别介绍了“贝叶斯统计推断”和“贝叶斯统计决策”的内容。第六章介绍了贝叶斯统计计算的若干方法,包括蒙特卡洛方法和马尔可夫链蒙特卡洛(MCMC)方法以及相关统计软件的简介。本书的每一章附右大量的例题和习题,书末附有常用的几个表格和部分习题解答供读者查用。  大约可在54学时内讲授本书的第1章至第六章的主要内容,教师可根据学时需要选讲本书第1章至第六章的部分内容。书中标“*”号的章节可略去不讲,留给读者作为阅读材料。第六章例题中的R代码和部分例题的数据文件等可从作者个人主页下载。  作者在编写本书的过程中参考了J.O.Berger教授的《统计决策论及贝叶斯分析》和茆诗松教授编写的《贝叶斯统计》等书中的一些内容,以及《贝叶斯分析》一书中由张伟平博士编写的有关贝叶斯统计计算的一些内容。在此表示衷心感谢。  本书编写准备过程中,中国科学技术大学统计与金融系的几个研究生帮助完成了本书部分中文的录入和排版,作者对他们的辛勤工作表示真诚的感谢。高等教育出版社为本书的出版给予了大力支持。在此一并致谢。

WSO2技术栈解决方案架构模式解析

本文基于solution-architecture-patterns项目中针对WSO2技术栈的架构模式进行深入解析。WSO2作为企业级开源中间件平台,提供了完整的API管理、身份认证、应用集成等解决方案。该项目系统地整理了基于WSO2组件的各类架构模式,为开发者提供了宝贵的参考。 ## 身份认证与访问管理模式 WSO2 Identity Server是业界领先的身份认证解决方案,项目提供了以下...

gitblog_00876的博客 563

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

详解前端异步编程的六种方案

前言我们知道Javascript语言的执行环境是\u0026quot;单线程\u0026quot;。也就是指一次只能完成一件任务。如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务。这种模式虽然实现起来比较简单,执行环境相对单纯,但是只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。常见的浏览器无响应(假死),往往就是因为某一段Javascript代码长时间运行...

weixin_34358365的博客 180

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

异步编程的六种方法

异步编程的六种方法 前言 异步编程:非阻塞模式。异步是指进程不需要一直等下去,而是继续执行下面的操作,不用管其他进程的状态。当有信息返回时,系统会通知进程进行处理,这样可以提高执行的效率。 异步编程的六种方法如下: 一、回调函数 这是异步编程最基本的方法。 假如有两个函数f1和f2。,后者等待前者的执行结果。如果f1是一个很耗时的任务,可以考虑改写f1,把f2写成f1的回调函数。 function f1(callback){     setTimeout(function () {       //

weixin_44480652的博客 5135

AI应用架构设计实战:六种常见架构模式与图解方法论

大模型正在加速渗透到各行业的应用开发中,从智能客服到知识库问答,技术团队普遍面临同一个问题:如何将模糊的业务需求转化为清晰、可落地、可演进的AI应用架构。任何系统的稳健运行都建立在逻辑分层与模块边界清晰的基础上,AI应用同样遵循这一原则。一个成熟的架构通常可从接入、编排、模型、数据四个层次展开,再结合具体业务场景裁剪为直连网关、按需代理、复杂工作流、RAG增强生成、事件驱动异步、混合并行等适配形态。其中,RAG与多智能体协作是当前最受关注的技术方向,前者强调检索与生成的高效配合,后者考验并发调度与状态管理能

weixin_29042035的博客 252
上一篇: 带你认识什么是redis主从复制集群的原理和部署
下一篇: SpringBoot中如何实现业务校验,这种方式才叫优雅!
Java_LingFeng
博客等级 码龄4年 505粉丝 259原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值