简单的做一下Dubbo的入门案例,遇到了一些小问题,对于dubbo的配置文件需要了解一下,案例中,做了提供者和消费者两个,都做了,在Customer需要在pom中,引用provider的依赖包。这个案例,主要做的是Cusumer和Provider, Cusumer如何调用Provider提供的服务。

Provider: 暴露服务的服务提供方。
Consumer: 调用远程服务的服务消费方。
Registry: 服务注册与发现的注册中心。
Monitor: 统计服务的调用次数和调用时间的监控中心。

dubbo切面实现方式 dubbo使用实例_spring

Provider (提供者)

实现提供者,需要配置dubbo.xml文件,接口和实现类同以前的做法一致,只是改成了配置到注册到zookeeper,而且需要一直服务。

环境搭建

pom.xml配置文件

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>yellowcong</groupId>
  <artifactId>dubbo-provider</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>dubbo-provider</name>
  <url>http://maven.apache.org</url>


    <!-- 配置国内比较快的 阿里云的Maven仓库 -->
    <repositories>
        <repository>
            <id>aliyunmaven</id>
            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
        </repository>
    </repositories>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <!-- dubbo -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>dubbo</artifactId>
        <version>2.5.6</version>
    </dependency>
    <!-- zkclient 客户端 -->
      <dependency>
          <groupId>com.github.sgroschupf</groupId>
          <artifactId>zkclient</artifactId>
          <version>0.1</version>
      </dependency>

    <!-- Junit 测试 -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.10</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

就引了两个依赖,发现就会将所有的依赖都导入了,jar包还真不少啊

dubbo切面实现方式 dubbo使用实例_ide_02

目录结构

dubbo切面实现方式 dubbo使用实例_ide_03

接口

package com.yellowcong.dubbo.provider;

import java.util.List;

import com.yellowcong.dubbo.entity.User;

/**
 * 创建日期:2017年10月15日 <br/>
 * 创建用户:yellowcong <br/>
 * 功能描述:Service层接口
 */
public interface UserService {

    /**
     * 
     * 创建日期:2017年10月15日<br/>
     * 创建用户:yellowcong<br/>
     * 功能描述:获取所有用户
     * @return
     */
    List<User> getUsers();

    void sayHello(String useranme);
}

实现类

package com.yellowcong.dubbo.provider.impl;

import java.util.ArrayList;
import java.util.List;

import com.yellowcong.dubbo.entity.User;
import com.yellowcong.dubbo.provider.UserService;

/**
 * 创建日期:2017年10月15日 <br/>
 * 创建用户:yellowcong <br/>
 * 功能描述:  
 */
public class UserServiceImpl implements UserService{

    public List<User> getUsers() {
        List<User> users = new ArrayList<User>();
        users.add(new User(1,"yellowcong","nickname"));
        users.add(new User(2,"zhangsan","nickname"));
        users.add(new User(3,"wangwu","nickname"));
        users.add(new User(4,"lisi","nickname"));
        return users;
    }

    public void sayHello(String useranme) {
        System.out.println("hello" +useranme);
    }

}

实体类

实体类对象,需要实现Serializable接口,这样就可以序列化传输Class对象,不然就会报错

package com.yellowcong.dubbo.entity;

/**
 * 创建日期:2017年10月15日 <br/>
 * 创建用户:yellowcong <br/>
 * 功能描述:  
 */
public class User implements Serializable{

    private static final long serialVersionUID = 1L;

    private int id; 
    private String username;
    private String nickname;

    public User(int id, String username, String nickname) {
        super();
        this.id = id;
        this.username = username;
        this.nickname = nickname;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getNickname() {
        return nickname;
    }
    public void setNickname(String nickname) {
        this.nickname = nickname;
    }
}

配置文件

spring-provider.xml,配置dubbo的service信息

<?xml version="1.0" encoding="UTF-8"?>
<!-- 添加 DUBBO SCHEMA -->
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://code.alibabatech.com/schema/dubbo 
       http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!-- 应用名 -->
    <dubbo:application name="dubbo-provider"/>
    <!-- 连接到哪个本地注册中心 
    这个注册的id是唯一的-->
    <dubbo:registry id="dubbodemo" address="zookeeper://192.168.66.110:2181?backup=192.168.66.110:2182,192.168.66.110:2183"/>

    <!-- 用dubbo协议在20880端口暴露服务 -->
    <dubbo:protocol name="dubbo" port="28080" />

    <!-- 实现类 -->     
    <bean id="userService" class="com.yellowcong.dubbo.provider.impl.UserServiceImpl"/>

    <!-- 声明需要暴露的服务接口
    registry 注册到那一个调度中心
    timeout 超时
    interface 接口,这个是接口类,不是我们的实现类
    retries 重复尝试注册次数
     -->
    <dubbo:service registry="dubbodemo" retries="0" timeout="3000"
        interface="com.yellowcong.dubbo.provider.UserService" ref="userService" />

</beans>

日志配置文件 log4j

###set log levels###
log4j.rootLogger=info, stdout
###输出到控制台###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[%d{dd/MM/yy hh:mm:ss:sss z}] %t %5p %c{2}: %m%n

启动注册

这个服务启动是我们依赖于Spring的ClassPathXmlApplicationContext 配置文件写的,但是实际开发中,不这么写,实际开发中,直接将应用放到容器上

package com.yellowcong.dubbo.main;

import java.io.IOException;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * 创建日期:2017年10月15日 <br/>
 * 创建用户:yellowcong <br/>
 * 功能描述:  
 */
public class DuboMain {

    public static void main(String[] args) throws Exception {
        //获取容器
        String []  xmls = {"spring-provider.xml"};
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(xmls);

        context.start();

        //让线程在这个地方阻塞着,这样服务就可以一直保持了
        System.in.read();
    }
}

管控台结果

管控台看到了我们注册的服务,通过控制台可以控制这个服务的路由规则,权限等

dubbo切面实现方式 dubbo使用实例_dubbo切面实现方式_04

Customer(消费者)

目录结构

dubbo切面实现方式 dubbo使用实例_dubbo切面实现方式_05

配置文件

spring-customer.xml,消费者配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!-- 添加 DUBBO SCHEMA -->
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://code.alibabatech.com/schema/dubbo 
       http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!-- 应用名 -->
    <dubbo:application name="dubbo-provider"/>
    <!-- 连接到哪个本地注册中心 
    这个注册的id是唯一的-->
    <dubbo:registry id="dubbodemo" address="zookeeper://192.168.66.110:2181?backup=192.168.66.110:2182,192.168.66.110:2183"/>

    <!-- 生成远程服务代理,可以和本地bean一样使用demoService -->
    <dubbo:reference id="demoService" check="false" interface="com.yellowcong.dubbo.provider.UserService"/>

</beans>

调用类

package com.yellowcong.dubbo.main;

import java.util.List;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.yellowcong.dubbo.entity.User;
import com.yellowcong.dubbo.provider.UserService;

/**
 * 创建日期:2017年10月15日 <br/>
 * 创建用户:yellowcong <br/>
 * 功能描述:  
 */
public class TestMain {

    public static void main(String[] args) {

        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-customer.xml");

        context.start();

        //调用Service服务
        UserService service = (UserService) context.getBean("demoService");

        service.sayHello("yellowcong");

        //获取用户
        List<User> users = service.getUsers();
        System.out.println(users.size());
        for(User user:users){
            System.out.println(user.getUsername());
        }
    }
}

调用结果

Client端获取到了Provider里面的结果

dubbo切面实现方式 dubbo使用实例_ide_06

常见错误

Exception in thread “main” java.lang.NoClassDefFoundError: org/I0Itec/zkclient/IZkStateListener异常

出现这个问题的原因是zkCleintのjar包缺少了,缺少的jar包坐标如下

dubbo切面实现方式 dubbo使用实例_dubbo_07

解决办法,添加zkClient的依赖

<!--zkclient客户端-->
<dependency>
    <groupId>com.github.sgroschupf</groupId>
    <artifactId>zkclient</artifactId>
    <version>0.1</version>
</dependency>

实体类没有序列化错误

实体类需要实现Serializable 接口

dubbo切面实现方式 dubbo使用实例_dubbo_08

服务Provider未启动

如果provider都没启动,咋玩啊

Exception in thread "main" com.alibaba.dubbo.rpc.RpcException: No provider available from registry 192.168.66.110:2181 for service com.yellowcong.dubbo.provider.UserService on consumer 192.168.56.1 use dubbo version 2.5.6, may be providers disabled or not registered ?