# **题目: 基于MongoDB集群和SpringBoot的物流订单系统**
# 1 实验需求和分析
## MongoDB
MongoDB(来自于英文单词“Humongous”,中文含义为“庞大”)是可以应用于各种规模的企业、各个行业以及各类应用程序的开源数据库。是我所在的实验室中首选的数据库。

图1.1 MongoDB图标
MongoDB其本身是10gen公司开发的一款以高性能和可扩展性为特征的开源软件,它是NoSQL中面向文档的数据库。其介于关系数据库和非关系数据库之间,也是非关系数据库当中功能最丰富,最像关系数据库的。其支持的数据结构非常松散,是类似JSON的BSON格式,因此可以存储比较复杂的数据类型。
MongoDB最大的特点是他的查询语言非常强大,其语法类似于面向对象的查询语言,几乎可以实现类似关系数据库单的绝大部分功能,而且还支持对数据库建立索引。
### 1.1.1 MongoDB的优点
作为一个NoSQL的经典的数据库,其本身具有很多优点:
**1.无表结构:**
> 毫无疑问,MongoDB的最大特点就是无表结构(类似于字典结构)。
> 例如:{“Welcome”:Beijing},{“age”:25}
**2.容易扩展:**
> MongoDB在最初的设计的时候就考虑到了扩展的问题。它所采用的面向文档的数据模型使其可以自动在多台服务器之间分散数据。这样就可以不用考虑如何扩展,让开发者更加专注于编写应用,适应了当前数据量的飞增。
**3.丰富的功能:**
> MongoDB有一些真正独特的、好用的功能,而其他数据库不具备或不完全具备:
1. 索引:快速查询;
2. 存储JavaScript:直接存取JavaScript的函数和值;
3. 聚合:支持MapReduce等聚合工具;
4. 固定集合:集合大小有上限;
5. 文件存储:支持用一种容易使用的协议存储大型文件和元数据。
**4.性能卓越:**
> 性能卓越是MongoDB的主要目标,体现在很多设计上:使用MongoDB传输协议作为与服务器的主要交互方式;对文档动态填充,预分配数据文件,用空间换性能的稳定;动态查询优化会“记住”执行查询最高效的方式等。
**5.简便的管理:**
> MongoDB尽量让服务器自动配置来简化数据库管理。除了启动数据库服务器之外,基本没有什么必要的管理操作。如果主服务器挂掉,MongoDB会自动切换到备份服务器上。总之尽可能让服务器自动配置。
### 1.1.2 MongoDB的不足
其目前还不支持JOIN查询和事务处理。虽然这个是可以规避的。同时还需要注意的是,使用MongoDB创建和更新数据的时候,数据不会实时写入到硬盘里的。所以有可能会有数据丢失的情况。而且本身在保存数据的时候需要预留很大的空间,对硬盘的空间需求较高。
## SpringBoot
,由于Spring的发展、微服务的发展使得SpringBoot越来越流行,已经成为JavaWeb开发的主流框架。SpringBoot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式,SpringBoot在蓬勃发展的快速应用开发领域(rapid
application
development)成为领导者。简而言之,SpringBoot是当前web开发主流,其简化了Spring的配置让开发者能够更容易上手Web项目的开发。且MongdoDB能够快速与SpringBoot整合,在项目中能够快速便捷操作MongoDB;
## 案例分析
我们都知道MongoDB是一款非常出色的非关系型文档数据库,你肯定会想问MongoDB这么强,我们该怎么用或者有啥运用场景呢?MongoDB的应用场景非常多,无论是数据存储还是日志存储越来越多的公司在使用MongoDB,而我们今天也在SpringBoot基础上使用MongoDB实现一个简易版本的物流订单管理系统。在使用前,你自己的电脑上要有IDEA编译器来创建项目,还要拥有MongoDB数据库和Compass(MongoDB可视化数据库管理工具
我想,大部分人都应该有着购物的经历,当商品下单时就会出现一个物流单号,接下来几天内的物流信息会根据这个单号更新。然后接下来的几天可能会到达不同地点,进行更新,你可能会好奇这样一个功能是如何实现,本案例就通过SpringBoot+MongoDB实现一个简易版本的物流订单系统。
## 核心思路
一个订单数据是如何产生和更新的呢?首先一个订单数据由下单时产生,然后该订单经历各个物流点更新物流信息和订单状态,最后在用户取件之后订单状态更新后数据基本就不再更新了。
下单模块:我想大部分人看过寄快递下单流程或者自己下过单,核心就是一个表单页面填写寄件人姓名、地址、手机等信息和收件人姓名、地址、手机等信息。所以在这里具体实现也是填写寄件人和收件人信息储存。
物流模块
:一个订单下单后可能经历若干物流地点,最终才能到达目的地被签收。而就各个物流点来看,各个物流点的管理人员对该物流订单添加一些物流信息,例如到达地址、订单目前状态、联系方式等等。而本案例在添加物流信息的实现上也通过一个表单添加该订单的物流信息,通过物流订单的id进行联立。如果使用关系型数据库,就单订单物流信息存储可能至少需要使用两张表来实现,一张订单(order)信息表存储订单一些固定栏位信息,一张物流(Logistics)信息表储存动态的物流变化,通过订单id实现两张表的关联。

图1.2 数据库E-R图
物流表中的order_id外键引用order表中的id字段进行关联。在查询订单数据的时候需要关联查询。物流订单系统确实可以使用关系数据库去实现,但是数据量过大可能会有性能瓶颈需要优化,如果采用MongoDB不仅可以提高效率,还可以使得流程变得更加简单。
订单的特点是随着递送过程,订单数据需要随时更新路径。数据结构上需要可以灵活应对,这点非常符合MongoDB的document文档模型,并且MongoDB支持GIS功能,非常适用于MongoDB来支撑物流业务(这里简易版本就不使用该功能了)。而物流行业里订单比较独立,跨订单的操作很少,创建、更新(追加)的操作会较多,物流业务模型上与MongoDB非常的匹配。
# 2 MongoDB分布式数据库搭建
## 2.1 环境搭建
本次实验中使用的操作系统是macOS Catalina 10.15.7,使用多个终端模拟分布式集群。

图2.1 使用五个终端模拟分布式集群。左上角为Replica Set a,右上角为Replica Set
b,左下角为Replica Set c,右下角为Config Server,中间为Query Router。
## 2.2 安装数据库
### 2.2.1 MongoDB下载与安装
我们使用 curl 命令来下载安装:
\# 进入 /usr/local
cd /usr/local
\# 下载
sudo curl -O https://fastdl.mongodb.org/osx/mongodb-osx-ssl-x86_64-4.0.9.tgz
\# 解压
sudo tar -zxvf mongodb-osx-ssl-x86_64-4.0.9.tgz
\# 重命名为 mongodb 目录
sudo mv mongodb-osx-x86_64-4.0.9/ mongodb
安装完成后,我们可以把 MongoDB 的二进制命令文件目录(安装目录/bin)添加到 PATH
路径中:
export PATH=/usr/local/mongodb/bin:\$PATH
## 2.3 配置Replica Sets + Sharding
MongoDB采用了“Replica Sets+Sharding”的解决方案。
①**Shard**:使用Replica
Sets(复制集),确保每个数据节点都有备份、自动容错转移和自动恢复的能力;
②**Config**:使用3