文章目录

一、概念二、功能介绍1、@Service2、@Reference3、@Method4、@Argument

三、分析四、如何实现?1、熔断(Circuit Breaker)XML配置方式注解方式

2、降级(Fallback)XML配置方式注解方式

3、限流(Rate Limiting)XML配置方式注解方式

4、负载均衡(Load Balancing)XML配置方式注解方式

五、扩展1、Feign和Openfeign区别?2、Hystrix和Sentinel的区别?

一、概念

Dubbo是一个开源的分布式服务框架,它提供了服务治理、负载均衡、容错机制等一系列功能。主要用于提高应用的性能和可扩展性,让应用间通过远程调用的方式进行通信。 通过Dubbo,可以将一个大型的应用系统拆分成多个服务,每个服务可以独立部署和升级,提高了系统的灵活性和可维护性。 Dubbo支持多种协议和传输方式,包括HTTP、REST、RMI等,同时还提供了可靠性保证、负载均衡、服务注册与发现等核心功能。 总的来说,Dubbo可以帮助企业构建分布式架构,并提供可靠的服务调用和管理机制。

二、功能介绍

通过看dubbo-2.7.1源码,我们可以看到org.apache.dubbo.config.annotation,下面提供了4个注解:@Service,@Reference,@Method和@Argument

1、@Service

@Service注解用于将一个类标记为Dubbo服务的提供者。在需要暴露服务的类上添加该注解,并配置相应的接口,Dubbo会自动将该类实现的接口注册为一个Dubbo服务。

注解源码如下:

@Documented

@Retention(RetentionPolicy.RUNTIME)

@Target({ElementType.TYPE})

@Inherited

public @interface Service {

/**

* Interface class, default value is void.class

*/

Class interfaceClass() default void.class;

/**

* Interface class name, default value is empty string

*/

String interfaceName() default "";

/**

* Service version, default value is empty string

*/

String version() default "";

/**

* Service group, default value is empty string

*/

String group() default "";

/**

* Service path, default value is empty string

*/

String path() default "";

/**

* Whether to export service, default value is true

*/

boolean export() default true;

/**

* Service token, default value is false

*/

String token() default "";

/**

* Whether the service is deprecated, default value is false

*/

boolean deprecated() default false;

/**

* Whether the service is dynamic, default value is false

*/

boolean dynamic() default false;

/**

* Access log for the service, default value is ""

*/

String accesslog() default "";

/**

* Maximum concurrent executes for the service, default value is 0 - no limits

*/

int executes() default 0;

/**

* Whether to register the service to register center, default value is true

*/

boolean register() default true;

/**

* Service weight value, default value is 0

*/

int weight() default 0;

/**

* Service doc, default value is ""

*/

String document() default "";

/**

* Delay time for service registration, default value is 0

*/

int delay() default 0;

/**

* @see Service#stub()

* @deprecated

*/

String local() default "";

/**

* Service stub name, use interface name + Local if not set

*/

String stub() default "";

/**

* Cluster strategy, legal values include: failover, failfast, failsafe, failback, forking

*/

String cluster() default "";

/**

* How the proxy is generated, legal values include: jdk, javassist

*/

String proxy() default "";

/**

* Maximum connections service provider can accept, default value is 0 - connection is shared

*/

int connections() default 0;

/**

* The callback instance limit peer connection

*

* @see Constants#DEFAULT_CALLBACK_INSTANCES

*/

int callbacks() default Constants.DEFAULT_CALLBACK_INSTANCES;

/**

* Callback method name when connected, default value is empty string

*/

String onconnect() default "";

/**

* Callback method name when disconnected, default value is empty string

*/

String ondisconnect() default "";

/**

* Service owner, default value is empty string

*/

String owner() default "";

/**

* Service layer, default value is empty string

*/

String layer() default "";

/**

* Service invocation retry times

*

* @see Constants#DEFAULT_RETRIES

*/

int retries() default Constants.DEFAULT_RETRIES;

/**

* Load balance strategy, legal values include: random, roundrobin, leastactive

*

* @see Constants#DEFAULT_LOADBALANCE

*/

String loadbalance() default Constants.DEFAULT_LOADBALANCE;

/**

* Whether to enable async invocation, default value is false

*/

boolean async() default false;

/**

* Maximum active requests allowed, default value is 0

*/

int actives() default 0;

/**

* Whether the async request has already been sent, the default value is false

*/

boolean sent() default false;

/**

* Service mock name, use interface name + Mock if not set

*/

String mock() default "";

/**

* Whether to use JSR303 validation, legal values are: true, false

*/

String validation() default "";

/**

* Timeout value for service invocation, default value is 0

*/

int timeout() default 0;

/**

* Specify cache implementation for service invocation, legal values include: lru, threadlocal, jcache

*/

String cache() default "";

/**

* Filters for service invocation

*

* @see Filter

*/

String[] filter() default {};

/**

* Listeners for service exporting and unexporting

*

* @see ExporterListener

*/

String[] listener() default {};

/**

* Customized parameter key-value pair, for example: {key1, value1, key2, value2}

*/

String[] parameters() default {};

/**

* Application spring bean name

*/

String application() default "";

/**

* Module spring bean name

*/

String module() default "";

/**

* Provider spring bean name

*/

String provider() default "";

/**

* Protocol spring bean names

*/

String[] protocol() default {};

/**

* Monitor spring bean name

*/

String monitor() default "";

/**

* Registry spring bean name

*/

String[] registry() default {};

/**

* Service tag name

*/

String tag() default "";

/**

* methods support

* @return

*/

Method[] methods() default {};

}

常用属性说明:

interface:指定实现的接口类,用于指定要发布的服务接口。包括2中方式,interfaceClass和interfaceName。version:指定服务的版本号,用于支持多个版本的服务并存。group:指定服务的分组,用于区分不同的服务实现。cluster:指定集群容错策略,用于处理服务提供者的故障和网络异常。actives:指定最大并发调用数,用于限制服务的并发访问量。executes:指定服务的最大线程池大小,用于限制服务的并发处理能力。

使用的话,类似org.springframework.stereotype.Service,示例如下:

@Service(interfaceClass=ForlanService.class,timeout = 300000)

public class ForlanServiceImpl implements ForlanService{

// 实现接口方法

}

2、@Reference

@Reference注解用于将一个接口的引用注入到当前类中,在需要使用Dubbo服务的地方添加该注解,并配置相应的接口,Dubbo会自动将该接口的一个远程代理注入到当前类中。

注解源码如下:

@Documented

@Retention(RetentionPolicy.RUNTIME)

@Target({ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE})

public @interface Reference {

/**

* Interface class, default value is void.class

*/

Class interfaceClass() default void.class;

/**

* Interface class name, default value is empty string

*/

String interfaceName() default "";

/**

* Service version, default value is empty string

*/

String version() default "";

/**

* Service group, default value is empty string

*/

String group() default "";

/**

* Service target URL for direct invocation, if this is specified, then registry center takes no effect.

*/

String url() default "";

/**

* Client transport type, default value is "netty"

*/

String client() default "";

/**

* Whether to enable generic invocation, default value is false

*/

boolean generic() default false;

/**

* When enable, prefer to call local service in the same JVM if it's present, default value is true

*/

boolean injvm() default true;

/**

* Check if service provider is available during boot up, default value is true

*/

boolean check() default true;

/**

* Whether eager initialize the reference bean when all properties are set, default value is false

*/

boolean init() default false;

/**

* Whether to make connection when the client is created, the default value is false

*/

boolean lazy() default false;

/**

* Export an stub service for event dispatch, default value is false.

*

* @see Constants#STUB_EVENT_METHODS_KEY

*/

boolean stubevent() default false;

/**

* Whether to reconnect if connection is lost, if not specify, reconnect is enabled by default, and the interval

* for retry connecting is 2000 ms

*

* @see Constants#DEFAULT_RECONNECT_PERIOD

*/

String reconnect() default "";

/**

* Whether to stick to the same node in the cluster, the default value is false

*

* @see Constants#DEFAULT_CLUSTER_STICKY

*/

boolean sticky() default false;

/**

* How the proxy is generated, legal values include: jdk, javassist

*/

String proxy() default "";

/**

* Service stub name, use interface name + Local if not set

*/

String stub() default "";

/**

* Cluster strategy, legal values include: failover, failfast, failsafe, failback, forking

*/

String cluster() default "";

/**

* Maximum connections service provider can accept, default value is 0 - connection is shared

*/

int connections() default 0;

/**

* The callback instance limit peer connection

*

* @see Constants#DEFAULT_CALLBACK_INSTANCES

*/

int callbacks() default 0;

/**

* Callback method name when connected, default value is empty string

*/

String onconnect() default "";

/**

* Callback method name when disconnected, default value is empty string

*/

String ondisconnect() default "";

/**

* Service owner, default value is empty string

*/

String owner() default "";

/**

* Service layer, default value is empty string

*/

String layer() default "";

/**

* Service invocation retry times

*

* @see Constants#DEFAULT_RETRIES

*/

int retries() default 2;

/**

* Load balance strategy, legal values include: random, roundrobin, leastactive

*

* @see Constants#DEFAULT_LOADBALANCE

*/

String loadbalance() default "";

/**

* Whether to enable async invocation, default value is false

*/

boolean async() default false;

/**

* Maximum active requests allowed, default value is 0

*/

int actives() default 0;

/**

* Whether the async request has already been sent, the default value is false

*/

boolean sent() default false;

/**

* Service mock name, use interface name + Mock if not set

*/

String mock() default "";

/**

* Whether to use JSR303 validation, legal values are: true, false

*/

String validation() default "";

/**

* Timeout value for service invocation, default value is 0

*/

int timeout() default 0;

/**

* Specify cache implementation for service invocation, legal values include: lru, threadlocal, jcache

*/

String cache() default "";

/**

* Filters for service invocation

*

* @see Filter

*/

String[] filter() default {};

/**

* Listeners for service exporting and unexporting

*

* @see ExporterListener

*/

String[] listener() default {};

/**

* Customized parameter key-value pair, for example: {key1, value1, key2, value2}

*/

String[] parameters() default {};

/**

* Application spring bean name

*/

String application() default "";

/**

* Module spring bean name

*/

String module() default "";

/**

* Consumer spring bean name

*/

String consumer() default "";

/**

* Monitor spring bean name

*/

String monitor() default "";

/**

* Registry spring bean name

*/

String[] registry() default {};

/**

* Protocol spring bean names

*/

String protocol() default "";

/**

* methods support

* @return

*/

Method[] methods() default {};

}

常用的属性说明:

interface:指定要引用的接口类,用于指定要调用的服务接口。包括2中方式,interfaceClass和interfaceName。version:指定要引用的服务的版本号,用于支持多个版本的服务并存。group:指定要引用的服务的分组,用于区分不同的服务实现。url:指定要引用的服务的URL地址,用于直连方式调用服务。loadbalance:指定负载均衡策略,用于决定服务调用时选择哪个提供者实例。默认为random,可选值还有roundrobin(轮询), leastactive(最小连接数)cluster:指定集群容错策略,用于处理服务提供者的故障和网络异常。timeout:指定服务的超时时间,用于限制服务调用的最大耗时。默认为0,表示不设置超时时间。check:指定是否启动时检查服务依赖关系,用于自动检测缺失的依赖服务。默认为true。只有当check=true且服务提供方处于可用状态时,才会引用该服务。async:指定服务调用是否异步,用于支持异步调用模式。默认为false。如果设置为true,则远程调用将以异步方式执行,并返回一个CompletableFuture对象。lazy:该属性用于指定是否要延迟初始化服务。默认为false。如果设置为true,则在第一次调用该服务时才会进行初始化。retries:该属性用于指定调用远程服务方法的重试次数,默认为2。如果设置为0,则表示不进行重试。mock:该属性用于指定远程服务的Mock实现类,默认为空。在远程服务不可用时,会使用Mock实现类的方法返回默认值。

使用的话,类似@Autowired,示例如下:

@Reference(version = "1.0.0")

private ForlanService forlanService;

3、@Method

@Method注解用于标记方法的信息,以便在方法调用时进行配置,它通常与@Reference或@Service一起使用。

注解源码如下:

@Documented

@Retention(RetentionPolicy.RUNTIME)

@Target({ElementType.ANNOTATION_TYPE})

@Inherited

public @interface Method {

String name();

int timeout() default -1;

int retries() default -1;

String loadbalance() default "";

boolean async() default false;

boolean sent() default true;

int actives() default 0;

int executes() default 0;

boolean deprecated() default false;

boolean sticky() default false;

boolean isReturn() default true;

String oninvoke() default "";

String onreturn() default "";

String onthrow() default "";

String cache() default "";

String validation() default "";

Argument[] arguments() default {};

}

用得少,要使用的话,在需要使用的方法上添加@Method注解,并设置相应的属性。 例如,假设你有一个接口定义如下:

public interface ForlanService {

@Method(name = "getById", timeout = 5000)

User getById(int id);

}

在上面的示例中,@Method注解应用于getById方法,并设置了两个属性:name和timeout。name属性指定方法在远程调用时的名称,timeout属性指定方法调用的超时时间为5000毫秒。

4、@Argument

@Argument注解用于标记方法参数的信息,以便在方法调用时进行配置,它通常与@Method一起使用。

注解源码如下:

@Documented

@Retention(RetentionPolicy.RUNTIME)

@Target({ElementType.ANNOTATION_TYPE})

@Inherited

public @interface Argument {

//argument: index -1 represents not set

int index() default -1;

//argument type

String type() default "";

//callback interface

boolean callback() default false;

}

用得少,要使用的话,在需要使用的方法参数上添加@Argument注解,并设置相应的属性。 例如,假设你有一个接口定义如下:

public interface ForlanService {

Forlan getById(@Argument(index = 0, callback = true) int id);

}

在上面的示例中,@Argument注解应用于getById方法的id参数,并设置了两个属性:index和callback。index属性指定参数的顺序索引,callback属性指定是否回调该参数。

三、分析

我们可以看到,@Service和@Reference的属性,刚好就满足某种特性,比如timeout控制超时时间;retries指定重试次数;mock在远程服务不可用时,会使用Mock实现类的方法返回默认值;executes限制服务的并发处理能力;loadbalance指定负载均衡策略,等等 所以,Hystrix和Sentinel的熔断降级和限流功能,是不是Dubbo就可以实现替代,同样可以防止系统因为某个服务的问题而崩溃,保护整个系统的正常运行。除此之外,Ribbon是一个客户端负载均衡的工具,Dubbo也一样可以替代

四、如何实现?

Dubbo怎么实现熔断、降级、限流,负载均衡,具体代码实现?

1、熔断(Circuit Breaker)

熔断机制用于在服务出现故障或异常时,暂时中断对该服务的调用,以避免连锁故障,Dubbo提供了circuitbreaker配置来启用熔断机制。

XML配置方式

在上面的示例中,retries属性设置了重试次数,circuitbreaker参数设置了熔断阈值,当调用失败次数达到阈值时,Dubbo会触发熔断。

注解方式

使用Dubbo的@Service注解标记服务提供者,并配置retries属性来设置重试次数,例如:

@Service(retries = 3,parameters = {"circuitbreaker", "10"})

public class ForlanServiceImpl implements ForlanService{

// ...

}

2、降级(Fallback)

降级机制用于在服务不可用时,提供备用的处理逻辑,Dubbo提供了mock配置来实现降级。

XML配置方式

以下是一个示例配置:

在上面的示例中,mock参数指定了一个实现了ForlanService接口的ForlanServiceMock类,当服务不可用时,Dubbo会调用该类中的方法来提供备用逻辑。

注解方式

使用Dubbo的@Reference注解标记服务消费者,并配置mock属性来指定降级逻辑,例如:

@Reference(mock = "com.example.ForlanServiceMock")

private ForlanService forlanService;

创建一个实现了UserService接口的ForlanServiceMock类,用于提供降级逻辑,例如:

public class ForlanServiceMock implements ForlanService{

// 实现降级逻辑

}

3、限流(Rate Limiting)

限流机制用于控制对服务的并发访问量,以保护服务的稳定性。Dubbo提供了executes配置来实现限流。

XML配置方式

在上面的示例中,executes属性设置了最大并发执行数,Dubbo会限制同时执行的请求数量不超过该值。

注解方式

使用Dubbo的@Service注解标记服务提供者,并配置executes属性来设置最大并发执行数,例如:

@Service(executes = 10)

public class ForlanServiceImpl implements ForlanService{

// ...

}

4、负载均衡(Load Balancing)

负载均衡机制用于在多个服务提供者之间分配请求,以实现负载均衡。Dubbo提供了多种负载均衡策略,例如随机、轮询、一致性哈希等。

XML配置方式

在上面的示例中,loadbalance参数设置了负载均衡策略为随机,Dubbo会随机选择一个服务提供者来处理请求。

注解方式

使用Dubbo的@Reference注解标记服务消费者,并配置loadbalance属性来指定负载均衡策略,例如:

@Reference(loadbalance = "random")

private ForlanService forlanService;

五、扩展

1、Feign和Openfeign区别?

OpenFeign是Spring Cloud在Feign的基础上支持了SpringMVC的注解

2、Hystrix和Sentinel的区别?

Hystrix和Sentinel都是用于分布式系统中的容错和熔断保护的开源框架,但两者在一些方面有所不同。

项目背景:Hystrix是由Netflix开发的,而Sentinel是由阿里巴巴开发的。这意味着Hystrix更多地关注于Netflix内部的需求,而Sentinel则更适合阿里巴巴的业务场景。语言支持:Hystrix主要支持Java语言,而Sentinel不仅支持Java,还支持Go、C++等多种语言。功能特性:Hystrix提供基于线程池隔离和信号量隔离的熔断机制,并提供了线程池的监控和度量功能。Sentinel除了提供熔断机制外,还具备流量控制、系统负载保护、统计和降级等功能。生态系统:Hystrix已进入维护模式,停止了新功能的开发。而Sentinel在国内得到了广泛的应用,并且还与Spring Cloud、Dubbo等框架进行了集成。综上所述,Hystrix和Sentinel在功能特性、语言支持和生态系统等方面存在一些差异,选择哪个取决于实际的业务需求和技术栈。

文章来源

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: