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-provider dubbo.application.logger=slf4j # 声明需要暴露的服务接口所在的包 dubbo.annotation. package =com.xunleijr.game # 用dubbo协议在 20880 端口暴露服务 dubbo.protocol.name=dubbo dubbo.protocol.port= 20880 dubbo.protocol.accessLog= true dubbo.provider.timeout= 3000 dubbo.provider.retries= 1 dubbo.provider.delay=- 1 # 使用zookeeper注册中心暴露服务地址 dubbo.registr.protocol=zookeeper dubbo.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-***-consumer dubbo.application.logger=slf4j dubbo.annotation. package =com.xunleijr.game dubbo.registr.protocol=zookeeper dubbo.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")