Dubbo高手之路2,6种扩展机制详解

news2024/12/27 17:54:24

在这里插入图片描述

目录

  • 一、Dubbo扩展机制的概述
  • 二、Dubbo的自适应扩展机制
    • 1. 什么是自适应扩展机制
    • 2. 自适应扩展机制的使用示例
  • 三、Dubbo的SPI扩展机制
    • 1. 什么是SPI扩展机制
    • 2. SPI扩展机制的使用示例
    • 3. Dubbo的SPI扩展机制中自定义扩展点的实现示例
  • 四、Dubbo的自定义扩展点机制
    • 1. 什么是自定义扩展点机制
    • 2. 自定义扩展点机制的使用示例
    • 3. Dubbo的自定义扩展点机制的实现示例
  • 五、Dubbo的过滤器扩展机制
    • 1. Dubbo的过滤器机制概述
    • 2. 过滤器扩展机制的使用示例
    • 3. 自定义过滤器的实现示例
  • 六、Dubbo的负载均衡扩展机制
    • 1. Dubbo的负载均衡扩展机制概述
    • 2. 负载均衡扩展机制的使用示例
    • 3.自定义负载均衡策略的实现示例
  • 七、Dubbo的容错机制扩展
    • 1. Dubbo的容错机制概述
    • 2. 容错机制扩展的使用示例
    • 3. 自定义容错策略的实现示例
  • 八、Dubbo的扩展机制实践
    • 1. 实现一个使用自定义扩展点、过滤器、负载均衡器和容错机制的 Dubbo 服务

大家好,我是哪吒。

Dubbo是一个高性能的Java RPC框架。RPC是远程过程调用的缩写,其基本思想是:客户端像调用本地方法一样,通过网络请求调用远程服务器上的服务。Dubbo可以帮助我们更方便地构建分布式应用程序,它具有高效的远程调用、服务自动注册和发现、负载均衡、容错机制等众多特性,是企业级应用中可靠的基础架构。

一、Dubbo扩展机制的概述

Dubbo是一个高性能的分布式服务框架,广泛应用于各种规模和种类的企业级项目中。在实际应用过程中,Dubbo的核心能力是扩展机制,它可以让Dubbo具有更强的可定制化能力,也可以让Dubbo更好地适应各种应用场景。

在这里插入图片描述

Dubbo的扩展机制主要包括:自适应扩展机制、SPI扩展机制、自定义扩展点机制、过滤器扩展机制、负载均衡扩展机制和容错机制扩展。这些机制使得Dubbo的使用更加灵活方便,可以满足不同需要的业务场景,也可以根据实际情况来选择合适的扩展机制。

在Dubbo的扩展机制中,尤其需要注意自定义扩展点机制和SPI扩展机制。这些机制是Dubbo中较为重要和常用的扩展机制,充分了解这些机制可以让应用程序更加灵活和可定制。

下图展示了Dubbo扩展机制的调用流程:

Client ExtensionLoader Extension 加载扩展点 创建扩展点 返回扩展点 返回扩展点 调用扩展点方法 返回结果 Client ExtensionLoader Extension

上图中,Dubbo客户端首先会通过ExtensionLoader加载需要使用的扩展点,ExtensionLoader会根据客户端传入的扩展点名和配置,创建对应的扩展点实例,并返回给客户端,客户端再通过返回的扩展点实例调用相应的方法。

二、Dubbo的自适应扩展机制

1. 什么是自适应扩展机制

自适应扩展机制是Dubbo提供的一种机制,它可以使Dubbo框架根据实际使用情况动态地选择不同的扩展实现,从而达到最优的效果。

自适应扩展机制的实现方式是通过在扩展接口的代理类中,根据实际情况动态地生成对应扩展实现的代理类实例。

下图是自适应扩展机制的详细时序图:

Client ExtensionLoader AdaptiveExtension ActualExtension 加载扩展点 解析配置文件 根据配置文件查找实现类 创建代理对象 根据配置使用具体的扩展点 返回具体的扩展点实现 返回代理对象 调用代理对象方法 调用具体的扩展点实现 返回结果 返回结果 Client ExtensionLoader AdaptiveExtension ActualExtension

上图中,Client先调用ExtensionLoader加载扩展点,并解析配置文件,ExtensionLoader根据配置文件查找实现类,然后创建一个AdaptiveExtension的代理对象,并将该代理对象返回给Client。Client调用代理对象的方法时,AdaptiveExtension会根据配置使用具体的扩展点实现,并将调用转发给具体的扩展点实现,最后将结果返回给Client。

2. 自适应扩展机制的使用示例

在Dubbo框架中,有一个名为Protocol的扩展接口,它有多种不同的实现方式,如dubbo、rmi、http等。在使用Dubbo时,我们可以通过@Reference注解来注入对应的扩展实现,如:

@Reference(protocol = "dubbo")
private DemoService demoService;

在上述代码中,我们指定了使用dubbo协议的DemoService接口的扩展实现。

我们也可以通过adaptive属性来实现自适应调用,如:

@Reference(adaptive = "true")
private Protocol protocol;

在上述代码中,我们使用了adaptive属性,并注入了Protocol类型的实例。这时,Dubbo框架会根据实际情况动态地生成对应实现的代理类,并返回对应的实例。

三、Dubbo的SPI扩展机制

1. 什么是SPI扩展机制

Dubbo使用了Java的SPI(Service Provider Interface)扩展机制。SPI是JDK内置的一种服务发现机制,其具体实现方式是在资源文件META-INF/services中通过名称为SPI接口的全限定类名创建一个文本文件,在这个文本文件中可以写入该SPI接口的实现类全限定类名,这样可以实现动态加载实现类的目的。

Dubbo中的SPI扩展机制能够在不修改核心源代码的前提下,通过修改配置文件或者实现自定义拓展类的方式来替换或增加核心功能。

下图描述了 Dubbo SPI 扩展机制的工作流程:

Dubbo Framework User Extension ExtensionLoader 向 Dubbo Framework 请求获取 ExtensionLoader 加载 ExtensionLoader 返回 ExtensionLoader 调用 ExtensionLoader 的方法 通过 SPI 机制加载 Extension 实现 返回 Extension 实现 返回 Extension 实现 Dubbo Framework User Extension ExtensionLoader

上图描述了 Dubbo SPI 扩展机制的工作流程,其中:

  1. 用户向 Dubbo Framework 请求获取 ExtensionLoader,ExtensionLoader 是 Dubbo SPI 扩展机制的核心类。
  2. Dubbo Framework 加载 ExtensionLoader,并返回给用户。
  3. 用户调用 ExtensionLoader 的方法。
  4. ExtensionLoader 根据指定的 Extension 接口,通过 SPI 机制加载 Extension 实现。
  5. Extension 实现将被加载,ExtensionLoader 返回 Extension 实现给用户。

2. SPI扩展机制的使用示例

首先,我们需要定义一个SPI扩展接口,让Dubbo的扩展实现类都实现该接口。示例代码:

package com.example.extension;

import com.alibaba.dubbo.common.extension.SPI;

@SPI("default")
public interface PrintService {
    void print(String msg);
}

在接口上添加@SPI注解,指定该扩展的默认实现类。

然后,我们需要在META-INF/services目录下创建一个“接口全限定类名”的文件名的文件,文件中写入我们实现的SPI扩展类的全限定类名。比如我们需要同过实现PrintService接口来实现打印功能,那么我们在META-INF/services/目录下创建一个名为“com.example.extension.PrintService”的文件,文件内容为:

com.example.extension.impl.ConsolePrintServiceImpl

接下来,我们就可以通过Dubbo框架自动加载通过SPI机制注册的实现类了。示例代码:

    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Main.class);
    PrintService printService = ExtensionLoader.getExtensionLoader(PrintService.class).getDefaultExtension();
    printService.print("hello world!");

以上代码中,我们使用Dubbo的扩展加载器ExtensionLoader来获取PrintService接口的默认实现类,然后调用该实现类的print()方法即可实现打印功能。

3. Dubbo的SPI扩展机制中自定义扩展点的实现示例

在Dubbo框架中,我们可以通过自定义扩展点来增强Dubbo的功能。自定义扩展点需要实现Dubbo提供的ExtensionFactory接口,并在META-INF/dubbo/internal/路径下创建一个文件名为com.alibaba.dubbo.common.extension.ExtensionFactory的文件,文件中写入

扩展点实现类的全限定类名。示例代码:

package com.example.extension;

import com.alibaba.dubbo.common.extension.ExtensionFactory;

public class MyExtensionFactory implements ExtensionFactory {
@Override
public <T> T getExtension(Class<T> type, String name) {
if (type.equals(PrintService.class)) {
return (T) new ConsolePrintServiceImpl();
}
return null;
}
}

在MyExtensionFactory中实现getExtension()方法,并根据type参数判断获取哪个扩展实现类。在本示例中,我们仅仅实现了PrintService接口的实现类,因此只需要判断type参数是否为PrintService类即可。

下一步,我们需要在META-INF/dubbo/internal/目录下创建一个名为com.alibaba.dubbo.common.extension.ExtensionFactory的文件,文件内容为我们实现的扩展点实现类全限定类名。比如我们实现的扩展点实现类为com.example.extension.MyExtensionFactory,那么我们就要在META-INF/dubbo/internal/目录下创建一个名为com.alibaba.dubbo.common.extension.ExtensionFactory的文件,并将文件内容写为com.example.extension.MyExtensionFactory。

最后,我们在程序中就可以使用自定义的扩展点了。示例代码:

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Main.class);
PrintService printService = ExtensionLoader.getExtensionLoader(PrintService.class).getExtension("console");
printService.print("hello world!");

在以上示例代码中,我们通过getExtension()方法来获取PrintService接口的实现类。getExtension()方法中的参数为扩展点的name属性,该属性值默认为“default”。在本示例中我们将name的值设置为“console”,因此即使用了我们自定义的扩展点实现类。

四、Dubbo的自定义扩展点机制

1. 什么是自定义扩展点机制

Dubbo的自定义扩展点机制是在SPI扩展机制的基础上,增加了自定义扩展点的实现方式。通过Dubbo的扩展机制,我们可以通过配置文件切换Dubbo内部的实现方式,但是对于用户自己实现的功能模块,如何进行扩展呢?这里就需要用到自定义扩展点机制了。

下图是自定义扩展点机制的详细时序图:

User Dubbo Extension 注册扩展点 扩展点注册 查找扩展点 扩展点查找 返回扩展点实例 返回扩展点实例 User Dubbo Extension

在上图中,用户首先将自己实现的扩展点注册到Dubbo中,然后在需要使用该扩展点的时候,Dubbo会根据扩展点的名称进行查找并返回相应的扩展点实例。通过这样的机制,用户可以灵活地扩展Dubbo的功能,同时也可以让Dubbo更加适应不同的业务场景。

自定义扩展点的核心思想就是:“面向接口编程,实现类实现接口,接口与实现类通过扩展点Binder关联。”其中,Binder的定义可以参考以下的代码:

public interface ExtensionFactory {
    // 返回一个扩展点的代理对象
    <T> T getExtension(Class<T> type, String name) throws IllegalStateException;
}

public interface ExtensionLoader<T> {
    T getExtension(String name);
}

public interface ExtensionBinder<T> {
    // 绑定
    void bind(T instance);
    // 获取绑定的扩展对象
    T get();
}

public interface ExtensionLoaderListener {
    void onLoad();
}

2. 自定义扩展点机制的使用示例

为了更好地理解Dubbo的自定义扩展点机制,我们可以通过一个简单的示例来演示其使用方法。假设我们有一个接口HelloService,我们想要通过自定义扩展点机制,为这个接口添加一个实现类。

首先,我们需要创建一个实现类HelloServiceImpl,该实现类需要实现HelloService接口。接着,我们需要在resources/META-INF/dubbo目录下创建一个名为com.xxx.HelloService的文件,该文件中需要指定HelloService接口的实现类名称。

helloService=com.xxx.HelloServiceImpl

接下来,我们需要在代码中获取HelloService接口的实例。这可以通过以下方式实现:

ExtensionLoader<HelloService> loader = ExtensionLoader.getExtensionLoader(HelloService.class);
HelloService helloService = loader.getExtension("helloService");
helloService.sayHello();

其中,getExtensionLoader()方法用于获取扩展点的ExtensionLoader实例,getExtension()方法用于
获取具体的扩展实例。在上面的代码中,我们通过“helloService”这个名称获取到了实现了HelloService接口的HelloServiceImpl实例,并调用了其中的sayHello()方法。

通过上述示例,我们可以看出,使用Dubbo的自定义扩展点机制非常简单,只需要在配置文件中指定实现类的名称,然后通过getExtensionLoader()和getExtension()方法获取实例即可。

3. Dubbo的自定义扩展点机制的实现示例

在Dubbo的自定义扩展点机制中,最核心的是ExtensionLoader类和ExtensionFactory类。其中,ExtensionLoader用于加载和管理扩展实例,ExtensionFactory用于创建扩展实例。
下面,我们将通过一个简单的示例,演示Dubbo的自定义扩展点机制的具体实现方式。

首先,我们需要定义一个扩展点接口:

public interface HelloService {
String sayHello(String name);
}

接着,我们需要实现该接口的一个实现类:

@SPI("helloWorld")
public class HelloWorldService implements HelloService {
@Override
public String sayHello(String name) {
return "Hello, " + name;
}
}

在这里,我们使用了@SPI注解来指定该扩展点的默认实现,如果配置文件中没有指定其他实现,则会使用该默认实现。

接下来,我们需要创建一个名为com.xxx.HelloService的文件,该文件中需要指定扩展点接口的实现类名称:

helloWorld=com.xxx.HelloWorldService

最后,我们需要在代码中获取HelloService接口的实例,这可以通过以下代码实现:

ExtensionLoader<HelloService> loader = ExtensionLoader.getExtensionLoader(HelloService.class);
HelloService helloService = loader.getExtension("helloWorld");
System.out.println(helloService.sayHello("Dubbo"));

在上述代码中,我们通过getExtensionLoader()方法获取HelloService接口的ExtensionLoader实例,然后通过getExtension()方法获取名为“helloWorld”的实现类实例,并调用其中的sayHello()方法。

五、Dubbo的过滤器扩展机制

1. Dubbo的过滤器机制概述

在这里插入图片描述

Dubbo的过滤器机制允许在调用前、调用后以及抛出异常时执行一些额外的操作。过滤器在调用链路中按顺序执行,可以在过滤器中实现各种功能,例如:日志记录、性能统计、权限控制等。

在这里插入图片描述

Dubbo中内置了多个过滤器,包括:ClassLoader过滤器、Context过滤器、Generic过滤器、Echo过滤器、Token过滤器、AccessLog过滤器等。

下面是Dubbo的过滤器机制的时序图:

服务提供者 过滤器1 过滤器2 过滤器3 服务消费者 发送请求 执行过滤器1逻辑 执行过滤器2逻辑 执行过滤器3逻辑 发送请求 处理请求 返回响应 返回响应 返回响应 返回响应 alt [过滤器3通过] [过滤器3拒绝请求] 返回响应 alt [过滤器2通过] [过滤器2拒绝请求] 返回响应 alt [过滤器1通过] [过滤器1拒绝请求] 服务提供者 过滤器1 过滤器2 过滤器3 服务消费者

上图中,服务消费者向服务提供者发送请求时,请求先经过过滤器1,如果过滤器1通过则进一步经过过滤器2,如果过滤器2通过则进一步经过过滤器3,如果过滤器3通过则将请求发送给服务提供者,服务提供者处理请求后将响应返回给服务消费者,响应也会经过相同的过滤器链路。如果任意一个过滤器拒绝请求,则直接返回错误响应。

2. 过滤器扩展机制的使用示例

Dubbo提供了扩展机制,可以在dubbo配置文件中配置过滤器,示例如下:

<dubbo:provider filter="accessLogFilter" />

在上面的例子中,accessLogFilter表示需要使用的过滤器名称,可以在dubbo配置文件中通过dubbo:filter标签进行定义。

3. 自定义过滤器的实现示例

要实现自定义过滤器,需要按照以下步骤进行:

  1. 定义一个类实现org.apache.dubbo.rpc.Filter接口;
  2. 实现接口中的方法;
  3. 在META-INF/dubbo目录下创建一个以org.apache.dubbo.rpc.Filter接口全限定名为名称的文件,并在文件中添加自定义过滤器的类名。
    下面是一个自定义的过滤器示例:
package com.example;

import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;

@Activate(group = "provider")
public class MyFilter implements Filter {
    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        // 在这里实现自己的逻辑
        return invoker.invoke(invocation);
    }
}

在上面的例子中,我们实现了一个MyFilter过滤器,并使用@Activate注解指定了它是一个provider端的过滤器,然后在invoke()方法中编写自己的逻辑,最后调用invoker.invoke(invocation)方法来执行调用链路中的下一个过滤器或服务。

六、Dubbo的负载均衡扩展机制

1. Dubbo的负载均衡扩展机制概述

负载均衡是分布式系统中的一个重要问题,它可以实现将请求分摊到多个服务提供者上,提高系统的并发能力和可用性。Dubbo的负载均衡扩展机制允许用户自定义负载均衡策略,实现更加灵活、适合特定场景的负载均衡算法。Dubbo内置了多种负载均衡算法,包括随机、轮询、最少活跃调用等。

下面是Dubbo的负载均衡扩展机制的时序图:

Provider Consumer Registry LoadBalancer Invoker 查询可用服务列表 返回可用服务列表 根据负载均衡策略选择服务 选择一个可用服务的Invoker 通过Invoker发起远程调用 远程调用服务 返回结果 返回结果 Provider Consumer Registry LoadBalancer Invoker

2. 负载均衡扩展机制的使用示例

Dubbo的负载均衡扩展机制可以通过在服务提供方和服务消费方的配置文件中指定负载均衡策略来使用。例如,在服务提供方的配置文件中可以添加以下配置:

<dubbo:service interface="com.xxx.XxxService" loadbalance="roundrobin" />

在服务消费方的配置文件中可以添加以下配置:

<dubbo:reference interface="com.xxx.XxxService" loadbalance="random" />

这样就可以实现使用Dubbo内置的轮询

3.自定义负载均衡策略的实现示例

用户可以通过实现Dubbo的LoadBalance接口来自定义负载均衡策略。以下是一个示例:

public class MyLoadBalance implements LoadBalance {
    @Override
    public <T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation) throws RpcException {
        // 自定义负载均衡算法实现
        return invokers.get(0);
    }
}

七、Dubbo的容错机制扩展

1. Dubbo的容错机制概述

Dubbo的容错机制是指当Dubbo服务调用出现异常时,Dubbo框架会根据预设的容错机制进行处理,以保证服务的高可用性。Dubbo框架默认提供了多种容错机制,如Failover、Failfast、Failsafe、Failback、Forking等,也支持自定义容错机制。

Dubbo的容错机制通常是通过在客户端代理层实现的,当远程服务调用出现异常时,客户端代理会根据预设的容错机制进行重试或处理,以保证服务的高可用性。

Provider ClusterInvoker Router LoadBalance Invoker Registry Monitor Consumer InvokerInvocationHandler 调用远程方法 调用ClusterInvoker.invoke方法 获取所有Invoker列表 进行负载均衡 选择一个Invoker 调用远程方法 返回结果 返回结果 返回结果 监控调用情况 更新调用统计信息 处理异常 返回异常信息 处理异常 返回异常信息 处理异常 返回异常信息 返回异常信息 抛出异常 Provider ClusterInvoker Router LoadBalance Invoker Registry Monitor Consumer InvokerInvocationHandler

在Dubbo的容错机制中,ClusterInvoker负责调用远程服务,并进行容错处理。当调用远程服务发生异常时,Dubbo会按照以下顺序进行容错处理:

  1. ClusterInvoker处理异常;
  2. 如果ClusterInvoker处理异常失败,则交由Router处理异常;
  3. 如果Router处理异常失败,则交由LoadBalance处理异常;
  4. 如果LoadBalance处理异常失败,则抛出异常给InvokerInvocationHandler,最终抛出给Consumer。同时,Dubbo还会将异常信息进行监控,并更新调用统计信息。

2. 容错机制扩展的使用示例

Dubbo默认的容错机制是Failover,即自动切换重试其他节点,达到容错和负载均衡的效果。如果需要使用其他容错机制,可以通过在服务提供方和服务消费方的配置文件中进行配置。例如,我们可以通过以下方式配置使用Failfast容错机制:

在服务提供方的配置文件中增加如下配置:

<dubbo:service interface="com.example.service.SomeService" retries="0"/>

在服务消费方的配置文件中增加如下配置:

<dubbo:reference interface="com.example.service.SomeService" check="false" cluster="failfast"/>

这样,在服务调用出现异常时,Dubbo框架会自动使用Failfast容错机制进行处理,即只进行一次调用,若调用失败则立即抛出异常,不进行重试。

3. 自定义容错策略的实现示例

如果需要实现自定义的容错策略,可以通过继承org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker类,并实现org.apache.dubbo.rpc.Invoker接口,来自定义容错策略的实现。

例如,我们可以通过以下代码实现一个自定义的容错策略:

public class MyClusterInvoker<T> extends AbstractClusterInvoker<T> {
    public MyClusterInvoker(Directory<T> directory) {
        super(directory);
    }

    @Override
    protected Result doInvoke(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance) throws RpcException {
        // 自定义容错逻辑
        ...
    }
}

在实现自定义容错策略后,需要在服务提供方和服务消费方的配置文件中进行配置。例如,在服务提供方的配置文件中增加如下配置:

<dubbo:service interface="com.example.service.SomeService" cluster="myClusterInvoker"/>

在服务消费方的配置文件中增加如下配置:

<dubbo:reference interface="com.example.service.SomeService" check="false" cluster="myClusterInvoker"/>

这样,在服务调用时,Dubbo框架会使用我们自定义的MyClusterInvoker容错策略进行处理。

八、Dubbo的扩展机制实践

1. 实现一个使用自定义扩展点、过滤器、负载均衡器和容错机制的 Dubbo 服务

在这个实践中,我们将实现一个使用自定义扩展点、过滤器、负载均衡器和容错机制的 Dubbo 服务。

首先,我们需要定义一个服务接口。例如,我们可以定义一个名为 SomeService 的服务接口,如下所示:

public interface SomeService {
    String sayHello(String name);
}

然后,我们需要实现该服务接口。例如,我们可以实现一个名为 SomeServiceImpl 的服务实现类,如下所示:

public class SomeServiceImpl implements SomeService {
    @Override
    public String sayHello(String name) {
        return "Hello, " + name + "!";
    }
}

接下来,我们需要配置 Dubbo 的扩展点、过滤器、负载均衡器和容错机制。例如,我们可以在服务提供方和服务消费方的配置文件中进行如下配置:

<!-- 扩展点配置 -->
<dubbo:protocol name="dubbo" extension="com.example.extension.MyProtocol"/>

<!-- 过滤器配置 -->
<dubbo:provider filter="com.example.filter.MyProviderFilter"/>
<dubbo:consumer filter="com.example.filter.MyConsumerFilter"/>

<!-- 负载均衡器配置 -->
<dubbo:reference interface="com.example.service.SomeService" loadbalance="com.example.loadbalance.MyLoadBalance"/>

<!-- 容错机制配置 -->
<dubbo:service interface="com.example.service.SomeService" cluster="com.example.cluster.MyCluster"/>
<dubbo:reference interface="com.example.service.SomeService" cluster="com.example.cluster.MyCluster"/>

其中,com.example.extension.MyProtocol 是一个自定义的 Dubbo 协议扩展点实现类,com.example.filter.MyProviderFilter 和 com.example.filter.MyConsumerFilter 是自定义的 Dubbo 过滤器实现类,com.example.loadbalance.MyLoadBalance 是一个自定义的 Dubbo 负载均衡器实现类,com.example.cluster.MyCluster 是一个自定义的 Dubbo 容错机制实现类。

最后,我们可以使用 Dubbo 的 API 在客户端调用该服务。例如,我们可以使用如下代码在客户端调用该服务:

// 获取 Dubbo 服务引用
SomeService someService = DubboReferenceBuilder.newBuilder()
        .setInterface(SomeService.class)
        .setUrl("dubbo://localhost:20880")
        .build();

// 调用 Dubbo 服务
String result = someService.sayHello("Dubbo");
System.out.println(result);

这样,我们就实现了一个使用自定义扩展点、过滤器、负载均衡器和容错机制的 Dubbo 服务。


上一篇:Dubbo高手之路1,Dubbo原理和机制,Dubbo的核心组件


在这里插入图片描述

🏆本文收录于,Java进阶教程系列。

全网最细Java零基础手把手入门教程,系列课程包括:基础篇、集合篇、Java8新特性、多线程、代码实战,持续更新中(每周1-2篇),适合零基础和进阶提升的同学。

🏆哪吒多年工作总结:Java学习路线总结,搬砖工逆袭Java架构师。

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

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

相关文章

阿里云对象存储OSS预留空间详细介绍

对象存储OSS预留空间是什么&#xff1f;预留空间是指定地域的&#xff0c;仅可抵扣该地域“标准存储 - 本地冗余”的OSS存储费用&#xff0c;不支持非存储容量费用抵扣&#xff0c;付费周期一年&#xff0c;阿里云对象存储推出全新预留空间产品&#xff08;Reserved Capacity&a…

Redis 之 缓存预热 缓存雪崩 缓存击穿 缓存穿透

目录 一、缓存预热 1.1 缓存预热是什么&#xff1f; 1.2 解决方案&#xff1a; 二、缓存雪崩 2.1 缓存雪崩是什么&#xff1f;怎么发生的&#xff1f; 2.2 怎么解决 三、缓存穿透 3.1 是什么&#xff1f;怎么产生的呢&#xff1f; 3.2 解决方案 3.2.1、采用回写增强&a…

想了解一个项目完整测试流程,看这篇文章就OK了

项目的测试流程大只包含的几个阶段&#xff1a;立项、需求评审、用例评审、测试执行、测试报告文档    一、立项后测试需要拿到的文档 1、需求说明书   2、原型图&#xff08;及UI图&#xff09;   3、接口文档   4、数据库字典&#xff08;表的数量、缓存机制&#x…

第57步 深度学习图像识别:CNN可视化(Pytorch)

基于WIN10的64位系统演示 一、写在前面 由于不少模型使用的是Pytorch&#xff0c;因此这一期补上基于Pytorch实现CNN可视化的教程和代码&#xff0c;以SqueezeNet模型为例。 二、CNN可视化实战 继续使用胸片的数据集&#xff1a;肺结核病人和健康人的胸片的识别。其中&…

新版百度、百家号旋转验证码识别

昨天突然发现&#xff0c;百度旋转验证码发生了变化&#xff0c;导致使用老版本验证码训练出来的识别模型效果不佳。所有昨天花了一天时间完成了新版模型的训练。 老版本验证码 新版本验证码 新版的验证码感觉像是AI绘画随机生成的&#xff0c;还有随机阴影出现。 验证码识别…

python -m参数的作用(python3 -m)

文章目录 Python -m 参数的作用直接执行模块代码模块自测试环境隔离避免名称冲突 其他&#xff1a;python3 --help Python -m 参数的作用 在Python中&#xff0c;使用-m参数可以执行一个模块作为脚本。它是用于从命令行直接运行一个Python模块的标志。这种方式具有以下几个方面…

git远程仓库的创建及使用

1.仓库的概念&#xff1a; 1.1 本地仓库&#xff1a; 了解远程仓库前我们先了解一下本地仓库&#xff0c;本地仓库开发人员在完成部分代码的编写之后&#xff0c;可以将这一部分的代码做一个提交。这个提交完全就是一个新的版本提交&#xff0c;当然这个提交动作是在开发者的电…

QT生成Word PDF文档

需求&#xff1a;将软件处理的结果保存为一个报告文档&#xff0c;文档中包含表格、图片、文字&#xff0c;格式为word的.doc和.pdf。生成word是为了便于用户编辑。 开发环境&#xff1a;qt4.8.4vs2010 在qt的官网上对于pdf的操作介绍如下&#xff1a;http://qt-project.org/…

【Linux】NAT技术——解决IP地址短缺手段

NAT技术 NAT&#xff08;Network Address Translation&#xff0c;网络地址转换&#xff09;技术&#xff0c;是解决IP地址不足的主要手段&#xff0c;并且能够有效地避免来自网络外部的攻击&#xff0c;隐藏并保护网络内部的计算机。 NAT技术背景 在IPv4协议中&#xff0c;…

Windows - UWP - 网络不好的情况下安装(微软商店)MicrosoftStore的应用

Windows - UWP - 网络不好的情况下安装&#xff08;微软商店&#xff09;MicrosoftStore的应用 前言 UWP虽然几乎被微软抛弃了&#xff0c;但不得不否认UWP应用给用户带来的体验。沙箱的运行方式加上微软的审核&#xff0c;用户使用起来非常放心&#xff0c;并且完美契合Wind…

idea cannot download sources 解决方法

问题 点击class文件右上角下载源码失败 解决方案 找到idea terminal 控制台cd 至maven工程执行 mvn dependency:resolve -Dclassifiersources

session是什么?它与cookie有什么关系?

session是什么&#xff1f; Session是服务器端使用的一种记录客户端状态的机制&#xff0c;使用上比Cookie简单一些&#xff0c;相应的也增加了服务器的存储压力。 session和cookie一样&#xff0c;都是用来记录web服务器和客户端通信状态的机制&#xff0c;session和cookie不同…

AspectCore和MSDI 实现Name注册以及解析对象

AspectCore 在注册服务这块比较简单&#xff0c;默认是无法根据Name去注册和解析对象&#xff0c;这边做一下这块的扩展 大致原理是根据自定义Name去生成对应的动态类型&#xff0c;然后使用委托或者对象的方式&#xff0c;进行注册 tips:由于底层原理的原因&#xff0c;无法…

JavaWeb 速通JSP

目录 一、JSP快速入门 1.基本介绍 : 2.运行原理 : 二、JSP语法 1.page指令 : 2.声明脚本 : 3.表达式脚本 : 4.Java代码脚本 : 5.JSP注释 : 三、JSP对象 1.九大内置对象 : 2.四大域对象 : 1 基本介绍 2 应用实例 3.关于请求转发标签 : 一、JSP快速入门 1.基本介绍 …

用友-NC-Cloud远程代码执行漏洞[2023-HW]

用友-NC-Cloud远程代码执行漏洞[2023-HW] 一、漏洞介绍二、资产搜索三、漏洞复现PoC小龙POC检测脚本: 四、修复建议 免责声明&#xff1a;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#…

KafkaStream:Springboot中集成

1、在kafka-demo中创建配置类 配置kafka参数 package com.heima.kafkademo.config;import lombok.Data; import org.apache.kafka.common.serialization.Serdes; import org.apache.kafka.streams.StreamsConfig; import org.springframework.boot.context.properties.Configu…

基于grpc从零开始搭建一个准生产分布式应用(2) - 工程构建

开始本章之前默认读者已经配置好了以下环境&#xff1a;Intellij IDEA 2022.1.2、JDK 1.8.0_144、Maven 3&#xff0c;另外也建议大家在一些免费代码托管平台开个帐号&#xff0c;这样就可以免费使用git做版本处理了&#xff0c;笔者自己私人使用的是阿里云的云效平台。因为此专…

【Lua基础入门】解密世界上最快的脚本语言

文章目录 前言一、Lua简介二、Lua功能三、安装LuaUbuntu LinuxWindows安装Lua 四、第一个Lua程序总结 前言 Lua是一种轻量级、快速且可嵌入的脚本语言&#xff0c;广泛应用于游戏开发、嵌入式系统、脚本扩展等领域。它的设计目标是简单、高效、可定制和易于集成。本文将介绍Lu…

射频入门知识-1

信号源 示波器 综合测试仪 功率计 噪声测试仪 频谱分析仪 频谱分析仪: 放大器的噪声系数测试 放大器增益测试 噪声和增益是放大器的最关键指标&#xff0c;学学怎么用频谱仪做放大器的噪声测试 那个 hbf740 输入和输出阻抗匹配具体怎么搞 《ADS2011射频电路设计与…

iOS Epub阅读器改造记录

六个月前在这个YHEpubDemo阅读器的基础上做了一些优化&#xff0c;这里做一下记录。 1.首行缩进修复 由于分页的存在&#xff0c;新的一页的首行可能是新的一行&#xff0c;则应该缩进&#xff1b;也可能是前面一页段落的延续&#xff0c;这时候不应该缩进。YHEpubDemo基于XDS…