由于网络配置服务端不可靠,会导致调用出现一种不确定的中间状态(超时)。为了避免超时导致客户端资源挂起或者耗尽,必须设置超时时间。
在想要暴露的服务上:
@Service(timeout = 1000)过期时间的配置遵循就近原则。自己配了根据自己的,自己没配再往外找。
在同一个地方配置的以消费者为准。
但是在实际开发中一般配置提供者端。
其它的配置的优先原则也是一样。
在启动消费者时,如果没有启动生产者,会默认进行检查抛出没有生产者的错误。
关闭启动时的检查:
在消费者中配置:
<!-- 生成远程调用对象,针对单个对象--> <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.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> <version>2.1.1.RELEASE</version> </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。
