当前位置: 首页> 教育> 高考 > Dubbo

Dubbo

时间:2025/8/25 11:06:46来源:https://blog.csdn.net/weixin_41879185/article/details/142211952 浏览次数:0次

基于 Spring Boot Starter 开发微服务应用

https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/quick-start/spring-boot/

Dubbo Demo

https://github.com/apache/dubbo-samples

高级特性和用法

框架与服务

1 版本与分组

Dubbo服务中,接口并不能唯一确定一个服务,只有 接口+分组+版本号 的三元组才能唯一确定一个服务。

  • 当同一个接口针对不同的业务场景、不同的使用需求或者不同的功能模块等场景,可使用服务分组来区分不同的实现方式。同时,这些不同实现所提供的服务是可并存的,也支持互相调用。
  • 当接口实现需要升级又要保留原有实现的情况下,即出现不兼容升级时,我们可以使用不同版本号进行区分。
使用方式

使用 @DubboService 注解,配置 group 参数和 version 参数:

生产者
//接口定义
public interface DevelopService {String invoke(String param);
}//接口实现1 都是同一个接口不同是的实现类
@DubboService(group = "group1", version = "1.0")
public class DevelopProviderServiceV1 implements DevelopService{@Overridepublic String invoke(String param) {StringBuilder s = new StringBuilder();s.append("ServiceV1 param:").append(param);return s.toString();}
}//接口实现2
@DubboService(group = "group2", version = "2.0")
public class DevelopProviderServiceV2 implements DevelopService{@Overridepublic String invoke(String param) {StringBuilder s = new StringBuilder();s.append("ServiceV2 param:").append(param);return s.toString();}
}
消费者

@DubboReference(group = "group1", version = "1.0")
private DevelopService developService;@DubboReference(group = "group2", version = "2.0")
private DevelopService developServiceV2;//group值为*,标识匹配任意服务分组
@DubboReference(group = "*")
private DevelopService developServiceAny;@Override
public void run(String... args) throws Exception {//调用DevelopService的group1分组实现System.out.println("Dubbo Remote Return ======> " + developService.invoke("1"));//调用DevelopService的另一个实现System.out.println("Dubbo Remote Return ======> " + developServiceV2.invoke("2"));
}

2 参数校验

特性说明

参数验证功能是基于 JSR303 实现的,用户只需标识 JSR303 标准的验证 annotation,并通过声明 filter 来实现验证。

Maven 依赖
<dependency><groupId>javax.validation</groupId><artifactId>validation-api</artifactId><version>1.0.0.GA</version>
</dependency>
<dependency><groupId>org.hibernate</groupId><artifactId>hibernate-validator</artifactId><version>4.2.0.Final</version>
</dependency>

使用场景

服务端在向外提供接口服务时,解决各种接口参数校验问题。

参考用例 https://github.com/apache/dubbo-samples/tree/master/dubbo-samples-validation

使用方式
参数标注示例
import java.io.Serializable;
import java.util.Date;import javax.validation.constraints.Future;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Past;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;public class ValidationParameter implements Serializable {private static final long serialVersionUID = 7158911668568000392L;@NotNull // 不允许为空@Size(min = 1, max = 20) // 长度或大小范围private String name;@NotNull(groups = ValidationService.Save.class) // 保存时不允许为空,更新时允许为空 ,表示不更新该字段@Pattern(regexp = "^\\s*\\w+(?:\\.{0,1}[\\w-]+)*@[a-zA-Z0-9]+(?:[-.][a-zA-Z0-9]+)*\\.[a-zA-Z]+\\s*$")private String email;@Min(18) // 最小值@Max(100) // 最大值private int age;@Past // 必须为一个过去的时间private Date loginDate;@Future // 必须为一个未来的时间private Date expiryDate;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public Date getLoginDate() {return loginDate;}public void setLoginDate(Date loginDate) {this.loginDate = loginDate;}public Date getExpiryDate() {return expiryDate;}public void setExpiryDate(Date expiryDate) {this.expiryDate = expiryDate;}
}
分组验证示例
public interface ValidationService { // 缺省可按服务接口区分验证场景,如:@NotNull(groups = ValidationService.class)   @interface Save{} // 与方法同名接口,首字母大写,用于区分验证场景,如:@NotNull(groups = ValidationService.Save.class),可选void save(ValidationParameter parameter);void update(ValidationParameter parameter);
}
方法中参数验证示例
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;public interface ValidationService {void save(@NotNull ValidationParameter parameter); // 验证参数不为空void delete(@Min(1) int id); // 直接对基本类型参数验证
}

3 集群容错

在集群调用失败时,Dubbo 提供了多种容错方案,缺省为 failover 重试。

各节点关系:

  • 这里的 Invoker 是 Provider 的一个可调用 Service 的抽象,Invoker 封装了 Provider 地址及 Service 接口信息
  • Directory 代表多个 Invoker,可以把它看成 List<Invoker> ,但与 List 不同的是,它的值可能是动态变化的,比如注册中心推送变更
  • Cluster 将 Directory 中的多个 Invoker 伪装成一个 Invoker,对上层透明,伪装过程包含了容错逻辑,调用失败后,重试另一个
  • Router 负责从多个 Invoker 中按路由规则选出子集,比如读写分离,应用隔离等
  • LoadBalance 负责从多个 Invoker 中选出具体的一个用于本次调用,选的过程包含了负载均衡算法,调用失败后,需要重选
Failover Cluster

失败自动切换,当出现失败,重试其它服务器。通常用于读操作,但重试会带来更长延迟。可通过 retries="2" 来设置重试次数(不含第一次)

重试次数配置如下:

<dubbo:service retries="2" />或<dubbo:reference retries="2" />或<dubbo:reference><dubbo:method name="findFoo" retries="2" />
</dubbo:reference>
Failsafe Cluster 失败安全

失败安全,出现异常时,直接忽略。通常用于写入审计日志等操作。

Failback Cluster 失败自动恢复

失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。

Forking Cluster 并行调用多个服务器

并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源可通过 forks="2" 来设置最大并行数。

Broadcast Cluster 广播调用

广播调用所有提供者,逐个调用,任意一台报错则报错。通常用于通知所有提供者更新缓存或日志等本地资源信息。

现在广播调用中,可以通过 broadcast.fail.percent 配置节点调用失败的比例,当达到这个比例后,BroadcastClusterInvoker 将不再调用其他节点,直接抛出异常。 broadcast.fail.percent 取值在 0~100 范围内。默认情况下当全部调用失败后,才会抛出异常。 broadcast.fail.percent 只是控制的当失败后是否继续调用其他节点,并不改变结果(任意一台报错则报错)。broadcast.fail.percent 参数 在 dubbo2.7.10 及以上版本生效。

Broadcast Cluster 配置 broadcast.fail.percent。

broadcast.fail.percent=20 代表了当 20% 的节点调用失败就抛出异常,不再调用其他节点。

@reference(cluster = "broadcast", parameters = {"broadcast.fail.percent", "20"})

集群模式配置

按照以下示例在服务提供方和消费方配置集群模式

<dubbo:service cluster="failsafe" />

<dubbo:reference cluster="failsafe" />

4 服务降级

Dubbo服务降级通常是指在服务不可用或负载过高时,为某些服务调用提供备选方案,以防止系统崩溃或性能下降。在Dubbo中,可以使用Mock机制来实现服务降级。

Mock伪造返回数据,可用作服务降级

  • 强制返回null
<dubbo:reference id="demoService" interface="com.example.DemoService" mock="return null"/>
  • 这种方式强制执行本地伪装逻辑,即使远程调用正常也会执行降级逻辑。
  • 一般用这种,直接降级
<dubbo:reference id="demoService" interface="com.example.DemoService" mock="force:true"/>

或者

@DubboService(version = "1.0.0",timeout = 3000, mock = "force:true")
  • 1 mock = force:return+null:强制服务返回null,不会进行RPC调用
  • 2 mock = fail:return+null:调用服务失败后返回null,会进行RPC调用。
  • 3 mock = throw:直接跑RpcException,不会RPC调用

以下是使用Dubbo Mock机制的步骤:

  1. 实现Mock接口。

  2. 配置Mock规则。

1 定义一个服务接口:public interface MyService {String sayHello(String name);
}
2 实现Mock接口:public class MyServiceMock implements MyService {@Overridepublic String sayHello(String name) {return "Mocked: Hello, " + name;}
}
3 在provider的配置文件中添加Mock规则:<dubbo:service interface="MyService" ref="myService" mock="MyServiceMock"/>
或者在注解配置中使用:@Service(version = "1.0.0", mock = "MyServiceMock")
public class MyServiceImpl implements MyService {// ...
}

MyService不可用时,Dubbo会自动使用MyServiceMock的实现。

注意:

  • 确保Mock类和服务接口在同一个ClassLoader下。

  • 如果使用注解配置,请确保Mock类在服务提供者的类路径下。

  • 如果服务提供者不可用,Dubbo也会使用Mock

以上是Dubbo服务降级的一种简单实现方式,具体的降级策略可能需要根据实际情况进行定制。

 

关键字:Dubbo

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: