之前我讲述了关于dubbo安装的一些基本的准备工作。之前也说过了,dubbo是一种远程服务调用。关于dubbo的底层原理,由于我是初学者的身份,在这里我也没有办法说明。但是根据我在网上的视频,我对dubbo在现在流行的工程框架中进行了部署和使用。这篇博客我就来讲述一下关于dubbo的具体使用。
目录
1.服务提供者的配置
2.服务消费者的配置
3.过程分析
4.dubbo和springboot的整合
我们知道,在用户请求服务的时候,远程服务器的服务必须优先启动。那么首先我来讲述一下关于服务提供者的配置。
在最初学习java的时候,我们都接触到了关于接口的编程。接口定义了一种规范,告诉实现代码的人应该完成什么样的工作,
接口的定义有助于工程的维护和更新还有不同工作人员代码的整合。在声明服务之前,我打算将我的服务接口写出。由于是测试,我的服务写的很简单。就以我们在jdbc操作中初始化数据为例。
首先新建一个java工程,在这里面声明一个接口如下所示
package com.lw.gmall.service;
public interface OrderService {
public void initOrder(String id);
}
在服务提供者的工程中实现这个接口,注意要在服务提供者的工程中引入刚才的工程。在pom.xml文件中加入如下的依赖
com.lw.gmall
dubbo-service-inter
0.0.1-SNAPSHOT
之后就是服务的实现,这些都不陌生。
package com.lw.gmall.service;
import java.util.Arrays;
import java.util.List;
import com.lw.gmall.entity.Address;
public class UserServiceImpl implements UserService{
public List getAddressById(String id) {
System.out.println("UserServiceImpl。。。。。1");
Address a1 = new Address(id,"河南省新乡市");
Address a2 = new Address(id,"河南省郑州市");
// try {
// Thread.sleep(4000);
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
return Arrays.asList(a1,a2);
}
}
忽略掉注释的地方,那是之后关于服务超时的测试。关于服务的声明已经完成,接下来就是服务的配置了。这也是整个dubbo框架使用的核心。
首先指定服务的名称,这个只是作为一个标记
然后声明注册中心的位置,我的注册中心配置在了我的linux虚拟机上,使用的是zookeeper作为注册中心,zookeeper默认监听2181端口
接下里指定通信规则,名称是dubbo因为是dubbo的框架。后面的端口号是指服务发布/监听在20881端口下,这个端口对于一个工程中的服务只能部署一次。
关于框架的基本服务配置完成后,接下来就是对服务进行暴露。 我声明了服务的版本号(默认是0.0.0)指明了服务的实现者
接下来我们就可以将我们的zookeeper进行启动了,启动的过程我之前的博客提到过。启动完成后,我们的服务就注册到了注册中心,只要将服务消费者进行配置注册,完整的功能模块就实现了。
关于代码的实现和之前提供者的实现是类似的,我不再重复。
package com.lw.gmall.service;
import java.util.List;
import com.lw.gmall.entity.Address;
public interface UserService {
public List getAddressById(String id);
}
package com.lw.gmall.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import com.lw.gmall.entity.Address;
@Service
public class OrderServiceImpl implements OrderService{
@Autowired
@Qualifier("userService")
private UserService userService;
public void initOrder(String id) {
//调用用户服务
List addressList = userService.getAddressById(id);
for(Address address : addressList){
System.out.println(address);
}
}
}
主要的难点是服务消费者的配置
这些和提供者也是类似的,配置到相应的zookeeper服务器上。
这是为了将相应的服务注入到容器中,这是在spring ioc容器中提到过的部分
这就是服务消费者的配置过程
这里我声明了两个启动类
提供者
package com.lw.gmall;
import java.io.IOException;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApplication {
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("provider.xml");
ioc.start();
System.out.println("1号服务提供者启动");
System.in.read();
}
}
消费者
package com.lw.gmall;
import java.io.IOException;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.lw.gmall.service.OrderService;
import com.lw.gmall.service.OrderServiceImpl;
public class MainApplication {
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("consumer.xml");
OrderService orderService = ioc.getBean(OrderServiceImpl.class);
for(int i=0;i<10;i++){
orderService.initOrder("1");
}
System.out.println("That is all");
System.in.read();
}
}
在首先启动提供者然后启动消费者后,可以控制台打印出了相应的结果。在实现了一系列的工作之后,我想分析一下服务的整个流程(当然是我自己根据测试结果的理解)
首先服务进行注册,也就是com.lw.gmall.service.UserService——>com.lw.gmall.service.UserServiceImpl。它的版本号是1.0.0
消费者在进行消费时,它会查找和它版本号相同的服务,于是就找到了我们之前的配置。
这里可以进行代码的参考。
回到消费者的服务调用代码中,关于userService的实现我做了如下的声明。
@Autowired
@Qualifier("userService")
private UserService userService;
这就是ioc容器的依赖注入,可以看到Qualifier注解中的userService也和dubbo:reference的服务引用中的id保持了一致。这样userService就实现了服务的注入。实际上它指向的是(远程的)的服务提供者。
刚才都只是dubbo的测试,那么如何才能将duboo和springboot进行整合呢。其实很简单,原理都是相同的,只是有一些部分需要根据springboot的特性进行处理。
引入如下的依赖。
com.alibaba.boot
dubbo-spring-boot-starter
0.2.0
服务的声明如下所示,这里有些需要强调的地方 首先@Service是import com.alibaba.dubbo.config.annotation.Service;这个非常重要,其次我在@Component中声明的AreYouOK一会也有别的用途
package com.lw.gmall.service;
import java.util.Arrays;
import java.util.List;
import org.springframework.stereotype.Component;
import com.alibaba.dubbo.config.annotation.Service;
import com.lw.gmall.entity.Address;
import com.lw.gmall.service.UserService;
@Service() //将服务进行暴露
@Component("AreYouOk")
public class UserServiceImpl implements UserService{
public List getAddressById(String id) {
Address a1 = new Address(id,"河南省新乡市");
Address a2 = new Address(id,"河南省郑州市");
return Arrays.asList(a1,a2);
}
}
在springboot的启动类中加入@EnableDubbo注解开启服务即可。
package com.lw.gmall;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
@EnableDubbo
@SpringBootApplication
public class SpringBootOrderServiceConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootOrderServiceConsumerApplication.class, args);
}
}
至于消费者的部分,有很多和提供者相似。我只提提重点的部分即可。其中的@Reference和dubbo:reference相同。它指向了服务的所在。至于下方的@Qualifier("AreYouOk")和上面的也进行了对应。当然这只是测试。我的建议是根据version也就是版本号实现服务的统一。
package com.lw.gmall.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import com.alibaba.dubbo.config.annotation.Reference;
import com.lw.gmall.entity.Address;
import com.lw.gmall.service.OrderService;
import com.lw.gmall.service.UserService;
@Service
public class OrderServiceImpl implements OrderService{
@Reference()
@Qualifier("AreYouOk")
private UserService userService;
public void initOrder(String id) {
//调用用户服务
List addressList = userService.getAddressById(id);
for(Address address : addressList){
System.out.println(address);
}
}
}
在启动完成之后同样实现了相同的效果。下一次我将深入讲述dubbo的用户文档,也就是关于dubbo配置的详细信息。