tags: [dubbo, 分布式]
categories: [dubbo]


前言

关于分布式是什么我们为什么要弄分布式这里不赘述,这里只总结一下分布式项目从0搭建的方法和注意事项,本项目各个模块之间调用是基于Dubbo+Zookeeper来实现的

一般情况下我们都是按照服务来切分的,用以各个服务之间的解耦和切分部署,父项目为普通的Maven项目,删掉了源代码文件夹和资源文件夹,只留下光秃秃的pom.xml,来对各个服务依赖进行统筹管理

这里不使用SpringBoot作为父项项目的原因是因为SpringBoot总会继承自父项SpringBoot,子模块必然会继承相关依赖,建立空的Maven项目更加合适

代码地址

https://github.com/bwensun/Embryo/tree/master/BLOG

项目搭建

项目结构

  1. BLOG
  2. ├─ .gitignore
  3. ├─ BLOG_API
  4. ├─ BLOG_API.iml
  5. ├─ pom.xml
  6. ├─ src
  7. └─ main
  8. └─ java
  9. ├─ BLOG_USER_SERVICE
  10. ├─ BLOG_USER_SERVICE.iml
  11. ├─ pom.xml
  12. ├─ src
  13. ├─ main
  14. ├─ java
  15. └─ resources
  16. └─ test
  17. └─ java
  18. ├─ BLOG_WEB
  19. ├─ BLOG_WEB.iml
  20. ├─ pom.xml
  21. ├─ src
  22. └─ main
  23. ├─ java
  24. └─ resources
  25. └─ pom.xml

项目建立

建立Maven项目父工程BLOG
正常输入GAV,groupId为项目名,artifactId为倒置的域名,版本号随意,我一般填入1.0,选择默认1.0快照版本也可以的
image.png

这里对项目的依赖做了统筹管理,在父pom中规定了依赖的版本,而子模块中只需写入GA信息即可,这样整个工程的依赖版本更迭时只需要修改父工程的依赖版本即可,另外父pom中也规定了整个项目共用了的依赖,通过依赖传递让子模块自动继承

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5. <packaging>pom</packaging>
  6. <modules>
  7. <module>BLOG_API</module>
  8. <module>BLOG_USER_SERVICE</module>
  9. <module>BLOG_WEB</module>
  10. </modules>
  11. <parent>
  12. <groupId>org.springframework.boot</groupId>
  13. <artifactId>spring-boot-starter-parent</artifactId>
  14. <version>2.2.2.RELEASE</version>
  15. <relativePath/> <!-- lookup parent from repository -->
  16. </parent>
  17. <groupId>com.bwensun</groupId>
  18. <artifactId>blog</artifactId>
  19. <version>0.0.1-SNAPSHOT</version>
  20. <name>blog</name>
  21. <description>个人博客项目</description>
  22. <properties>
  23. <java.version>1.8</java.version>
  24. <main.class>com.bwensun.blog.BlogApplication</main.class>
  25. <!--maven依赖版本控制-->
  26. <mybatis-spring-boot-starter>1.3.0</mybatis-spring-boot-starter>
  27. <dubbo-spring-boot-starter>0.2.0</dubbo-spring-boot-starter>
  28. <mybatis-generator-core>1.3.7</mybatis-generator-core>
  29. <druid-spring-boot-starter>1.1.10</druid-spring-boot-starter>
  30. <mysql-connector-java>5.1.44</mysql-connector-java>
  31. <lombok>1.16.18</lombok>
  32. <pagehelper>5.1.10</pagehelper>
  33. <springfox-swagger2>2.6.1</springfox-swagger2>
  34. </properties>
  35. <dependencyManagement>
  36. <dependencies>
  37. <dependency>
  38. <groupId>com.bwensun</groupId>
  39. <artifactId>BLOG_API</artifactId>
  40. <version>${project.version}</version>
  41. </dependency>
  42. <dependency>
  43. <groupId>org.mybatis.spring.boot</groupId>
  44. <artifactId>mybatis-spring-boot-starter</artifactId>
  45. <version>${mybatis-spring-boot-starter}</version>
  46. </dependency>
  47. <dependency>
  48. <groupId>com.alibaba.boot</groupId>
  49. <artifactId>dubbo-spring-boot-starter</artifactId>
  50. <version>${dubbo-spring-boot-starter}</version>
  51. </dependency>
  52. <dependency>
  53. <groupId>org.mybatis.generator</groupId>
  54. <artifactId>mybatis-generator-core</artifactId>
  55. <version>${mybatis-generator-core}</version>
  56. </dependency>
  57. <dependency>
  58. <groupId>com.alibaba</groupId>
  59. <artifactId>druid-spring-boot-starter</artifactId>
  60. <version>${druid-spring-boot-starter}</version>
  61. </dependency>
  62. <dependency>
  63. <groupId>mysql</groupId>
  64. <artifactId>mysql-connector-java</artifactId>
  65. <version>${mysql-connector-java}</version>
  66. </dependency>
  67. </dependencies>
  68. </dependencyManagement>
  69. <!--公有依赖-->
  70. <dependencies>
  71. <dependency>
  72. <groupId>org.springframework.boot</groupId>
  73. <artifactId>spring-boot-starter</artifactId>
  74. </dependency>
  75. <dependency>
  76. <groupId>org.springframework.boot</groupId>
  77. <artifactId>spring-boot-starter-test</artifactId>
  78. <scope>test</scope>
  79. <exclusions>
  80. <exclusion>
  81. <groupId>org.junit.vintage</groupId>
  82. <artifactId>junit-vintage-engine</artifactId>
  83. </exclusion>
  84. </exclusions>
  85. </dependency>
  86. <!--lombok-->
  87. <dependency>
  88. <groupId>org.projectlombok</groupId>
  89. <artifactId>lombok</artifactId>
  90. <version>${lombok}</version>
  91. </dependency>
  92. <dependency>
  93. <groupId>com.github.pagehelper</groupId>
  94. <artifactId>pagehelper</artifactId>
  95. <version>${pagehelper}</version>
  96. </dependency>
  97. <!-- swagger2 -->
  98. <dependency>
  99. <groupId>io.springfox</groupId>
  100. <artifactId>springfox-swagger-ui</artifactId>
  101. <version>${springfox-swagger2}</version>
  102. </dependency>
  103. <dependency>
  104. <groupId>io.springfox</groupId>
  105. <artifactId>springfox-swagger2</artifactId>
  106. <version>${springfox-swagger2}</version>
  107. </dependency>
  108. </dependencies>
  109. <build>
  110. <plugins>
  111. <plugin>
  112. <groupId>org.springframework.boot</groupId>
  113. <artifactId>spring-boot-maven-plugin</artifactId>
  114. <configuration>
  115. <mainClass>${main.class}</mainClass>
  116. </configuration>
  117. <executions>
  118. <execution>
  119. <goals>
  120. <goal>repackage</goal>
  121. </goals>
  122. </execution>
  123. </executions>
  124. </plugin>
  125. </plugins>
  126. </build>
  127. </project>


建立BLOG_API模块**
Dubbo官网服务化最佳实践中有提及,建议将服务接口、服务模型、服务异常等均放在 API 包中,我们也遵循其规范,右键项目New Module -> 名为BLOG_API和父项目类似,注意设置Maven Repository设置,版本号和父项目一致,可以从pom.xml中看到继承自父项目
API模块用于定义一些公有的实体类、工具类、异常类和服务接口,调用方引入该模块,通过接口调用服务而不用关心到底是哪一个Service是实现了该功能
建立完毕后注意执行mvn clean install 安装到本地仓库

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <parent>
  6. <artifactId>blog</artifactId>
  7. <groupId>com.bwensun</groupId>
  8. <version>0.0.1-SNAPSHOT</version>
  9. </parent>
  10. <modelVersion>4.0.0</modelVersion>
  11. <artifactId>BLOG_API</artifactId>
  12. </project>


建立BLOG_USER_SERVICE模块和BLOG_Web模块
建立模块过程和之前方法一致
这里需要注意的是这两个项目我重新引入了SpringBoot相关的依赖,标记文件夹,并添加启动类,和配置文件使之成为一个单独的SpringBoot项目,用以启动和调用服务
Zookeeper的安装和启动连接:略
以下是pom.xmlapplication.yaml配置,启动类略
BLOG_USER_SERVICE模块**
pom.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <parent>
  6. <artifactId>blog</artifactId>
  7. <groupId>com.bwensun</groupId>
  8. <version>0.0.1-SNAPSHOT</version>
  9. </parent>
  10. <modelVersion>4.0.0</modelVersion>
  11. <artifactId>BLOG_USER_SERVICE</artifactId>
  12. <dependencies>
  13. <dependency>
  14. <groupId>com.bwensun</groupId>
  15. <artifactId>BLOG_API</artifactId>
  16. </dependency>
  17. <dependency>
  18. <groupId>com.alibaba.boot</groupId>
  19. <artifactId>dubbo-spring-boot-starter</artifactId>
  20. </dependency>
  21. <!--mybatis-->
  22. <dependency>
  23. <groupId>org.mybatis.spring.boot</groupId>
  24. <artifactId>mybatis-spring-boot-starter</artifactId>
  25. </dependency>
  26. <dependency>
  27. <groupId>org.mybatis.generator</groupId>
  28. <artifactId>mybatis-generator-core</artifactId>
  29. </dependency>
  30. <!--druid连接池-->
  31. <dependency>
  32. <groupId>com.alibaba</groupId>
  33. <artifactId>druid-spring-boot-starter</artifactId>
  34. </dependency>
  35. <!--mysql-->
  36. <dependency>
  37. <groupId>mysql</groupId>
  38. <artifactId>mysql-connector-java</artifactId>
  39. <scope>runtime</scope>
  40. </dependency>
  41. </dependencies>
  42. <build>
  43. <plugins>
  44. <plugin>
  45. <groupId>org.mybatis.generator</groupId>
  46. <artifactId>mybatis-generator-maven-plugin</artifactId>
  47. <version>1.3.7</version>
  48. <configuration>
  49. <!--自定义路径,否则会自动识别GeneratorConfig.xml文件-->
  50. <!-- <configurationFiile>${basedir}/src/main/resources/generatorConfig.xml</configurationFile>-->
  51. <!--是为了运行mvn mybatis-generator:generate -e时显示具体过程-->
  52. <verbose>true</verbose>
  53. <!--为了生成文件时后一次生成的文件覆盖前一次生成的同名文件-->
  54. <overwrite>true</overwrite>
  55. </configuration>
  56. <dependencies>
  57. <dependency>
  58. <groupId>mysql</groupId>
  59. <artifactId>mysql-connector-java</artifactId>
  60. <version>5.1.44</version>
  61. </dependency>
  62. </dependencies>
  63. </plugin>
  64. </plugins>
  65. </build>
  66. </project>

yaml

  1. dubbo:
  2. application:
  3. name: boot-order-service-consumer
  4. registry:
  5. #address: zookeeper://localhost:2181ip
  6. address: zookeeper://ip:2181?backup=47.103.215.103:2182,47.103.215.103:2183
  7. file: dubbo-registry/dubbo-registry.properties
  8. # monitor:
  9. # protocol: registry
  10. server:
  11. port: 8081
  12. spring:
  13. profiles:
  14. include: druid
  15. mybatis:
  16. mapper-locations: classpath:mapper/*.xml

启动类
注意@EnableDubbo这个注解要加上

  1. @SpringBootApplication
  2. @EnableDubbo
  3. public class BlogUserServiceApplication {
  4. public static void main(String[] args) {
  5. SpringApplication.run(BlogUserServiceApplication.class, args);
  6. }
  7. }

BLOG_WEB模块
pom.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <parent>
  6. <artifactId>blog</artifactId>
  7. <groupId>com.bwensun</groupId>
  8. <version>0.0.1-SNAPSHOT</version>
  9. </parent>
  10. <modelVersion>4.0.0</modelVersion>
  11. <artifactId>BLOG_WEB</artifactId>
  12. <dependencies>
  13. <dependency>
  14. <groupId>org.springframework.boot</groupId>
  15. <artifactId>spring-boot-starter-web</artifactId>
  16. </dependency>
  17. <dependency>
  18. <groupId>com.alibaba.boot</groupId>
  19. <artifactId>dubbo-spring-boot-starter</artifactId>
  20. </dependency>
  21. <dependency>
  22. <groupId>com.bwensun</groupId>
  23. <artifactId>BLOG_API</artifactId>
  24. </dependency>
  25. </dependencies>
  26. </project>

yaml

  1. dubbo:
  2. application:
  3. name: boot-order-service-consumer
  4. registry:
  5. address: zookeeper://IP:2181?backup=47.103.215.103:2182,47.103.215.103:2183
  6. file: dubbo-registry/dubbo-registry.properties
  7. # monitor:
  8. # protocol: registry
  9. server:
  10. port: 8081

启动类

注意@EnableDubbo这个注解要加上

  1. @SpringBootApplication
  2. @EnableDubbo
  3. public class BlogWebApplication {
  4. public static void main(String[] args) {
  5. SpringApplication.run(BlogWebApplication.class, args);
  6. }
  7. }

**

写个Demo

BLOG_API添加实体类、接口

  • 添加实体类
  1. @Getter
  2. @Setter
  3. @ToString
  4. public class User implements Serializable {
  5. /**
  6. * 主键
  7. */
  8. private Integer id;
  9. /**
  10. * 用户名
  11. */
  12. private String userName;
  13. /**
  14. * 密码
  15. */
  16. private String password;
  17. private static final long serialVersionUID = 1L;
  18. }
  • 添加服务接口

    1. @Component
    2. public interface UserService {
    3. /**
    4. * 用户信息分页查询
    5. * @return 分页用户对象
    6. */
    7. PageInfo<User> getUserList();
    8. }

BLOG_USER_SERVICE实现该接口

  • 实现该服务接口

注意:
Service为import ``com.alibaba.dubbo.config.annotation.``Service

  1. @Component
  2. @Service
  3. public class UserServiceImpl implements UserService {
  4. @Resource
  5. UserMapper userMapper;
  6. @Override
  7. public PageInfo<User> getUserList() {
  8. PageHelper.startPage(1, 10);
  9. List<User> users = userMapper.selectAll();
  10. return new PageInfo<>(users);
  11. }
  • 具体Dao层略

**

BLOG_WEB添加控制器

  1. @RestController
  2. @RequestMapping("user")
  3. public class UserController {
  4. @Reference
  5. UserService userService;
  6. @RequestMapping("userList")
  7. public PageInfo<User> getUserList(){
  8. return userService.getUserList();
  9. }
  10. }

测试

  1. 启动BLOG_USER_SERVICE项目来注册到ZK之中,控制台打印如下

image.png

  1. 启动BLOG_WEB项目,用于接受客户端的请求,同样他会连接ZK来获取服务image.png
  2. 访问localhost:8081/user/userList可以发现已经接受了返回的查询结果image.png

问题和解决

事实上,在实际测试中遇到了非常多问题,我把这些都记录下来,放到了

相关

  1. Dubbo官方文档
  2. Spring Boot-整合Dubbo