1、支持多种协议的服务发布
默认是dubbo://,还支持rest://、webservice://、thrift://等等
2、支持多种不同的注册中心组件
nacos、ZooKeeper、Redis可能还会支持Consul、Eureka等等
3、支持多种序列化技术
acro、fst、fastjson、kryo等等
4、集群容错
Dubbo总共默认提供了6中容错模式,默认是Failover Cluster,如果默认的还不够你使用的,可以自定义,Dubbo这点是最好的,好多处理方案都可以提供插拔式的拓展
容错模式 作用 Failover Cluster 失败自动切换,当服务调用失败后,会切换到集群中的其他机器进行重试,默认重试2次,可以通过retries进行修改重试次数,不过这里需要注意的是重试会带来响应延迟,所以一般情况这个默认会用于读操作,因为这种事务性操作会带来数据重复的问题 Failfast Cluster 快速失败,当服务调用失败后,服务立即报错,只会发起一次调用,一般情况会用于幂等的写操作,比如数据新增,因为服务调动失败时,很有可能这个请求已经在服务器端处理成功了,只是因为网络延迟导致响应失败,为了避免这种在结果不确定的情况下导致数据重复插入的问题,可以使用这种模式 Failsafe Cluster 失败安全,就是出现异常时,直接忽略异常继续执行,不至于直接报错 Failback Cluster 失败后自动回复,当一个服务器调用出现异常时,在后台记录这条失败的请求定时重发,这种模式是和用于消息通知操作,保证这个请求会一定发送成功 Forking Cluster 并行调用集群中的多个服务,只要其中一个成功就返回,可以通过forks属性来设置最大并行数,这个并行数个人建议不要太高 Broadcast Cluster 广播调用所有的服务提供者,任意一个服务报错都标识服务调用失败,这个模式通常用于通知所有的服务提供者更新缓存或者本地资源信息 1、配置方式:只需要在@Service注解上添加cluster属性值即可,代码如下:
@Service(cluster = "failfast") //服务注册 @org.springframework.stereotype.Service //spring注入 public class HelloServiceImpl implements IHelloService { public String sayHello(String name) { return name; } }
2、实际应用开发中,查询语句建议使用默认的Failover Cluster,而增删改则建议使用Failfast Cluster或者Failover Cluster(retries="0")的模式,防止出现数据重复等问题,建议设计接口的时候把查询接口方法单独做成一个接口提供查询
5、负载均衡
概念就不多说了,了解Nginx或者做过分布式的都清楚,在Dubbo里提供了四种负载均衡策略,默认是random随机,如果这四个不够用,还是和4中提到的一样,通过SPI机制来自行拓展
策略值 作用 Random LoadBalance 随机算法,可以针对性能较好的服务器设置相对大的权重,权重越大,随机的概率就越大,和nginx负载均衡一个概念 Round LoadBalance 轮询,按照公约后的权重设置轮询比例 LeastActive LoadBalance 最小活跃调用,处理较慢的节点将会受到更少的请求 ConsistentHash LoadBalance 一致性Hash,相同参数的请求总是发送到同一个服务提供者 代码实现如下:
@Service(cluster = "failfast",loadbalance = "roundrobin") //服务注册 @org.springframework.stereotype.Service //spring注入 public class HelloServiceImpl implements IHelloService { public String sayHello(String name) { return name; } }
或者在调用的时候指定
@Reference(retries = 0,check = false,loadbalance = "roundrobin") private IHelloService iHelloService;
6、服务降级
降级有多个层面的分类:
1、按照是否自动化可分为自动降级和人工降级
①人工降级一般具有一定的前置性,比如在电商大促之前,人为的去关闭服务中不太核心的服务,比如推荐、评价等
②自动降级大多来自于系统中出现某些异常时自动触发
- 故障降级,调用的服务宕机了,或者网络故障或者返回异常,这个时候为了保证上游的服务正常,不能直接抛出异常,需要自定义兜底数据返回给上游客户端
- 限流降级,只要是应用,它能接受的流量肯定是有限的,为了保证服务正常不垮掉,一般情况下,开发人员会针对核心业务进行限流,当请求达到预设的阈值时,就要做拦截,这个时候可以上锁,或者排队请求
2、按照功能可分为读服务降级和写服务降级
Dubbo框架为我们提供了一种Mock配置来实现兜底服务降级,也就是说,当调用的时候,下游服务出现异常无法访问的时候,要求客户端不能抛出异常,而是将实现准备好的兜底数据返回到客户端,具体代码实现如下:
//配置兜底数据
public class MockHelloService implements IHelloService{
@Override
public String sayHello(String name){
//设置兜底数据,服务调用异常时返回
return "服务器异常,请稍后再试!";
}
}
--------------------------------------------------------------------
//远程调用处理
@Reference(
mock="com.cb.dubbospringcloudconsumer.service.MockHelloService",
cluster="failfast"
)
private IHelloService iHelloService;
这样,当消费者调用生产者服务的时候,生产者挂掉了,那么消费者就会直接返回:"服务器异常,请稍后再试!",这样,降级的目的就达到了