Dubbo实战介绍2 - 服务的注册与发现

注册中心

dubbo支持多注册中心,不仅支持多种形式的注册中心,还支持向多个注册中心注册。目前dubbo支持的注册中心有如下四种

Multicast注册中心

   该注册中心不需要启动任何中心节点,只要广播地址一样,就可以互相发现。组播受网络结果影响,只适合小规模的应用或开发阶段使用。

ZooKeeper 注册中心

   是一个树形的目录服务,为分布式应用提供一致性服务,还支持变更推送功能,推荐生产环境使用

Redis注册中心

   基于redis实现的注册中心,使用key/value结构存储服务的url地址和过期时间,同时使用redis的publish/subscribe事件通知数据变更。

Simple注册中心

   它本身就是一个dubbo服务,可以减少第三方的依赖,是整体通讯方式一致。

由于dubbo建议使用zk作为注册中心,所以本文主要介绍zk注册中心。

我们在服务提供者、消费者的配置文件使用了<dubbo:registry/>标签后指定zk的地址后,就可以使用zk注册中心了配置如下,两种方式

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

dubbo目前支持zkclient和curator两种zk的客户端实现,默认是zkclient,如果想要使用curator,则可以定制client="curator"

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

还可以使用group属性将同一个zk分成多组注册中心,代码如下

<dubbo:registry id="shanghairegistry" address="zookeeper://127.0.0.1:2181" group="shanghai"/>
<dubbo:registry id="beijingregistry"  address="zookeeper://127.0.0.1:2181" group="beijing"/>

前面说的都是单机配置,那么zk的集群配置方式呢?两种方式如下
 

<dubbo:registry address="zookeeper://127.0.0.1:2181?backup=127.0.0.2:2181,127.0.0.3:2181" />
<dubbo:registry protocol="zookeeper" address="127.0.0.1:2181,127.0.0.2:2181,127.0.0.3:2181" />

除了可以向zk的集群模式注册中心注册,还可以向多个注册中心注册

<dubbo:registry id= "shanghairegistry" address="zookeeper://127.0.0.1:2181"/>
<dubbo:registry id= "beijingregistry" address="zookeeper://127.0.0.1:2182"/>
<dubbo:service interface="com.yang.test.api.TestService" ref="testServcie" registry="shanghairegistry,beijingregistry"/>

服务暴露

在通过注册中心注册后,是如何提供服务给消费者使用的呢?这就需要<dubbo:service/>标签进行服务暴露了,用法如下

<dubbo:service interface="com.yang.test.api.TestService" ref="testServcie"/>

其中,interface属性提供服务的接口,ref属性是该接口的具体实现类的引用。

如果服务需要预热的时间,比如初始化缓存,等待相关资源就位等,可以使用delay属性进行服务延迟暴露,用法如下

<dubbo:service interface="com.yang.test.api.TestService" ref="testServcie" delay="5000"/> //或者设置-1,表示延迟到spring初始化完成后暴露服务

如果一个服务的并发量过大,超出了服务器的承载能力,可以使用executes属性控制并发。

<dubbo:service interface="com.yang.test.api.TestService" ref="testServcie" executes="10"/>//并发执行(或占用的线程池的线程数)不能超过10个

除了限制接口,还可以具体到接口内的某一个方法,代码如下

<dubbo:service interface="com.yang.test.api.TestService" ref="testServcie">
    <dubbo:method name="sayHello" executes="10"/>
</dubbo:service>

以上是从提供者实现的并发控制,客户端同样可以实现控制并发,即通过active属性限制代码如下

<dubbo:service interface="com.yang.test.api.TestService" ref="testServcie" actives="10" />//限制每个客户端的并发执行(占线程的请求数)不超过10个

同服务提供者一样,也可以限制到具体的方法

<dubbo:service interface="com.yang.test.api.TestService" ref="testServcie">
        <dubbo:method name="sayHello" actives="10"/>
        <!--不建议在客户端控制并发,应由服务提供者来控制-->
 </dubbo:service>

如果线程超过了给定的值,就会报异常。

为了保障服务的 稳定性,除了限制并发线程,还可以限制服务端的链接数量。

<dubbo:protocol name="dubbo" port="20880" accepts="10"/>
<dubbo:provider protocol="dubbo" accepts="10"/>

同样,也可以限制客户端的使用连接数量

<dubbo:service interface="com.yang.test.api.TestService" ref="testServcie" connections="10"/>
<dubbo:reference id="testService" interface="com.yang.test.api.TestService" connections="10"/>

如果<dubbo:service/> <dubbo:reference/> 都配置了connections,则<dubbo:reference/>优先,由于服务提供者更了解自身的承载能力,建议服务提供者控制连接数。

在服务报暴露过程中,除了控制并发,控制连接数,服务隔离也是一项重要的措施,dubbo提供了分组隔离,即前面的group属性分组。

引用服务

在服务提供者暴露了服务后,消费者就可以使用如下方式引用服务了。

 <dubbo:reference id="testService" interface="com.yang.test.api.TestService"/>

在默认情况下使用同步方式远程调用的,如果想使用异步方式,则可以设置async属性为true,并使用Future获取返回值,代码如下

<dubbo:reference id="testService" interface="com.yang.test.api.TestService">
    <dubbo:method name="sayHello" async="true"/>
</dubbo:reference>

然后在代码中通过以下方式异步调用

@RestController
@RequestMapping("/")
public class TestController {

    @Autowired
    private TestService testService;

    @RequestMapping("test")
    public String hello() throws Exception{
        testService.sayHello("Hello springboot-dubbo!");
        //拿到future引用
        Future<String> future = RpcContext.getContext().getFuture();
        //如果已返回,则直接拿到返回值,否则线程等待(wait),直到拿到返回值,线程才会被唤醒(notify)
        String result = future.get();
        return result;
    }
}

在异步调用中还可以设置是否需要等待发送和返回值,设置如下

sent = "true" ,等待消息发出,消息发送失败抛出异常。

sent =  "false" 不等待消息发出,将消息放入I/O队列,即可返回。

return = "false" 只是想异步,完全忽略返回值 以减少Future对象的创建和管理

<dubbo:reference id="testService" interface="com.yang.test.api.TestService">
        <dubbo:method name="sayHello" async="true" sent="true"/>
</dubbo:reference>
<dubbo:reference id="testService" interface="com.yang.test.api.TestService">
        <dubbo:method name="sayHello" async="true" sent="false"/>
    </dubbo:reference>
<dubbo:reference id="testService" interface="com.yang.test.api.TestService">
     <dubbo:method name="sayHello" async="true" return="false"/>
</dubbo:reference>

Dubbo中的异步调用时基于N/O的非阻塞机制实现的,客户端不需要开始多线程即可实现,相对线程开销小。

Dubbo回调

Dubbo远程调用过程中如果出现了异常或着需要回调,则可以使用dubbo的事件通知机制,主要一下三总

oninvoke(原参数1,原参数2。。。) 为在发起远程调用之前触发的事件

onreturn(返回值,原参数1,原参数2。。。) 为在远程调用之后的回调事件

onthrow(Throwable ex原参数1,原参数2。。。,) 为出现异常时候触发的事件,可以在该事件实现服务降级。

在消费者实现事件通知时候,先定义一个INotify,并实现相关业务。

public interface INotify {
    void onreturn(String resStr,String inSter);
    void onthrow(Throwable ex,String resStr,String inSter);
    void oninvoke(String resStr,String inSter);
}

实现接口

public class notiryImpl implements INotify{
    @Override
    public void onreturn(String resStr, String inSter) {
        System.out.println("after");
    }

    @Override
    public void onthrow(Throwable ex, String resStr, String inSter) {
        System.out.println("yichang");
    }

    @Override
    public void oninvoke(String resStr, String inSter) {
        System.out.println("before");
    }
}

然后就是在配置文件中配置

<dubbo:reference id="testService" interface="com.yang.test.api.TestService">
        <dubbo:method name="sayHello" async="true" onreturn="notify.onreturn"                 onthrow="notify.onthrow"/>
</dubbo:reference>

Dubbo缓存

dubbo为了加速热门数据的访问速度,提供了声明式缓存,可以在消费方配置cache属性开始缓存功能.

<dubbo:reference id="testService" interface="com.yang.test.api.TestService" cache="lru" />

缓存类型:

   lru 基于最近最少使用原则删除多余的缓存,保持最热的数据被缓存

  Threadlocal:当前的线程缓存
  jache :如jsr107继承,可以桥接各种缓存实现。

 

源码地址:https://download.csdn.net/download/u013083284/10744134

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值