本篇是实例教程,分享搭建dubbo+zookeeper一些必经的坑
更多请查看Dubbo官方文档
本篇最终项目dubbo.demo下载
这里引用官方文档的一张图片,来简单说明各个节点的角色职责
节点角色说明:
本篇分两个部分。
第一,搭建好provider和consumer后,使用Main方法阻塞来模拟,不涉及到SpringMVC。
第二,搭建后,使用SpringMVC进行注入调用远程服务接口。
框架版本:
请参考window7环境下ZooKeeper的安装及运行 单机搭建很简单。
直接放到tomcat的webapp文件夹下,运行tomcat。
打开浏览器输入:http://localhost:8080/dubbo-admin-2.4.1
(运行前记得先打开zookeeper服务)
输入账号密码root,进入这个页面就算成功了。
导入依赖,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.0modelVersion>
<groupId>com.soecodegroupId>
<artifactId>dubbo.providerartifactId>
<packaging>warpackaging>
<version>0.0.1-SNAPSHOTversion>
<name>dubbo.provider Maven Webappname>
<url>http://maven.apache.orgurl>
<dependencies>
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>1.2.14version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>dubboartifactId>
<version>2.4.10version>
dependency>
<dependency>
<groupId>org.apache.zookeepergroupId>
<artifactId>zookeeperartifactId>
<version>3.3.4version>
dependency>
<dependency>
<groupId>com.101tecgroupId>
<artifactId>zkclientartifactId>
<version>0.3version>
dependency>
dependencies>
<build>
<finalName>dubbo.providerfinalName>
build>
project>
在service包下创建接口HelloService.java
package com.soecode.dubbo.service;
public interface HelloService {
/**
* say hello
* @param name
* @return
*/
public String sayHello(String name);
}
在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+"!";
}
}
接下来填写dubbo-provider.xml来暴露接口
<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:application name="demo-provider" />
<dubbo:registry address="zookeeper://127.0.0.1:2181" />
<dubbo:protocol name="dubbo" port="20880" />
<dubbo:service interface="com.soecode.dubbo.service.HelloService" ref="helloServiceImpl"/>
beans>
到此服务接口已经定义好,接下来要通过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();
}
}
运行ProviderApp,即可。
如何校验是否成功注册?进入dubbo-admin,点菜单栏上的提供者,如下图就注册成功了,成功暴露接口。
引入依赖,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.0modelVersion>
<groupId>com.soecodegroupId>
<artifactId>dubbo.consumerartifactId>
<packaging>warpackaging>
<version>0.0.1-SNAPSHOTversion>
<name>dubbo.consumer Maven Webappname>
<url>http://maven.apache.orgurl>
<dependencies>
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>1.2.14version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>dubboartifactId>
<version>2.4.10version>
dependency>
<dependency>
<groupId>org.apache.zookeepergroupId>
<artifactId>zookeeperartifactId>
<version>3.3.4version>
dependency>
<dependency>
<groupId>com.101tecgroupId>
<artifactId>zkclientartifactId>
<version>0.3version>
dependency>
<dependency>
<groupId>com.soecodegroupId>
<artifactId>dubbo.providerartifactId>
<version>0.0.1-SNAPSHOTversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webartifactId>
<version>4.1.7.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>4.1.7.RELEASEversion>
dependency>
<dependency>
<groupId>taglibsgroupId>
<artifactId>standardartifactId>
<version>1.1.2version>
dependency>
<dependency>
<groupId>jstlgroupId>
<artifactId>jstlartifactId>
<version>1.2version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.5.4version>
dependency>
dependencies>
<build>
<finalName>dubbo.consumerfinalName>
build>
project>
配置dubbo-consumer.xml,向zookeeper注册接口(有点像存根)
<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" />
<dubbo:registry address="zookeeper://127.0.0.1:2181" />
<dubbo:reference id="helloService" interface="com.soecode.dubbo.service.HelloService"/>
beans>
创建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();
}
}
至此,已经完成了第一部分,在main方法模拟调用远程接口。
在dubbo.consumer引入springMVC,pom.xml 添加以下jar包:
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webartifactId>
<version>4.1.7.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>4.1.7.RELEASEversion>
dependency>
<dependency>
<groupId>taglibsgroupId>
<artifactId>standardartifactId>
<version>1.1.2version>
dependency>
<dependency>
<groupId>jstlgroupId>
<artifactId>jstlartifactId>
<version>1.2version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.5.4version>
dependency>
在resource文件夹下创建spring-web.xml
<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">
<mvc:annotation-driven/>
<mvc:default-servlet-handler/>
<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>
<context:component-scan base-package="com.soecode.dubbo.web"/>
beans>
修改web.xml,使其运行时加载配置文件。
<web-app>
<display-name>dubbo.consumerdisplay-name>
<context-param>
<param-name>contextConfigLocationparam-name>
<param-value>
classpath:/dubbo-consumer.xml
param-value>
context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
listener>
<servlet>
<servlet-name>dubbo.consumer-dispatcherservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:spring-web.xmlparam-value>
init-param>
<load-on-startup>0load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>dubbo.consumer-dispatcherservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
web-app>
在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";
}
}
运行,地址栏输入:http://localhost:8080/dubbo.consumer/hello/index
几个坑,你可能会遇到:
一、遇到这个报错
java.lang.NullPointerException
at org.springframework.core.SerializableTypeWrapper$TypeProxyInvocationHandler.invoke(SerializableTypeWrapper.java:239)
解决办法:这是因为spring的jar包冲突,dubbo自带一个2.x.x版本的spring。pom修改如下:
<dependency>
<groupId>com.alibabagroupId>
<artifactId>dubboartifactId>
<version>2.4.10version>
<exclusions>
<exclusion>
<groupId>org.springframeworkgroupId>
<artifactId>springartifactId>
exclusion>
exclusions>
dependency>
二、其他都做好了,就是无法启动。
解决方法:可以尝试provider打包成jar,consumer引入。
三、无法读取dubbo的配置文件
解决方法:下载dubbo.xsd,手动添加xsd。具体方法可以参考。解决:dubbo找不到dubbo.xsd报错
最后,一起进步一起学习吧!