20分钟springboot搭建dubbo服务

本文介绍本人通过springboot搭建dubbo服务的项目实例,此服务为dubbo+springboot+mybatis项目,使用到swagger-ui及mybatis-generator功能。
数据层实现,逆向工程使用部分描述简写,详情参考https://www.jianshu.com/p/6bcaf86e84f0

主体结构如图:


image.png

此服务为父子级maven项目,主体demoDubbo,内嵌:
common(使用mybatis-generator生成实体及mapper,放置实体类);
provider(提供者,放置mapper,提供调用数据层的方法及service接口实现);
api(放置provider的接口,起到关联provider和consumer的作用);
consumer(消费者,存放controller)

0.前期准备:

  1. 本地安装zookeeper(本人使用虚拟机安装的zookeeper,具体自行百度或参考下方链接):
    window安装:https://www.jianshu.com/p/0dbbb97d7e21
    linux安装:https://www.jianshu.com/p/cd6c2110aa71

  2. 数据库执行下面语句,创建d_user表

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for d_user
-- ----------------------------
DROP TABLE IF EXISTS `d_user`;
CREATE TABLE `d_user`  (
  `id` int(0) NOT NULL,
  `name` varchar(25) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `ip` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of d_user
-- ----------------------------
INSERT INTO `d_user` VALUES (1001, '雨欣', '100011');
INSERT INTO `d_user` VALUES (1002, '雨欣:324:324:324', '100012');

SET FOREIGN_KEY_CHECKS = 1;

如下:


image.png
  1. 创建maven父级项目
    依次点击idea: File>new>Project新建项目,选择maven,next后创建项目名dubbo新窗口打开,如下:


    image.png

    父级项目删除src,test文件夹。

1.创建common子项目

右键父项目名,new>module如下


image.png

选择maven项目,勾选如下确定,下一步(可不用勾选webapp)


image.png

创建项目名common,依次下一步创建common子项目,删除pom中的内容,粘贴逆向工程配置内容,并引入依赖如下:

  

    
      javax.persistence
      persistence-api
      1.0
      compile
    


  

  
    common
    
    

    
      
        org.mybatis.generator
        mybatis-generator-maven-plugin
        1.3.2
        
          
            src/main/resources/generator/genteratorCongfig.xml
          
          true
          true
        
        
          
            mysql
            mysql-connector-java
            8.0.16
          
          
            tk.mybatis
            mapper
            3.4.2
          
        
      
    

  

删除main文件夹内的webapps文件夹,创建java,resources文件夹如下:


image.png

!!若文件夹属性不对(后续子项目都会涉及),可点击File>project Structure修改文件属性,如下


image.png

在resources下创建文件夹generator,并创建逆向工程文件配置如下:


image.png

其中config.properties文件内容如下,注意修改你的数据库配置,自动生成的mapper,dao子文件夹名称,以及生成路径

jdbc.driverClass=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowMultiQueries=true
jdbc.user=root
jdbc.password=root


#模块名
moduleName=d_user
#表名
tableName=d_user
#默认路径
modelPath=com.example.demo1

其中genteratorCongfig.xml 文件内容如下




    

    
        
        

        
            
            
            
        

        
        

        
        

        
        

        
        

        
        
        

双击生成mapper;dao;model如下


image.png

implements Serializable 添加序列化实体对象如下:


image.png

Dubbo服务间的调用需要实体序列化,不然调用会报错:

org.apache.dubbo.remoting.RemotingException: Failed to send response: Response [id=2, version=2.0.2, status=20, event=false, error=null, result=AppResponse [value=com.example.common.model.entity.d_user.DUser@3f3ffb93, exception=null]], cause: java.lang.IllegalStateException: Serialized class com.example.common.model.entity.d_user.DUser must implement java.io.Serializable
java.lang.IllegalStateException: Serialized class com.example.common.model.entity.d_user.DUser must implement java.io.Serializable

生成如下:


image.png

2.创建provider子项目

首先同创建common子项目,创建provider子项目
修改pom文件如下:




  4.0.0

  org.example
  provider
  1.0-SNAPSHOT
  war

  provider Maven Webapp
  
  http://www.example.com



  
    org.springframework.boot
    spring-boot-starter-parent
    2.0.4.RELEASE
     
  


  
    UTF-8
    1.7
    1.7
    2.7.8
    
    2.53.0
  

  
    
    
      org.example
      common
      1.0-SNAPSHOT
      compile
    

    
    
      org.springframework.boot
      spring-boot-starter-web
    

    
    
      mysql
      mysql-connector-java
      8.0.16
      runtime
    

    
    
      org.mybatis.spring.boot
      mybatis-spring-boot-starter
      1.1.1
    

    
    
      org.mybatis
      mybatis
      3.4.6
      compile
    

    
    
      junit
      junit
      test
    

    
      org.springframework
      spring-test
      test
    

    
      org.springframework.boot
      spring-boot-test
      test
    

    
    
      tk.mybatis
      mapper
      4.1.5
    


    
    
    
      org.apache.dubbo
      dubbo-spring-boot-starter
      ${dubbo.version}
    

    
    
      org.apache.dubbo
      dubbo-dependencies-zookeeper
      ${dubbo.version}
      pom
      
        
          org.slf4j
          slf4j-log4j12
        
      
    

    
    
      org.seleniumhq.selenium
      selenium-server-standalone
      ${selenium.version}
    


  

  
    provider
    
    
      
        src/main/java
        
          **/*.properties
          **/*.xml
          **/*.yml
        
        false
      
      
        src/main/resources
        
          **/*.properties
          **/*.xml
          **/*.yml
        
        false
      
    
    
    
  



添加并修改yml文件如下:(注意zookeeper配置)

spring:
  application:
    name: this-provider
#  profiles:
#    active: test
  datasource:
    #MySQL数据库支持配置
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowMultiQueries=true
    username: root
    password: root
    type: com.zaxxer.hikari.HikariDataSource
    hikari:
      minimum-idle: 5
      maximum-pool-size: 100
      idle-timeout: 600000
      pool-name: OrderHikariCP
      max-lifetime: 1800000
      connection-timeout: 60000
      connection-test-query: SELECT 1
server:
  port: 8081
mybatis:
  config-location: classpath:mybatis-config.xml
  type-aliases-package: org.example.provider.dao.**
  mapper-locations: classpath:mapper/*/*.xml
dataType: 0

dubbo:
  # Base packages to scan Dubbo Component: @org.apache.dubbo.config.annotation.Service
  scan:
    # 扫描 DubboService 注解
    base-packages: org.example.provider.**
  ## ApplicationConfig Bean
  application:
    # 服务id
    id: this-provider
    # 服务名称
    name: this-provider
    # QOS服务:通过一些命令来返回响应的结果,达到动态控制的目的
    qos-port: 22212
    qos-enable: true
  ## ProtocolConfig Bea                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        n
  protocol:
    # 底层通讯协议,在多协议时使用?
    id: dubbo
    name: dubbo
    port: 10345
    status: server
    payload: 83886080
  ## RegistryConfig Bean
  registry:
    id: this-provider
    # 使用的zookeeper 地址
    address: 10.1.31.199:2181
    protocol: zookeeper
  provider:
    # 当 ProtocolConfig 和 ServiceConfig 某属性没有配置时,采用此缺省值,可选
    timeout: 300000
    payload: 83886080
  consumer:
    # 当 ReferenceConfig 某属性没有配置时,采用此缺省值,可选
    timeout: 300000
    check: false

添加并修改mybatis-config文件如下:




    
        
    
    
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
    



再将common的dao层及mapper文件夹移至provider中(pom内引入common依赖后,修改引入路径),
整体结构如下:


image.png

在mapper.xml文件内编写sql查询语句,并在dao内,添加该方法:

  
    id,name,ip
  
  
  
    DUser selectAllById(@Param("id") Integer id);

创建service文件夹,预留存放Service接口实现;
创建application启动类文件ProviderApplication如下:

package com.example.provider;

import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
import tk.mybatis.spring.annotation.MapperScan;

/**
 * 订单provider启动类
 *
 * @author ZSC-DXHY
 */

@SpringBootApplication
@ComponentScan(value = {"com.example"})
@MapperScan(basePackages = "com.example.provider.dao.**")
@EnableConfigurationProperties
@EnableDubbo
public class ProviderApplication extends SpringBootServletInitializer {
    
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(ProviderApplication.class);
    }
    
    public static void main(String[] args) {
        new SpringApplicationBuilder(ProviderApplication.class)
                .run(args);
    }
}

创建test测试项,测试数据查询实现如下:
在src下创建文件夹test,修改文件夹属性为Tests,在目录下创建providerApplicationTests测试类代码如下:

package com.example.demomybatis;
import com.example.provider.ProviderApplication;
import com.example.provider.dao.d_user.DUserMapper;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.junit.runner.RunWith;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = ProviderApplication.class)
public class providerApplicationTests {

    @Autowired
    DUserMapper dUserMapper;


    @Test
    public void contextLoads() {
        System.out.println("here==="+dUserMapper.selectAllById(1001).getName());
    }


}

启动测试文件,查询成功:


image.png

整体结构如下:


image.png

3.创建api子项目

首先同创建common子项目,创建api子项目,并创建文件夹java/com/example/api,添加service接口层,如下:


image.png

在api的service内添加接口方法DUserService;
在provider的service创建impl文件夹,并在内添加接口方法的实现类DUserServiceImpl实现DUserService接口。
代码如下:

package com.example.api.service;

import com.example.common.model.entity.d_user.DUser;

public interface DUserService {
    DUser selectById(Integer id);
}

package com.example.provider.service.impl;


import com.example.api.service.DUserService;
import com.example.common.model.entity.d_user.DUser;
import com.example.provider.dao.d_user.DUserMapper;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;

@DubboService
public class DUserServiceImpl implements DUserService {

    @Autowired
    DUserMapper dUserMapper;

    @Override
    public DUser selectById(Integer id){
        return dUserMapper.selectAllById(id);
    }
}

注意:
1dubbo的service注解使用DubboService
2为api项目的pom添加common依赖,为provider项目添加api依赖

3.创建consumer子项目

首先同创建common子项目,创建consumer子项目,并创建目录结构;
consumer使用swagger-ui接口,大致创建可仿common及provider子项目实现,具体结构如下:


image.png

其中pom文件内容如下:




  4.0.0

  org.example
  consumer
  1.0-SNAPSHOT
  war

  consumer Maven Webapp
  
  http://www.example.com
  
    org.springframework.boot
    spring-boot-starter-parent
    2.0.4.RELEASE
     
  



  
    UTF-8
    1.7
    1.7
    2.7.8
    
    2.53.0
  

  
    
    
      org.springframework.boot
      spring-boot-starter-web
    

    
    
    
      org.apache.dubbo
      dubbo-spring-boot-starter
      ${dubbo.version}
    

    
    
      org.apache.dubbo
      dubbo-dependencies-zookeeper
      ${dubbo.version}
      pom
      
        
          org.slf4j
          slf4j-log4j12
        
      
    

    
    
      org.seleniumhq.selenium
      selenium-server-standalone
      ${selenium.version}
    

    

    
    
      io.springfox
      springfox-swagger2
      2.6.1
    
    
      io.springfox
      springfox-swagger-ui
      2.6.1
    
    
      com.spring4all
      spring-boot-starter-swagger
      1.5.1.RELEASE
    
    
    
      com.alibaba
      fastjson
      1.2.47
    
    
    
      org.example
      api
      1.0-SNAPSHOT
      compile
    

  

  
    consumer
  


application.yml文件如下:

spring:
  application:
    name: consumer
  profiles:
    active: test
server:
  port: 8082
  servlet:
    context-path: /
  max-http-header-size: 4048576


dubbo:
  # Base packages to scan Dubbo Component: @org.apache.dubbo.config.annotation.Service
  scan:
    # 扫描 DubboService 注解
    base-packages: org.example.consmuer.**
  ## ApplicationConfig Bean
  application:
    # 服务id
    id: this-consumer
    # 服务名称
    name: this-consumer
    # QOS服务:通过一些命令来返回响应的结果,达到动态控制的目的
    qos-port: 22213
    qos-enable: true
  ## RegistryConfig Bean
  registry:
    id: this-provider
    # 使用的zookeeper 地址
    address: 10.1.31.199:2181
    protocol: zookeeper
  provider:
    # 当 ProtocolConfig 和 ServiceConfig 某属性没有配置时,采用此缺省值,可选
    timeout: 300000
  consumer:
    # 当 ReferenceConfig 某属性没有配置时,采用此缺省值,可选
    timeout: 300000
    check: false

swagger2Config文件如下:

package com.example.config;

import com.google.common.base.Predicates;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2
public class Swagger2Config {
    @Bean
    public Docket createRestApi(){
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.any())// 对所有api进行监控
                .paths(Predicates.not(PathSelectors.regex("/error.*")))//错误路径不监控
                .paths(PathSelectors.regex("/.*"))// 对根下所有路径进行监控
                .build();
    }
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("测试swagger-dubbo接口")
                .description("dxhy-api文档")
                // .termsOfServiceUrl("/")
                .version("1.0")
                .build();
    }
}

创建的controller实现类文件如下:

package com.example.consumer.openapi;


import com.example.api.service.DUserService;
import com.example.common.model.entity.d_user.DUser;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.web.bind.annotation.*;

@Api(value = "demo",description = "API for demo",protocols = "http")
@RestController
@RequestMapping("/demo")
public class testController {

    @DubboReference
    private DUserService duserService;

    @ApiOperation(value="",notes="")
    @GetMapping("/getById")
    public DUser demoForController(@RequestParam(value="id",defaultValue ="1001" )@ApiParam(value="uersId")String id){
        DUser user =new DUser();
        if(StringUtils.isNotEmpty(id)){
            user = duserService.selectById(Integer.valueOf(id));
        }
        return user;
    }
}

注意:duserService接口引入api的,注解使用:@DubboReference
启动项文件ConsumerStarter 内容为:

package com.example.consumer;

import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

/**
 * 订单服务启动类
 *
 * @author ZSC-DXHY
 */
@SpringBootApplication
@ComponentScan(value = {"com.example"})
@EnableDubbo
@EnableSwagger2
public class ConsumerStarter extends SpringBootServletInitializer {
    
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(ConsumerStarter.class);
    }
    
    public static void main(String[] args) {
        new SpringApplicationBuilder(ConsumerStarter.class)
                .run(args);
    }
    
}

至此项目创建完毕。

5测试项目功能实现

先启动provider服务;


image.png

再启动consumer服务;


image.png

浏览器访问swagger-ui链接如下:

http://localhost:8082/swagger-ui.html#!/test-controller/demoForControllerUsingGET
image.png

整体实现成功~

注意:此文章写的比较粗糙,但是整体实现没问题,父子级关系并未实现依赖引用包,后续完善~

你可能感兴趣的:(20分钟springboot搭建dubbo服务)