dubbo注解开发实战

来源:互联网 发布:大数据在社保行业应用 编辑:程序博客网 时间:2024/06/05 03:16

 

Dubbox注解开发详细教程

问题描述:

1,dubbox开发环境是如何搭建的?

2,dubbox 注解开发使用如何使用的?

3,dubbox注解开发之服务超时?

4,dubbox 注解开发之集群失败重试?

5,dubbox注解之高效序列化?

6,dubbox 注解开发之集群负载均衡?

 

第1章            Dubbox开发环境搭建

 

1.1   Dubbox下载

dubbx是当当网对原阿里dubbo2.x的升级,并且兼容原有的dubbox。其中升级了zookeeper和spring版本,并且支持restfull风格的远程调用。

dubbox git地址:  https://github.com/dangdangdotcom/dubbox 


1.2   Dubbox源码编译

下载完毕dubbox源码以后,需要在项目中引入dubbox相关的包文件,此时需要把源码进行编译打包部署到仓库中.

运行maven命令:mvn clean install -Dmaven.test.skip=true 


将dubbox的源码打包发布到本地仓库,目的是为了获取:

dubbo-admin-2.8.4.war和dubbo-monitor.war以及相关的dubbox依赖jar包.

 

1.3   项目依赖

 下面的坐标依赖仅仅是项目kryo,jackson序列化优化所需的坐标,项目需要依赖的spring,dubbox集群负载及其他的坐标,自行导入即可.

 

   <!-- dubbo相关 -->

        <dependency>

            <groupId>com.alibaba</groupId>

            <artifactId>dubbo</artifactId>

            <version>2.8.4</version>

            <exclusions>

                <exclusion>

                    <groupId>javax.servlet</groupId>

                    <artifactId>javax.servlet-api</artifactId>

                </exclusion>

            </exclusions>

        </dependency>

        <dependency>

            <groupId>org.apache.zookeeper</groupId>

            <artifactId>zookeeper</artifactId>

            <version>3.4.7</version>

        </dependency>

        <dependency>

            <groupId>com.github.sgroschupf</groupId>

            <artifactId>zkclient</artifactId>

            <version>0.1</version>

        </dependency>

        <!-- kryo序列化 -->

        <dependency>

            <groupId>com.esotericsoftware.kryo</groupId>

            <artifactId>kryo</artifactId>

            <version>2.24.0</version>

        </dependency>

        <dependency>

            <groupId>de.javakaffee</groupId>

            <artifactId>kryo-serializers</artifactId>

            <version>0.42</version>

        </dependency>

        <!-- Jackson序列化 -->

        <dependency>

            <groupId>com.fasterxml.jackson.core</groupId>

            <artifactId>jackson-databind</artifactId>

            <version>2.4.2</version>

        </dependency>

<dependency>

            <groupId>org.jboss.resteasy</groupId>

            <artifactId>resteasy-client</artifactId>

            <version> 3.0.7.Final</version>

        </dependency>

 

        <dependency>

            <groupId>com.googlecode.xmemcached</groupId>

            <artifactId>xmemcached</artifactId>

            <version>2.4.0</version>

        </dependency>

       

        <dependency>

            <groupId>com.caucho</groupId>

            <artifactId>hessian</artifactId>

            <version>4.0.33</version>

        </dependency>

       

        <dependency>

            <groupId>org.apache.cxf</groupId>

            <artifactId>cxf-rt-core</artifactId>

            <version>2.6.1</version>

        </dependency>

1.4   发布服务

项目发布服务使用批量扫描的方式进行服务器注册.

<dubbo:applicationname="demo-service" />

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

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

    <!-- 发布服务 -->

    <dubbo:annotation package="cn.it"/>

1.5   服务消费

 

服务消息者也使用批量扫描的方法,引入服务对象.

<!-- 引用dubbo 服务 -->

    <dubbo:application name="demo-web"/>

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

    <!-- 引用服务 -->

    <dubbo:annotation package="cn.it"/>

 

dubbox在发布服务和消费服务和dubbo并没有什么本质的变化,但是主要是在一些细节方面有些小的变化,下面在dubbox优化方面来说明他的变化。

1.6   服务测试

1.6.1    项目结构


Service服务提供者,web层服务消费者.interface是发布服务及依赖服务的关键.              

1.6.1   启动测试

测试前提是你的linux中zookeeper服务器已经安装成功,此时测试使用的zookeeper注册中心模式来注册服务对象.

 

 

第2章            Dubbox注解开发使用

2.1   服务提供者

使用dubbox提供的注解开发结合配置文件dubbox扫描配置,把service服务对象发布到zookeeper注册中心即可.dubbox通过Service注解即可实现服务注册,但是必须注意service直接必须使用dubbox提供的注解.

importcom.alibaba.dubbo.config.annotation.Service;

 

@Service

public class DemoServiceImpl implements DemoService {

 

    public String findAll(){

       

        String str = "welcome to me!";

       

        return str;

       

    }

   

 

}

2.2   服务消费者

服务表现层消费者使用@Reference这个注解来直接引用服务层服务,此注解由dubbox提供.

 

importorg.springframework.stereotype.Controller;

importorg.springframework.web.bind.annotation.PathVariable;

importorg.springframework.web.bind.annotation.RequestMapping;

importorg.springframework.web.bind.annotation.ResponseBody;

 

import cn.it.DemoService;

 

importcom.alibaba.dubbo.config.annotation.Reference;

 

@Controller

public class DemoController {

   

    @Reference//引入服务

    private DemoServicedemoService;

   

    @RequestMapping("/demo/rest/{name}")

    @ResponseBody

    public String rest(@PathVariable String name){

        String str = demoService.findAll();

        return str+":"+name;

    }

 

}

 

 

第3章            Dubbox性能优化实战

为了更好了解dubbox做了什么优化,及dubbox在项目应用中我们需要做什么优化,提高项目的性能,因此做了一下的测试.

3.1   性能测试

3.1.1   测试环境

·        两台独立服务器

·        4核Intel(R) Xeon(R) CPU E5-2603 0 @1.80GHz

·        8G内存

·        服务器之间网络通过百兆交换机

·        CentOS5

·        JDK7

·        Tomcat7

·        JVM参数-server -Xms1g -Xmx1g -XX:PermSize=64M-XX:+UseConcMarkSweepGC

3.1.2   测试脚本

和dubbo自身的基准测试保持接近:

10个并发客户端持续不断发出请求:

·        传入嵌套复杂对象(但单个数据量很小),不做任何处理,原样返回

·        传入50K字符串,不做任何处理,原样返回(TODO:结果尚未列出)

进行5分钟性能测试。(引用dubbo自身测试的考虑:“主要考察序列化和网络IO的性能,因此服务端无任何业务逻辑。取10并发是考虑到http协议在高并发下对CPU的使用率较高可能会先打到瓶颈。”)

3.1.3   测试结果

下面的结果主要对比的是REST和dubbo RPC两种远程调用方式,并对它们作不同的配置,例如:

·        “REST: Jetty+XML+GZIP”的意思是:测试REST,并采用jetty server,XML数据格式,启用GZIP压缩。

·        “Dubbo: hessian2”的意思是:测试dubbo RPC,并采用hessian2序列化方式。

针对复杂对象的结果如下(响应时间越小越好,TPS越大越好):

远程调用方式

平均响应时间

平均TPS(每秒事务数)

REST: Jetty + JSON

7.806

1280

REST: Jetty + JSON + GZIP

TODO

TODO

REST: Jetty + XML

TODO

TODO

REST: Jetty + XML + GZIP

TODO

TODO

REST: Tomcat + JSON

2.082

4796

REST: Netty + JSON

2.182

4576

Dubbo: FST

1.211

8244

Dubbo: kyro

1.182

8444

Dubbo: dubbo serialization

1.43

6982

Dubbo: hessian2

1.49

6701

Dubbo: fastjson

1.572

6352

仅就目前的结果,一点简单总结:

1)dubbo RPC(特别是基于高效java序列化方式如kryo,fst)比REST的响应时间和吞吐量都有较显著优势,内网的dubbo系统之间优先选择dubbo RPC。

2)在 REST的实现选择上,仅就性能而言,目前tomcat7和netty最优(当然目前使用的jetty和netty版本都较低)。tjws和sunhttp server在性能测试中表现极差,平均响应时间超过200ms,平均tps只有50左右(为了避免影响图片效果,没在上面列出)。

3)在REST中JSON数据格式性能优于XML(数据暂未在以上列出)。

4)在REST中启用GZIP对企业内网中的小数据量复杂对象帮助不大,性能反而有下降(数据暂未在以上列出)。

根据以上测试结果,对dubbox发布服务以及消费服务做出以下优化。

平均响应时间:


 



3.2   Dubbox注解之超时

服务超时主要是指服务消费者给服务提供者发送请求,服务提供者迟迟没有回应,超过表现层预期访问的时间,那么表现层服务任务服务超时,就会抛出异常错误.

那么为了防止过快的服务超时,保持一个长连接,因此需要修改超时设置.

@Controller

public class DemoController {

   

    @Reference(timeout=100000) //超时时间为100000ms

    private DemoServicedemoService;

   

    @RequestMapping("/demo/rest/{name}")

    @ResponseBody

    public String rest(@PathVariable String name){

        String str = demoService.findAll();

        return str+":"+name;

    }

 

}

3.3   Dubbox注解之失败重试

服务失败自动切换,当出现失败,重试其它服务器 。通常用于读操作,但重试会带来更长延迟

可通过 retries="2" 来设置重试次数

表现层设置服务重试

@Controller

public class DemoController {

   

    @Reference(timeout=100000,retries=2)//对所有的service方法都起作用

    private DemoServicedemoService;

   

    @RequestMapping("/demo/rest/{name}")

    @ResponseBody

    public String rest(@PathVariable String name){

        String str = demoService.findAll();

        return str+":"+name;

    }}

 

服务层设置失败重试:

@Service(retries=2)

public class DemoServiceImpl implements DemoService {

   

    public String findAll(){

       

        String str = "welcome to me!";

       

        return str;

       

    }

   

 

}

3.4   Dubbox注解之序列化

从上面性能测试即可看出,dubbox序列化有多种方式,其中kryo序列化是最高效的一种序列化方式.

3.4.1    Kryo序列化实现

<dubbo:applicationname="demo-service"/>

    <dubbo:protocolname="dubbo"serialization="kryo"port="20880"/>

    <dubbo:registryaddress="zookeeper://192.168.66.66:2181"/>

    <!-- 发布服务 -->

    <dubbo:annotationpackage="cn.it"/>

必须注意,以上kryo序列化必须在相关坐标依赖的情况下才能进行正确的执行.

3.4.2    Jackson序列化

<dubbo:applicationname="demo-service"/>

    <dubbo:protocolname="dubbo"serialization="jackson"port="20880"/>

    <dubbo:registryaddress="zookeeper://192.168.66.66:2181"/>

    <!-- 发布服务 -->

    <dubbo:annotationpackage="cn.it"/>

因此我们发现dubbox高效率的序列化实现非常简单,只需要在dubboprotocol中配置serialization即可实现.

3.5      Dubbox注解开发之集群

3.5.1    负载均衡依赖坐标

Dubbox实现集群配置,必须导入dubbox集群坐标

 

<dependency>

            <groupId>com.alibaba</groupId>

            <artifactId>dubbo-cluster</artifactId>

            <version>2.8.4</version>

</dependency>

3.5.2    负载均衡测试服务器

准备3台tomcat服务器,一台表现层服务器,2台服务层服务器,提供负载均衡测试

配置tomcat服务器权限,使用tomcat热部署,必须先配置tomcat权限:

权限配置完毕后,启动所有的tomcat服务器.

3.5.3    服务热部署

配置服务tomcat插件热部署地址.

    <plugin>

                <groupId>org.apache.tomcat.maven</groupId>

                <artifactId>tomcat7-maven-plugin</artifactId>

                <configuration>

                    <!-- 指定端口 -->

                    <port>8080</port>

                    <!-- 请求路径 -->

                    <path>/</path>

                    <!-- 部署地址 -->

                    <url>http://192.168.66.66:9001/manager/text</url>

                    <username>tomcat</username>

                    <password>tomcat</password>

                </configuration>

            </plugin>

执行tomcat插件命令即可实现把项目部署到tomcat服务器ROOT目录下:

命令:tomcat:redeploy

3.5.4    集群负载配置

在集群负载均衡时,Dubbo 提供了多种均衡策略,缺省为 random 随机调用

Random LoadBalance

Ø  随机,按权重设置随机概率。

Ø  在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较

均匀,有利于动态调整提供者权重。

Ø  配置案例

 

@Service(loadbalance="random",retries=2)//此配置为默认负载策略,可以不配置

public class DemoServiceImpl implements DemoService {

   

    public String findAll(){

       

        String str = "welcome to me!";

       

        return str;

       

    }

   

 

}

 

RoundRobin LoadBalance

Ø  轮循,按公约后的权重设置轮循比率。

Ø  存在慢的提供者累积请求的问题,比如:第二台机器很慢,但没挂,当请求调到第二台

时就卡在那,久而久之,所有请求都卡在调到第二台上。

Ø  配置案例:

 

@Service(loadbalance="roundrobin",retries=2)

public class DemoServiceImpl implements DemoService {

   

    public String findAll(){

       

        String str = "welcome to me!";

       

        return str;

       

    }

   

 

}

 

LeastActive LoadBalance

Ø  最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。

Ø  使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。

Ø  配置案例:

 

@Service(loadbalance="leastactive",retries=2)

public class DemoServiceImpl implements DemoService {

   

    public String findAll(){

       

        String str = "welcome to me!";

       

        return str;

       

    }

   

 

}

 

ConsistentHash LoadBalance

Ø  一致性 Hash,相同参数的请求总是发到同一提供者。

Ø  当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,

不会引起剧烈变动。

Ø  配置案例:

 

@Service(loadbalance="consistenthash",retries=2)

public class DemoServiceImpl implements DemoService {

   

    public String findAll(){

       

        String str = "welcome to me!";

       

        return str;

       

    }

   

 

}

更多资源: 请关注微信公众号: IT核心资源分享(100T高清架构师资源共享)



原创粉丝点击