搭建一个简单的dubbo服务

参考地址:

dubbo官网:http://dubbo.apache.org/zh-cn/docs/user/references/registry/zookeeper.html

博客:http://www.cnblogs.com/lighten/p/6828026.html

以上两个教程经实践发现都有部分谬误,本教程做了一定更正

1.简介

dubbo是一个分布式服务框架,由阿里巴巴的工程师开发,致力于提供高性能和透明化的RPC远程服务调用。可惜的是该项目在2012年之后就没有再更新了,之后由当当基于dubbo开发了dubbox。这里对dubbo的入门构建进行简单的介绍。不涉及dubbo的运行机制,只是搭建过程,方便学习者快速构建项目,运行、熟悉该框架。

dubbo提供了两种构建项目的方法:

  1. 通过Spring容器快速构建,其中还有注解的方式;
  2. 通过直接使用API(不推荐)。以下对其一一说明。

2.spring配置的形式

1.导入maven依赖

<!--如果引入的是2.6.2以下版本,xml文件头引入的xsd地址会报错-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.3</version>
<exclusions>
<exclusion>
<!-- 排除传递spring依赖 -->
<artifactId>spring</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
</exclusions>
</dependency> <!--下面分别是两种不同的zookeeper客户端实现,选择一种就好-->
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.4</version>
</dependency> <dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.12.0</version>
</dependency> <!--后期可能还会用到如下zookeeper客户端jar包依赖,但是目前这个demo不引入也没有问题-->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.3.3</version>
</dependency> <!--spring配置方式,自然需要spring相关的依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.2.17.RELEASE</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency> <!--打印日志相关-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.4</version>
</dependency>

zkclient和curator

curator和zkclient分别为两种不同的zookeeper实现,两者使用的同时都需要开启先zookeeper注册中心的服务端。(关于如何下载配置并启动zookeeper服务端,参考win10环境下搭建zookeeper伪集群)

在本项目中,它默认是使用了curator实现的,要改成zkclient实现,需要在<dubbo:registry address="zookeeper://127.0.0.1:2181/" client="zkclient" />标签中加入 client="zkclient",并换成zkclient的依赖。

(在dubbo官网中称2.5以上的dubbo版本默认使用zookeeper实现,但是实测结果却相反)

2.定义服务接口(对提供方和调用方都可见)

package dubboXml;

public interface DemoService {
String sayHello(String name);
}

3.服务提供方配置

  1. 实现服务接口

    package dubboXml;
    
    public class DemoServiceImpl implements DemoService{
    public String sayHello(String name) {
    return "Hello " + name;
    }
    }
  2. spring配置

    <?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://dubbo.apache.org/schema/dubbo"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
    http://dubbo.apache.org/schema/dubbo
    http://dubbo.apache.org/schema/dubbo/dubbo.xsd"> <!-- 提供方应用信息,用于计算依赖关系 -->
    <dubbo:application name="hello-world-app" /> <!-- 使用zookeeper注册中心暴露服务地址 -->
    <dubbo:registry address="zookeeper://127.0.0.1:2181" client="zkclient" /> <!-- 用dubbo协议在20880端口暴露服务 -->
    <dubbo:protocol name="dubbo" port="20880" /> <!-- 声明需要暴露的服务接口 -->
    <dubbo:service interface="dubboXml.DemoService" ref="demoService" /> <!-- 和本地bean一样实现服务 -->
    <bean id="demoService" class="dubboXml.DemoServiceImpl" />
    </beans>
  3. 读取配置,提供服务

    package dubboXml;
    
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class Provider {
    public static void main(String[] args) throws Exception {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"provider.xml"});
    context.start();
    System.in.read(); // 按任意键退出
    }
    }

4.服务调用方配置

  1. spring配置

    <?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://dubbo.apache.org/schema/dubbo"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
    http://dubbo.apache.org/schema/dubbo
    http://dubbo.apache.org/schema/dubbo/dubbo.xsd"> <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
    <dubbo:application name="consumer-of-helloworld-app" /> <!-- 使用zookeeper注册中心暴露发现服务地址 -->
    <dubbo:registry address="zookeeper://127.0.0.1:2181" /> <!-- 生成远程服务代理,可以和本地bean一样使用demoService -->
    <dubbo:reference id="demoService" interface="dubboXml.DemoService" />
    </beans>
  2. 读取配置,调用服务

    package dubboXml;
    
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class Consumer {
    public static void main(String[] args) throws Exception {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"consumer.xml"});
    context.start();
    DemoService demoService = (DemoService)context.getBean("demoService"); // 获取远程服务代理
    String hello = demoService.sayHello("nihao"); // 执行远程方法
    System.out.println( hello ); // 显示调用结果
    }
    }

最终结果:

5.其他说明

  • 如果涉及传输对象,那么被传输的对象类应该实现serializable接口。因为对象远程传输是以二进制的形式进行的,那么在传输之前需要实现序列化。
  • 我的demo地址:demoXml

我的目录结构:

3.注解配置的方式

maven配置同上。

1.服务接口和传输对象

服务接口

package com.common.server;

import java.util.List;

public interface DemoService {

    public String greet(String name);
public List<User> getUsers(); }

传输对象:实现序列化接口

package com.common.server;

import java.io.Serializable;

public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    private String name;
private int age;
private String sex; public User(String name, int age, String sex) {
this.name = name;
this.age = age;
this.sex = sex;
} public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
} @Override
public String toString() {
return "User [name=" + name + ", age=" + age + ", sex=" + sex + "]";
}
}

2.服务提供方

  1. 实现接口(注意加上相应注解)

    package com.provider;
    
    import com.alibaba.dubbo.config.annotation.Service;
    import com.common.server.DemoService;
    import com.common.server.User; import java.util.ArrayList;
    import java.util.List; /**
    * 实现类上打上service注解:注意,是dubbo的service注解
    */
    @Service
    public class DemoServiceImpl implements DemoService { @Override
    public String greet(String name) {
    return "Hello " + name;
    } @Override
    public List<User> getUsers() {
    List<User> list = new ArrayList<>(); User user1 = new User("张三",10,"男");
    User user2 = new User("李四",11,"女");
    User user3 = new User("王五",12,"男"); list.add(user1);
    list.add(user2);
    list.add(user3); return list;
    } }
  2. xml配置

    (与全xml配置服务的方式相比,这里去掉了bean和<dubbo:service>,使用<dubbo:anotition>取代了,相当于自动扫描并暴露服务)

    <?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="provider" /> <!-- 使用zookeeper注册中心暴露服务地址 -->
    <dubbo:registry address="zookeeper://127.0.0.1:2181" client="zkclient" />
    <!--<dubbo:registry address="N/A"/>--> <!-- 用dubbo协议在20880端口暴露服务 -->
    <dubbo:protocol name="dubbo" port="20880" /> <!-- 注解实现,指向服务提供者实现类的包扫描-->
    <dubbo:annotation package="com.provider" />
    </beans>
  3. 开启服务提供

    package com.provider;
    
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import java.io.IOException;
    
    /**
    * 服务提供者
    */
    public class Provider { public static void main(String[] args) throws IOException {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"provider.xml"});
    context.start();
    System.in.read();
    }
    }

3.服务调用方

  1. 类中注入并使用远程服务代理(为什么不在加载spring文件的类中注入?因为那是入口)

    package com.consumer;
    import com.alibaba.dubbo.config.annotation.Reference;
    import com.common.server.DemoService;
    import org.springframework.stereotype.Component; /**
    * 服务消费者:service是spring的注解
    */
    @Component("anotationConsumer")
    public class AnotationConsumer { /**
    * 远程服务代理,可以和本地bean一样使用demoService
    */
    @Reference(check = false)
    private DemoService demoService; public void print(){
    System.out.println(demoService.greet("张三"));
    System.out.println(demoService.getUsers());
    }
    }
  2. consumer.xml spring配置文件

    <?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"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://code.alibabatech.com/schema/dubbo
    http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <dubbo:application name="consumer"/> <dubbo:registry address="zookeeper://127.0.0.1:2181" client="zkclient" /> <!--指向服务调用者所在的包-->
    <dubbo:annotation package="com.consumer" /> <!-- 配置spring注解包扫描 -->
    <context:component-scan base-package="com.consumer"></context:component-scan> </beans>
  3. 启动服务

    package com.consumer;
    
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class Consumer {
    
        public static void main(String[] args) {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"consumer.xml"});
    context.start(); AnotationConsumer anotationConsumer = (AnotationConsumer) context.getBean("anotationConsumer");
    anotationConsumer.print();
    }
    }

调用结果:

4.附加信息

  • 无论是哪种配置方式,如果使用了注册中心,那么注册和调用的时候必须先开启注册中心。
  • demo地址:dubboAnotation
  • 还有一种api调用的形式,由于不常用所以这里没有提供教程。如果有兴趣可以查看参考帖。

dubbo学习笔记:快速搭建的更多相关文章

  1. Hadoop学习笔记(10) ——搭建源码学习环境

    Hadoop学习笔记(10) ——搭建源码学习环境 上一章中,我们对整个hadoop的目录及源码目录有了一个初步的了解,接下来计划深入学习一下这头神象作品了.但是看代码用什么,难不成gedit?,单步 ...

  2. Hadoop学习笔记(4) ——搭建开发环境及编写Hello World

    Hadoop学习笔记(4) ——搭建开发环境及编写Hello World 整个Hadoop是基于Java开发的,所以要开发Hadoop相应的程序就得用JAVA.在linux下开发JAVA还数eclip ...

  3. 学习笔记 - 快速傅里叶变换 / 大数A * B的另一种解法

    转: 学习笔记 - 快速傅里叶变换 / 大数A * B的另一种解法 文章目录 前言 ~~Fast Fast TLE~~ 一.FFT是什么? 二.FFT可以干什么? 1.多项式乘法 2.大数乘法 三.F ...

  4. MongoDB学习笔记:快速入门

    MongoDB学习笔记:快速入门   一.MongoDB 简介 MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统.在高负载的情况下,添加更多的节点,可以保证服务器性能.M ...

  5. Dubbo -- 系统学习 笔记 -- 快速启动

    Dubbo -- 系统学习 笔记 -- 目录 快速启动 服务提供者 服务消费者 快速启动 Dubbo采用全Spring配置方式,透明化接入应用,对应用没有任何API侵入,只需用Spring加载Dubb ...

  6. NuGet学习笔记3——搭建属于自己的NuGet服务器

    文章导读 创建NuGetServer Web站点 发布站点到IIS 添加本地站点到包包数据源 在上一篇NuGet学习笔记(2) 使用图形化界面打包自己的类库 中讲解了如何打包自己的类库,接下来进行最重 ...

  7. NuGet学习笔记(3) 搭建属于自己的NuGet服务器

    文章导读 创建NuGetServer Web站点 发布站点到IIS 添加本地站点到包包数据源 在上一篇NuGet学习笔记(2) 使用图形化界面打包自己的类库 中讲解了如何打包自己的类库,接下来进行最重 ...

  8. NuGet学习笔记(3)——搭建属于自己的NuGet服务器(转)

    在上一篇NuGet学习笔记(2) 使用图形化界面打包自己的类库 中讲解了如何打包自己的类库,接下来进行最重要的一步,从零开始搭建属于自己的NuGet服务器,诚然园子里及其它很多地方已经有完全写好的Nu ...

  9. flink学习笔记-快速生成Flink项目

    说明:本文为<Flink大数据项目实战>学习笔记,想通过视频系统学习Flink这个最火爆的大数据计算框架的同学,推荐学习课程: Flink大数据项目实战:http://t.cn/EJtKh ...

随机推荐

  1. pyspider示例代码一:利用phantomjs解决js问题

    本系列文章主要记录和讲解pyspider的示例代码,希望能抛砖引玉.pyspider示例代码官方网站是http://demo.pyspider.org/.上面的示例代码太多,无从下手.因此本人找出一下 ...

  2. vue项目 菜单侧边栏随着右侧内容盒子的高度实时变化

    测试的时候发现,在选择模板.选择产品第二步第三步的时候.如果超出两行的话会盖住看不见,(因为高度所有统一都被写死了,又加了overflow~emmm~)所以要改成走马灯形式.如图: 那么问题来了,我步 ...

  3. 多个docker 挂载VOLUME的心得

    假如有一个mysql镜像 在Dockerfile中制定VOLUME /var/lib/mysql 那么当执行: docker run -d -e MYSQL_ROOT_PASSWORD=root -- ...

  4. 学习C++的50条忠告

    1. 把C++当成一门新的语言学习: 2. 看<Thinking In C++>,不要看<C++变成死相>: 3. 看<The C++ Programming Langu ...

  5. nginx 集群介绍

    nginx 集群介绍 完成一次请求的步骤 1)用户发起请求 2)服务器接受请求 3)服务器处理请求(压力最大) 4)服务器响应请求 缺点:单点故障 单台服务器资源有限 单台服务器处理耗时长 ·1)部署 ...

  6. Oracle学习笔记(十三)

    十四.触发器(监听数据操作的工具) 1.什么是触发器? 数据库触发器是一个与表相关联的.存储的PL/SQL程序 作用: 每当一个特定的数据操作语句(insert.update.delete)在指定的表 ...

  7. RocketMQ服务器监控误区

    请不要监控10912端口 case: result: 监控10912端口会导致HAService异常,新起线程,吃掉内存,无限次监控虚拟机将宕机! 时间上是直接因果关系. 监控10911 和 9876 ...

  8. threadpoolExecutor----自动执行任务

    使用threadpoolExecutor,主要是任务的提交的执行和获取结果. 提交任务的方法有: 1.submit 2.execute 3.queue的add 其中1和2的使用必须是threadpoo ...

  9. ubuntu 安装 hubicfuse

    如果你没有gcc,请先安装gcc: 1: apt-get install build-essential 1. 从github上clone源码: https://github.com/TurboGit ...

  10. TSQL--自增键和索引对表的插入效率测试

    问题描述:数据库操作中,需要对表频繁插入数据,但发现插入效率不高. 解决思路:将数据缓存在服务器上,积攒到一定条数后批处理发送到数据库,在插入时考虑并发和索引对插入效率的影响. 测试结果:      ...