今天在实现简单的用户账户注册功能时,给用户邮箱发送邮件来进行激活账号功能时,出现了前台ajax提交申请后,用户注册失败,失败原因是该用户已存在.
检查发现单击一次注册按钮后,后台发送多次请求.第一次请求将用户信息写入mysql,第二次则报错用户已存在.最后debug后发现在邮件发送的代码上延迟了很长时间,怀疑是dubbo的问题.
最后百度后找到答案原因,是因为发送邮件时间超时(dubbo的默认超时timeout为1s),导致dubbo判定本次服务调用失败,dubbo的重试机制会在进行2次服务调用,而用户信息在第一次调用服务是就被写入数据库
自己总结的解决方案:
1.配置dubbo的服务调用超时时间与重试次数 (用户等待时间长,体验度可能会较低)
2.使用MQ消息队列进行异步通信,将发送邮件代码与注册代码分开,解耦的同时减少用户等待时间,增加用户体验度
感谢各位大佬分享的干货,以下内容copy出自–> https://www.cnblogs.com/study-everyday/p/7220186.html
dubbo的超时机制与重试机制
摘要: dubbo启动时默认有重试机制和超时机制。 超时机制的规则是如果在一定的时间内(默认1s),provider没有返回,则认为本次调用失败, 重试机制在出现调用失败时,会再次调用。如果在配置的调用次数内都失败,则认为此次请求异常,抛出异常。
dubbo启动时默认有重试机制和超时机制。
超时机制的规则是如果在一定的时间内,provider没有返回,则认为本次调用失败,
重试机制在出现调用失败时,会再次调用。如果在配置的调用次数内都失败,则认为此次请求异常,抛出异常。
如果出现超时,通常是业务处理太慢,可在服务提供方执行:jstack PID > jstack.log 分析线程都卡在哪个方法调用上,这里就是慢的原因。
如果不能调优性能,请将timeout设大。
某些业务场景下,如果不注意配置超时和重试,可能会引起一些异常。
超时设置
DUBBO消费端设置超时时间需要根据业务实际情况来设定,
如果设置的时间太短,一些复杂业务需要很长时间完成,导致在设定的超时时间内无法完成正常的业务处理。
这样消费端达到超时时间,那么dubbo会进行重试机制,不合理的重试在一些特殊的业务场景下可能会引发很多问题,需要合理设置接口超时时间。
比如发送邮件,可能就会发出多份重复邮件,执行注册请求时,就会插入多条重复的注册数据。
(1)合理配置超时和重连的思路
1.对于核心的服务中心,去除dubbo超时重试机制,并重新评估设置超时时间。
2.业务处理代码必须放在服务端,客户端只做参数验证和服务调用,不涉及业务流程处理
(2)Dubbo超时和重连配置示例
<!-- 服务调用超时设置为5秒,超时不重试-->
<dubbo:service interface="com.provider.service.DemoService" ref="demoService" retries="0" timeout="5000"/>
重连机制
dubbo在调用服务不成功时,默认会重试2次。
Dubbo的路由机制,会把超时的请求路由到其他机器上,而不是本机尝试,所以 dubbo的重试机器也能一定程度的保证服务的质量。
但是如果不合理的配置重试次数,当失败时会进行重试多次,这样在某个时间点出现性能问题,调用方再连续重复调用,
系统请求变为正常值的retries倍,系统压力会大增,容易引起服务雪崩,需要根据业务情况规划好如何进行异常处理,何时进行重试。