天天看点

dubbo简易入门

从这个帖子中初步入门学习了dubbo,对分布式服务框架有个大体的认识,由于git hub上的demo并不完整,自己手动写了以下样本,以供自己后期复习使用。

代码样本使用了spring 4 + springmvc + mybatis 3 + maven + dubbo + zookeeper构建项目。

使用顺序:

启动zookeeper->执行Provider类->执行consumer类

第一步:安装zookeeper

参考我写的简易课程:

http://blog.csdn.net/baidu_36720706/article/details/79611216

第二步:文件配置与编码

1.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.heavent.spring</groupId>
  <artifactId>dubbo</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging><properties>
	<junit.version>4.9</junit.version>
	<slf4j-version>1.7.21</slf4j-version>
	<spring.version>4.3.4.RELEASE</spring.version>
	<jackson-core.version>2.7.0</jackson-core.version>
	<mysql-connector-java.version>5.1.32</mysql-connector-java.version>
	<mybatis.version>3.4.1</mybatis.version>
	<mybatis-spring.version>1.3.0</mybatis-spring.version>
  </properties>
  
  <dependencies>
  		<!-- junit -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>${junit.version}</version>
			<scope>test</scope>
		</dependency>
		
		<!-- Log4j -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>${slf4j-version}</version>
		</dependency>
		<dependency>  
			<groupId>org.slf4j</groupId>  
		    <artifactId>slf4j-log4j12</artifactId>  
		    <version>${slf4j-version}</version>  
		</dependency>
		
		<!-- Spring -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aspects</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
			<version>${spring.version}</version>
		</dependency>
		
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-core</artifactId>
			<version>${jackson-core.version}</version>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>${jackson-core.version}</version>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-annotations</artifactId>
			<version>${jackson-core.version}</version>
		</dependency>
		
		<!-- mysql -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>${mysql-connector-java.version}</version>
		</dependency>
		
		<!-- https://mvnrepository.com/artifact/commons-dbcp/commons-dbcp -->
		<dependency>
		    <groupId>commons-dbcp</groupId>
		    <artifactId>commons-dbcp</artifactId>
		    <version>1.4</version>
		</dependency>

		
		<!-- mybatis -->
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis</artifactId>
			<version>${mybatis.version}</version>
		</dependency>
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis-spring</artifactId>
			<version>${mybatis-spring.version}</version>
		</dependency>
		
		
		<!-- dubbo -->
	    <dependency>
	      <groupId>com.alibaba</groupId>
	      <artifactId>dubbo</artifactId>
	      <version>2.5.3</version>
	      <exclusions>
	        <exclusion>
	          <groupId>org.springframework</groupId>
	          <artifactId>spring</artifactId>
	        </exclusion>
	      </exclusions>
	    </dependency>
	    <dependency>
	      <groupId>com.101tec</groupId>
	      <artifactId>zkclient</artifactId>
	      <version>0.10</version>
	    </dependency>
		
		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>javax.servlet.jsp-api</artifactId>
			<version>2.3.1</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.5</version>
			<scope>provided</scope>
		</dependency>
		
  </dependencies>
  
  <build>
		<finalName>yzsm_pay</finalName>
		<resources>
			<resource>
				<directory>src/main/java</directory>
				<includes>
					<include>**/*.properties</include>
					<include>**/*.xml</include>
				</includes>
				<filtering>false</filtering>
			</resource>
			<resource>
				<directory>src/main/resources</directory>
			</resource>
		</resources>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>1.7</source>
					<target>1.7</target>
					<encoding>UTF-8</encoding>
					<compilerArguments>
						<!-- <verbose /> -->
						<extdirs>${project.basedir}\webapp\WEB-INF\lib</extdirs>
					</compilerArguments>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-war-plugin</artifactId>
				<version>2.1.1</version>
				<configuration>
					<webResources>
						<resource>
							<directory>webapp</directory>
						</resource>
					</webResources>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.mortbay.jetty</groupId>
				<artifactId>jetty-maven-plugin</artifactId>
				<configuration>
					<webAppSourceDirectory>webapp</webAppSourceDirectory>
					<webAppConfig>
						<allowDuplicateFragmentNames>true</allowDuplicateFragmentNames>
					</webAppConfig>
					<webApp>
						<contextPath>/</contextPath>
					</webApp>
					<stopKey>webx</stopKey>
					<stopPort>9998</stopPort>
					<connectors>
						<connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
							<port>5508</port>
							<maxIdleTime>60000</maxIdleTime>
						</connector>
					</connectors>
					<requestLog implementation="org.eclipse.jetty.server.NCSARequestLog">
						<filename>target/access.log</filename>
						<retainDays>90</retainDays>
						<append>false</append>
						<extended>false</extended>
						<logTimeZone>GMT+8:00</logTimeZone>
					</requestLog>
					<systemProperties>
						<systemProperty>
							<name>productionMode</name>
							<value>${productionMode}</value>
						</systemProperty>
					</systemProperties>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>
           

2.配置web.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	id="WebApp_ID" version="2.5">
	<display-name>dubbo</display-name>
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
	  	classpath:applicationContext.xml
	  	classpath:spring-mybatis.xml
	  </param-value>
	</context-param>
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	<listener>
		<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
	</listener>
	<servlet>
		<servlet-name>SpringMVC</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:spring-mvc.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
		<!-- <async-supported>true</async-supported>  -->
	</servlet>
	<servlet-mapping>
		<servlet-name>SpringMVC</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

	<filter>
		<filter-name>encodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>encodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<welcome-file-list>
		<welcome-file>index.html</welcome-file>
	</welcome-file-list>
</web-app>
           

3.配置服务提供者provider

①对provider提供服务的接口进行配置(spring-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: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-admin 或 dubbo-monitor 会显示这个名字,方便辨识-->
    <dubbo:application name="demotest-provider" owner="programmer" organization="dubbox"/>
    <!--使用 zookeeper 注册中心暴露服务,注意要先开启 zookeeper-->
    <dubbo:registry address="zookeeper://localhost:2181"/>
    <!-- 用dubbo协议在20880端口暴露服务 -->
    <dubbo:protocol name="dubbo" port="20880" />
    <!--使用 dubbo 协议实现定义好的 api.DemoService 接口-->
    <dubbo:service inter ref="demoService" protocol="dubbo" />
    <!--具体实现该接口的 bean-->
    <bean id="demoService" class="com.heavent.spring.dubbo.demo.DemoServiceImpl"/>
</beans>
           

在配置这里可能遇到

http://code.alibabatech.com/schema/dubbo

无法访问的问题,这里需要再dubbo的jar包下解压,将META-INF\dubbo.xsd拷到IDE工具根目录下(我是复制到eclipse根目录下),然后在eclipse中进行以下操作:

在Window->Preferences->XML->XML Catalog进行配置

dubbo简易入门

在xml中右击选择Validate后即消除报错

②编写Provider启动类

package com.heavent.spring.dubbo.demo;

import java.io.IOException;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Provider {
	public static void main(String[] args) throws IOException {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-dubbo-provider.xml");
        System.out.println(context.getDisplayName() + ": here");
        context.start();
        System.out.println("服务已经启动...");
        System.in.read();
    }
	
}
           

③对Consumer类调用哪些方法接口进行配置(spring-dubbo-consumer.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: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="demotest-consumer" owner="programmer" organization="dubbox"/>
    <!--向 zookeeper 订阅 provider 的地址,由 zookeeper 定时推送-->
    <dubbo:registry address="zookeeper://localhost:2181"/>
    <!--使用 dubbo 协议调用定义好的 api.DemoService 接口-->
    <dubbo:reference id="demoService" inter/>
    
</beans>
           

④编写Consumer启动类

package com.heavent.spring.dubbo.demo;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Consumer {
	
	 public static void main(String[] args) {
	        //测试常规服务
	        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-dubbo-consumer.xml");
	        context.start();
	        System.out.println("consumer start");
	        DemoService demoService = context.getBean(DemoService.class);
	        System.out.println("consumer");
	        System.out.println(demoService.getPermissions(111L));
	        System.out.println(demoService.getUserInfo(1140123154).toString());
	}
	 
}
           

⑤自定义对象传输需要进行序列化处理

其中需要用到的User类需要继承序列化接口,才可以正常被远程调用

package com.heavent.spring.pojo.bo;

/**
 * 用户类
 * @Title	注册用户	
 * @Desc	
 * @Author	zhuohuahai
 * @Date	2018年3月19日
 */
public class User extends Base {
	
	private static final long serialVersionUID = -6807226745284401474L;
	
	private String name;
	private Integer age;
	private String protrait;
	private Integer gender;
	private String phone;
	private String address;
	
	@Override
	public String toString() {
		return "User [name=" + name + ", age=" + age + ", protrait=" + protrait + ", gender=" + gender + ", phone="
				+ phone + ", address=" + address + "]";
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	public String getPhone() {
		return phone;
	}
	public void setPhone(String phone) {
		this.phone = phone;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	public String getProtrait() {
		return protrait;
	}
	public void setProtrait(String protrait) {
		this.protrait = protrait;
	}
	public Integer getGender() {
		return gender;
	}
	public void setGender(Integer gender) {
		this.gender = gender;
	}
	
}
           

Base类编写:

package com.heavent.spring.pojo.bo;

import java.io.Serializable;

/**
 * 用户类
 * @Title	注册用户	
 * @Desc	
 * @Author	zhuohuahai
 * @Date	2018年3月19日
 */
public class Base implements Serializable {
	
	private static final long serialVersionUID = 3751694926750620662L;
	
	private Integer id;
	private String createtime;
	private String updatetime;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getCreatetime() {
		return createtime;
	}
	public void setCreatetime(String createtime) {
		this.createtime = createtime;
	}
	public String getUpdatetime() {
		return updatetime;
	}
	public void setUpdatetime(String updatetime) {
		this.updatetime = updatetime;
	}
	
}
           

⑥定义的接口以及接口实现类

DemoService.java

package com.heavent.spring.dubbo.demo;

import java.util.List;

import com.heavent.spring.pojo.bo.User;

public interface DemoService {
	
	public List<String> getPermissions(Long id);
	public User getUserInfo(Integer uid);
}
           

DemoServiceImpl

package com.heavent.spring.dubbo.demo;

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

import com.heavent.spring.pojo.bo.User;

public class DemoServiceImpl implements DemoService {

	@Override
	public List<String> getPermissions(Long id) {
		List<String> demo = new ArrayList<String>();
        demo.add(String.format("Permission_%d", id - 1));
        demo.add(String.format("Permission_%d", id));
        demo.add(String.format("Permission_%d", id + 1));
		return demo;
	}
	
	@Override
	public User getUserInfo(Integer uid) {
		User user = new User();
		user.setAddress("Guangdong ShenZhen");
		user.setAge(25);
		user.setCreatetime(String.valueOf(System.currentTimeMillis()));
		user.setGender(1);
		user.setId(uid);
		user.setName("Heavent");
		user.setPhone("155210xxxxx");
		user.setProtrait("xxxx");
		
		return user;
	}

}
           

第三步:检验

①确保Zookeeper已执行

②执行Provider类开启服务(根据xml配置自动将接口绑定至zookeeper中)

③执行Consumer类(根据xml配置自动查找zookeeper中已注册的接口)

dubbo简易入门
dubbo简易入门