简介
关于dubbo的原理及api zookeeper的使用 可自行百度
dubbo官网 http://dubbo.io/
工程代码结构
接口层(archetype-dubbo-api)
package com.yaphis.archetype.dubbo.api;
import com.yaphis.archetype.dubbo.api.bean.Request;
import com.yaphis.archetype.dubbo.api.bean.Response;
/**
* 需要暴露的接口定义
*
* @author yaphis 2016年2月15日 下午10:32:37
*/
public interface DubboService {
public Response execute(Request request);
}
package com.yaphis.archetype.dubbo.api.bean;
import java.io.Serializable;
/**
* 接口请求实体(必须序列化)
*
* @author yaphis 2016年2月15日 下午10:33:38
*/
public class Request implements Serializable {
private static final long serialVersionUID = -6108135813653701709L;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Request [name=" + name + "]";
}
}
package com.yaphis.archetype.dubbo.api.bean;
import java.io.Serializable;
/**
* 接口响应实体(必须序列化)
*
* @author yaphis 2016年2月15日 下午10:33:55
*/
public class Response implements Serializable {
private static final long serialVersionUID = -758877214314064622L;
private String resCode;
private String resMsg;
public Response(String resCode, String resMsg) {
super();
this.resCode = resCode;
this.resMsg = resMsg;
}
public String getResCode() {
return resCode;
}
public void setResCode(String resCode) {
this.resCode = resCode;
}
public String getResMsg() {
return resMsg;
}
public void setResMsg(String resMsg) {
this.resMsg = resMsg;
}
@Override
public String toString() {
return "Response [resCode=" + resCode + ", resMsg=" + resMsg + "]";
}
}
package com.yaphis.archetype.dubbo.api.mock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.yaphis.archetype.dubbo.api.DubboService;
import com.yaphis.archetype.dubbo.api.bean.Request;
import com.yaphis.archetype.dubbo.api.bean.Response;
/**
* 接口本地Mock实现(在dubbo服务调用异常时会默认调用该实现,可用取代try-catch做服务降级)
*
* @author yaphis 2016年2月15日 下午10:35:09
*/
public class DubboServiceMock implements DubboService {
private static final Logger LOG = LoggerFactory.getLogger(DubboServiceMock.class);
@Override
public Response execute(Request request) {
LOG.info("DubboServiceMock execute!");
Response response = new Response("999999", "系统异常");
return response;
}
}
服务提供者(archetype-dubbo-service)
package com.yaphis.archetype.dubbo.api.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import com.alibaba.dubbo.rpc.RpcContext;
import com.yaphis.archetype.dubbo.api.DubboService;
import com.yaphis.archetype.dubbo.api.bean.Request;
import com.yaphis.archetype.dubbo.api.bean.Response;
/**
* 暴露的接口在服务提供者端的实现
*
* @author yaphis 2016年2月15日 下午10:39:09
*/
@Service
public class DubboServiceImpl implements DubboService {
private static final Logger LOG = LoggerFactory.getLogger(DubboServiceImpl.class);
@Override
public Response execute(Request request) {
LOG.info("ThreadName:{}", RpcContext.getContext().getAttachment("ThreadName"));// 获取隐式参数 可用来做框架通用参数透传,例如跟踪日志等
LOG.info("DubboServiceImpl execute!request:{}", request);
Response response = new Response("000000", "成功");
return response;
}
}
package com.yaphis.archetype.dubbo.api.impl;
import com.alibaba.dubbo.container.Main;
/**
* dubbo服务端启动类(通过shell脚本启动)
*
* @author Yaphis 2016年2月2日 下午2:29:05
*/
public class Server {
public static void main(String[] args) {
// 把spring配置文件放在META-INF/spring目录下,dubbo启动容器会自动加载 这是推荐的做法
Main.main(args);// 服务提供者启动只有这一行代码,因此其实也可以通过shell直接启动com.alibaba.dubbo.container.Main类
}
}
archetype-dubbo-service.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:amq="http://activemq.apache.org/schema/core"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"
default-lazy-init="false">
<!-- 自动扫描 -->
<context:component-scan base-package="com.yaphis.archetype.dubbo.api.impl" />
<!-- 加载配置文件、利用spring的属性替换解决测试、生产环境的差异 -->
<context:property-placeholder location="classpath:config.properties" />
<!-- dubbo配置 -->
<dubbo:application name="archetype-dubbo-service" logger="slf4j" />
<!-- 注册中心支持zookeeper、redis、Muticast、Simple注册中心 -->
<!-- 推荐使用zookeeper作为注册中心 多个address间用,分隔 -->
<dubbo:registry protocol="zookeeper" address="${zookeeper.address}" client="zkclient" />
<!-- 协议类型和暴露服务的端口 -->
<dubbo:protocol name="dubbo" port="${server.port}" />
<!-- 暴露的服务 -->
<!-- delay=-1延迟到spring容器启动完成再暴露服务 强烈不建议使用applicationContext显式获取bean,应该像本例一样使用ioc依赖注入获取bean -->
<dubbo:service interface="com.yaphis.archetype.dubbo.api.DubboService" ref="dubboServiceImpl" delay="-1" />
<!-- 超时时间 服务提供方更加清楚每个服务的耗时 这边进行设置是更加合理的 -->
<dubbo:provider timeout="5000" />
</beans>
config.properties
#这里的配置 可以用${zookeeper.address}占位符的形式,用maven的profile替换 来解决线上、测试环境配置的差异配置问题
zookeeper.address=127.0.0.1:2181
server.port=20880
#配置1
config1=${config1}
dubbo.properties
#dubbo的配置文件,启动时会自动读取类路径下的该配置文件 与xml配置效果相同
dubbo.container=spring,log4j
dubbo.service.loadbalance=random
logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="LOG_PATH" value="/var/logs/archetype-dubbo-service/" />
<property name="LOG_PATTEN" value="[%-5level] %d{HH:mm:ss.SSS} [%X{ThreadName}] [%logger{64}:%line] >>> %msg%n" />
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>${LOG_PATTEN}</Pattern>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>${LOG_PATH}/service.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${LOG_PATH}/service_%d{yyyy-MM-dd}.log</FileNamePattern>
</rollingPolicy>
<encoder charset="UTF-8">
<pattern>${LOG_PATTEN}</pattern>
</encoder>
</appender>
<appender name="ERRORFILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>${LOG_PATH}/errorService.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${LOG_PATH}/errorService_%d{yyyy-MM-dd}.log</FileNamePattern>
</rollingPolicy>
<encoder charset="UTF-8">
<pattern>${LOG_PATTEN}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<OnMismatch>DENY</OnMismatch>
<OnMatch>ACCEPT</OnMatch>
</filter>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE" />
<appender-ref ref="ERRORFILE" />
</root>
</configuration>
pom.xml(仅贴出maven依赖部分代码,jar包版本号定义在父工程,可百度最新的jar版本)
<dependencies>
<!-- project -->
<dependency>
<groupId>com.yaphis</groupId>
<artifactId>archetype-dubbo-api</artifactId>
<version>${project.version}</version>
</dependency>
<!-- spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- dubbo -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<exclusions>
<exclusion>
<artifactId>spring</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
<exclusion>
<artifactId>netty</artifactId>
<groupId>org.jboss.netty</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- zookeeper -->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<exclusions>
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
<exclusion>
<artifactId>log4j</artifactId>
<groupId>log4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<exclusions>
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
<exclusion>
<artifactId>log4j</artifactId>
<groupId>log4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- log4j zookeeper依赖 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
</dependencies>
消费者(archetype-dubbo-client)
package com.yaphis.archetype.dubbo.client;
import java.util.UUID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.alibaba.dubbo.rpc.RpcContext;
import com.yaphis.archetype.dubbo.api.DubboService;
import com.yaphis.archetype.dubbo.api.bean.Request;
import com.yaphis.archetype.dubbo.api.bean.Response;
/**
* 消费者调用方式,直接使用依赖注入
*
* @author yaphis 2016年2月15日 下午11:04:16
*/
@Service
public class ClientService {
private static final Logger LOG = LoggerFactory.getLogger(ClientService.class);
@Autowired
private DubboService dubboService;
public void call() {
RpcContext.getContext().setAttachment("ThreadName", UUID.randomUUID().toString());// 隐式传参
Request request = new Request();
request.setName("yaphis");
Response response = dubboService.execute(request);
LOG.info("response:{}", response);
}
}
package com.yaphis.archetype.dubbo.client;
import java.util.Arrays;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* 消费者启动类
*
* @author yaphis 2016年2月15日 下午11:03:12
*/
public class Client {
@SuppressWarnings("resource")
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:META-INF/spring/*.xml");
System.out.println(Arrays.toString(context.getBeanDefinitionNames()));
ClientService clientService = context.getBean(ClientService.class);
clientService.call();
}
}
archetype-dubbo-client.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:amq="http://activemq.apache.org/schema/core"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"
default-lazy-init="false">
<context:component-scan base-package="com.yaphis.archetype.dubbo.client" />
<!-- dubbo配置 -->
<dubbo:application name="archetype-dubbo-client" logger="slf4j" />
<!-- 注册中心支持zookeeper、redis、Muticast、Simple注册中心 -->
<!-- 多个address间用,分隔 -->
<dubbo:registry protocol="zookeeper" address="127.0.0.1:2181" client="zkclient" />
<!-- 暴露的服务 -->
<dubbo:reference id="dubboService" interface="com.yaphis.archetype.dubbo.api.DubboService" check="false" />
<!-- mock使用 -->
<!-- mock属性 当发生RPC异常的时候调用,用于做服务降级,一般情况不需要,开启mock时建议打开dubbo的info日志否则看不到异常 -->
<!-- <dubbo:reference id="dubboService" interface="com.yaphis.archetype.dubbo.api.DubboService" mock="com.yaphis.archetype.dubbo.api.mock.DubboServiceMock" check="false" /> -->
<!-- 超时时间 -->
<dubbo:consumer timeout="5000" />
<!-- 启动检查 -->
<!-- <dubbo:consumer check="false" /> -->
<!-- 直连测试 仅适合用在测试环境 -->
<!-- <dubbo:reference id="dubboService" interface="com.yaphis.archetype.dubbo.api.DubboService" url="dubbo://127.0.0.1:20880" /> -->
</beans>
pom.xml(仅贴出maven依赖,jar版本号定义在父工程,可直接百度最新的版本号)
<dependencies>
<!-- project -->
<dependency>
<groupId>com.yaphis</groupId>
<artifactId>archetype-dubbo-api</artifactId>
<version>${project.version}</version>
</dependency>
<!-- spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- dubbo -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<exclusions>
<exclusion>
<artifactId>spring</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
<exclusion>
<artifactId>netty</artifactId>
<groupId>org.jboss.netty</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- zookeeper -->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<exclusions>
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
<exclusion>
<artifactId>log4j</artifactId>
<groupId>log4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<exclusions>
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
<exclusion>
<artifactId>log4j</artifactId>
<groupId>log4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- log4j zookeeper依赖 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
</dependencies>