通俗易懂的 Dubbo 教程(九):服务降级

什么是服务降级?

当服务器压力比较大的时候,我们可以通过服务降级,屏蔽掉一些非关键服务,给它们定义一个降级后的返回策略,从而降低核心业务的压力。

通俗的说,服务降级就是在远程调用失败(例如超时)之后,直接采用降级措施,返回一个我们已经定义好的提示。例如,在12306抢票高峰时,明明票还有,但查询列表总是空的,过了高峰之后再次查询,又会恢复正常,这可能是因为超时或者网络问题导致查询失败,最后不得不采用了服务降级进行处理,给我们返回一个已经定义好的值。

如何实现服务降级

Dubbo 中有一个 mock 的配置,我们可以通过这个配置实现服务降级。其中,mock 的配置有两种:

  1. 通过 boolean 值指定是否实行服务降级,其中默认为 false,当配置为 true 时,缺省通过在服务名后面加上 Mock 后缀的类来指定降级后的返回值
  2. 直接 return null,统一返回空

需要注意的是,mock 只会在非业务异常的时候执行,比如超时,又或者是网路异常。

测试

首先我们来看一下不做服务降级会是什么后果,我们在服务提供者中故意令其超时,由于 Dubbo 默认超时时间为1s,我们就令其睡眠两秒,代码如下:

package edu.szu.producer.serviceImpl;

import com.alibaba.dubbo.config.annotation.Service;
import edu.szu.api.service.NameService;
import org.springframework.stereotype.Component;

@Component
@Service
public class NameServiceImpl implements NameService {

    @Override
    public String updateName(String name) {
        //让其超时
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "远程调用的值:" + name;
    }
}

然后运行服务提供者与服务消费者,果不其然,直接报错。

在这里插入图片描述
在这里插入图片描述

然后我们添加 return null 的降级设置,代码如下,看看其效果

package edu.szu.consumer.serviceImpl;

import com.alibaba.dubbo.config.annotation.Reference;
import edu.szu.api.service.NameService;
import edu.szu.consumer.service.ChangeService;
import org.springframework.stereotype.Component;

@Component
public class ChangeServiceImpl implements ChangeService {

    //定义服务降级的策略:直接返回空
    @Reference(mock = "return null")
    NameService nameService;

    @Override
    public String change(String name) {
        return nameService.updateName(name);
    }
}

显然它会直接返回空,这需要我们做进一步的处理。需要注意的是,当我们将 mock 设置为 return null 时,它不会进行远程调用,而是直接返回一个空就行了。
在这里插入图片描述
在这里插入图片描述
在某些情况下,直接返回空对我们的用户不太友好,这时我们可以给用户返回一个我们之前定义好的值。首先我们在 api 模块中指定一个服务降级的处理策略,其中这个处理类名缺省为在服务名上加上 Mock 后缀,且应该与服务接口在同路径下。

package edu.szu.api.service;

public class NameServiceMock implements NameService {

    //定义服务降级的返回值
    @Override
    public String updateName(String name) {
        return "服务降级了!";
    }
}

然后在消费者中配置 mock 属性为 true。

package edu.szu.consumer.serviceImpl;

import com.alibaba.dubbo.config.annotation.Reference;
import edu.szu.api.service.NameService;
import edu.szu.consumer.service.ChangeService;
import org.springframework.stereotype.Component;

@Component
public class ChangeServiceImpl implements ChangeService {

    //定义服务降级的策略
    @Reference(mock = "true")
    NameService nameService;

    @Override
    public String change(String name) {
        return nameService.updateName(name);
    }
}

然后我们发起一次远程调用,由于调用超时,显然是失败的,但由于我们进行了服务降级,会返回我们指定的返回值。

在这里插入图片描述
另外,该方法与直接 return null 不同的是,如果我们的远程调用成功了,不会执行服务降级,会返回远程调用的结果,而 return null 事实上根本不进行远程调用就直接返回空了。

进阶

当然,我们也可以通过 Admin 控制台来实现服务降级。
在这里插入图片描述
我们发现对服务可以进行屏蔽与容错操作,其中,屏蔽表示对服务不发起远程调用,直接返回空就行了;而容错则表示在对该服务的方法调用失败后,再返回空,这两个是不同的。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值