Dubbo官方网站: http://dubbo.apache.org/zh-cn/
前言
我将会用一个小demo来介绍如何与Spring Boot整合;
如果看我文章的朋友没有用过Spring Boot,Dubbo,那么我推荐你还是先去熟悉一下,因为本篇文章没有介绍如何安装。
这次的demo是获取用户订单信息的小demo
目前这个demo正在我的github上: https://github.com/aaaTao66/dubbo-demo
开发环境
- win10
- idea 2019
- zookeeper
- dubbo
- jdk1.8
创建项目
- 首先我们创建一个maven项目非Spring Boot项目,这个项目的名字叫做 xxx-interface。
我这里叫做:gmall-interface
根据 Dubbo的官方文档的 服务最佳化实践 里面说的:
建议将服务接口、服务模型、服务异常等均放在 API 包中,因为服务模型和异常也是 API 的一部分,这样做也符合分包原则:重用发布等价原则(REP),共同重用原则(CRP)。
这就是我们建立 gmall-interface 的原因,也就是我们要把Java Bean 和 接口放在这个项目里面,让每一个微服务的项目依赖于它。
- 然后我们再创建两个 Spring Boot的项目,一个提供者,一个消费者。
提供者项目名:boot-user-service-provider;(用户,可以什么都不勾选)
消费者项目名:boot-order-service-consumer;(订单,记得初始化的时候要勾选web)
编写程序
项目:gmall-interface
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| package com.carson.gmall.bean;
import java.io.Serializable;
public class UserAddress implements Serializable {
private Integer id; private String userAddress; private String userId; private String consignee; private String phoneNum; private String isDefault;
|
记得要实现序列化
打个比方,如果我们的 A 客户端 想要调用 B客户端的一个方法,这个时候 A 服务器要与B服务器建立起连接,而且A服务器调用方法的时候要还要传入参数,而这个参数要在网络间传递,我们需要序列化。
然后B服务器发现有外界的服务器想要调用我的方法,同时还给我传了参数,由于是序列化传过来的,所以B服务器要把参数反序列化。
然后方法调用完之后,还有一个返回值,这个时候基本与刚才一样,先是序列化,然后A再把它反序列化,这样就可以得到返回结果了。
OrderService:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import com.carson.gmall.bean.UserAddress;
import java.util.List;
public interface UserService {
List<UserAddress> getUserAddressList(String userId); }
|
UserService:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import com.carson.gmall.bean.UserAddress;
import java.util.List;
public interface UserService {
List<UserAddress> getUserAddressList(String userId); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion>
<groupId>com.carson.gmall</groupId> <artifactId>gmall-interface</artifactId> <version>1.0-SNAPSHOT</version>
<dependencies> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.8</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>2.8.0</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.2</version> </dependency> </dependencies> </project>
|
提供者项目:boot-user-service-provider
除了Spring Boot自带的,还需要添加这两个,dubbo的 0.2.0 版本是给Spring Boot 2.x用的。
如果Spring Boot是 1.x版本,那么dubbo应该用 0.1.0.
1 2 3 4 5 6 7 8 9 10 11 12
| 与 gmall-interface 进行关联。 <dependency> <groupId>com.carson.gmall</groupId> <artifactId>gmall-interface</artifactId> <version>1.0-SNAPSHOT</version> </dependency> dubbo依赖 <dependency> <groupId>com.alibaba.boot</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>0.2.0</version> </dependency>
|
然后就是Spring Boot的配置文件:
1 2 3 4 5 6 7 8 9
| dubbo: application: name: boot-order-service-consumer registry: address: zookeeper://127.0.0.1:2181 monitor: protocol: registry server: port: 8081
|
没有用过可能看不懂这一段配置,其实对应的就是dubbo官方文档的那一段 provider.xml :
具体网址 :http://dubbo.apache.org/zh-cn/docs/user/quick-start.html
但是我的配置里面没有 声明需要暴露的服务接口 ,这个等一下会说为什么。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import com.alibaba.dubbo.config.annotation.Service; import com.carson.gmall.bean.UserAddress; import com.carson.gmall.bootuserserviceprovider.service.UserService; import org.springframework.stereotype.Component;
import java.util.Arrays; import java.util.List;
@Service @Component public class UserServiceImpl implements UserService {
public List<UserAddress> getUserAddressList(String userId) {
UserAddress address1 = new UserAddress(1, "河北省衡水市", "1", "carson","12345678911","Y"); UserAddress address2 = new UserAddress(1, "山东省德州市", "2", "eason", "4562144", "Y");
return Arrays.asList(address1,address2); } }
|
注意我的注解 @Service,这个注解不是Spring的,而是dubbo的:
import com.alibaba.dubbo.config.annotation.Service;
这个注解的意思就是:声明需要暴露的服务接口;
这个方法我们可以看到我设置了两个收获地址,并且把它以list方式返回。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
@EnableDubbo @SpringBootApplication public class BootUserServiceProviderApplication {
public static void main(String[] args) { SpringApplication.run(BootUserServiceProviderApplication.class, args); }
}
|
消费者项目:boot-order-service-consumer
pom 文件与刚才的提供者一样。
1 2 3 4 5 6 7 8 9
| dubbo: application: name: boot-order-service-consumer registry: address: zookeeper://127.0.0.1:2181 monitor: protocol: registry server: port: 8081
|
具体配的什么,可以参考duboo官方文档的快速启动,也就是刚才上面的网址:
http://dubbo.apache.org/zh-cn/docs/user/quick-start.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| package com.carson.gmall.bootorderserviceconsumer.service.impl;
import com.alibaba.dubbo.config.annotation.Reference; import com.carson.gmall.bean.UserAddress; import com.carson.gmall.bootuserserviceprovider.service.OrderService; import com.carson.gmall.bootuserserviceprovider.service.UserService; import com.sun.org.apache.bcel.internal.generic.RETURN; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;
import java.util.List;
@Service public class OrderServiceImpl implements OrderService {
@Reference UserService userService;
public List<UserAddress> initOrder(String userId) { System.out.println("用户id:"+userId); List<UserAddress> userAddressList = userService.getUserAddressList(userId); return userAddressList; } }
|
注意 @Reference: 远程调用UserService, 自己会去注册中心去发现
1 2 3 4 5 6 7 8 9 10 11 12
| @Controller public class OrderController {
@Autowired private OrderService orderService;
@ResponseBody @RequestMapping("/initOrder") public List<UserAddress> initOrder(@RequestParam("uid") String userId) { return orderService.initOrder(userId); } }
|
@ResponseBody: 把获取到的结果以 json方式响应
1 2 3 4 5 6 7
| @EnableDubbo @SpringBootApplication public class BootOrderServiceConsumerApplication { public static void main(String[] args) { SpringApplication.run(BootOrderServiceConsumerApplication.class, args); } }
|
和提供者一样
启动zookeeper和dubbo和这两个项目,可以在dubbo控制台看到,已经有了消费者和提供者
然后,我们刚才启动的Spring Boot,有一个是web项目,并且设置了端口 8081,让我们试着访问这个 8081端口,并且带上参数:
成功获取到了订单信息;