这里引用官方文档的一张图片,来简单说明各个节点的角色职责
节点角色说明:
- Provider: 暴露服务的服务提供方。
- Consumer: 调用远程服务的服务消费方。
- Registry: 服务注册与发现的注册中心。
- Monitor: 统计服务的调用次调和调用时间的监控中心。
- Container: 服务运行容器。
一、本篇概述
本篇分两个部分。
第一,搭建好provider和consumer后,使用Main方法阻塞来模拟,不涉及到SpringMVC。
第二,搭建后,使用SpringMVC进行注入调用远程服务接口。
二、准备工作
框架版本:
- tomcat8,jdk7
- dubbo-admin-2.4.1.war 这是dubbo管理war包,修改war直接扔到tomcat跑就可以了。
- zookeeper-3.4.5 本实例使用zookeeper作为注册中心,其实还能使用其他的,这里不详细讲解。
2.1 搭建zookeeper(我这里是window环境)
请参考window7环境下ZooKeeper的安装及运行 单机搭建很简单。
2.2 部署dubbo-admin-2.4.1.war
直接放到tomcat的webapp文件夹下,运行tomcat。
- 配置信息都在WEB-INF/dubbo.properties下,管理员账号密码都是root,zookeeper的地址等。
打开浏览器输入:http://localhost:8080/dubbo-admin-2.4.1
(运行前记得先打开zookeeper服务)
输入账号密码root,进入这个页面就算成功了。
三、创建提供者provider工程(使用maven构建)
dubbo.provider项目结构如下图:
导入依赖,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>com.soecode</groupId>
<artifactId>dubbo.provider</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>dubbo.provider Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<!-- Logger日志 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
</dependency>
<!-- dubbo -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.4.10</version>
</dependency>
<!-- zookeeper -->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.3.4</version>
</dependency>
<!-- zkclient 用于访问zookeeper -->
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.3</version>
</dependency>
</dependencies>
<build>
<finalName>dubbo.provider</finalName>
</build>
</project>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
在service包下创建接口HelloService.java
package com.soecode.dubbo.service;
public interface HelloService {
/**
* say hello
* @param name
* @return
*/
public String sayHello(String name);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
在Service.impl下实现接口HelloServiceImpl.java
package com.soecode.dubbo.service.impl;
import org.springframework.stereotype.Service;
import com.soecode.dubbo.service.HelloService;
@Service("helloServiceImpl")
public class HelloServiceImpl implements HelloService {
public String sayHello(String name) {
return "hello,"+name+"!";
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
接下来填写dubbo-provider.xml来暴露接口
<?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:context="http://www.springframework.org/schema/context"
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://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- 注解包扫描位置: 因为这里的实现类使用注解的方式 -->
<context:component-scan base-package="com.soecode.dubbo.*" />
<!-- 接入dubbo的应用程序名称 -->
<dubbo:application name="demo-provider" />
<!-- 注册仓库地址:zookeeper组件,192.168.61.128:2181 -->
<dubbo:registry address="zookeeper://127.0.0.1:2181" />
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20880" />
<!--
声明需要暴露的服务接口,
请注意ref属性中指定的HelloService接口实现类,它并没有在xml文件中定义,而是使用注解的方式在class中定义
-->
<dubbo:service interface="com.soecode.dubbo.service.HelloService" ref="helloServiceImpl"/>
</beans>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
到此服务接口已经定义好,接下来要通过main方法读取配置文件,来达到zookeeper服务注册的效果。
创建ProviderApp.java
package com.soecode.dubbo;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* 服务提供者示例
* @author antgan
* @date 2017/1/12
*
*/
public class ProviderApp {
public static void main(String[] args) throws Exception {
//读取配置文件
new ClassPathXmlApplicationContext(new String[]{"dubbo-provider.xml"});
System.out.println("provider服务已注册");
//使线程阻塞
System.in.read();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
运行ProviderApp,即可。
如何校验是否成功注册?进入dubbo-admin,点菜单栏上的提供者,如下图就注册成功了,成功暴露接口。
四、创建消费者consumer项目
dubbo.consumer项目结构
引入依赖,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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.soecode</groupId>
<artifactId>dubbo.consumer</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>dubbo.consumer Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<!-- log4j日志 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
</dependency>
<!-- dubbo -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.4.10</version>
</dependency>
<!-- zookeeper -->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.3.4</version>
</dependency>
<!-- zkclient -->
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.3</version>
</dependency>
<!-- 引用dubbo.provider -->
<dependency>
<groupId>com.soecode</groupId>
<artifactId>dubbo.provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- SpringMVC -->
<!-- spring web依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<!--3: Servlet web 相关依赖 -->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.4</version>
</dependency>
</dependencies>
<build>
<finalName>dubbo.consumer</finalName>
</build>
</project>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
配置dubbo-consumer.xml,向zookeeper注册接口(有点像存根)
<?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="demo-consumer" />
<!-- 注册仓库地址:zookeeper组件,192.168.61.128:2181 -->
<dubbo:registry address="zookeeper://127.0.0.1:2181" />
<!-- 引用的服务,那个interface一定是一个被引入到DUBBO仓库的接口定义 -->
<dubbo:reference id="helloService" interface="com.soecode.dubbo.service.HelloService"/>
</beans>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
创建ConsumerApp.java,运行测试
package com.soecode.dubbo;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.soecode.dubbo.service.HelloService;
/**
* 消费者示例
* @author antgan
* @date 2017/1/12
*
*/
public class ConsumerApp {
public static void main(String[] args) throws Exception {
//读取配置文件
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"dubbo-consumer.xml"});
//获取在zookeeper注册的服务接口
HelloService helloService = (HelloService)context.getBean("helloService");
//调用接口
System.out.println("HelloService = " + helloService.sayHello("ant"));
//不让控制台消失,按任意键结束
System.in.read();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
运行结果:
我们也可以在dubbo-admin上看一下,如下
至此,已经完成了第一部分,在main方法模拟调用远程接口。
五、consumer引入SpringMVC
在dubbo.consumer引入springMVC,pom.xml 添加以下jar包:
<!-- SpringMVC -->
<!-- spring web依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<!--3: Servlet web 相关依赖 -->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.4</version>
</dependency>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
在resource文件夹下创建spring-web.xml
<?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:mvc="http://www.springframework.org/schema/mvc"
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.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 配置SpringMVC -->
<!-- 1:开启SpringMVC注解模式 -->
<!-- 简化配置:
1)自动注册DefaultAnnotationHandlerMapping,AnnotationMethodHandlerAdapter
2) 提供一系列:数据绑定,数字和日期的format等功能,支持xml,json读写-->
<mvc:annotation-driven/>
<!--2: 静态资源配置
1) 加入静态资源的处理,如js,gif,png
2)允许使用"/"处理
-->
<mvc:default-servlet-handler/>
<!-- 3: 配置jsp 显示ViewResolver -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" /> <!-- 前缀 -->
<property name="suffix" value=".jsp" /> <!-- 后缀 -->
</bean>
<!-- 4: 扫描web相关的bean -->
<context:component-scan base-package="com.soecode.dubbo.web"/>
</beans>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
修改web.xml,使其运行时加载配置文件。
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>dubbo.consumer</display-name>
<!-- 加载dubbo-consumer.xml -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:/dubbo-consumer.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 配置DispatcherServlet -->
<servlet>
<servlet-name>dubbo.consumer-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 加载spring-web.xml -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-web.xml</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dubbo.consumer-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
在dubbo.web包下创建HelloController.java
package com.soecode.dubbo.web;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import com.soecode.dubbo.service.HelloService;
@Controller
@RequestMapping("hello")
public class HelloController {
/**
* 注入远程接口
*/
@Autowired
private HelloService helloService;
/**
* 调用远程接口,返回index.jsp页面
* @param model
* @return
*/
@RequestMapping("index")
public String index(Model model){
model.addAttribute("str", helloService.sayHello("ant"));
return "index";
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
运行,地址栏输入:http://localhost:8080/dubbo.consumer/hello/index
几个坑,你可能会遇到:
一、遇到这个报错
java.lang.NullPointerException
at org.springframework.core.SerializableTypeWrapper$TypeProxyInvocationHandler.invoke(SerializableTypeWrapper.java:239)
- 1
- 2
- 3
解决办法:这是因为spring的jar包冲突,dubbo自带一个2.x.x版本的spring。pom修改如下:
<!-- dubbo -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.4.10</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
</exclusion>
</exclusions>
</dependency>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
二、其他都做好了,就是无法启动。
解决方法:可以尝试provider打包成jar,consumer引入。
三、无法读取dubbo的配置文件
解决方法:下载dubbo.xsd,手动添加xsd。具体方法可以参考。解决:dubbo找不到dubbo.xsd报错
最后,一起进步一起学习吧!