Dubbo是一个开源的分布式服务框架,它提供了服务治理、负载均衡、容错机制等一系列功能。主要用于提高应用的性能和可扩展性,让应用间通过远程调用的方式进行通信。
通过Dubbo,可以将一个大型的应用系统拆分成多个服务,每个服务可以独立部署和升级,提高了系统的灵活性和可维护性。
Dubbo支持多种协议和传输方式,包括HTTP、REST、RMI等,同时还提供了可靠性保证、负载均衡、服务注册与发现等核心功能。
总的来说,Dubbo可以帮助企业构建分布式架构,并提供可靠的服务调用和管理机制。
通过看dubbo-2.7.1源码,我们可以看到org.apache.dubbo.config.annotation,下面提供了4个注解:@Service,@Reference,@Method和@Argument
@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{
// 实现接口方法
}
@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;
@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毫秒。
@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怎么实现熔断、降级、限流,负载均衡,具体代码实现?
熔断机制用于在服务出现故障或异常时,暂时中断对该服务的调用,以避免连锁故障,Dubbo提供了circuitbreaker配置来启用熔断机制。
<dubbo:service interface="com.example.ForlanService" retries="3">
<dubbo:parameter key="circuitbreaker" value="10"/>
dubbo:service>
在上面的示例中,retries属性设置了重试次数,circuitbreaker参数设置了熔断阈值,当调用失败次数达到阈值时,Dubbo会触发熔断。
使用Dubbo的@Service注解标记服务提供者,并配置retries属性来设置重试次数,例如:
@Service(retries = 3,parameters = {"circuitbreaker", "10"})
public class ForlanServiceImpl implements ForlanService{
// ...
}
降级机制用于在服务不可用时,提供备用的处理逻辑,Dubbo提供了mock配置来实现降级。
以下是一个示例配置:
<dubbo:reference id="forlanService" interface="com.example.ForlanService">
<dubbo:parameter key="mock" value="com.example.ForlanServiceMock"/>
dubbo:reference>
在上面的示例中,mock参数指定了一个实现了ForlanService接口的ForlanServiceMock类,当服务不可用时,Dubbo会调用该类中的方法来提供备用逻辑。
@Reference(mock = "com.example.ForlanServiceMock")
private ForlanService forlanService;
public class ForlanServiceMock implements ForlanService{
// 实现降级逻辑
}
限流机制用于控制对服务的并发访问量,以保护服务的稳定性。Dubbo提供了executes配置来实现限流。
<dubbo:service interface="com.example.ForlanService" executes="10"/>
在上面的示例中,executes属性设置了最大并发执行数,Dubbo会限制同时执行的请求数量不超过该值。
使用Dubbo的@Service注解标记服务提供者,并配置executes属性来设置最大并发执行数,例如:
@Service(executes = 10)
public class ForlanServiceImpl implements ForlanService{
// ...
}
负载均衡机制用于在多个服务提供者之间分配请求,以实现负载均衡。Dubbo提供了多种负载均衡策略,例如随机、轮询、一致性哈希等。
<dubbo:reference id="userService" interface="com.example.ForlanService">
<dubbo:parameter key="loadbalance" value="random"/>
dubbo:reference>
在上面的示例中,loadbalance参数设置了负载均衡策略为随机,Dubbo会随机选择一个服务提供者来处理请求。
使用Dubbo的@Reference注解标记服务消费者,并配置loadbalance属性来指定负载均衡策略,例如:
@Reference(loadbalance = "random")
private ForlanService forlanService;
OpenFeign是Spring Cloud在Feign的基础上支持了SpringMVC的注解
Hystrix和Sentinel都是用于分布式系统中的容错和熔断保护的开源框架,但两者在一些方面有所不同。