# 搭建用户管理服务
# 创建通用的 Dubbo 依赖项目
我们使用 Dubbo 通信还需要集成 Kryo 高速序列化框架,故还需要在 myshop-commons 项目中增加依赖
    <dependency>
        <groupId>de.javakaffee</groupId>
        <artifactId>kryo-serializers</artifactId>
    </dependency>
1
2
3
4
2
3
4
# 创建通用的 Dubbo 依赖项目
创建一个名为 myshop-commons-dubbo 项目,在之前的课程中我们知道 Dubbo 需要创建服务提供者和服务消费者两个角色,他们都需要依赖 Dubbo 的 Starter POM,并且我们的项目都需要集成熔断机制,所以我们会提取出一个通用的项目以便于所有 Dubbo 项目统一依赖,简化我们的开发流程。
# POM
    <?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>
    
        <parent>
            <groupId>com.cmcc</groupId>
            <artifactId>myshop-dependencies</artifactId>
            <version>1.0.0-SNAPSHOT</version>
            <relativePath>../myshop-dependencies/pom.xml</relativePath>
        </parent>
    
        <artifactId>myshop-commons-dubbo</artifactId>
        <packaging>jar</packaging>
    
        <url>http://www.cmcc.com</url>
        <inceptionYear>2018-Now</inceptionYear>
    
        <dependencies>
            <!-- Spring Boot Starter Settings -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
            </dependency>
            <dependency>
                <groupId>com.alibaba.boot</groupId>
                <artifactId>dubbo-spring-boot-starter</artifactId>
            </dependency>
            <dependency>
                <groupId>com.alibaba.boot</groupId>
                <artifactId>dubbo-spring-boot-actuator</artifactId>
            </dependency>
    
            <!-- Spring Cloud Settings -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
            </dependency>
        </dependencies>
    </project>
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
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
# 配置 Hystrix Servlet
    package com.cmcc.myshop.commons.dubbo.config.servlet;
    
    import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
    import org.springframework.boot.web.servlet.ServletRegistrationBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class HystrixDashboardConfiguration {
        @Bean
        public ServletRegistrationBean getServlet() {
            HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
            ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
            registrationBean.setLoadOnStartup(1);
            registrationBean.addUrlMappings("/hystrix.stream");
            registrationBean.setName("HystrixMetricsStreamServlet");
            return registrationBean;
        }
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 创建用户管理服务提供者
# 创建用户管理服务接口项目
创建一个名为 myshop-service-user-api 项目,该项目只负责定义接口
# POM
    <?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>
    
        <parent>
            <groupId>com.cmcc</groupId>
            <artifactId>myshop-dependencies</artifactId>
            <version>1.0.0-SNAPSHOT</version>
            <relativePath>../myshop-dependencies/pom.xml</relativePath>
        </parent>
    
        <artifactId>myshop-service-user-api</artifactId>
        <packaging>jar</packaging>
    
        <url>http://www.cmcc.com</url>
        <inceptionYear>2018-Now</inceptionYear>
    
        <dependencies>
            <dependency>
                <groupId>com.cmcc</groupId>
                <artifactId>myshop-commons-domain</artifactId>
                <version>${project.parent.version}</version>
            </dependency>
        </dependencies>
    </project>
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
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
# TbUserService
    package com.cmcc.myshop.service.user.api;
    
    import com.cmcc.myshop.commons.domain.TbUser;
    
    import java.util.List;
    
    public interface TbUserService {
        List<TbUser> selectAll();
    }
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 创建用户管理服务提供者
创建一个名为 myshop-service-user-provider 项目
# POM
    <?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>
    
        <parent>
            <groupId>com.cmcc</groupId>
            <artifactId>myshop-dependencies</artifactId>
            <version>1.0.0-SNAPSHOT</version>
            <relativePath>../myshop-dependencies/pom.xml</relativePath>
        </parent>
    
        <artifactId>myshop-service-user-provider</artifactId>
        <packaging>jar</packaging>
    
        <url>http://www.cmcc.com</url>
        <inceptionYear>2018-Now</inceptionYear>
    
        <dependencies>
            <!-- Spring Boot Starter Settings -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
    
            <!-- Projects Settings -->
            <dependency>
                <groupId>com.cmcc</groupId>
                <artifactId>myshop-commons-dubbo</artifactId>
                <version>${project.parent.version}</version>
            </dependency>
            <dependency>
                <groupId>com.cmcc</groupId>
                <artifactId>myshop-commons-mapper</artifactId>
                <version>${project.parent.version}</version>
            </dependency>
            <dependency>
                <groupId>com.cmcc</groupId>
                <artifactId>myshop-service-user-api</artifactId>
                <version>${project.parent.version}</version>
            </dependency>
        </dependencies>
        
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <configuration>
                        <mainClass>com.cmcc.myshop.service.user.provider.MyShopServiceUserProviderApplication</mainClass>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </project>
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
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
# Application
    package com.cmcc.myshop.service.user.provider;
    
    import com.alibaba.dubbo.container.Main;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.hystrix.EnableHystrix;
    import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
    import org.springframework.transaction.annotation.EnableTransactionManagement;
    import tk.mybatis.spring.annotation.MapperScan;
    
    @EnableHystrix
    @EnableHystrixDashboard
    @SpringBootApplication(scanBasePackages = "com.cmcc.myshop")
    @EnableTransactionManagement
    @MapperScan(basePackages = "com.cmcc.myshop.commons.mapper")
    public class MyShopServiceUserProviderApplication {
        public static void main(String[] args) {
            SpringApplication.run(MyShopServiceUserProviderApplication.class, args);
            Main.main(args);
        }
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# TbUserServiceImpl
    package com.cmcc.myshop.service.user.provider.api.impl;
    
    import com.alibaba.dubbo.config.annotation.Service;
    import com.cmcc.myshop.commons.domain.TbUser;
    import com.cmcc.myshop.commons.mapper.TbUserMapper;
    import com.cmcc.myshop.service.user.api.TbUserService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.transaction.annotation.Transactional;
    
    import java.util.List;
    
    @Service(version = "${services.versions.user.v1}")
    @Transactional(readOnly = true)
    public class TbUserServiceImpl implements TbUserService {
    
        @Autowired
        private TbUserMapper tbUserMapper;
    
        @Override
        public List<TbUser> selectAll() {
            return tbUserMapper.selectAll();
        }
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# application.yml
    # Spring boot application
    spring:
      application:
        name: myshop-service-user-provider
      datasource:
        druid:
          url: jdbc:mysql://192.168.10.131:3306/myshop?useUnicode=true&characterEncoding=utf-8&useSSL=false
          username: root
          password: 123456
          initial-size: 1
          min-idle: 1
          max-active: 20
          test-on-borrow: true
          driver-class-name: com.mysql.cj.jdbc.Driver
    server:
      port: 8501
    
    # MyBatis Config properties
    mybatis:
      type-aliases-package: com.cmcc.myshop.commons.domain
      mapper-locations: classpath:mapper/*.xml
    
    # Services Versions
    services:
      versions:
        user:
          v1: 1.0.0
    
    # Dubbo Config properties
    dubbo:
      ## Base packages to scan Dubbo Component:@com.alibaba.dubbo.config.annotation.Service
      scan:
        basePackages: com.cmcc.myshop.service.user.provider.api.impl
      ## ApplicationConfig Bean
      application:
        id: myshop-service-user-provider
        name: myshop-service-user-provider
        qos-port: 22222
        qos-enable: true
      ## ProtocolConfig Bean
      protocol:
        id: dubbo
        name: dubbo
        port: 20881
        status: server
        serialization: kryo
      ## RegistryConfig Bean
      registry:
        id: zookeeper
        address: zookeeper://192.168.10.131:2181?backup=192.168.10.131:2182,192.168.10.131:2183
    
    # Enables Dubbo All Endpoints
    management:
      endpoint:
        dubbo:
          enabled: true
        dubbo-shutdown:
          enabled: true
        dubbo-configs:
          enabled: true
        dubbo-services:
          enabled: true
        dubbo-references:
          enabled: true
        dubbo-properties:
          enabled: true
      # Dubbo Health
      health:
        dubbo:
          status:
            ## StatusChecker Name defaults (default : "memory", "load" )
            defaults: memory
            ## StatusChecker Name extras (default : empty )
            extras: load,threadpool
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
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
# 创建用户管理服务消费者
# 补充说明
生成的领域模型还需要实现序列化接口,并将 @Table 注解中 myshop.. 部分去掉,如:
    @Table(name = "tb_user")
1
# 创建用户管理服务消费者项目
创建一个名为 myshop-service-user-consumer 项目
# POM
    <?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>
    
        <parent>
            <groupId>com.cmcc</groupId>
            <artifactId>myshop-dependencies</artifactId>
            <version>1.0.0-SNAPSHOT</version>
            <relativePath>../myshop-dependencies/pom.xml</relativePath>
        </parent>
    
        <artifactId>myshop-service-user-consumer</artifactId>
        <packaging>jar</packaging>
    
        <url>http://www.cmcc.com</url>
        <inceptionYear>2018-Now</inceptionYear>
    
        <dependencies>
            <!-- Spring Boot Starter Settings -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
    
            <!-- Projects Settings -->
            <dependency>
                <groupId>com.cmcc</groupId>
                <artifactId>myshop-commons-dubbo</artifactId>
                <version>${project.parent.version}</version>
            </dependency>
            <dependency>
                <groupId>com.cmcc</groupId>
                <artifactId>myshop-static-backend</artifactId>
                <version>${project.parent.version}</version>
            </dependency>
            <dependency>
                <groupId>com.cmcc</groupId>
                <artifactId>myshop-service-user-api</artifactId>
                <version>${project.parent.version}</version>
            </dependency>
        </dependencies>
        
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <configuration>
                        <mainClass>com.cmcc.myshop.service.user.consumer.MyShopServiceUserConsumerApplication</mainClass>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </project>
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
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
# Application
    package com.cmcc.myshop.service.user.consumer;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.hystrix.EnableHystrix;
    import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
    
    @EnableHystrix
    @EnableHystrixDashboard
    @SpringBootApplication(scanBasePackages = "com.cmcc.myshop")
    public class MyShopServiceUserConsumerApplication {
        public static void main(String[] args) {
            SpringApplication.run(MyShopServiceUserConsumerApplication.class, args);
        }
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# TbUserController
    package com.cmcc.myshop.service.user.consumer.controller;
    
    import com.alibaba.dubbo.config.annotation.Reference;
    import com.cmcc.myshop.commons.domain.TbUser;
    import com.cmcc.myshop.service.user.api.TbUserService;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    
    import java.util.List;
    
    @Controller
    @RequestMapping(value = "user")
    public class TbUserController {
    
        @Reference(version = "${services.versions.user.v1}")
        private TbUserService tbUserService;
    
        @RequestMapping(value = "list", method = RequestMethod.GET)
        public String list(Model model) {
            List<TbUser> tbUsers = tbUserService.selectAll();
            model.addAttribute("tbUsers", tbUsers);
            return "user/list";
        }
    }
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
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
# list.html
    <!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-4.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <div th:each="tbUser : ${tbUsers}">
            <div th:text="${tbUser.username}"></div>
        </div>
    </body>
    </html>
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# application.yml
    # Spring boot application
    spring:
      application:
        name: myshop-service-user-consumer
      thymeleaf:
        cache: false # 开发时关闭缓存,不然没法看到实时页面
        mode: LEGACYHTML5 # 用非严格的 HTML
        encoding: UTF-8
        servlet:
          content-type: text/html
    server:
      port: 8601
    
    # Services Versions
    services:
      versions:
        user:
          v1: 1.0.0
    
    # Dubbo Config properties
    dubbo:
      scan:
        basePackages: com.cmcc.myshop.service.user.consumer.controller
      ## ApplicationConfig Bean
      application:
        id: myshop-service-user-consumer
        name: myshop-service-user-consumer
      ## ProtocolConfig Bean
      protocol:
        id: dubbo
        name: dubbo
        serialization: kryo
      ## RegistryConfig Bean
      registry:
        id: zookeeper
        address: zookeeper://192.168.10.131:2181?backup=192.168.10.131:2182,192.168.10.131:2183
    
    # Dubbo Endpoint (default status is disable)
    endpoints:
      dubbo:
        enabled: true
    
    management:
      server:
        port: 8701
      # Dubbo Health
      health:
        dubbo:
          status:
            ## StatusChecker Name defaults (default : "memory", "load" )
            defaults: memory
      # Enables Dubbo All Endpoints
      endpoint:
        dubbo:
          enabled: true
        dubbo-shutdown:
          enabled: true
        dubbo-configs:
          enabled: true
        dubbo-services:
          enabled: true
        dubbo-references:
          enabled: true
        dubbo-properties:
          enabled: true
      endpoints:
        web:
          exposure:
            include: "*"
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
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
