简单的做一下Dubbo的入门案例,遇到了一些小问题,对于dubbo的配置文件需要了解一下,案例中,做了提供者和消费者两个,都做了,在Customer需要在pom中,引用provider的依赖包。这个案例,主要做的是Cusumer和Provider, Cusumer如何调用Provider提供的服务。
Provider: 暴露服务的服务提供方。
Consumer: 调用远程服务的服务消费方。
Registry: 服务注册与发现的注册中心。
Monitor: 统计服务的调用次数和调用时间的监控中心。
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包还真不少啊
目录结构
接口
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();
}
}
管控台结果
管控台看到了我们注册的服务,通过控制台可以控制这个服务的路由规则,权限等
Customer(消费者)
目录结构
配置文件
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里面的结果
常见错误
Exception in thread “main” java.lang.NoClassDefFoundError: org/I0Itec/zkclient/IZkStateListener异常
出现这个问题的原因是zkCleintのjar包缺少了,缺少的jar包坐标如下
解决办法,添加zkClient的依赖
<!--zkclient客户端-->
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>0.1</version>
</dependency>
实体类没有序列化错误
实体类需要实现Serializable 接口
服务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 ?