由于网络配置服务端不可靠,会导致调用出现一种不确定的中间状态(超时)。为了避免超时导致客户端资源挂起或者耗尽,必须设置超时时间。
<dubbo:reference timeout="3000" id="userService" interface="com.ego.inter.service.UserService">
<dubbo:method name="queryAllAddress" timeout="1000"/>
dubbo:reference>
<dubbo:consumer timeout="2000"/>
<dubbo:service timeout="3000" interface="com.ego.inter.service.UserService" ref="userService">
<dubbo:method name="queryAllAddress" timeout="4000"/>
dubbo:service>
<dubbo:provider timeout="5000"/>
在想要暴露的服务上:
@Service(timeout = 1000)
@Reference(timeout = 1000,check = false)
过期时间的配置遵循就近原则。自己配了根据自己的,自己没配再往外找。
在同一个地方配置的以消费者为准。
但是在实际开发中一般配置提供者端。
其它的配置的优先原则也是一样。
在启动消费者时,如果没有启动生产者,会默认进行检查抛出没有生产者的错误。
关闭启动时的检查:
在消费者中配置:
<dubbo:reference timeout="3000" id="userService" check="false" interface="com.ego.inter.service.UserService">
<dubbo:method name="queryAllAddress" timeout="1000"/>
dubbo:reference>
<dubbo:consumer timeout="2000" check="false"/>
全局配置(消费者):
<dubbo:consumer timeout="2000" check="false" retrise="3"/>
单独对象配置(消费者):
<dubbo:reference timeout="3000" id="userService" check="false" retrise="5" interface="com.ego.inter.service.UserService">
<dubbo:method name="queryAllAddress" retrise="1" timeout="1000"/>
dubbo:reference>
注解配置:
@Service(retrise=4)
@Reference(retrise=5)
也是遵循就近原则。
当一个接口实现,出现不兼容升级时,可以使用版本号过渡,版本号不同的服务间不互相引用。
版本迁移步骤:
配置:
<dubbo:service interface="com.ego.provider.impl.UserServiceImpl1" version="1.0.0"/>
<dubbo:service interface="com.ego.provider.impl.UserServiceImpl2" version="2.0.0"/>
<dubbo:reference id="userService" interface="com.ego.inter.service.UserService" version="1.0.0"/>
<dubbo:reference id="userService" interface="com.ego.inter.service.UserService" version="2.0.0"/>
<dubbo:reference id="userService" interface="com.ego.inter.service.UserService" version="*"/>
注解版:
@Service(version="1.0.0")
@Reference(version="*")
远程服务后,客户端通常只剩下接口,而实现全在服务端,但是提供方有些时候也想在客户端执行部分逻辑。
开启方法(位于服务端):
<dubbo:service interface="com.ego.provider.impl.UserServiceImpl"
version="2.0.0" stub="com.ego.provider.impl.SubUserServiceImpl"/>
注解:
@Reference(stub="com.ego.provider.impl.SubUserServiceImpl")
创建SubUserServiceImpl本地实现类:
public class SubUserServiceImpl implements UserService {
// 远程的接口服务对象
private UserService userService;
public SubUserServiceImpl(UserService userService) {
this.userService = userService;
}
public List<UserAddress> queryAllAddress() {
try {
return userService.queryAllAddress();
}catch (Exception e){
return Arrays.asList(new UserAddress(0,"error","error"));
}
}
}
如果zookeeper注册中心宕机,还可以消费dubbo的服务
特性:
就是绕过注册中心直接连接服务器。
@Reference(url="localhost:20880")
UserService userService;
在集群负载均衡时,Dubbo提供了很多种均衡策略,默认是随机调用。
概念:按照权重随机,权重越大被调用到的几率就越大(默认为100)。
设置方法(提供者):
@Service(height=200)
也可以在Dubbo-admin界面上点击“半权”或者“倍”
概念:轮询,按照权重的比例设置轮询。
设置方式:
@Service(height=200,loadbalance="roundrobin")
概念:最少活跃调用数,相同活跃数的随机,活跃指数调用前后计数差。
@Service(loadbalance="leastactive")
一致性的Hash,相同参数的请求总是发到同一提供者。
当某一台提供者挂了时,原本该发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。
默认160份虚拟节点。
@Service(loadbalance="consistenthash")
权重可以使用dubbo-admin来动态的调解权重。
当服务器压力剧增的情况下,根据实际业务情况及流量,对一些服务和页面有策略的不处理或换种简单的方式处理,从而释放服务器资源以保证核心交易正常运作或搞笑运作。
可以通过服务降级功能临时屏蔽某个出错的非关键服务,并定义降级后的返回策略。
幂等操作:多次请求对数据没有影响,如:查询,修改,删除。
非幂等操作:只有添加,在出错的时候不能重试。
在dubbo-admin上开启。
如果调用失败,返回为null,并不会报错。
设置方式:
注解:
@Reference(cluster="failover")
xml:
<dubbo:reference cluster="failover"/>
失败自动切换,当出现失败,重试其它服务器。通常用于读操作,但重试会带来更长延迟。可通过**retries=“2”**来设置重试次数(不含第一次)。
快速失败,只发起一次调用,立即失败报错,通常用于非幂性的写操作。
安全失败,出现异常时,直接忽略,通常用于吸入审计日志等操作。
失败自动恢复,后台记录失败请求,定时重发。通常用于消费通知操作。
并行调用多台服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多的资源,可以通过**forks=“2”**来设置最大并行数量。
广播调用所有提供者,逐个调用,任意一台报错则报错。通常用于通知所有提供者更新缓存或者日志等本地资源信息。
在通过控制那些远程访问系统、服务和第三方库节点,从而对延迟和故障提供更强大的容错能力,Hystrix具备拥有回退机制和断路器功能的线程和信号隔离,请求缓存和请求打包,以及监控配置等功能。
在消费者和提供者的pom中添加(基于SpringBoot项目)
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-hystrixartifactId>
<version>2.1.1.RELEASEversion>
dependency>
修改提供者的UserServiceImpl:
/**
* import org.apache.dubbo.config.annotation.Service;
* @date 2020/10/12 11:16
*/
@Service
public class UserServiceImpl implements UserService {
@HystrixCommand
@Override
public List<UserAddress> queryAllAddress() {
UserAddress userAddress = new UserAddress(1,"山东省日照市东港区","吴彦祖");
UserAddress userAddress1 = new UserAddress(2,"山东省济宁市任城区","吴亦凡");
List<UserAddress> addresses = new ArrayList<UserAddress>();
addresses.add(userAddress);
addresses.add(userAddress1);
System.out.println("20881");
return addresses;
}
}
修改消费者的OrderServiceImpl:
@Service
public class OrderServiceImpl implements OrderService {
@Reference
private UserService userService;
@HystrixCommand(fallbackMethod = "hello")
@Override
public List<UserAddress> initOrder() {
return userService.queryAllAddress();
}
/**
* 失败时调用的方法,不会把错误抛出;
* 回调的方法要与调用回调方法的方法的参数一致;
* 也就是说上面的方法的参数要和这个一致。
* @return
*/
public List<UserAddress> hello(){
return Arrays.asList(new UserAddress(1,"错误","错误"));
}
}
在消费者和提供者的启动类上添加**@EnableHystrix**注解表示启动Hystrix。