Dubbo分层架构深度解析
引言
Dubbo作为一款备受欢迎的高性能、轻量级的Java RPC框架,在现代分布式系统中扮演着至关重要的角色。随着互联网行业的快速发展,服务间的通信变得越来越频繁,这也使得对于高效、可靠的远程通信方案的需求变得愈发迫切。在这样的背景下,Dubbo以其优异的性能表现和丰富的特性成为了众多企业和开发者的首选。
在本文中,我们将聚焦于Dubbo的分层架构,深入解析其内部结构和工作原理。通过对Dubbo架构的剖析,读者将能够更清晰地理解Dubbo是如何实现高性能、可扩展的RPC通信的。本文旨在为读者提供一个全面、系统的Dubbo架构导览,帮助他们更好地应用Dubbo构建稳健、高效的分布式系统。
首先,我们将介绍Dubbo的背景和优势,让读者对Dubbo有一个初步的了解。然后,我们将逐层深入,从服务层到配置层,逐一解释Dubbo各个层次的设计原理和功能特点。最后,我们将对Dubbo分层架构进行总结,并展望其在实现高效、稳定的服务治理方面的价值。
通过本文的阅读,读者将能够对Dubbo的内部机制有一个全面而深入的认识,从而更加灵活地运用Dubbo解决实际的分布式系统通信问题。
Dubbo的基本概念
在深入探讨Dubbo的分层架构之前,让我们先来了解一些Dubbo的基本概念,这些概念是理解Dubbo框架的基础。
RPC(远程过程调用)
RPC是指远程过程调用,是一种计算机通信协议。在分布式系统中,RPC允许一个程序调用另一个程序中的函数或方法,而不需要程序员显式地处理远程通信。Dubbo就是基于RPC协议实现的,它让分布式系统中的各个服务之间能够方便地进行通信。
服务提供者(Provider)
服务提供者是指提供某种服务的应用程序,它将自己的服务注册到注册中心,等待消费者的调用。在Dubbo中,服务提供者将自己提供的服务以接口的形式暴露出来,并通过Dubbo框架来管理和暴露这些服务。
服务消费者(Consumer)
服务消费者是指需要调用某种服务的应用程序,它通过Dubbo框架从注册中心获取服务提供者的地址,并发起远程调用以访问服务。服务消费者在Dubbo中使用远程服务的方式就像调用本地方法一样简单。
注册中心
注册中心是Dubbo架构中的一个重要组件,用于管理服务提供者和服务消费者之间的关系。服务提供者会将自己的地址和提供的服务注册到注册中心,而服务消费者则可以从注册中心获取到服务提供者的地址信息,从而实现服务的调用和发现。
这些基本概念构成了Dubbo框架的核心,理解了这些概念后,我们可以更深入地探讨Dubbo的分层架构及其工作原理。
Dubbo分层架构概览
Dubbo框架采用了一种分层的架构设计,每个层次都有清晰的职责划分,从而使得整个框架具备高度的可扩展性和灵活性。下面我们来简要介绍Dubbo的分层架构,为读者呈现一个整体的框架图。
1. 服务层(Service Layer)
服务层是Dubbo架构的基础,它负责管理服务提供者和服务消费者之间的通信。在这一层中,Dubbo通过定义接口的方式将服务提供者的功能暴露给服务消费者,从而实现远程调用的透明化。
2. 集群层(Cluster Layer)
集群层主要负责处理集群中多个服务提供者的情况。Dubbo支持多种负载均衡策略,以及容错机制,通过这些机制可以有效地管理集群中的服务提供者,保证服务的高可用性和稳定性。
3. 注册中心层(Registry Layer)
注册中心层用于服务的注册和发现,它是Dubbo架构中的核心组件之一。在这一层中,服务提供者会将自己的地址和提供的服务注册到注册中心,而服务消费者则可以从注册中心获取到服务提供者的地址信息,从而实现服务的调用和发现。
4. 协议层(Protocol Layer)
协议层定义了Dubbo框架支持的各种通信协议,包括Dubbo协议、HTTP协议、RMI协议等。每种协议都有自己的特点和适用场景,开发者可以根据实际需求选择合适的协议来进行通信。
5. 传输层(Transport Layer)
传输层负责处理底层的网络通信,Dubbo框架采用了Netty作为默认的网络通信框架,它提供了高性能、异步的网络通信能力,能够满足Dubbo对于网络通信的高要求。
6. 数据序列化层(Serialization Layer)
数据序列化层负责将Java对象序列化为字节流进行网络传输,以及将接收到的字节流反序列化为Java对象。Dubbo支持多种序列化框架,包括Java原生的序列化、Hessian、JSON等,开发者可以根据实际需求选择合适的序列化方式。
7. 配置层(Config Layer)
配置层用于管理Dubbo框架的各种配置信息,包括服务的暴露、引用、负载均衡策略、容错机制等。Dubbo支持多种配置方式,包括XML配置、注解配置和API配置,开发者可以根据实际情况选择最合适的配置方式。
通过以上分层架构的设计,Dubbo框架能够很好地解耦各个功能模块,使得每个模块都能够独立演化,从而实现了高度的可扩展性和灵活性。在后续的章节中,我们将逐层深入,详细探讨Dubbo框架各个层次的设计原理和工作机制。
服务层(Service Layer)
服务层是Dubbo架构中的基础层,负责管理服务的提供和消费。在分布式系统中,服务的提供和消费是其核心功能之一,而Dubbo通过服务层来实现这一重要功能。
服务提供者(Provider)
服务提供者是指提供具体服务实现的应用程序,它将自己的服务通过Dubbo框架暴露给其他应用程序使用。在Dubbo中,服务提供者需要做以下工作:
- 实现服务接口:服务提供者需要编写具体的服务实现类,并实现服务接口中定义的方法。
- 暴露服务:服务提供者通过Dubbo框架将自己提供的服务暴露出去,让其他应用程序可以远程调用。
- 配置服务:服务提供者可以通过配置文件或注解等方式,配置服务的相关信息,如服务端口、超时时间等。
服务提供者通过以上步骤,将自己的服务注册到注册中心,并等待其他应用程序的调用请求。
服务消费者(Consumer)
服务消费者是指需要调用服务的应用程序,它通过Dubbo框架从注册中心获取服务提供者的地址,并发起远程调用以访问服务。在Dubbo中,服务消费者需要做以下工作:
- 引用服务:服务消费者通过Dubbo框架引用需要调用的远程服务,获取服务接口的代理对象。
- 调用服务:通过服务接口的代理对象,服务消费者可以像调用本地方法一样调用远程服务的方法。
- 配置服务:服务消费者也可以通过配置文件或注解等方式,配置引用的服务的相关信息,如服务的地址、超时时间等。
服务消费者通过以上步骤,从注册中心获取服务提供者的地址信息,并发起远程调用以访问服务,从而实现了分布式系统中的服务调用功能。
服务层是Dubbo架构中的核心层之一,它为分布式系统中的服务提供和消费提供了基础支持,是整个Dubbo框架的重要组成部分。
集群层(Cluster Layer)
集群层是Dubbo架构中的重要组成部分,负责处理集群中多个服务提供者的情况,以及保证服务的高可用性和稳定性。在分布式系统中,单个服务提供者的容量可能无法满足整个系统的需求,因此需要通过集群来提供更大的服务容量和更高的可靠性。
负载均衡
负载均衡是集群层的核心功能之一,它负责将请求合理地分发到集群中的各个服务提供者上,以实现负载均衡。Dubbo框架支持多种负载均衡策略,包括随机负载均衡、轮询负载均衡、最少活跃调用负载均衡等。不同的负载均衡策略适用于不同的场景,开发者可以根据实际情况选择合适的负载均衡策略。
容错机制
容错机制是集群层的另一个重要功能,它负责处理由于网络故障、服务提供者故障等原因导致的服务调用失败情况。Dubbo框架通过采用多种容错机制来保证服务的高可用性,包括失败自动切换、失败重试、失败安全等。这些容错机制能够有效地处理各种异常情况,保证了服务的稳定性和可靠性。
在集群层中,负载均衡和容错机制是密切相关的,它们共同工作以保证集群中的服务能够按照预期的方式运行。通过合理地配置负载均衡策略和容错机制,可以有效地提高服务的性能和可用性,从而为用户提供更好的服务体验。
集群层作为Dubbo架构中的重要组成部分,为分布式系统中的服务提供和消费提供了可靠的基础支持。在后续的章节中,我们将进一步探讨集群层的实现原理和工作机制,以及如何通过合理地配置集群层来提高服务的性能和可用性。
注册中心层(Registry Layer)
注册中心是Dubbo架构中的关键组件之一,负责服务的注册与发现。在分布式系统中,服务的提供者和消费者可能存在于不同的节点上,因此需要一个统一的地方来管理服务的注册和查找。注册中心正是为了解决这个问题而存在的。
服务注册与发现
服务注册:当服务提供者启动时,它会向注册中心注册自己提供的服务,并提供自己的网络地址和其他相关信息。注册中心会将这些信息保存起来,以便服务消费者查询。
服务发现:当服务消费者需要调用某个服务时,它会向注册中心查询该服务的地址信息。注册中心会返回一个或多个服务提供者的地址列表给消费者,消费者再根据负载均衡策略选择其中一个地址发起调用。
Dubbo框架支持多种注册中心的实现,包括Zookeeper、Redis、Multicast等。不同的注册中心有不同的特点和适用场景,开发者可以根据实际需求选择合适的注册中心来使用。
注册中心的作用类似于黄页服务,它记录了服务的提供者和消费者的地址信息,并提供了查询服务的功能。通过注册中心,服务提供者和消费者可以实现解耦,动态地发现和使用服务,从而实现了分布式系统中的服务治理。
协议层(Protocol Layer)
在Dubbo框架中,协议层负责定义服务调用的规则和格式,以及处理服务调用过程中的通信细节。它是服务提供者和服务消费者之间通信的桥梁,确保它们能够相互理解和协作。
协议支持
Dubbo框架支持多种协议,每种协议都有自己的特点和适用场景。
-
Dubbo协议:Dubbo协议是Dubbo框架的默认协议,它基于TCP长连接,采用自定义的传输格式,具有较高的性能和稳定性。Dubbo协议支持异步调用、单向调用和双向调用等多种调用方式,适用于对性能和稳定性要求较高的场景。
-
RMI协议:RMI(Remote Method Invocation)协议是一种基于Java的远程调用协议,它使用Java序列化技术传输对象,并通过Java远程方法调用机制实现服务调用。RMI协议使用Java标准的远程调用API,适用于Java环境下的服务调用。
-
Hessian协议:Hessian协议是一种基于HTTP的远程调用协议,它使用Hessian序列化技术将对象序列化为字节流,并通过HTTP协议传输。Hessian协议简单易用,支持跨语言调用,适用于网络环境较差或需要与非Java平台进行通信的场景。
-
HTTP协议:HTTP协议是一种基于HTTP的远程调用协议,它使用JSON或XML等通用的数据格式进行数据交换,并通过HTTP协议传输。HTTP协议具有良好的跨平台性和跨语言性,适用于Web服务调用和与其他系统进行集成的场景。
信息交换
在Dubbo框架中,服务提供者和服务消费者之间的信息交换是通过Dubbo协议定义的通信格式进行的。通常情况下,服务提供者会将服务接口的元数据信息注册到注册中心,服务消费者在调用服务时会从注册中心获取服务提供者的地址信息,并通过Dubbo协议发起调用。
在服务调用过程中,Dubbo框架会根据配置的负载均衡策略选择合适的服务提供者,并通过Dubbo协议发送请求。服务提供者接收到请求后,会根据协议定义的规则进行处理,并将调用结果返回给服务消费者。整个调用过程中,Dubbo协议保证了服务提供者和服务消费者之间的通信顺畅和可靠。
在不同的场景下,可以根据实际需求选择合适的协议来进行服务调用。Dubbo框架提供了灵活的配置选项,开发者可以根据具体的业务需求和性能要求来选择最适合的协议,以提供更高效、稳定的服务。
传输层(Transport Layer)
在Dubbo的分层架构中,传输层负责处理网络通信,确保服务提供者和服务消费者之间可以进行可靠的数据传输。
网络通信
Dubbo中主要使用的网络通信框架是Netty。Netty是一个基于Java NIO的网络通信框架,具有高性能、高可靠性和可扩展性的特点。
-
基于NIO的异步通信:Netty采用非阻塞IO模型,利用Java NIO提供的Selector机制实现了异步通信,可以处理大量的并发连接,提高了系统的吞吐量和响应速度。
-
事件驱动的架构:Netty采用了事件驱动的设计模式,所有的I/O操作都是异步的,并通过事件监听器进行处理。这种设计使得Netty具有良好的可扩展性,可以轻松地定制和扩展各种网络应用。
-
高性能的编解码器:Netty提供了一套高性能的编解码器,可以对数据进行快速而灵活的序列化和反序列化操作,支持各种常见的协议和数据格式,如HTTP、WebSocket、TCP等。
在Dubbo中的作用
传输层在Dubbo框架中扮演着至关重要的角色,它负责实现服务提供者和服务消费者之间的数据传输和通信协议。通过使用Netty等高性能的网络通信框架,Dubbo能够在分布式环境下实现高效、稳定的服务调用。
在Dubbo的传输层中,Netty负责处理各种网络通信细节,如连接管理、数据编解码、流量控制等,同时支持多种协议和传输方式,如TCP、UDP、HTTP等,为Dubbo提供了灵活和可靠的网络通信基础。
数据序列化层(Serialization Layer)
在Dubbo中,数据序列化层负责将Java对象转换为字节流或其他格式,以便在网络上传输。这一层的设计旨在提供灵活的序列化方式,使得Dubbo可以支持不同的数据传输协议和数据格式。
序列化框架
Dubbo支持多种序列化框架,包括但不限于:
-
Java原生序列化:Java提供了默认的序列化机制,可以通过实现
java.io.Serializable接口来实现对象的序列化和反序列化。这种方式简单易用,但性能较差,并且不够灵活,不适合在分布式系统中大规模使用。 -
Hessian:Hessian是一种基于二进制的轻量级序列化框架,支持跨语言,性能较Java原生序列化有所提升,但仍然存在一些性能和兼容性方面的问题。
-
JSON:JSON作为一种文本格式的数据交换标准,在Dubbo中也被广泛使用。JSON序列化简单高效,易于阅读和调试,并且与现代Web开发中的RESTful服务很好地契合。
-
Protobuf:Protobuf是Google开发的一种高效的二进制序列化协议,具有良好的性能和跨语言特性。Dubbo通过集成Protobuf,可以实现更高效的数据序列化和传输。
优缺点
不同的序列化框架各有优缺点:
-
性能:性能是选择序列化框架时需要考虑的关键因素之一。一些二进制格式的序列化框架如Protobuf通常比文本格式的序列化框架如JSON和XML具有更好的性能。
-
可读性:对于调试和日志记录来说,序列化后的数据是否易于阅读也是一个重要的考虑因素。JSON等文本格式通常比二进制格式更容易阅读。
-
兼容性:不同的序列化框架可能存在兼容性问题,特别是在跨语言的场景下。因此,选择一个支持良好且广泛使用的序列化框架是很重要的。
-
体积:序列化后的数据大小也是一个需要考虑的因素。一些二进制格式的序列化框架通常可以生成更小的数据包,从而减少网络传输的开销。
在Dubbo中,可以根据具体的业务需求和性能要求选择合适的序列化框架,并通过配置来实现灵活的切换和定制。
配置层(Config Layer)
配置层在Dubbo架构中起着至关重要的作用,它负责管理Dubbo的各种配置信息,包括服务暴露、引用、集群、注册中心、协议、以及各种策略的配置等。
外部配置
-
XML配置:Dubbo最早提供了XML配置方式,通过在XML配置文件中定义各种服务和引用的配置信息,包括接口、版本、超时时间、集群等。XML配置方式简单直观,易于理解和维护,适用于中小型项目。
<dubbo:service interface="com.example.UserService" ref="userService" version="1.0.0"/> <dubbo:reference id="userService" interface="com.example.UserService" version="1.0.0"/> -
注解配置:随着Spring注解的流行,Dubbo也提供了基于注解的配置方式,通过在服务实现类上添加
@Service和@Reference等注解,可以实现对服务的暴露和引用,使得配置更加简洁和灵活。@Service(interfaceClass = com.example.UserService.class, version = "1.0.0") public class UserServiceImpl implements UserService {// Service implementation }@Reference(interfaceClass = com.example.UserService.class, version = "1.0.0") private UserService userService; -
API配置:除了XML和注解配置外,Dubbo还提供了API方式进行配置,通过编程的方式动态配置服务的各种属性,使得配置更加灵活和可控。
ServiceConfig<UserService> serviceConfig = new ServiceConfig<>(); serviceConfig.setInterface(UserService.class); serviceConfig.setRef(userService); serviceConfig.setVersion("1.0.0"); serviceConfig.export();ReferenceConfig<UserService> referenceConfig = new ReferenceConfig<>(); referenceConfig.setInterface(UserService.class); referenceConfig.setVersion("1.0.0"); UserService userService = referenceConfig.get();
服务治理
配置层不仅负责服务的静态配置,还涉及到服务治理的方方面面。服务治理是指对服务进行管理、监控、调度、路由等一系列操作的过程,其核心目标是确保服务的可用性、可靠性和性能。
-
路由规则配置:Dubbo允许通过配置路由规则来控制请求的流向,比如根据IP、版本等条件进行路由,以实现流量控制和灰度发布等功能。
-
动态配置中心:Dubbo提供了与ZooKeeper、Nacos等注册中心集成的方式,可以将配置信息存储在注册中心,实现动态配置的管理和发布,使得配置更加灵活和动态化。
-
负载均衡策略配置:在配置层可以指定服务的负载均衡策略,包括轮询、随机、一致性哈希等,以实现不同的负载均衡方式。
配置层的灵活性和丰富性为Dubbo提供了强大的可扩展性和适应性,使得开发者可以根据具体的需求和场景来定制和配置Dubbo的各项功能,从而实现更加灵活、高效和稳定的服务治理。
总结
Dubbo作为一款高性能、轻量级的Java RPC框架,其分层架构为构建分布式系统提供了坚实的基础和灵活的解决方案。通过对Dubbo分层架构的深度解析,我们可以更好地理解其设计原理和工作机制,从而更加高效地进行系统设计和开发。
在Dubbo的分层架构中,各个层次相互配合、相互独立,每一层都有其特定的功能和职责。服务层负责服务的提供和消费,集群层处理服务的负载均衡和容错机制,注册中心层负责服务的注册与发现,协议层定义了服务之间的通信协议,传输层处理网络通信,数据序列化层负责数据的序列化和反序列化,配置层管理Dubbo的各种配置信息和服务治理。
Dubbo分层架构的优势在于:
- 模块化设计:每个模块都有清晰的职责和接口定义,使得系统的各个部分可以相互独立开发、测试和部署。
- 可扩展性强:各个层次之间松耦合,可以根据需求灵活地进行扩展和定制,满足不同场景的需求。
- 高性能高可用:通过负载均衡、容错机制等技术手段,保证了服务的高性能和高可用性,提升了系统的稳定性和可靠性。
- 透明化开发:Dubbo屏蔽了底层的复杂性,提供了简洁易用的API和配置方式,使得开发者可以更专注于业务逻辑的实现。
总的来说,Dubbo分层架构的设计理念是为了帮助开发者构建高效、稳定的分布式系统,提供了丰富的功能和灵活的扩展性,是构建大规模分布式系统的理想选择。
通过深入理解Dubbo的分层架构,我们可以更好地应用Dubbo框架进行系统设计和开发,并结合实际场景进行合理的配置和调优,从而为用户提供更加稳定可靠的服务。
参考资料
-
官方文档:Dubbo官方网站提供了详尽的文档,包括用户手册、开发指南、架构设计等,对于深入理解Dubbo的使用和原理都有很大帮助。链接:https://dubbo.apache.org/zh/docs/v2.7/user/
-
《阿里巴巴Dubbo分布式服务框架:原理与实践》:这本书由Dubbo的核心开发团队编写,深入浅出地介绍了Dubbo的设计思想、架构原理和实际应用,对于想要深入了解Dubbo的读者来说是一本不可多得的好书。
-
Dubbo源码:通过阅读Dubbo的源码,可以更加深入地理解其内部实现原理和设计思想,对于解决实际问题和定制化需求具有很大帮助。Dubbo的源码托管在GitHub上,地址为:https://github.com/apache/dubbo
-
Dubbo博客和社区文章:在各类技术社区和博客平台,例如CSDN、知乎、简书等,都有很多关于Dubbo的技术文章和经验分享,可以从中学习到更多实践经验和技术解决方案。
-
《Spring实战(第四版)》:虽然不是专门针对Dubbo的书籍,但其中关于Spring Boot和Spring Cloud的内容,以及对微服务架构的介绍,对于理解Dubbo在实际项目中的应用也有一定的帮助。
综上所述,通过参考以上资料,读者可以全面深入地了解Dubbo的设计原理、工作机制以及在实际项目中的应用和优化方法,从而更好地应用Dubbo进行系统设计和开发。
相关文章:
Dubbo分层架构深度解析
引言 Dubbo作为一款备受欢迎的高性能、轻量级的Java RPC框架,在现代分布式系统中扮演着至关重要的角色。随着互联网行业的快速发展,服务间的通信变得越来越频繁,这也使得对于高效、可靠的远程通信方案的需求变得愈发迫切。在这样的背景下&am…...
LocalDate 数据库不兼容问题,因为LocalDate 是 long 类型的
我今天遇到一报错: SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession316f9272] was not registered for synchronization because synchronization is not active JDBC Connection [HikariProxyConnection2127597288 wrapping com.mysql.cj.jdbc…...
RVM(相关向量机)、CNN_RVM(卷积神经网络结合相关向量机)、RVM-Adaboost(相关向量机结合Adaboost)
当我们谈到RVM(Relevance Vector Machine,相关向量机)、CNN_RVM(卷积神经网络结合相关向量机)以及RVM-Adaboost(相关向量机结合AdaBoost算法)时,每种模型都有其独特的原理和结构。以…...
Java--方法的使用
1.1什么是方法 方法顾名思义就是解决问题的办法,在程序员写代码的时候,会遇到很多逻辑结构一样,解决相同问题时,每次都写一样的代码,这会使代码看起来比较绒余,代码量也比较多,为了解决这个问题…...
linux - 主次设备号自动申请
alloc_chrdev_region 原型如下,该函数向内核申请一个空闲的主设备号。 alloc_chrdev_region(&g_aputriger_dev, 0, APUTRIGER_MAX_NUM, "aputriger0"); 第四个参数是我们使用cat /proc/devices 看到的名称 /*** alloc_chrdev_region() - register a…...
我写了一套几乎无敌的参数校验组件!基于 SpEL 的参数校验组件「SpEL Validator」
前言 大家好,我是阿杆,不是阿轩。 参数校验这个东西,很多情况下都是比较简单的,用 NotNull、Size 等注解就可以解决绝大多数场景,但也有一些场景是这些基本注解解决不了的,只能用一些其他的方式处理&…...
输入序列太长 gan CGAN
transformer序列长度大导致计算复杂度高 GAN 2. 训练过程 第一阶段:固定「判别器D」,训练「生成器G」。使用一个性能不错的判别器,G不断生成“假数据”,然后给这个D去判断。开始时候,G还很弱,所以很容易被…...
uni-app scroll-view隐藏滚动条的小细节 兼容主流浏览器
开端 想写个横向滚动的列表适配浏览器,主要就是隐藏一下滚动条在手机上美观一点。 但是使用uni-app官方文档建议的::-webkit-scrollbar在目标标签时发现没生效。 .scroll-view_H::-webkit-scrollbar{display: none; }解决 F12看了一下,原来编译到浏览…...
Java常用API之LinkedList类解读
写在开头:本文用于作者学习我将官方文档中LinkedList 1.6版本中类中绝大部分API全测了一遍并打印了结果,日拱一卒,常看常新。 自己补充了一些对该数据结构的理解,如有不对的地方,请各位指正,谢谢。 首先&…...
移动端自适应
基本实现核心思想 基本原则上是,布局更多地使用flex,然后尺寸使用rem,vw,vh为单位如果是根据不同的屏幕需要有不同的布局了,一般通过检测屏幕尺寸换不同的站点或者媒体查询使用css rem 以html字体太小为1rem的大小&…...
自动化运维工具-Ansible
一、Ansible概述 Ansible是一种基于python开发的自动化运维工具,它只需要在服务端安装ansible,无需在每个客户端安装客户端程序,通过ssh的方式来进行客户端服务器的管理,基于模块来实现批量数据配置、批量设备部署以及批量命令执…...
力扣:62. 不同路径
62. 不同路径 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。 问总共有多少条不同的路径&…...
store内路由跳转router.push
选择action还是mutation 选择action mutation 是用来改变state的,不应该包含路由相关操作mutation是同步执行的,不应该包含异步操作,而路由是异步操作 action中进行路由跳转 因为vuex中没有this,所以不能用this.$router&#…...
ChatGPT Web Midjourney一键集成最新版
准备工具 服务器一台 推荐使用浪浪云服务器 稳定 安全 有保障 chatgpt api 推荐好用白嫖的api 项目演示 项目部署 浏览器访问casaos 添加软件原添加 https://gitee.com/langlangy_1/CasaOS-AppStore-LangLangy/raw/master/chatmjd.zip 安装此软件 等待安装 安装后再桌面设置…...
springboot mongodb分片集群事务
前置 mongodb分片集群想要使用事务,需要对应分片没有仲裁节点 代码 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId><version>2.1.0.RELEASE</version></d…...
node报错——解决Error: error:0308010C:digital envelope routines::unsupported——亲测可用
今天在打包vue2项目时,遇到一个报错: 最关键的代码如下: Error: error:0308010C:digital envelope routines::unsupportedat new Hash (node:internal/crypto/hash:80:19)百度后发现是node版本的问题。 在昨天我确实操作了一下node&…...
golang系统内置函数整理
go语言中有很多系统内置的函数, 为了方便学习,对系统内置函数的函数定义 入参和返回值做如下整理,以方便学习和记忆。 Go语言系统级别的内置函数不多,但是包含的知识点可不少,是学习go语言说必须要搞明白的基础知识 …...
武汉星起航:五对一服务体系,助力创业者成功进军跨境电商市场
随着全球化的深入发展和互联网的普及,跨境电商已成为越来越多国内创业者的首选。然而,跨境电商市场的复杂性和多变性使得许多新手创业者望而却步。在这样的背景下,武汉星起航电子商务有限公司以其独特的五对一服务体系,为创业者提…...
C++常用库函数——strcmp、strchr
1、strcmp:比较两个字符串的值是否相等 例如 char a1[6] "AbDeG",*s1 a1;char a2[6] "AbdEg",* s2 a2;s1 2;s2 2;printf("%d \n", strcmp(s1, s2));return(0); s1指向a1,s2指向a2,strcmp表示比较s1和s…...
vue3怎么使用vant的IndexBar 索引栏
Vant 是一个基于 Vue 的移动端 UI 组件库,它提供了许多常见的移动端组件,包括 IndexBar 索引栏。以下是如何在 Vue 3 中使用 Vant 的 IndexBar 索引栏的步骤: 安装 Vant 如果你还没有安装 Vant,你可以使用 npm 或 yarn 来安装它…...
国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...
多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...
C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...
让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比
在机器学习的回归分析中,损失函数的选择对模型性能具有决定性影响。均方误差(MSE)作为经典的损失函数,在处理干净数据时表现优异,但在面对包含异常值的噪声数据时,其对大误差的二次惩罚机制往往导致模型参数…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...
Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
