文档章节

Dubbo学习:服务降级

OSC_Mgxcbo
 OSC_Mgxcbo
发布于 2017/08/29 15:23
字数 1409
阅读 45
收藏 1

 

Dubbo学习(十三):服务降级

2016-04-26 16:45 4345人阅读 评论(1) 收藏 举报

 分类:

Dubbo(13) 

版权声明:本文为博主原创文章,未经博主允许不得转载。

一、dubbo降级服务    

    dubbo开发中,可能由于服务没有启动或者网络不通,调用中会出现RpcException,也就是远程调用失败。如果是服务启动顺序的问题,可能加工check="false"的配置可以得到很好的解决。但是,如果是服务宕掉或者并发数太高导致的RpcException该如何处理?

    经过过12306抢票的人应该经常会遇到这个问题:在抢票高峰的时候,明明票还有,但是查询出来的列表却是为空的(如果没票列表也应该会呈现);等高峰过后再查询,列表又恢复正常。个人猜测应该是查询过程中出现了问题,要么超时,要么网络问题导致查询失败采用的服务降级处理。所以,最终呈现给用户的并不是内部系统出错之类的提示,而是一个空的列表。好了,言归正传,在dubbo中想实现服务降级,需要怎么样做可以实现?

    查看dubbo的官方文档,可以发现有个mock的配置,mock只在出现非业务异常(比如超时,网络异常等)时执行。mock的配置支持两种,一种为boolean值,默认的为false。如果配置为true,则缺省使用mock类名,即类名+Mock后缀;另外一种则是配置"return null",可以很简单的忽略掉异常。

二、结合dubbo的例子

说明下面将通过一个例子进行说明:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

/**接口定义*/

public interface IUser {

  

    public void addUser(User u);

      

    public User getUserById(int id);

      

}

  

/**实现类*/

public class UserImpl implements IUser {

      

    private static List<User> USER_LIST = new ArrayList<User>();

      

    static{

        for(int i=0;i<10;i++){

            User u = new User();

            u.setAddress("address"+i);

            u.setId(i);

            u.setName("name"+i);

              

            USER_LIST.add(u);

        }

    }

      

    public void addUser(User u) {

        USER_LIST.add(u);

        System.out.println("total:"+USER_LIST.size());

    }

  

    public User getUserById(int id) {

        for(int i=0;i<USER_LIST.size();i++){

            if(USER_LIST.get(i).getId() == id){

                return USER_LIST.get(i);

            }

        }

        return null;

    }

}

 

dubbo-provider.xml配置:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"

    xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://code.alibabatech.com/schema/dubbo        http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

 

    <!-- 提供方应用信息,用于计算依赖关系 -->

    <dubbo:application name="hello-world-app" />

 

    <!-- 使用multicast广播注册中心暴露服务地址 -->

    <dubbo:registry address="zookeeper://127.0.0.1:2181" />

 

    <!-- 用dubbo协议在20880端口暴露服务 -->

    <dubbo:protocol name="dubbo" port="20880" />

 

    <!-- 声明需要暴露的服务接口 -->

    <dubbo:service interface="com.zzq.test.iface.IUser" ref="userImpl" timeout="10000" />

 

    <!-- 和本地bean一样实现服务 -->

    <bean id="userImpl" class="com.zzq.test.ifaceimpl.UserImpl" />

 

</beans>

调用方的配置:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"

    xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://code.alibabatech.com/schema/dubbo        http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

  

    <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->

    <dubbo:application name="dubbo-consumer"  />

  

    <dubbo:registry address="zookeeper://127.0.0.1:2181" />

  

    <!-- 生成远程服务代理,可以和本地bean一样使用demoService -->

    <dubbo:reference id="iUser" interface="com.zzq.test.iface.IUser"  timeout="10000" check="false" mock="return null">

    </dubbo:reference>

  

</beans>

调用的测试代码:

?

1

2

3

4

5

6

7

8

9

10

11

12

public static void main(String[] args) throws Exception{

        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"classpath:dubbo-consumer.xml"});

        context.start();

         

        IUser iUser = (IUser)context.getBean("iUser");

        User u = new User();

        u.setAddress("aaa");

        u.setId(311);

        u.setName("n3");

        iUser.addUser(u);

        System.out.println(iUser.getUserById(1));

    }

通过测试,如果服务启动,则程序按照预期的运行正常;如果服务没启动,则此时运行程序,程序并未报错,打印出null。

三、思考

    通过以上的例子可以知道,通过mock的配置,可以很好的实现dubbo服务降级。但是,仔细查看上面的例子会发现,IUser本身定义了两个接口,一个是新增用户,一个是根据id查询用户信息。对于根据id查询用户信息,在调用失败的时候返回null很好理解,可能是由于验证失败或者记录删除了,但是对于新增用户,可能就需要抛出具体的业务信息,否则程序无法处理后续的业务,包括页面弹出”添加成功“或者列表刷新的时候无法查看到最新的记录,这样体验将会非常不好。所以,如果要有较好的区分,可以通过以下的方式,可以更好的实现降级:

(1)将接口进行归类,查询类和变更操作类:对于查询的分为一个接口类,变更的归类为其他的接口类,这样对于查询的可以使用mock="return null"进行降级操作;对于变更类的,可以仍旧使用try……catch进行异常捕获处理;

(2)配置mock="true",同时mock实现接口,接口名要注意命名规范:接口名+Mock后缀。此时如果调用失败会调用Mock实现。mock实现需要保证有无参的构造方法。

配置mock="true"的情况,对于上面的例子即在IUser的同个路径下,添加类IUserMock,实现如下:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

public class IUserMock implements IUser {

 

    @Override

    public void addUser(User u) {

        throw new RuntimeException("add user fail!");

    }

 

    @Override

    public User getUserById(int id) {

        return null;

    }

 

}

 

本文转载自:http://blog.csdn.net/zuoanyinxiang/article/details/51251836

OSC_Mgxcbo
粉丝 3
博文 40
码字总数 6598
作品 0
私信 提问
dubbo 视频教程

深度解剖dubbo源码 为什么要学习dubbo 源码? 1.如果你想深入学习SOA的微服务架构设计,那通过读dubbo源码是一条非常不错的通往SOA架构设计之路,毕竟SOA的服务治理就是dubbo首先提出来的,比...

qq594295b3c16b8
2017/06/16
0
0
服务框架dubbo(一):基础篇

学习博文:https://www.imooc.com/t/6300745 dubbo是一个分布式服务框架,致力于提供高性能透明化RPC远程调用方案,提供SOA服务治理解决方案。 由于dubbo各个分层都是很多扩展, 注册中心有r...

Java搬砖工程师
2018/11/21
61
0
【Dubbo】-- 掌握Dubbo原理你需要明白这些

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 https://blog.csdn.net/YYZZHC999/article/details/98490704 把这些问题都搞明白说明源码没白...

杨晓慧_Hepburn
08/05
0
0
分布式系统中服务降级策略探究已经出炉了!!!

在分布式系统架构中多个系统之间通常是通过远程RPC调用进行通信,也就是 A 系统调用 B 系统服务,B 系统调用 C 系统的服务。当尾部应用 C 发生故障而系统 B 没有服务降级时候可能会导致 B,甚...

阿里加多
2018/05/23
0
0
分布式系统中服务降级策略探究-chat

在分布式系统架构中多个系统之间通常是通过远程RPC调用进行通信,也就是 A 系统调用 B 系统服务,B 系统调用 C 系统的服务。当尾部应用 C 发生故障而系统 B 没有服务降级时候可能会导致 B,甚...

阿里加多
2018/05/11
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Mybatis Plus删除

/** @author beth @data 2019-10-17 00:30 */ @RunWith(SpringRunner.class) @SpringBootTest public class DeleteTest { @Autowired private UserInfoMapper userInfoMapper; /** 根据id删除......

一个yuanbeth
今天
4
0
总结

一、设计模式 简单工厂:一个简单而且比较杂的工厂,可以创建任何对象给你 复杂工厂:先创建一种基础类型的工厂接口,然后各自集成实现这个接口,但是每个工厂都是这个基础类的扩展分类,spr...

BobwithB
今天
5
0
java内存模型

前言 Java作为一种面向对象的,跨平台语言,其对象、内存等一直是比较难的知识点。而且很多概念的名称看起来又那么相似,很多人会傻傻分不清楚。比如本文我们要讨论的JVM内存结构、Java内存模...

ls_cherish
今天
4
0
友元函数强制转换

友元函数强制转换 p522

天王盖地虎626
昨天
5
0
js中实现页面跳转(返回前一页、后一页)

本文转载于:专业的前端网站➸js中实现页面跳转(返回前一页、后一页) 一:JS 重载页面,本地刷新,返回上一页 复制代码代码如下: <a href="javascript:history.go(-1)">返回上一页</a> <a h...

前端老手
昨天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部