Dubbo是 阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,现在已经移交给了Apache进行孵化。项目地址Dubbo。我们今天来看看它是如何与spring boot 结合的。开始之前,我们需要安装一个软件Zookeeper,文中示例用到了,如果需要启动测试的话,请自行安装。
对于Dubbo的provider项目,又两个子项目构成,一个是api项目,主要定义了接口,一个是core,主要就是api中定义接口的实现。为啥需要两个项目,因为这个api项目是以后需要提供给第三方使用的。所谓的RPC就是像引用本地服务一样的引用远程的服务。consumer项目引用provider中的api项目,调用api形成的动态代理对象,从而形成远程调用的功能。
我们想看provider项目。因为api项目就是定义了接口没啥需要说明的,所以有兴趣的同学,自己拉下代码来自己看就行,我们说一下core项目。先看下他的pom文件
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
</dependency>
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
</dependency>
<dependency>
<groupId>com.shuqi</groupId>
<artifactId>spring-boot-dubbo-provider-api</artifactId>
</dependency>
dubbo的jar自然需要引入的,还有一个zkclient,这是使用zookeeper作为注册中心所需要的jar包,操作zk。另外就是spring-boot-dubbo-provider-api,我们的api项目,就是实现里面的方法。我们看一下配置类
package com.shuqi;
import com.alibaba.dubbo.config.*;
import com.alibaba.dubbo.config.spring.ServiceBean;
import com.shuqi.service.LogService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class DubboConfig {
@Bean
public ApplicationConfig application() {
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("log");
return applicationConfig;
}
@Bean
public RegistryConfig registry() {
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.setAddress("127.0.0.1:2181");
registryConfig.setProtocol("zookeeper");
return registryConfig;
}
@Bean
public ProtocolConfig protocol() {
ProtocolConfig protocolConfig = new ProtocolConfig();
protocolConfig.setPort(20880);
protocolConfig.setThreads(100);
return protocolConfig;
}
// @Bean
// public MonitorConfig monitor() {
// MonitorConfig monitorConfig = new MonitorConfig();
// monitorConfig.setProtocol("registry");
// return monitorConfig;
// }
@Bean
public ProviderConfig provider() {
ProviderConfig providerConfig = new ProviderConfig();
providerConfig.setTimeout(30000);
providerConfig.setRetries(0);
providerConfig.setVersion("LATEST");
providerConfig.setProxy("javassist");
return providerConfig;
}
@Bean
public ConsumerConfig consumer() {
ConsumerConfig rc = new ConsumerConfig();
rc.setTimeout(30000);
rc.setRetries(0);
rc.setVersion("LATEST");
rc.setCheck(false);
return rc;
}
/***********************暴露服务******************************/
@Bean
public ServiceBean logServiceServiceBean(LogService logService){
ServiceBean<LogService> serviceBean=new ServiceBean<>();
serviceBean.setInterface(LogService.class);
serviceBean.setRef(logService);
return serviceBean;
}
}
我们最为关注的就是logServiceServiceBean,这个暴露的服务。当consumer使用LogService来搞事情时,调用到provider端,真正处理操作的是LogService在core项目中的实现类。剩下的配置,我们会在Dubbo模块中讲解。
看完了provider端的配置,我们再看下consumer项目,所需要的jar与provider中core项目中是一致的。
我们看下配置类
package com.shuqi;
import com.alibaba.dubbo.config.*;
import com.alibaba.dubbo.config.spring.ReferenceBean;
import com.alibaba.dubbo.config.spring.ServiceBean;
import com.shuqi.service.LogService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class DubboConfig {
@Bean
public ApplicationConfig application() {
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("consumer");
return applicationConfig;
}
@Bean
public RegistryConfig registry() {
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.setAddress("127.0.0.1:2181");
registryConfig.setProtocol("zookeeper");
return registryConfig;
}
@Bean
public ProtocolConfig protocol() {
ProtocolConfig protocolConfig = new ProtocolConfig();
protocolConfig.setPort(20881);
protocolConfig.setThreads(100);
return protocolConfig;
}
// @Bean
// public MonitorConfig monitor() {
// MonitorConfig monitorConfig = new MonitorConfig();
// monitorConfig.setProtocol("registry");
// return monitorConfig;
// }
@Bean
public ProviderConfig provider() {
ProviderConfig providerConfig = new ProviderConfig();
providerConfig.setTimeout(30000);
providerConfig.setRetries(0);
providerConfig.setVersion("LATEST");
providerConfig.setProxy("javassist");
return providerConfig;
}
@Bean
public ConsumerConfig consumer() {
ConsumerConfig rc = new ConsumerConfig();
rc.setTimeout(30000);
rc.setRetries(0);
rc.setVersion("LATEST");
rc.setCheck(false);
return rc;
}
/*************************引用服务********************************/
@Bean
public ReferenceBean<LogService> logService(){
ReferenceBean<LogService> referenceBean=new ReferenceBean<>();
referenceBean.setInterface(LogService.class);
return referenceBean;
}
}
我们可以看到大部分的配置是相同的,多了一个引用的服务logService,利用provider api中的定义的接口,生成代理对象,作为操作LogService接口的真正的“幕后黑手”,发起远程调用。
做好准备工作后,使用就很简单了
package com.shuqi.controller;
import com.shuqi.service.LogService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
public class LogController {
@Resource
private LogService logService;
@RequestMapping("/log")
public String create() {
Long id = logService.create(null);
return "log的id为" + id;
}
}
是不是做到了像引用本地服务一般调用远程服务。玩起来吧。
网友评论