天天看点

Dubbo常用配置解析

回到顶部

如何发布服务,需要将需要暴露的服务接口发布出去供客户端调用,需要在java同级目录新建一个resources目录,然后将resoureces目录标记成Test Resoureces Root,然后在esources目录下新建MATE-INF.spring目录,在该目录下添加配置文件dubbo-server.xml文件

  dubbo的服务端配置文件如下

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

<code>&lt;?xml version=</code><code>"1.0"</code> <code>encoding=</code><code>"UTF-8"</code><code>?&gt;</code>

<code>&lt;beans xmlns=</code><code>"http://www.springframework.org/schema/beans"</code> <code>xmlns:xsi=</code><code>"http://www.w3.org/2001/XMLSchema-instance"</code>

<code> </code><code>xmlns:dubbo=</code><code>"http://code.alibabatech.com/schema/dubbo"</code> <code>xsi:schemaLocation=</code><code>"http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://code.alibabatech.com/schema/dubbohttp://code.alibabatech.com/schema/dubbo/dubbo.xsd"</code><code>&gt;</code>

<code>&lt;!--提供方信息,用于计算依赖关系--&gt;</code>

<code>&lt;dubbo:application name=</code><code>"dubbo-server"</code> <code>owner=</code><code>"mic"</code><code>/&gt;</code>

<code>&lt;!--注册中心 暴露服务地址--&gt;</code>

<code>&lt;dubbo:registry address=</code><code>"zookeeper://192.168.126.129:2181"</code><code>/&gt;</code>

<code>&lt;!--用dubbo协议在</code><code>20880</code> <code>端口暴露服务--&gt;</code>

<code>&lt;dubbo:protocol port=</code><code>"20880"</code> <code>name=</code><code>"dubbo"</code><code>/&gt;</code>

<code>&lt;!--声明需要暴露的服务接口,指定协议为dubbo,设置版本号</code><code>1.1</code><code>.</code><code>1</code><code>--&gt;</code>

<code>&lt;dubbo:service</code><code>interface</code><code>=</code><code>"com.gupaoedu.dubbo.IGpHello"</code>  <code>ref=</code><code>"gpHelloService"</code> <code>protocol=</code><code>"dubbo"</code> <code>version=</code><code>"1.1.1"</code><code>/&gt;</code>

<code>&lt;!--声明需要暴露的服务接口,指定协议为dubbo,设置版本号</code><code>1.1</code><code>.</code><code>2</code><code>--&gt;</code>

<code>&lt;dubbo:service</code><code>interface</code><code>=</code><code>"com.gupaoedu.dubbo.IDemoService"</code>    <code>ref=</code><code>"demoService"</code> <code>protocol=</code><code>"dubbo"</code> <code>version=</code><code>"1.1.2"</code><code>/&gt;</code>

<code>&lt;!--和本地服务一样实现服务--&gt;</code>

<code>&lt;bean id=</code><code>"gpHelloService"</code> <code>class</code><code>=</code><code>"com.gupaoedu.dubbo.GpHelloImpl"</code><code>/&gt;</code>

<code>&lt;bean id=</code><code>"demoService"</code> <code>class</code><code>=</code><code>"com.gupaoedu.dubbo.DemoService"</code><code>/&gt;</code>

<code>&lt;/beans&gt;</code>

服务端的接口以及实现类

<code>public</code> <code>interface</code> <code>IGpHello {String sayHello(String msg);}</code>

<code>public</code> <code>interface</code> <code>IDemoService {String protocolDemo(String msg);}</code>

<code>public</code> <code>class</code> <code>GpHelloImpl</code><code>implements</code> <code>IGpHello{</code>

<code>@Override</code>

<code>public</code> <code>String sayHello(String msg) {</code><code>return</code> <code>"Hello:"</code><code>+msg;}</code>

<code>}</code>

<code>public</code> <code>class</code> <code>GpHelloImpl2</code><code>implements</code> <code>IGpHello{</code>

<code>public</code> <code>String sayHello(String msg) {</code><code>return</code> <code>"Hello,i'm server 2:"</code><code>+msg;}</code>

编写Main方法,用spring容器来启动服务

<code>public</code> <code>class</code> <code>Main {</code>

<code>public</code> <code>static</code> <code>void</code> <code>main(String[] args)</code><code>throws</code> <code>IOException {</code>

<code>//默认情况下会使用spring容器来启动服务</code>

<code>com.alibaba.dubbo.container.Main.main(</code><code>new</code> <code>String[]{</code><code>"spring"</code><code>,</code><code>"log4j"</code><code>});}</code>

服务启动过程会进行服务注册,启动监听端口,启动服务之后

在客户端通过远程调用访问服务端发布的服务,相应的客户端配置文件 dubbo-client.xml 如下

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

<code>xsi:schemaLocation=</code><code>"http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://code.alibabatech.com/schema/dubbohttp://code.alibabatech.com/schema/dubbo/dubbo.xsd"</code><code>&gt;</code>

<code>&lt;!--提供方信息--&gt;</code>

<code>&lt;dubbo:application name=</code><code>"dubbo-client"</code> <code>owner=</code><code>"mic"</code><code>/&gt;</code>

<code>&lt;!--注册中心--&gt;</code>

<code>&lt;dubbo:registry id=</code><code>"zokeeper"</code> <code>address=</code><code>"zookeeper://192.168.126.129:2181?register=false"</code> <code>file=</code><code>"d:/dubbo-server"</code><code>/&gt;</code>

<code>&lt;!--声明需要暴露的服务接口,指定版本号--&gt;</code>

<code>&lt;dubbo:reference id=</code><code>"gpHelloService"</code> <code>interface</code><code>=</code><code>"com.gupaoedu.dubbo.IGpHello"</code> <code>registry=</code><code>"zookeeper"</code> <code>version=</code><code>"1.1.1"</code><code>/&gt;</code>

其实我们可以在zookeeper的客户端可以发现,事实上已经发布了服务方已经发布了两个不同版本的服务,具体如下

我们知道,这两个版本正是我们在服务发布方设置的不同版本号,同样的,在消费端,我们可以通过设置指定的版本号获取相应的版本服务,消费的代码如下

Dubbo常用配置解析
Dubbo常用配置解析

在控制台,我们可以看到同样的服务发布地址url。

  什么叫主机绑定呢?主机绑定的流程是什么?

在发布一个dubbo服务的时候,会生成一个dubbo://ip:port的协议地址。这就是主机绑定过程,那么这个IP是如何生成的呢?大家可以通过ServiceConfig.java 中的 doExportUrlForlProtocol 方法中找到如下代码块。大致的逻辑是,首先从配置文件中获取,如果失败再尝试从本地网卡中获取host,如果这个也失败,会继续执行,直到找到合适的IP地址。

Dubbo常用配置解析
Dubbo常用配置解析

在分析dubbo的集群容错前,先了解什么是容错机制?容错机制指的是某种系统控制在一 定范围内的一种允许或包容犯错情况的发生,举个简单例 子,我们在电脑上运行一个程序,有时候会出现无响应的情况,然后系统会弹出一个提示框让我们选择,是立即结 束还是继续等待,然后根据我们的选择执行对应的操作, 这就是“容错”。

       在分布式架构下,网络、硬件、应用都可能发生故障,由 于各个服务之间可能存在依赖关系,如果一条链路中的其 中一个节点出现故障,将会导致雪崩效应。为了减少某一 个节点故障的影响范围,所以我们才需要去构建容错服务(这里要说明一点,容错机制仅仅是处理节点故障的一种机制), 来优雅的处理这种中断的响应结果 。

Dubbo提供了6种容错机制,分别如下 

1. failsafe 失败安全,可以认为是把错误吞掉(记录日 志) 

2. failover(默认)   重试其他服务器; retries(2) ,缺省的重试次数,不包含第一次

3. failfast 快速失败, 失败以后立马报错 

4. failback  失败后自动恢复。 

5. forking  forks. 设置并行数 

6. broadcast  广播,任意一台报错,则执行的方法报错 

配置方式如下,通过cluster方式,配置指定的容错方案

配置的优先级别

客户端会优于服务端,这里还可以细化,可以细化到方法级别

1. 方法级优先,接口级次之,全局配置再次之。 

2. 如果级别一样,则消费方优先,提供方次之

其中,服务提供方配置,通过URL经由注册中心传递给消 费方

什么应该配置在客户端,什么应该配置在服务端,retires、loadBlance、cluster(客户端)、timeout(服务端)

以 timeout 为例,建议由服务提供方设置超时,因为一个方法需要执行多长 时间,服务提供方更清楚,如果一个消费方同时引用多个 服务,就不需要关心每个服务的超时设置。

降级的目的是为了保证核心服务可用。 

降级可以有几个层面的分类: 自动降级和人工降级; 按 照功能可以分为:读服务降级和写服务降级; 

1. 对一些非核心服务进行人工降级,在大促之前通过降级 开关关闭哪些推荐内容、评价等对主流程没有影响的功 能 

2. 故障降级,比如调用的远程服务挂了,网络故障、或者 RPC服务返回异常。 那么可以直接降级,降级的方案比 如设置默认值、采用兜底数据(系统推荐的行为广告挂 了,可以提前准备静态页面做返回)等等 

3. 限流降级,在秒杀这种流量比较集中并且流量特别大的 情况下,因为突发访问量特别大可能会导致系统支撑不 了。这个时候可以采用限流来限制访问量。当达到阀值 时,后续的请求被降级,比如进入排队页面,比如跳转 到错误页(活动太火爆,稍后重试等) 

dubbo的降级方式: Mock 机制

实现步骤

1. 在client端创建一个TestMock类,实现对应IGpHello 的接口(需要对哪个接口进行 mock,就实现哪个), 名称必须以Mock结尾 

2. 在client端的xml配置文件中,添加如下配置,增加一 个mock属性指向创建的TestMock 

3. 模拟错误(设置 timeout),模拟超时异常,运行测试代码即可访问到TestMock这个类。当服务端故障解除 以后,调用过程将恢复正常 

服务端的类及实现类,以及配置文件,参考第一点的类及实现类以及配置文件,然后再客户端的配置文件的加上mock,具体见如下截图。

根据Mock机制实现步骤

首先我们再客户端添加一个TestMock类,实现IGpHello接口,配置文件我已经添加好了,可以看到我这里的配置相对第一点客户端的配置添加了几个参数 timeout、failover、mock。这里主要是看mock和timeout配置,因为我们是要去验证mock机制,而failover是集群容错的配置,之所以我这里没有将这个参数去掉,是因为确定这里他们不会有配置冲突,配置好之后,先发布服务端的服务,然后运气客户端的App.java.在控制台我们可以看到打印结果,系统繁忙,这个结果说明,我们设置1秒超时,客户端远程调用服务超时,报错了,然后就走到了Mock里。

Dubbo常用配置解析

然后我们再验证,将超时间加大,设置为100,再运行,此时就不会报错,就会正常输出Hello world,输出结果如下

Dubbo常用配置解析

好了,总结一下,整理了两个晚上,没有整理出我预想的效果,这篇文章主要是以一种开发文档的形式简单介绍了dubbo的多版本机制实现、主机绑定、集群容错处理机制、以及服务降级处理。后续会介绍dubbo的SPI机制,他是dubbo一种核心机制,我也是刚学习dubbo源码不久,到时候有问题忘大家指正。该篇文章也存在许多不足的地方,比如结构可能不是非常清晰,描述也可能不是非常通俗易懂,后续我会努力矫正,今天就到这了,太困了现在,不写了睡觉。

欢迎扫码关注我的微信公众号,我会不定期的更新一些个人技术文章