dubbo 用户指南: http://dubbo.io/User+Guide-zh.htm 开发指南:http://dubbo.io/Developer+Guide-zh.htm#DeveloperGuide-zh-%E7%89%88%E6%9C%AC%E7%AE%A1%E7%90%86
一、引入dubbo相关包
在game子模块pom.xml加入相关maven包
因为dubbo和zkclient的日志默认使用的是log4j,与我们系统使用的logback不一致, dubbo使用的spring2.5.6与我们系统使用的sping4也不一致,所以需要去掉他们默认的,改成我们自己系统一致的。
<dependency> <groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.5.3</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
</exclusion>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency> <dependency> <groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.9</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency> <dependency> <groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>1.7.25</version>
</dependency> |
二、将原来的game-service模块拆分成game-service和game-provider两个子模块
原game-service子模块中service所有接口类放入新game-service子模块中,原game-service子模块中service.impl和component等包放入game-provider子模块中
修改后的game-service作为接口的定义,game-provider作为提供者实现接口。
项目拆分之后消费者模块需要修改成只引入game-service子模块
三、服务提供者实现
1、在game-provider子模块pom.xml引入game-service子模块和原game-service项目maven包
2、在game-provider子模块src/main/resource下创建 dubbo_provider.properties 文件
# 提供方应用信息,用于计算依赖关系dubbo.application.name=game-providerdubbo.application.logger=slf4j# 声明需要暴露的服务接口所在的包dubbo.annotation.package=com.xunleijr.game
# 用dubbo协议在20880端口暴露服务
dubbo.protocol.name=dubbodubbo.protocol.port=20880
dubbo.protocol.accessLog=true
dubbo.provider.timeout=3000
dubbo.provider.retries=1
dubbo.provider.delay=-1
# 使用zookeeper注册中心暴露服务地址dubbo.registr.protocol=zookeeperdubbo.registry.address.production=dubbo.registry.address.quasi_production=10.26.91.214:2181
dubbo.registry.address.test=192.168.20.36:2181
dubbo.registry.register=true
dubbo.registry.subscribe=true
|
3、创建Dubbo提供者配置类
package com.xunleijr.game.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ProtocolConfig;
import com.alibaba.dubbo.config.ProviderConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.xunleijr.game.annotation.AnnotationBean;
import com.xunleijr.game.common.AppConstant;
@Configuration@PropertySource(value = "classpath:dubbo_provider.properties")
public class DubboProviderConfig {
@Value("${dubbo.application.name}")
private String applicationName;
@Value("${dubbo.registr.protocol}")
private String protocol;
@Value("${dubbo.registry.address.production}")
private String registryAddress_production;
@Value("${dubbo.registry.address.quasi_production}")
private String registryAddress_quasiProduction;
@Value("${dubbo.registry.address.test}")
private String registryAddress_test;
@Value("${dubbo.protocol.name}")
private String protocolName;
@Value("${dubbo.protocol.port:20880}")
private int protocolPort;
@Value("${dubbo.provider.timeout:3000}")
private int timeout;
@Value("${dubbo.provider.retries:1}")
private int retries;
@Value("${dubbo.provider.delay:1}")
private int delay;
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
/**
* 设置dubbo扫描包
*
* @param packageName
* @return
*/
@Bean
public static AnnotationBean annotationBean(@Value("${dubbo.annotation.package}") String packageName) {
AnnotationBean annotationBean = new AnnotationBean();
annotationBean.setPackage(packageName);
return annotationBean;
}
/**
* 注入dubbo上下文
*
* @return
*/
@Bean
public ApplicationConfig applicationConfig() {
// 当前应用配置
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName(this.applicationName);
return applicationConfig;
}
/**
* 注入dubbo注册中心配置,基于zookeeper
*
* @return
*/
@Bean
public RegistryConfig registryConfig() {
// 连接注册中心配置
RegistryConfig registry = new RegistryConfig();
registry.setProtocol(protocol);
String registryAddress = null;
switch (AppConstant.CURR_SYSTEM_ENVIRONMENT) {
case PRODUCTION_ENVIRONMENT:
registryAddress = registryAddress_production;
break;
case QUASI_PRODUCTION_ENVIRONMENT:
registryAddress = registryAddress_quasiProduction;
break;
case TEST_ENVIRONMENT:
registryAddress = registryAddress_test;
break;
}
registry.setAddress(registryAddress);
System.out.println("########### registry Config 【" + protocol + ":" + registryAddress + "】");
return registry;
}
/**
* 默认基于dubbo协议提供服务
*
* @return
*/
@Bean
public ProtocolConfig protocolConfig() {
// 服务提供者协议配置
ProtocolConfig protocolConfig = new ProtocolConfig();
protocolConfig.setName(protocolName);
protocolConfig.setPort(protocolPort);
protocolConfig.setThreads(200);
System.out.println("########### protocol config【" + protocolName + ":" + protocolPort + "】");
return protocolConfig;
}
/**
* dubbo服务提供
*
* @param applicationConfig
* @param registryConfig
* @param protocolConfig
* @return
*/
@Bean(name = "defaultProvider")
public ProviderConfig providerConfig(ApplicationConfig applicationConfig, RegistryConfig registryConfig,
ProtocolConfig protocolConfig) {
ProviderConfig providerConfig = new ProviderConfig();
providerConfig.setTimeout(timeout);
providerConfig.setRetries(retries);
providerConfig.setDelay(delay);
providerConfig.setApplication(applicationConfig);
providerConfig.setRegistry(registryConfig);
providerConfig.setProtocol(protocolConfig);
System.out.println("########### provider init...");
return providerConfig;
}
} |
4、修改接口实现类的@Service注解为@com.alibaba.dubbo.config.annotation.Service(version = "1.0.0")
5、将game-model子模块中除protocol buffer相关类之外的类实现java.io.Serializable接口
6、创建服务提供者启动类
package com.xunleijr.game;
import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.xunleijr.game.config.DubboProviderConfig;
import com.xunleijr.game.config.MainConfig;
/** * 服务提供者启动类
* @author Yixi
*
*/
public class ProviderMain {
private static Logger logger = LoggerFactory.getLogger(ProviderMain.class);
@SuppressWarnings("resource")
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(MainConfig.class);
ctx.register(DubboProviderConfig.class);
ctx.refresh();
ctx.registerShutdownHook();// 在JVM注册一个关闭钩子,确保IOC容器最终会被正确关闭
ctx.start();
logger.info("dubbo provider start...");
try {
// 输入任意字符退出
System.in.read();
} catch (IOException e) {}
}
} |
四、服务消费者实现
1、消费者src/main/resources下创建dubbo_consumer.properties文件
dubbo.application.name=game-***-consumerdubbo.application.logger=slf4jdubbo.annotation.package=com.xunleijr.game
dubbo.registr.protocol=zookeeperdubbo.registry.address.production=dubbo.registry.address.quasi_production=10.26.91.214:2181
dubbo.registry.address.test=192.168.20.36:2181
dubbo.registry.register=true
dubbo.registry.subscribe=true
|
2、创建Dubbo消费者配置类
package com.xunleijr.game.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.spring.AnnotationBean;
import com.xunleijr.game.common.AppConstant;
@Configuration@PropertySource(value = "classpath:dubbo_consumer.properties")
public class DubboConsumerConfig {
@Value("${dubbo.application.name}")
private String applicationName;
@Value("${dubbo.registr.protocol}")
private String protocol;
@Value("${dubbo.registry.address.production}")
private String registryAddress_production;
@Value("${dubbo.registry.address.quasi_production}")
private String registryAddress_quasiProduction;
@Value("${dubbo.registry.address.test}")
private String registryAddress_test;
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
/**
* 设置dubbo扫描包
*
* @param packageName
* @return
*/
@Bean
public static AnnotationBean annotationBean(@Value("${dubbo.annotation.package}") String packageName) {
AnnotationBean annotationBean = new AnnotationBean();
annotationBean.setPackage(packageName);
return annotationBean;
}
/**
* 注入dubbo上下文
*
* @return
*/
@Bean
public ApplicationConfig applicationConfig() {
// 当前应用配置
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName(this.applicationName);
return applicationConfig;
}
/**
* 注入dubbo注册中心配置,基于zookeeper
*
* @return
*/
@Bean
public RegistryConfig registryConfig() {
// 连接注册中心配置
RegistryConfig registry = new RegistryConfig();
registry.setProtocol(protocol);
String registryAddress = null;
switch (AppConstant.CURR_SYSTEM_ENVIRONMENT) {
case PRODUCTION_ENVIRONMENT:
registryAddress = registryAddress_production;
break;
case QUASI_PRODUCTION_ENVIRONMENT:
registryAddress = registryAddress_quasiProduction;
break;
case TEST_ENVIRONMENT:
registryAddress = registryAddress_test;
break;
}
registry.setAddress(registryAddress);
return registry;
}
} |
3、在springmvc初始化时加载dubbo配置
修改WebInitializer.java
public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
**** @Override
protected Class<?>[] getRootConfigClasses() {
// 加载配置文件类
return new Class[] { DubboConsumerConfig.class };
}
****} |
4、修改消费者类中需要远程调用接口类上面的@Autowired注解修改为@com.alibaba.dubbo.config.annotation.Reference(version = "1.0.0")