您所在的位置:主页 > JAVA技术 >

Spring Boot开发MongoDB应用实践

时间:2018-05-07 10:43来源:未知 作者:os 点击:

Spring Boot开发MongoDB应用实践

本文继续上一篇定时任务中提到的邮件服务,简单讲解Spring Boot中如何使用MongoDB进行应用开发。

上文中提到的这个简易邮件系统大致设计思路如下:

1、发送邮件支持同步和异步发送两种

2、邮件使用MongDB进行持久化保存

3、异步发送,直接将邮件批量保存在MongoDB中,然后通过后台定时任务发送

4、同步发送,先调用Spring的发送邮件功能,接着将邮件批量保存至MongDB

5、不论同步还是异步,邮件发送失败,定时任务可配置为进行N次重试

一、MongoDB

MongoDB现在已经是应用比较广泛的文档型NoSQL产品,有不少公司都拿MongoDB来开发日志系统。随着MongoDB的不断迭代更新,据说最新版已经支持ACID和事务了。不过鉴于历史上MongoDB应用的一些问题,以及考虑到数据持久化和运维的要求,核心业务系统存储的技术选型要非常慎重。

1、什么是MongoDB

MongoDB是由C++语言编写的一个基于分布式文件存储的开源数据库系统。MongoDB将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象(也就是BSON,10gen开发的一个数据格式),字段值可以包含其他文档,数组及文档数组。主要优点可以概括如下:

(1)、SchemaLess,结构灵活,表结构更改非常自由,不用每次修改的时候都付出代价(想想RDBMS修改表结构要注意什么),适合业务快速迭代表结构非常不确定的场景,而且json和大多数的语言有天然的契合,还支持数组,嵌套文档等数据类型

(2)、自带高可用,自动主从切换(副本集)

(3)、自带水平分片(分片),内置了路由,配置管理,应用只要连接路由,对应用来说是透明的

2、添加依赖

 mongodb

3、添加配置

配置MongoDB连接串:

spring.data.mongodb.uri=mongodb://name:pass@ip:port/database?maxPoolSize=256

如果使用多台MongoDB数据库服务器,参考配置如下:

spring.data.mongodb.uri=mongodb://user:pwd@ip1:port1,ip2:port2/database?maxPoolSize=512

连接串的一般配置,可以参考:猛击这里

环境搭建好了,下面就是着手编码了。

通常我们会有各种语言的MongoDB客户端,直接引入调用API。在Spring Boot中,直接使用MongoTemplate即可。

4、定义DAO接口

 MailDao

5、实现DAO

 MailDaoImpl

6、数据访问对象实体

实体MailDO这里只列举了我在实际开发应用中经常用到的字段,这个实体抽象如下:

 MailDO

请大家注意实体上的注解,@Document(collection = "mailinfo")将会在文档数据库中创建一个mailinfo的表,@Id表示指定该字段为主键, @Field("mail_no")表面实体字段mailNo存在MongoDB中的字段名称为mail_no。

根据MongoDB官方文档介绍,如果在插入数据时没有指定主键,MongoDB会自动给插入行自动加上一个主键_id,MongoDB客户端把这个id类型称为ObjectId,看上去就是一个UUID。我们可以通过注解自己设置主键类型,但是根据实践,_id名称是无法改变的。@Id和 @Field("mail_id")表面看上去是我想创建一个mail_id为主键的表,但是实际主键只有_id而没有mail_id。当然,主键的类型不一定非要是UUID,可以是你自己根据业务生成的唯一流水号等等。

同时,还需要注意attatchment_urls这个字段,看上去数组也可以直接存进MongoDB中,毕竟SchemaLess曾经是MongoDB宣传过的比RDBMS最明显的优势之一。

7、邮件接口

 MailApiServiceImpl

到这里,MongoDB的主要存储和查询就搞定了。

二、邮件

在上面的邮件接口API实现中,我们定义了邮件发送服务MailService,在Spring Boot中发送邮件也非常简单。

1、邮件配置

 mailsetting

2、简单邮件

通过Spring的JavaMailSender对象,可以轻松实现邮件发送。

发送简单邮件代码:

 sendSimpleMail

3、HTML邮件

同理,我们经常要发送带格式的HTML邮件,发送代码可以参考如下:

 sendHtmlMail

邮件附件的处理,本文仅仅是简单示例,实际情况是通常都免不了要上传分布式文件系统,如FastDFS等,有空我会继续写一下Spring Boot和分布式文件系统的应用实践。

还记得上一篇文章里的定时任务发送邮件吗?贴一下MailServiceImpl下的补偿发送实现:

 自动查询并发送邮件

这里贴出来的示例代码是线性的一个一个发送邮件,我们完全可以改造成多线程的并行处理方式来提升邮件发送处理能力。

三、MongoDB注意事项

1、常见参数设置问题

MongoDB的默认最大连接数是100,不同的客户端有不同的实现,对于读多写多的应用,最大连接数可能成为瓶颈。

不过设置最大连接数也要注意内存开销,合理配置连接池maxPoolSize。

2、MongoDB事务性

早期版本的MongoDB已经支持行级的事务,支持简单的行级操作原子性,单行的操作要么全部成功,要么全部失败。

MongoDB的WiredTiger引擎本身支持事务,官方在最新版本中,号称完全支持ACID和事务。

3、MongoDB如何提升查询速度

可以选取合适字段创建索引,和RDBMS一样,MongoDB的索引也有很多种,如:单字段索引、复合索引、多Key索引、哈希索引等。

在常见的查询字段上合理添加索引,或者定期归档数据,减少查询数据量,这些手段都可以有效提高查询速度。

还有一种非常常见的手段就是Sharding,也就是数据库分片技术。当数据量比较大的时候,我们需要把数据分片运行在不同的机器中,以降低CPU、内存和IO的压力。MongoDB分片技术类似MySQL的水平切分和垂直切分,主要由两种方式做Sharding:垂直扩展和横向切分。垂直扩展的方式就是进行集群扩展,添加更多的CPU,内存,磁盘空间等。横向切分则是通过数据分片的方式,通过集群统一提供服务。

4、MongoDB的高可用方案

真正的高可用系统,很少有单实例的应用形态存在。

MongoDB支持主从方式、双机双工方式(互备互援)和集群工作方式(多服务器互备方式),减少单点出故障的可能。