【Dubbo核心 详解四】Dubbo服务提供者的详解

news2025/2/24 9:30:06

请添加图片描述

✅创作者:陈书予
🎉个人主页:陈书予的个人主页
🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区
🌟专栏地址: Dubbo核心详解(附代码示例)

文章目录

  • 引言
  • 一、服务提供者
    • 1.1 服务提供者介绍
      • Dubbo 服务提供者启动流程时序图
      • Dubbo 服务提供者关闭流程时序图
      • 1.1.1 Dubbo服务提供者的定义
      • 1.1.2 服务暴露的方式
        • Dubbo 服务提供者暴露服务流程时序图
      • 1.1.3 服务注册的实现
    • 1.2 服务提供者配置
      • 1.2.1 服务提供者的XML配置
      • 1.2.2 服务提供者的注解配置
    • 1.3 服务提供者的容错处理
      • 1.3.1 失败重试机制
      • 1.3.2 隔离机制
      • 1.3.3 超时机制
    • 1.4 服务提供者集群
      • 1.4.1 集群容错模式
      • 1.4.2 集群容错策略
      • 1.4.3 集群容错实现
  • 二、服务提供者的网络通信
    • 2.1 服务概述
      • 2.1.1 Dubbo基于TCP通信
      • 2.1.2 通信级别的概念
      • 2.1.3 通信协议
    • 2.2 服务的序列化方式
      • 2.2.1 Dubbo默认的序列化方式
      • 2.2.2 序列化方式的扩展支持
    • 2.3 服务的传输方式
      • 2.3.1 Dubbo协议的传输方式
      • 2.3.2 传输方式的扩展支持
  • 三、服务提供者的线程模型
    • 3.1 线程模型的概念
      • 3.1.1 什么是线程模型
      • 3.1.2 Dubbo线程模型
    • 3.2 服务提供者的线程模型
      • 3.2.1 线程池模型
      • 3.2.2 单一线程模型
      • 3.2.3 伸缩线程模型
  • 四、服务提供者的动态配置
    • 4.1 配置方式
      • 4.1.1 配置方式的概述
      • 4.1.2 动态配置方式
    • 4.2
    • 4.2 配置规则
      • 4.2.1 配置规则的概述
      • 4.2.2 配置规则的实现

引言

当今分布式系统已经成为企业中不可或缺的一部分。在分布式系统中,服务网格是一个重要的组成部分。服务网格用于管理和调度服务,以确保系统的可用性和可扩展性。其中 Dubbo 是一个流行的服务网格框架,它提供了一种简单、可靠、高性能的方式来构建分布式系统。在 Dubbo 中,服务提供者是框架的核心组件之一,它负责提供服务并将服务暴露给外部应用程序。本文将介绍 Dubbo 中的服务提供者,包括服务提供者的定义、服务暴露的方式、服务注册的实现、服务提供者的容错处理、服务提供者集群以及服务提供者的网络通信。

一、服务提供者

1.1 服务提供者介绍

Dubbo 服务提供者是指使用 Dubbo 协议提供服务的 Java 程序,它是 Dubbo 服务架构的核心部分。服务提供者通过在服务消费方和提供方之间提供 RPC(远程过程调用) 服务,实现了服务之间的松耦合和低耦合。

在 Dubbo 服务架构中,服务提供者主要负责将服务暴露给服务消费方,并将服务消费方的请求转化为 Dubbo 协议的请求,然后将响应返回给服务消费方

Dubbo 服务提供者启动流程时序图

在这里插入图片描述

Dubbo 服务提供者关闭流程时序图

在这里插入图片描述

1.1.1 Dubbo服务提供者的定义

服务提供者是 Dubbo 框架的核心组件之一,它是负责提供服务的应用程序。在 Dubbo 中,服务提供者的定义如下:

  • 服务提供者是一个 Java 类,它实现了 Dubbo 服务接口。
  • 服务提供者必须实现DubboRPC接口,该接口定义了服务调用的基本逻辑。
  • 服务提供者必须实现getService()方法,该方法返回服务实例的引用。

在 Dubbo 中,服务暴露的方式有两种:广播式服务暴露和点式服务暴露。广播式服务暴露是指服务提供者向所有注册的客户端广播服务发布信息,客户端根据服务名称和版本号等信息自动发现服务。点式服务暴露是指服务提供者向单个客户端广播服务发布信息,客户端主动请求服务。

1.1.2 服务暴露的方式

在 Dubbo 服务架构中,服务提供者可以将服务暴露为 HTTP 服务、RPC 服务或者二者的结合体。具体来说,服务提供者可以通过以下几种方式暴露服务:

  • HTTP 服务:服务提供者可以通过 HTTP 协议提供服务,服务消费方可以通过 HTTP 请求的方式调用服务提供者的服务。
  • RPC 服务:服务提供者可以通过 Dubbo 协议提供 RPC 服务,服务消费方可以通过 Dubbo 协议的 RPC 请求调用服务提供者的服务。
  • HTTP+RPC 服务:服务提供者可以通过 HTTP 协议提供 RPC 服务,服务消费方可以通过 HTTP 请求的方式调用服务提供者的 RPC 服务。

Dubbo 服务提供者暴露服务流程时序图

在这里插入图片描述

1.1.3 服务注册的实现

Dubbo 服务注册是指将服务提供者的信息注册到 Dubbo 注册中心,让服务消费者可以通过注册中心查找到服务提供者并进行调用。下面是一个简单的 Dubbo 服务注册实现示例,基于 Apache Barrow 框架:

  1. 创建服务接口

在这个示例中,我们定义了一个名为 MyService 的服务接口,它有两个方法:hello()world()

@Service  
public interface MyService {  
    String hello() throws Exception;

    String world() throws Exception;  
}
  1. 实现服务接口

在这个示例中,我们实现了 MyService 服务接口,并添加了一个 hello() 方法。

@Component  
public class MyServiceImpl implements MyService {  
    @Override  
    public String hello() throws Exception {  
        System.out.println("Hello from MyServiceImpl!");  
        return "Hello, world!";  
    }  
}
  1. 注册服务

在这个示例中,我们将 MyService 服务接口注册到 Dubbo 注册中心。

import org.apache.dubbo.common.URL;  
import org.apache.dubbo.common.constant.CommonConstants;  
import org.apache.dubbo.common.extension.ExtensionLoader;  
import org.apache.dubbo.common.name.NameFactory;  
import org.apache.dubbo.common.service.ServiceLoader;  
import org.apache.dubbo.registry.Registry;  
import org.apache.dubbo.registry.web.WebRegistry;

public class DubboBootstrap {

    public static void main(String[] args) throws Exception {  
        // 创建 Registry  
        Registry registry = new WebRegistry();  
        // 设置注册中心 URL  
        URL url = URL.valueOf("dubbo://localhost:9090/my-service?registry=" + registry);  
        // 创建 NameFactory  
        NameFactory nameFactory = new NameFactory();  
        // 注册中心配置  
        ExtensionLoader.loadExtensions(registry, "dubbo.extension.provides");  
        // 注册服务  
        registry.bind(url, new MyService());  
        // 启动服务  
        System.out.println("Dubbo Bootstrap started...");  
    }

}  

在这个示例中,我们首先创建了一个 WebRegistry,它使用 WebServlet 监听端口 9090,用于向注册中心注册和查找服务。然后,我们将 MyService 服务接口注册到注册中心。最后,我们启动了 Dubbo 服务。

  1. 服务消费者

在这个示例中,我们将创建一个服务消费者,它使用 Dubbo 注册中心查找服务并调用服务接口。

import org.apache.dubbo.common.URL;  
import org.apache.dubbo.common.constant.CommonConstants;  
import org.apache.dubbo.common.extension.ExtensionLoader;  
import org.apache.dubbo.common.name.NameFactory;  
import org.apache.dubbo.common.service.ServiceLoader;  
import org.apache.dubbo.registry.Registry;  
import org.apache.dubbo.registry.consumer.consumer.ConsumerRegistry;

public class DubboConsumer {

    public static void main(String[] args) throws Exception {  
        // 创建 Registry  
        Registry registry = new ConsumerRegistry(new HashMap<URL, Registry>());  
        // 注册中心 URL  
        URL url = URL.valueOf("dubbo://localhost:9090/my-service?registry=" + registry);  
        // 查找服务  
        ServiceLoader<MyService> serviceLoader = ServiceLoader.load(MyService.class);  
        for (MyService service : serviceLoader) {  
            URL serviceUrl = service.getUrl();  
            registry.bind(serviceUrl, service);  
        }  
        // 启动服务  
        System.out.println("Dubbo Consumer started...");  
    }

}  

在这个示例中,我们创建了一个 ConsumerRegistry,它使用 HashMap 存储注册中心的信息。然后,我们将 MyService 服务接口注册到注册中心。最后,我们使用 ServiceLoader 查找服务,并将其绑定到注册中心。

1.2 服务提供者配置

1.2.1 服务提供者的XML配置

XML 配置是 Dubbo 服务架构中最常用的配置方式。服务提供者可以通过 XML 文件来配置服务相关的信息,如服务接口、服务实现、负载均衡、超时时间等。XML 配置如下:

<dubbo:application name="example-service-group"  
             context="default">  
    <dubbo:service interface="com.example.DemoService"  
                   name="demoService"  
                   version="1.0">  
        <dubbo:argument value="com.example.DemoService"/>  
        <dubbo:method name="sayHello" args="hello"/>  
    </dubbo:service>  
    <dubbo:服务提供者 address="http://localhost:8080/example-service"/>  
    <dubbo:服务提供者 address="http://localhost:8080/example-service/"/>  
    <dubbo:服务提供者 address="http://localhost:8080/example-service?负载均衡算法=weight"/>  
    <dubbo:服务提供者 address="http://localhost:8080/example-service?负载均衡算法=roundrobin"/>  
    <dubbo:服务提供者 address="http://localhost:8080/example-service?超时时间=5000"/>  
</dubbo:application>  

1.2.2 服务提供者的注解配置

注解配置是 Dubbo 服务架构中另一种常用的配置方式。服务提供者可以通过注解来配置服务相关的信息,如服务接口、服务实现、负载均衡、超时时间等。注解配置如下:

@ApplicationPath("path1")  
@Name("demoService")  
@Version("1.0")  
public class DemoService implements DemoService {  
    @Override  
    public String sayHello(String hello) {  
        return "Hello, " + hello + "!";  
    }  
}

1.3 服务提供者的容错处理

1.3.1 失败重试机制

在这里插入图片描述

解释:

  1. 客户端(Client)向Dubbo服务提供者(Provider)发送请求。
  2. 如果请求成功,服务提供者将返回响应。
  3. 如果请求失败,则Dubbo服务提供者将通过熔断器(Circuit Breaker)返回服务熔断响应。
  4. 如果请求过载,Dubbo服务提供者将通过熔断器返回请求过载响应。
  5. 如果服务降级,则Dubbo服务提供者将返回服务降级响应,使用线程池(Thread Pool)处理请求。

1.3.2 隔离机制

在这里插入图片描述

Dubbo服务提供者的容错处理的隔离机制实现了服务的隔离,当一个服务出现问题时,该服务的容错处理机制会隔离该服务,以防止问题扩大到整个应用程序中。隔离容器可以是一个独立的线程池,这个线程池只处理隔离的服务,以此来保护应用程序的其他部分。

1.3.3 超时机制

在 Dubbo 服务架构中,服务提供者支持超时机制,以保障服务的响应速度和可用性。超时机制可以通过配置服务提供者的超时时间参数来实现。

下图描述了 Dubbo 服务提供者的容错处理的失败超时机制的流程。在该图中,服务提供者首先向服务注册中心注册服务,然后消费者通过服务注册中心查找到服务提供者列表,向服务提供者发送请求。服务提供者在处理请求时,如果请求超时,会返回超时响应;否则,会返回正常响应。

在这里插入图片描述

1.4 服务提供者集群

1.4.1 集群容错模式

  1. Failover Cluster(失败自动切换)

Failover Cluster是Dubbo默认的集群容错模式,它适用于可重试的失败场景。在该模式下,Dubbo会自动地将调用失败的请求重试到其他的服务提供者上,直到其中一个服务提供者成功返回为止。

在这里插入图片描述

  1. Failfast Cluster(快速失败)

Failfast Cluster适用于非幂等性的请求场景。在该模式下,Dubbo只会尝试调用一次服务提供者,如果调用失败则立即返回失败结果,不会进行重试。

在这里插入图片描述

  1. Failsafe Cluster(失败安全)

Failsafe Cluster适用于非关键性请求场景。在该模式下,Dubbo会直接忽略服务提供者的异常,将异常视为服务调用失败,并将失败结果返回给调用方。

在这里插入图片描述

  1. Failback Cluster(失败自动恢复)

Failback Cluster适用于对可靠性要求较高、但不想阻塞服务调用的场景。在该模式下,Dubbo会将调用失败的请求保存到本地,定时重新尝试调用服务提供者,直到成功返回为止。

在这里插入图片描述

1.4.2 集群容错策略

在 Dubbo 服务提供者集群中,常见的容错策略包括如下几种:

  • 轮询策略:在集群中选择一台服务器作为主服务器,其他服务器作为从服务器。当主服务器出现故障时,从服务器会自动切换到主服务器,并继续提供服务。
  • 故障转移策略:在集群中选择一台服务器作为主服务器,其他服务器作为从服务器。当主服务器出现故障时,从服务器会自动切换到其他正常服务器上,并继续提供服务。
  • 负载均衡策略:在集群中将所有服务提供者部署在不同的节点上,并通过负载均衡算法来均衡服务提供者的负载。
  • 容错连接策略:在集群中将所有服务提供者部署在不同的节点上,并通过集群间的通信来保障集群的稳定性和可用性。

1.4.3 集群容错实现

在 Dubbo 服务提供者集群中,常用的容错实现方式包括如下几种:

  • 服务注册与发现:将服务提供者部署在注册中心上,服务消费者可以通过注册中心来查找服务提供者,并提供服务。
  • 服务网关:在服务提供者和服务消费者之间加入服务网关,网关作为服务提供者和消费者之间的接口,负责处理服务调用和容错处理。
  • 消息队列:将服务提供者和消费者之间的通信通过消息队列来实现,当服务提供者出现故障时,可以通过消息队列来传递消息,继续提供服务。
  • 集群间通信:将服务提供者部署在不同的节点上,通过集群间通信来保障集群的稳定性和可用性。常用的集群间通信方式包括负载均衡、消息队列、Zookeeper 等。

二、服务提供者的网络通信

2.1 服务概述

2.1.1 Dubbo基于TCP通信

Dubbo 是基于 TCP 通信的,它支持多种通信模式,包括经典模式、RPC 模式和 HTTP 模式。在经典模式下,Dubbo 使用 TCP 协议进行通信,服务提供者和消费者之间的通信是通过套接字进行的。在 RPC 模式下,Dubbo 使用 Dubbo 协议进行通信,服务提供者和消费者之间的通信也是通过套接字进行的。在 HTTP 模式下,Dubbo 使用 HTTP 协议进行通信,服务提供者和消费者之间的通信是通过 HTTP 请求和响应进行的。

2.1.2 通信级别的概念

在 Dubbo 中,通信级别指的是服务消费者和服务提供者之间的通信级别。具体来说,通信级别包括如下几个:

  • 接口级别:指服务消费者和服务提供者之间的接口级别通信,也就是服务消费者通过接口调用服务提供者的方法。
  • 方法级别:指服务消费者和服务提供者之间的方法级别通信,也就是服务消费者通过接口调用服务提供者的方法,服务提供者在接收到调用后,执行具体的服务逻辑。
  • 服务级别:指服务消费者和服务提供者之间的服务级别通信,也就是服务消费者通过调用服务提供者的服务,服务提供者在接收到调用后,执行具体的服务逻辑。

2.1.3 通信协议

在 Dubbo 中,服务消费者和服务提供者之间的通信采用 Dubbo 协议进行。Dubbo 协议采用 JSON 格式进行传输,支持远程调用和事件监听等功能。具体来说,Dubbo 协议包括以下内容:

  • 服务接口信息:包括服务接口的类名、版本号、方法信息等。
  • 服务实现信息:包括服务实现的类名、版本号、方法信息等。
  • 调用参数信息:包括调用方法的参数类型、参数值等。
  • 调用结果信息:包括调用方法的返回值类型、返回值值等。

2.2 服务的序列化方式

2.2.1 Dubbo默认的序列化方式

在 Dubbo 中,默认的序列化方式为 Java 序列化。Java 序列化是一种将对象序列化为字符串的序列化方式,它支持对象在内存中的序列化和反序列化,可以保证对象在不同平台和不同语言之间进行传输和交换。但是,Java 序列化在传输过程中可能会出现数据丢失和变形等问题,因此需要谨慎使用。

2.2.2 序列化方式的扩展支持

Dubbo 提供了多种序列化方式,包括 JSON 序列化、XML 序列化、化石序列化等。服务提供者可以根据需要,自行选择序列化方式。同时,Dubbo 还提供了序列化方式的扩展支持,可以自定义序列化方式,满足不同的需求。

2.3 服务的传输方式

2.3.1 Dubbo协议的传输方式

Dubbo 协议采用 HTTP 协议进行传输,支持客户端和服务器之间的通信。具体来说,Dubbo 协议的传输方式包括如下几种:

  • GET 方式:客户端向服务器发送 GET 请求,服务器返回请求结果。
  • POST 方式:客户端向服务器发送 POST 请求,服务器接收请求数据,并根据请求数据执行相应的操作。
  • PUT 方式:客户端向服务器发送 PUT 请求,服务器将请求数据保存到服务器中。
  • DELETE 方式:客户端向服务器发送 DELETE 请求,服务器删除请求数据。

2.3.2 传输方式的扩展支持

Dubbo 协议的传输方式可以通过自定义 HTTP 客户端和服务器进行扩展支持。自定义 HTTP 客户端和服务器可以实现自定义的传输方式,满足不同的需求。同时,Dubbo 还提供了 HTTP 传输方式的扩展支持,可以自定义 HTTP 传输方式,满足不同的需求。

三、服务提供者的线程模型

3.1 线程模型的概念

3.1.1 什么是线程模型

线程模型是指描述计算机程序中线程 (也称为进程或实例) 如何执行的模型。在一个计算机程序中,线程是程序执行的基本单位。每个线程都有自己的堆栈、变量和执行顺序,它们可以独立地运行,直到它们被阻塞或超时为止。线程模型描述了线程如何协作、同步和通信,以确保程序的正确性和可靠性。

3.1.2 Dubbo线程模型

Dubbo 线程模型是 Dubbo 框架中用于实现服务消费和服务提供者之间通信的线程模型。在 Dubbo 中,服务消费者和服务提供者之间是通过线程池进行的,每个线程池代表一个服务消费者或服务提供者,线程池中的线程负责执行服务消费者的请求或服务提供者的服务。

3.2 服务提供者的线程模型

3.2.1 线程池模型

线程池模型是指服务提供者在执行服务请求时使用的线程模型。在线程池模型中,服务提供者会创建一个或多个线程,用于执行服务请求。每个线程都拥有自己的堆栈和变量,当服务请求结束时,服务提供者会自动销毁线程,释放资源。

3.2.2 单一线程模型

单一线程模型是指服务提供者在执行服务请求时使用的线程模型。在单一线程模型中,服务提供者只会创建一个线程,用于执行服务请求。当服务请求结束时,服务提供者不会自动销毁线程,而是等待线程完成任务后才会销毁线程。

3.2.3 伸缩线程模型

伸缩线程模型是指服务提供者在执行服务请求时使用的线程模型,它可以根据实际需求自动增加或减少线程的数量。在伸缩线程模型中,服务提供者会创建多个线程,当服务请求数量增加时,服务提供者会自动增加线程的数量,以保证服务请求的及时处理。当服务请求数量减少时,服务提供者会自动减少线程的数量,减少资源浪费。

四、服务提供者的动态配置

4.1 配置方式

4.1.1 配置方式的概述

静态配置是指在代码中直接编写服务提供者的配置信息,例如服务接口的 IP 地址、端口号、协议、依赖库等信息。这种方式的优点是简单易用,可以快速地搭建服务提供者,但是在运行时无法根据实际情况进行修改。

动态配置是指在运行时根据请求的实际情况动态地配置服务提供者。这种方式的优点是灵活性高,可以根据实际情况进行修改,但是在代码量上会多一些。

4.1.2 动态配置方式

Dubbo 提供了多种方式来实现动态配置,其中最常用的方式是使用 RegisterUtil.register() 方法进行注册。在使用动态配置时,需要先创建一个 RegisterUtil 对象,然后使用该对象进行注册。注册完成后,可以通过调用 RegisterUtil.unregister() 方法来取消注册。

另外,Dubbo 还支持使用 XML 文件进行配置,可以使用 XML 文件来存储服务提供者的配置信息。XML 文件的格式如下:

<dubbo:service interface="com.example.demo.Service"  
       name="demoService"  
       registry-address="localhost:20888">  
    <dubbo:reference name="demoDao" interface="com.example.demo.Dao" />  
</dubbo:service>  

在上面的 XML 文件中,interface 属性指定了服务接口的名称,name 属性指定了服务的名称,registry-address 属性指定了服务注册中心的连接地址,dubbo:reference 属性指定了服务依赖的对象。

4.2

4.2 配置规则

4.2.1 配置规则的概述

Dubbo 的配置规则主要包括以下几个方面:

  • 服务接口的命名空间:服务接口的命名空间指定了服务接口的命名空间,例如 com.example.demo.
  • 服务名称:服务名称指定了服务的名称,例如 demoService.
  • 服务注册中心:服务注册中心指定了服务注册的中心地址,例如 localhost:20888.
  • 服务依赖库:服务依赖库指定了服务依赖的其他库,例如 com.example.demo.Dao.

4.2.2 配置规则的实现

在实现服务提供者的配置信息时,需要按照上述规则进行编写。例如,下面是一个符合规则的服务提供者的配置信息:

@Component  
public class DemoService implements Service {  
 
    @Override  
    public void run(String name, Map<String, Object> params) throws Exception {  
        System.out.println(name + " is running...");  
    }  
}

@Component  
public class DemoDao implements Dao {  
 
    @Override  
    public void doSomething(String name) throws Exception {  
        System.out.println(name + " is done.");  
    }  
}

@Configuration  
public class DemoConfig {  
 
    @Bean  
    public Service service() {  
        return new DemoService();  
    }  
 
    @Bean  
    public Dao dao() {  
        return new DemoDao();  
    }  
}

在上面的代码中,@Component 注解标记了 DemoServiceDemoDao 两个组件,并且它们都实现了 Service 接口。@Configuration 注解标记了 DemoConfig 类,它包含了两个 @Bean 注解,分别标记了 DemoServiceDemoDao 组件的注入点。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/561849.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

NPDP|产品经理的硬实力体现在哪里?

在企业里&#xff0c;产品经理是一个具有综合职能的职位&#xff0c;其工作的范围可以说已经遍及到了公司的每个角落其接触的人员也涉及公司几乎所有的部门。 产品经理是产品品牌塑造者、更是营销骨干&#xff0c;是一套完善的营销运作制度&#xff0c;更是博大精深的营销操作…

git clone 报错10054,解决方法

使用git clone下载工程时&#xff0c;报错提示如下&#xff1a; fatal: unable to access https://github.com/deozhang/GaoZhongShuXue.git/: OpenSSL SSL_read: Connection was reset, errno 10054 报错提示的代码是10054&#xff0c;根据提示和网上搜索结果&#xff0c;可以…

Ae:跟踪运动

使用跟踪器 Tracker面板的跟踪运动 Track Motion功能&#xff0c;可通过手动添加和设置跟踪点来跟踪对象的运动&#xff0c;并能将获得的跟踪数据应用于其它对象。 Ae菜单&#xff1a;窗口/跟踪器 Tracker 点击跟踪器面板上的“跟踪运动”按钮&#xff0c;会为图层添加“动态跟…

Charles使用教程【简易版】

Charles抓包教程 1、电脑安装charles 2、电脑打开charles后安装root证书 3、电脑信任证书 4、手机连接与电脑同一wifi 5、设置手机代理 wlan设置中将当前 wifi 的代理改成手动&#xff0c;主机名填电脑 ip&#xff0c;端口填8888 此时如果当前手机是第一次被你的电脑设备代理或…

【JavaSE】Java基础语法(四)

文章目录 &#x1f37c;1. 循环细节&#x1f962;1.1 循环语句-dowhile循环&#x1f962;1.2 三种循环的区别&#x1f962;1.3 跳转控制语句 &#x1f37c;2. Random&#x1f962;2.1 Random产生随机数&#x1f962;2.2 Random练习-猜数字 &#x1f37c;1. 循环细节 &#x1f…

[资料分享]基于单片机防酒驾酒精检测报警系统装置设计、基于数字电路演讲计时protues仿真设计

基于单片机防酒驾酒精检测报警系统装置设计 一、说明 通过MQ3传感器检测酒精浓度&#xff0c;信号由ADCO832进行处理模数转化再到单片机进行处理&#xff0c;当检测到浓度超过“酒驾”报警值时&#xff0c;红灯亮起&#xff0c;当检测到浓度超过“醉驾”报警值时&#xff0c;…

网关网卡配置

Vmvare虚拟机设置外网IP 查看当前主机的网卡名/当前IP/子网掩码&#xff0c;网关地址 ifconfig route -n 查看DNS nslookup hcos 网卡名称为enp0s3&#xff0c;IP地址为10.0.2.15&#xff0c;子网掩码为255.255.255.0&#xff0c;网关为10.0.2.2&#xff1b; Centos设置IP/网…

【Java编程系列】gateway限流实践时发生的问题和解决方案

前期回顾&#xff1a; 【Java编程系列】Springcloud-gateway自带限流方案实践篇 1、实践中发生的问题 主要有以下几个问题&#xff1a; 1、限流返回的响应数据无法自定义 (LogFormatUtils.java:91) - [7b93af46-20] Completed 429 TOO_MANY_REQUESTS 返回后显示的情况如下&a…

C++第二章:变量和基本内置类型

变量和基本内置类型 一、基本内置类型1.1 算数类型1.2 带符号类型和无符号类型1.3 类型转换含有无符号类型的表达式 1.4 字面值常量整形和浮点型字面值字符和字符串字面值转义序列指定字面值的类型 二、变量2.1 变量的定义初始化列表初始化默认初始化 2.2 变量声明和定义的关系…

【web-ctf】ctf_BUUCTF_web(2)

文章目录 BUUCTF_webSQL注入1. [RCTF2015]EasySQL2. [CISCN2019 华北赛区 Day1 Web5]CyberPunk3. [CISCN2019 总决赛 Day2 Web1]Easyweb4. [GYCTF2020]Ezsqli5. [网鼎杯 2018]Comment 文件上传漏洞1. [WUSTCTF2020]CV Maker2. [NPUCTF2020]ezinclude3. [SUCTF 2019]EasyWeb 文件…

TADK 23.03 release note

主要功能概述&#xff1a; 基于深度学习的应用分类&#xff1a;在原有的基于机器学习的应用分类(AppID)能力基础上&#xff0c;扩展出新的深度学习参考模型和推理引擎。FFEL的raw byte特征提取&#xff1a;增加了流特征提取库(FFEL)对数据包中的raw byte特征提取能力&#xff0…

Meta AI 重磅推出LIMA!媲美GPT-4、无需RLHF就能对齐!

深度学习自然语言处理 原创作者&#xff1a;鸽鸽 昨天Meta AICMU这篇文章一出&#xff0c;twitter都炸了&#xff01; LIMA&#xff0c;只使用1000个精心挑选的样本微调一个 65B LLaMa&#xff0c;无需RLHF&#xff0c;性能媲美甚至优于GPT-4&#xff01; 论文&#xff1a;LIMA…

游戏洞察丨自来水还是井水,后流量时代的私域挑战

流量生意本质上是买卖用户浏览时间的生意&#xff0c;如果用户增长到顶&#xff0c;那就意味着供给到顶。对比 2021 年&#xff0c;2022 年的游戏出海在谷歌和 Facebook 上投入的广告成本几乎翻了一倍。新晋“渠道王者”TikTok 逐渐走进大家的视野。该现象背后的原因在于&#…

解决幂等问题,只需要记住这个口诀!

△Hollis, 一个对Coding有着独特追求的人△ 这是Hollis的第 417 篇原创分享 作者 l Hollis 来源 l Hollis&#xff08;ID&#xff1a;hollischuang&#xff09; 作为开发人员&#xff0c;我们每天都要开发大量的接口&#xff0c;其中包括了读接口和写接口&#xff0c;而对于写接…

将矩阵按指定对角线转化为一个上三角矩阵numpy.triu()方法

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 将矩阵按指定对角线转化为一个上三角矩阵 numpy.triu() 选择题 关于以下代码说法错误的一项是? import numpy as np a np.array([[1,2],[3,4]]) print("【显示】a\n",a) print(&…

应用程序和 API 攻击呈上升趋势

Akamai Technologies 发布了一份新的互联网现状报告&#xff0c;标题为“突破安全漏洞&#xff1a;针对组织的应用程序和 API 攻击的兴起”。 报告显示&#xff0c;亚太地区和日本&#xff08;APJ&#xff09;的金融服务业仍然是该地区受攻击最严重的行业&#xff0c;Web 应用…

大模型推理性能优化之KV Cache解读

0. 引言 做大模型性能优化的一定对KV Cache不陌生&#xff0c;那么我们对这个技术了解到什么程度呢&#xff1f;请尝试回答如下问题&#xff1a; KV Cache节省了Self-Attention层中哪部分的计算&#xff1f;KV Cache对MLP层的计算量有影响吗&#xff1f;KV Cache对block间的数据…

知识点滴 - 什么是膳食结构

膳食结构是指膳食中各类食物的数量及其在膳食中所占的比重&#xff0c;由于影响膳食结构的这些因素是在逐渐变化的&#xff0c;所以膳食结构不是一成不变的&#xff0c;人们可以通过均衡调节各类食物所占的比重&#xff0c;充分利用食品中的各种营养&#xff0c;达到膳食平衡&a…

适配器模式:代码接口的神奇转换

一、概要 适配器模式&#xff08;Adapter Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许将一个类的接口转换成客户端所期望的另一个接口&#xff0c;使得原本由于接⼝不兼容⽽不能⼀起⼯作的那些类可以⼀起⼯作。通俗来讲&#xff0c;就是通过适配器来连接两个不…

Js 如何实现一个类似 chatGPT 打字机效果

在使用chatGPT的时候,会有一个打字机的效果,以下是分别使用原生Js和Vue实现 原生 JS 实现 如下是示例代码 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>Printer 打字机效果</title><style>* {margin: 0;bor…