美文网首页
dubbo开发指南(一)

dubbo开发指南(一)

作者: 万总有点菜 | 来源:发表于2019-02-24 17:47 被阅读4次

    引入接口jar

    将jar包 install到本地maven仓库
    在windows的cmd下运行如下指令

    mvn install:install-file -DgroupId=com.lczyfz.cscrawler -DartifactId=api -Dversion=1.0-SNAPSHOT -Dpackaging=jar -Dfile=E:\ cscrawler.jar
    

    然后在pom文件中引入

    <!-- 服务化API依赖 -->
           <dependency>
               <groupId>com.lczyfz.cscrawler</groupId>
               <artifactId>api</artifactId>
               <version>1.0-SNAPSHOT</version>
           </dependency>
    

    或者将jar放到工程lib中

            <dependency>
                <groupId>bitwalker</groupId>
                <artifactId>UserAgentUtils</artifactId>
                <version>1.13</version>
                <systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/UserAgentUtils-1.13.jar</systemPath>
            </dependency>
    

    调用说明

    在调用的类引入

    import com.alibaba.dubbo.config.annotation.Reference;
    

    使用注解注入对象

    @Reference
    TestCrawlerApi testCrawlerApi;
    //调用对象的方法
    System.out.println("===Service====" + testCrawlerApi.sayCrawler("Service"));
    

    发布说明

    创建api

    package com.lczyfz.cscrawler.api;
    
    /**
     * Created by maple on 2019-01-23.
     */
    public interface TestCrawlerApi {
        public String sayCrawler(String name);
    }
    

    实现接口,在类引入

    import com.alibaba.dubbo.config.annotation.Reference;
    import com.lczyfz.cscrawler.api.TestCrawlerApi;
    

    使用@Service

    package com.lczyfz.cscrawler.modules.test.service;
    
    import com.alibaba.dubbo.config.annotation.Reference;
    import com.lczyfz.cscrawler.api.TestCrawlerApi;
    import com.lczyfz.csstorage.api.TestApi;
    import org.springframework.stereotype.Service;
    
    
    /**
     * Created by maple on 2019-01-23.
     */
    @org.springframework.stereotype.ServiceService
    @com.alibaba.dubbo.config.annotation.Service
    public class TryApiService implements TestCrawlerApi{
        @Override
        public String sayCrawler(String name) {
            return "Crawler " + name;
        }
    }
    

    常用配置说明

    *启动时检查

    @Reference(check = false)
    Dubbo 缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止 Spring 初始化完成,以便上线时,能及早发现问题,默认 check="true"。
    可以通过 check="false" 关闭检查,比如,测试时,有些服务不关心,或者出现了循环依赖,必须有一方先启动。
    另外,如果你的 Spring 容器是懒加载的,或者通过 API 编程延迟引用服务,请关闭 check,否则服务临时不可用时,会抛出异常,拿到 null 引用,如果 check="false",总是会返回引用,当服务恢复时,能自动连上。

    *多版本

    当一个接口实现,出现不兼容升级时,可以用版本号过渡,版本号不同的服务相互间不引用。
    可以按照以下的步骤进行版本迁移:
    在低压力时间段,先升级一半提供者为新版本
    再将所有消费者升级为新版本
    然后将剩下的一半提供者升级为新版本

    老版本服务提供者配置:
    @com.alibaba.dubbo.config.annotation.Service(version = "1.0.0")
    新版本服务提供者配置:
    @com.alibaba.dubbo.config.annotation.Service(version = "2.0.0")
    老版本服务消费者配置:
    @Reference(version = "1.0.0")
    新版本服务消费者配置:
    @Reference(version = "2.0.0")

    *回声测试

    回声测试用于检测服务是否可用,回声测试按照正常请求流程执行,能够测试整个调用是否通畅,可用于监控。
    所有服务自动实现 EchoService 接口,只需将任意服务引用强制转型为 EchoService,即可使用。

    // 远程服务引用
    EchoService echoService = (EchoService) memberService; // 强制转型为EchoService
    // 回声测试可用性
    String status = echoService.$echo("OK"); 
    assert(status.equals("OK"));
    
    上下文信息

    上下文中存放的是当前调用过程中所需的环境信息。所有配置信息都将转换为 URL 的参数,参见 schema 配置参考手册 中的对应URL参数一列。
    RpcContext 是一个 ThreadLocal 的临时状态记录器,当接收到 RPC 请求,或发起 RPC 请求时,RpcContext 的状态都会变化。比如:A 调 B,B 再调 C,则 B 机器上,在 B 调 C 之前,RpcContext 记录的是 A 调 B 的信息,在 B 调 C 之后,RpcContext 记录的是 B 调 C 的信息。

    • 服务消费方
    // 远程调用
    xxxService.xxx();
    // 本端是否为消费端,这里会返回true
    boolean isConsumerSide = RpcContext.getContext().isConsumerSide();
    // 获取最后一次调用的提供方IP地址
    String serverIP = RpcContext.getContext().getRemoteHost();
    // 获取当前服务配置信息,所有配置信息都将转换为URL的参数
    String application = RpcContext.getContext().getUrl().getParameter("application");
    // 注意:每发起RPC调用,上下文状态会变化
    yyyService.yyy();
    
    • 服务提供方
    public class XxxServiceImpl implements XxxService {
        public void xxx() {
            // 本端是否为提供端,这里会返回true
            boolean isProviderSide = RpcContext.getContext().isProviderSide();
            // 获取调用方IP地址
            String clientIP = RpcContext.getContext().getRemoteHost();
            // 获取当前服务配置信息,所有配置信息都将转换为URL的参数
            String application = RpcContext.getContext().getUrl().getParameter("application");
            // 注意:每发起RPC调用,上下文状态会变化
            yyyService.yyy();
            // 此时本端变成消费端,这里会返回false
            boolean isProviderSide = RpcContext.getContext().isProviderSide();
        } 
    }
    
    访问日志

    如果你想记录每一次请求信息,可开启访问日志,类似于apache的访问日志。注意:此日志量比较大,请注意磁盘容量。
    将访问日志输出到当前应用的log4j日志:
    <dubbo:protocol accesslog="true" />

    *性能调优参数
    • delay 默认0 延迟注册服务时间(毫秒) ,设为-1时,表示延迟到Spring容器初始化完成时暴露服务
    • timeout 默认1000 远程服务调用超时时间(毫秒)
    • retries 默认 2 远程服务调用重试次数,不包括第一次调用,不需要重试请设为0
    本地存根

    远程服务后,客户端通常只剩下接口,而实现全在服务器端,但提供方有些时候想在客户端也执行部分逻辑,比如:做 ThreadLocal 缓存,提前验证参数,调用失败后伪造容错数据等等,此时就需要在 API 中带上 Stub,客户端生成 Proxy 实例,会把 Proxy 通过构造函数传给 Stub,然后把 Stub 暴露给用户,Stub 可以决定要不要去调 Proxy。

    /user-guide/images/stub.jpg

    在 spring 配置文件中按以下方式配置:

    @com.alibaba.dubbo.config.annotation.Service(stub = "com.foo.BarServiceStub")
    

    提供 Stub 的实现 :

    package com.foo;
    public class BarServiceStub implements BarService { 
        private final BarService barService;
    
        // 构造函数传入真正的远程代理对象
        public (BarService barService) {
            this.barService = barService;
        }
    
        public String sayHello(String name) {
            // 此代码在客户端执行, 你可以在客户端做ThreadLocal本地缓存,或预先验证参数是否合法,等等
            try {
                return barService.sayHello(name);
            } catch (Exception e) {
                // 你可以容错,可以做任何AOP拦截事项
                return "容错数据";
            }
        }
    }
    
    *本地伪装

    本地伪装 通常用于服务降级,比如某验权服务,当服务提供方全部挂掉后,客户端不抛出异常,而是通过 Mock 数据返回授权失败。
    在 spring 配置文件中按以下方式配置:

    @Reference(mock = "com.foo.BarServiceMock")
    
    

    在工程中提供 Mock 实现

    package com.foo;
    public class BarServiceMock implements BarService {
        public String sayHello(String name) {
            // 你可以伪造容错数据,此方法只在出现RpcException时被执行
            return "容错数据";
        }
    }
    
    

    如果服务的消费方经常需要 try-catch 捕获异常,如:

    Offer offer = null;
    try {
        offer = offerService.findOffer(offerId);
    } catch (RpcException e) {
       logger.error(e);
    }
    
    

    请考虑改为 Mock 实现,并在 Mock 实现中 return null。如果只是想简单的忽略异常,在 2.0.11 以上版本可用:

    <dubbo:reference interface="com.foo.BarService" mock="return null" />
    

    相关文章

      网友评论

          本文标题:dubbo开发指南(一)

          本文链接:https://www.haomeiwen.com/subject/sakbyqtx.html