我在自己家里用近10台树莓派搭建了一个集群,平时在这个集群上学习一些技术知识。虽然这些机器性能不太好,但用起来比虚拟机和Docker要方便一些,应为虚拟机要装在自己电脑上,每次都要重启。

这个源代码是基于这个树莓派集群搭建的微服务的框架,采用Spring Cloud框架,包括了服务网关(Spring Cloud Gateway),服务器注册与发现(Spring Cloud Eureka),配置中心(Spring Cloud Config),服务调用(Spring Cloud OpenFeign),Redis数据库集群,MySQL数据库集群,RabbitMQ消息队列集群。

希望对想学习Spring Cloud微服务的同学有所帮助。

业务场景说明

整个系统模拟了一个十分简单的业务场景:会员购买产品生成订单。

业务提供三个微服务,产品服务、会员服务、订单服务。产品提供了产品新增、更新、列表、详情四个接口;会员提供了创建、详情、会员订单查询三个接口;订单提供了创建、支付、取消三个接口。

数据库采用三个独立的库:会员库、产品库、订单库。每个微服务访问自己的数据库,彼此独立。创建订单的时候,订单微服务会通过Rest调用产品和会员的接口,以检查产品和会员是否存在。

查询产品详情的时候,会使用Redis缓存。

订单支付了之后,会向消息队列发送一条消息,可以模拟消费端收到消息后发送邮件或短信的动作(暂未实现)。

当然,这只是做了一个十分简单的模拟场景,显示中的情况比上述场景要复杂得多。

产品微服务

数据库定义

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for prct_product
-- ----------------------------
DROP TABLE IF EXISTS `prct_product`;
CREATE TABLE `prct_product`  (
  `prct_id` int UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '商品ID',
  `prct_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '商品名称',
  `prct_desc` varchar(1023) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '商品描述',
  `prct_price` decimal(10, 2) NOT NULL COMMENT '产品单价',
  `stock` int NOT NULL COMMENT '库存',
  `created_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `created_by` varchar(31) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '创建人',
  `updated_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `updated_by` varchar(31) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '更新人',
  PRIMARY KEY (`prct_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 36 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;

SET FOREIGN_KEY_CHECKS = 1;

创建产品

1
POST http://xx.xx.xx.xx:port/product/
  • 示例数据:
1
2
3
4
5
6
7
8
{
    "prctName": "iphone 12",
    "prctDesc": "<p class='comment-con'>描述信息</p>",
    "prctPrice": 7999,
    "stock": 9999,
    "created_by": "liwenbo",
    "updated_by": "liwenbo"
}

查询产品

1
GET http://liwenbo.net:59000/product?pageNo=1

其中pageNo是分页的参数。

产品详情

1
GET http://liwenbo.net:59000/product/{id}

其中{id}为产品的id。

更新产品

1
PUT http://liwenbo.net:59000/product/{id}
  • 示例数据
1
2
3
4
5
6
7
8
{
    "prctId": 4,
    "prctName": "iphone 12",
    "prctDesc": "<p class='comment-con'>描述信息</p>",
    "prctPrice": 7999,
    "stock": 9999,
    "updated_by": "liwenbo"
}

会员微服务

数据库定义

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for mbr_member
-- ----------------------------
DROP TABLE IF EXISTS `mbr_member`;
CREATE TABLE `mbr_member`  (
  `mbr_id` int UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '会员ID',
  `mbr_account` char(31) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '会员账号',
  `mbr_mobile` char(31) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '手机号',
  `mbr_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '姓名',
  `mbr_gender` tinyint NOT NULL COMMENT '性`',
  `balance` decimal(10, 2) NOT NULL COMMENT '账户余额',
  `last_login_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '最后登录时间',
  `last_login_ip` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '最后登录IP',
  `created_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
  PRIMARY KEY (`mbr_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;

SET FOREIGN_KEY_CHECKS = 1;

创建会员

1
POST http://liwenbo.net:59000/member/

示例数据

1
2
3
4
5
6
{
    "mbrAccount":"liwenbo",
    "mbrMobile": "18502788888",
    "mbrName": "Liwenbo",
    "mbrGender": 1
}

会员详情

1
GET /member/{id}

返回示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
{
    "timestamp": 1631361994718,
    "message": "ok",
    "code": 200,
    "server": "127.0.1.1",
    "data": {
        "mbrId": 4,
        "mbrAccount": "user_1631328296",
        "mbrMobile": "804-576-4600",
        "mbrName": "Israel Stamm xx",
        "mbrGender": 1,
        "balance": 0.0
    }
}

会员订单

1
GET /member/3/orders/

返回示例:

 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
{
    "timestamp": 1631362022699,
    "message": "ok",
    "code": 200,
    "server": "127.0.1.1",
    "data": [
        {
            "ordId": 24,
            "ordCode": "1631347760954",
            "mbrId": 3,
            "prctId": 4,
            "prctName": "iphone 402",
            "ordQuantity": 1,
            "ordPrice": 7999.0,
            "ordStatus": "PAYED"
        },
        {
            "ordId": 25,
            "ordCode": "1631347767405",
            "mbrId": 3,
            "prctId": 4,
            "prctName": "iphone 402",
            "ordQuantity": 1,
            "ordPrice": 7999.0,
            "ordStatus": "NEW"
        }
    ]
}

更新会员

1
PUT /member/4

示例数据:

1
2
3
4
5
6
7
{
    "mbrId": 4,
    "mbrAccount": "user_1631328296",
    "mbrMobile": "{{$randomPhoneNumber}}",
    "mbrName": "Israel Stamm xx",
    "mbrGender": 1
}

订单服务

数据库定义

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for ord_order
-- ----------------------------
DROP TABLE IF EXISTS `ord_order`;
CREATE TABLE `ord_order`  (
  `ord_id` int UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '订单ID',
  `ord_code` char(31) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '订单编码,形如202106051147001',
  `mbr_id` int NOT NULL COMMENT '会员ID',
  `prct_id` int NOT NULL COMMENT '产品ID',
  `prct_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '[冗余] 产品名称',
  `ord_quantity` int NOT NULL COMMENT '购买数量',
  `ord_price` decimal(10, 2) NOT NULL COMMENT '订单总价格',
  `created_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '订单创建时间',
  `ord_status` tinyint NOT NULL COMMENT '订单状态, 0 - 未支付, 1 - 已支付,  2 - 已取消',
  PRIMARY KEY (`ord_id`) USING BTREE,
  UNIQUE INDEX `ord_code`(`ord_code`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 26 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;

SET FOREIGN_KEY_CHECKS = 1;

创建订单

1
POST /order/

示例数据:

1
2
3
4
5
6
7
{
    "mbrId": 3,
    "prctId": 4,
    "prctName": "小米11",
    "ordQuantity": 1,
    "ordPrice": 3799
}

订单支付

1
GET /order/pay/?orderCode={code}

{code} 为订单的编号(不是id)

订单取消

1
GET /order/cancel/?orderCode={code}

{code} 为订单的编号(不是id)