架构之旅-多层架构-数据

简述

本文中,将使用MyBatis + Druid来构建数据访问层访问MySQL,使用dubbo+zookeeper来充当service provider,并修改service来使用dubbo(service consumer)。

源代码

iarc-data

环境

IDE: IntelliJ IDEA
JDK: 1.8.0_u162
Framework: MyBatis, Druid, Dubbo
App Coordinator: Zookeeper
DB: MySQL
WebServer: Tomcat (本地端口8088)

开发

准备

  • zookeeper
    把Zookeeper安装目录中/conf/zoo_simple.cfg重命名为zoo.cfg。然后执行 Zookeeper安装目录/bin/zkServer.cmd
  • 在tomcat中安装dubbo admin来监控服务参考

工程结构

1
2
3
4
5
--root(maven pom父工程)
----iarc-entity (实体类 module)
----iarc-service-api (服务接口 module)
----iarc-service (服务站点-spring boot)
----iarc-data (数据服务 module)

SQL初始化脚本

1
2
3
4
5
6
7
8
9
10
11
CREATE SCHEMA ijava;
use ijava;
CREATE TABLE user
(
id INT AUTO_INCREMENT
PRIMARY KEY,
name VARCHAR(50) NOT NULL
)
COMMENT 'user table'
ENGINE = InnoDB;
INSERT INTO ijava.user (name) VALUES ('ivan'), ('du');

iarc-data

  • spring boot configuration

    1
    2
    3
    server.port=8002
    endpoints.jmx.unique-names=true
    spring.jmx.default-domain=iarc.data
  • dubbo configuration

    1
    2
    3
    4
    5
    6
    7
    8
    9
    spring.dubbo.application.name=iarc.data
    spring.dubbo.registry.address=zookeeper://127.0.0.1:2181
    spring.dubbo.registry.group=dubbo
    spring.dubbo.protocol.name=dubbo
    spring.dubbo.protocol.port=20882
    spring.dubbo.scan=cn.icmyfuture.iarc.data
    spring.dubbo.consumer.retries=0
    spring.dubbo.consumer.timeout=10000
    spring.dubbo.consumer.check=false
  • Custom Dubbo Auto Config class

    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    import com.alibaba.dubbo.config.*;
    import lombok.Getter;
    import lombok.Setter;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.boot.context.properties.EnableConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.Ordered;
    import org.springframework.core.annotation.Order;

    import javax.annotation.PreDestroy;

    @Configuration
    @EnableConfigurationProperties({CustomDubboAutoConfig.CustomDubboProperties.class})
    @Order(Ordered.LOWEST_PRECEDENCE)
    public class CustomDubboAutoConfig {
    private static final Logger logger = LoggerFactory.getLogger(CustomDubboAutoConfig.class);

    @ConfigurationProperties(prefix = "spring.dubbo")
    @Setter
    @Getter
    class CustomDubboProperties{
    private MonitorConfig monitor;
    private ConsumerConfig consumer;
    private ProviderConfig provider;
    private ModuleConfig module;
    private MethodConfig method;
    }


    @Autowired
    private CustomDubboProperties dubboProperties;

    @Bean
    public ConsumerConfig consumerConfig() {
    ConsumerConfig consumerConfig = this.dubboProperties.getConsumer();
    if (consumerConfig == null) {
    consumerConfig = new ConsumerConfig();
    }
    return consumerConfig;
    }

    @Bean
    public MonitorConfig monitorConfig(){
    MonitorConfig monitorConfig = this.dubboProperties.getMonitor();
    if (monitorConfig == null) {
    monitorConfig = new MonitorConfig();
    }
    return monitorConfig;
    }


    @Bean
    public ProviderConfig providerConfig() {
    ProviderConfig providerConfig = this.dubboProperties.getProvider();
    if (providerConfig == null) {
    providerConfig = new ProviderConfig();
    }
    return providerConfig;
    }

    @Bean
    public MethodConfig requestMethodConfig() {
    MethodConfig methodConfig = dubboProperties.getMethod();
    if (methodConfig == null) {
    methodConfig = new MethodConfig();
    }
    return methodConfig;
    }

    @PreDestroy
    public void shutdownDestroy() {
    ProtocolConfig.destroyAll();
    }
    }
  • Druid configuration

    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
    spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
    spring.datasource.druid.ijava.url=jdbc:mysql://localhost:3306/ijava?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true&autoReconnect=true&failOverReadOnly=false&connectTimeout=10000&serverTimezone=Asia/Shanghai
    spring.datasource.druid.ijava.driverClassName=com.mysql.cj.jdbc.Driver
    spring.datasource.druid.ijava.username=***
    spring.datasource.druid.ijava.password=***
    spring.datasource.druid.ijava.initialSize=1
    spring.datasource.druid.ijava.minIdle=1
    spring.datasource.druid.ijava.maxActive=20
    spring.datasource.druid.ijava.maxWait=60000
    spring.datasource.druid.ijava.timeBetweenEvictionRunsMillis=60000
    spring.datasource.druid.ijava.minEvictableIdleTimeMillis=300000
    spring.datasource.druid.ijava.testWhileIdle=true
    spring.datasource.druid.ijava.testOnBorrow=false
    spring.datasource.druid.ijava.testOnReturn=false
    spring.datasource.druid.ijava.validationQuery=SELECT 1
    spring.datasource.druid.ijava.poolPreparedStatements=true
    spring.datasource.druid.ijava.maxPoolPreparedStatementPerConnectionSize=20
    spring.datasource.druid.ijava.filters=stat,slf4j
    spring.datasource.druid.ijava.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=2000
    #WebStatFilter,为了进行Druid DB监控
    spring.datasource.druid.WebStatFilter.enabled=true
    spring.datasource.druid.WebStatFilter.urlPattern=/druid/*
    spring.datasource.druid.WebStatFilter.exclusions=false
    #StatViewServlet,为了进行Druid DB监控
    spring.datasource.druid.StatViewServlet.enabled=true
    spring.datasource.druid.StatViewServlet.urlPattern=/druid/*
    spring.datasource.druid.StatViewServlet.resetEnable=false

iarc-service

  • port && jmx unique configuration

    1
    2
    3
    server.port=8002
    endpoints.jmx.unique-names=true
    spring.jmx.default-domain=iarc.data
  • dubbo configuration

    1
    2
    3
    4
    5
    6
    7
    8
    spring.dubbo.application.name=iarc.service
    spring.dubbo.registry.address=zookeeper://127.0.0.1:2181
    spring.dubbo.registry.group=dubbo
    spring.dubbo.protocol.port=20881
    spring.dubbo.scan=cn.icmyfuture.iarc.service
    spring.dubbo.consumer.retries=0
    spring.dubbo.consumer.timeout=10000
    spring.dubbo.consumer.check=false
  • dubbo service reference

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    @RestController
    @RequestMapping(value = "/user")
    public class UserController {
    @Reference
    private UserService userService;

    @CrossOrigin(origins = "*")
    @GetMapping("getUser/{id}")
    public User getUser(@PathVariable("id") int id) {
    return userService.getUser(id);
    }
    }
  • Custom Dubbo Auto Config class
    与iarc-data节中相同

调试

部署

maven 编译打包

1
mvn clean install -Dmaven.test.skip=true

部署data/service至centos

将打包好的iarc-service.war, iarc-data.war复制到 $CATALINA_HOME/webapps目录下,tomcat会自动解压war包,访问http://localhost:8080/iarc-service/user/getUser/1进行验证

参考