在本系列的几个月前,我向您介绍了Amazon的Elastic Beanstalk,这是一种用于Java应用程序开发的平台即服务(PaaS)。 正如我所展示的,Beanstalk具有非常多的用途,它允许开发人员使用几乎任何工具组合来完成工作。 除了使用Play进行快速的Web开发外,我还可以使用另一个PaaS MongoHQ来管理我的MongoDB实例。 结合这两个PaaS基础架构意味着大部分应用程序维护工作都由我完成,因此我可以专注于构建出色的云到移动应用程序。
MongoHQ PaaS对于该项目非常有效,但是如果我更喜欢将数据存储在传统的RDBMS中怎么办? 毕竟,大多数Java开发人员更愿意对关系数据库进行编码。 确实,并非像每个NoSQL数据存储库所要求的那样,并非每个项目都能负担得起ACID。
本月,我将带您开始使用Amazon Relational Database Service(RDS),这是Amazon Web Services系列的又一个出色的通用功能。 使用Amazon RDS与运行MongoHQ托管的MongoDB实例一样容易。 尽管它会带来一些有趣的扩展问题,但它的关系性一点也不难管理。 我们只需要花几个周期预先定义一个模式,然后我们就可以开始了。
亚马逊RDS
Amazon Relational Database Service是一种PaaS,可为应用程序开发提供按需的,基于云的可扩展MySQL实例。 但是,如果RDS 只是运行在云中的MySQL的一个实例,我将不在这里写。 毕竟,我早在2009年就解释了如何利用运行MySQL的Amazon EC2映像(请参阅参考资料 )。
使RDS值得一看的是,它是由Amazon管理和运营的PaaS,提供了Elastic Beanstalk中提供的许多相同的服务和灵活性。 Amazon提供备份,复制甚至补丁。 而且,RDS具有完全可扩展性-您只需单击几下即可增加应用程序的存储容量。 Amazon还允许您跨可用性区域复制RDS,因此,如果一个区域出现故障或某个区域中安排了维护时段,您仍然可以提供数据。 您甚至可以置备数据库的只读实例,以确保提高对大量应用程序或期间的读取速度。
已经为与MySQL兼容而构建的应用程序可以立即利用RDS,因此,当数据库处于云中时,与您的应用程序有关的其他任何事情都无需更改。 最后,与AWS的其他所有功能一样,RDS是按需付费的模型。 硬件或许可证没有前期费用。 使用它们时,您需要为容量,存储和带宽付费。
设置和配置RDS
通过AWS,您可以通过命令行或AWS管理控制台配置各种服务。 我倾向于使用控制台,因为它指定了可用于RDS各个方面的选项。 因此,我们将从在AWS管理控制台中选择RDS选项卡,然后单击启动实例按钮开始。
在屏幕上,您应该看到一个对话框,可让您指定MySQL数据库实例的详细信息,例如机器大小,MySQL版本以及为该数据库实例分配的存储量。 请注意,AWS可以选择将数据库部署到多个可用性区域。 这样做实际上会创建一个群集,这样,如果某个特定区域出现故障,其他区域将确保覆盖。
如图1所示,您需要指定数据库的架构名称,admin用户和密码:
图1.设置RDS实例
在单击Continue之后 ,将显示另一个对话框,该对话框在高层配置数据库-从其名称开始,该名称在其JDBC URL中起作用。 您还可以更改MySQL将侦听的端口,并选择数据库将驻留的可用性区域,如图2所示:
图2.配置RDS实例
接下来是与您如何使AWS备份数据以及何时可以安排维护有关的管理选项,如图3所示:
图3. RDS管理选项
单击继续并查看配置后,启动RDS实例。 这可能需要几分钟才能完成,因此现在是喝咖啡或赶上Twitter的好时机。 一旦RDS启动并运行,一切将快速发展!
RDS安全性
实例上线后,您需要再做一件事,然后使用您喜欢SQL管理工具访问它。 如果您以前使用过AWS,那么默认情况下某些事情就被锁定就不足为奇了,因此您需要显式允许访问。
RDS的安全性约束非常强大,允许您指定可以与RDS进行通信的单个IP或IP范围; 但是,出于本文的目的,我将使事情变得简单,并允许任何IP与我的实例通信。 为此,请进入“ RDS DB安全组”窗格,然后将CIDR / IP约束编辑为0.0.0.0/0,这基本上意味着允许所有IP。 该步骤如图4所示:
图4. RDS安全设置
完成此步骤后,重新启动RDS实例。 (右键单击AWS管理仪表板中的实例,您可以看到重新启动的选项。)
如果选择正在运行的RDS实例,则将看到“描述”窗格(如图5所示),其中提供了一些重要的细节。 现在,最受关注的是端点 ,这是您用于连接到MySQL实例的URL。
图5. RDS仪表板
![AWS控制台上的RDS仪表板的屏幕快照。](https://i-blog.csdnimg.cn/blog_migrate/879f2502330156a88d54e9209d06fc3c.png)
现在,您可以使用自己喜欢的数据库管理工具(如果愿意,也可以使用命令行)并将其指向RDS实例。 我将使用Sequel Pro,它像大多数面向GUI的工具一样,提供了一个漂亮的界面来查看表和数据,并提供了一个查询控制台。 要进行连接,您需要知道数据库的用户名,密码和端点URL。
Magnus,RDBMS样式
如果你读过我介绍了Amazon的Elastic魔豆(见相关信息 ),你熟悉马格努斯,则该项目建立的云到移动应用程序我。 对于Magnus,我在MongoDB中创建了两个集合: Account
和Location
。 (不过,请注意,我可以很容易地将一个名为Account
集合包含在每个文档中包含Location
的嵌入式文档。)拥有两个集合使我能够保留帐户位置,在我的应用场景中,该位置将来自世界各地的移动设备。
我将模拟相同的关系来演示Amazon RDS,但是这次我将以老式的方式进行处理。 像Magnus这样的应用程序,其位置更新频繁分布于全球,可以从切换到RDS中受益,特别是考虑到RDS可以在众多可用区域中进行群集。 记住,在RDBMS领域中还有其他技术,例如分片,可以将数据分解为逻辑分区。 因此,您也可以按地理位置分摊帐户和位置。 无论如何,群集,复制和分片各有利弊,在着手制定单独策略之前,应权衡这些优点和缺点。
为了将Magnus引入SQL领域,我需要首先定义我的关系表,(可预测地)我将其称为account
和location
。 如清单1所示:
清单1.一个帐户表
CREATE TABLE `account` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(30) DEFAULT NULL,
PRIMARY KEY (`id`)
)
在清单2的location
表中,我提供了一个外键给account
。 这样,我在account
s和它们的各个location
s之间建立了一对多关系。
清单2.位置表
CREATE TABLE `location` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`account_id` int(11) DEFAULT NULL,
`latitude` double DEFAULT NULL,
`longitude` double DEFAULT NULL,
`date_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`name` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `account_id` (`account_id`),
FOREIGN KEY (`account_id`) REFERENCES `account` (`id`)
)
定义表后,我需要在RDS实例中创建它们。 在RDS实例中创建表就像在本地计算机上运行的MySQL实例中创建表一样。 只需打开终端或将您喜欢的GUI指向RDS端点并创建表。 就这么简单。
配置播放
Play Web应用程序框架(请参阅参考资料 )在Amazon RDS中和在Elastic Beanstalk中一样工作良好,因此我将再次使用它来开发我的应用程序。 Play使得切换各种数据存储区非常容易,并且开箱即用地支持JPA。 从MongoHQ实施切换到使用Amazon RDS的实施,只需对我的模型进行一些更改。 一方面,Play的内置JPA支持意味着我需要更改Magnus的application.conf
文件,并将其指向我的RDS实例,如清单3所示:
清单3.位置表
db.url=jdbc:mysql://magnus.cp3pl5vineyp.us-east-1.rds.amazonaws.com/magnus_locations
db.driver=com.mysql.jdbc.Driver
db.user=admin
db.pass=g3tf0kl
这里没什么特别的-清单3是100%的JDBC!
建模关系
与几乎所有RDBMS ORM库一样,我将使用顶级Java对象以一对一的关系对表进行建模:一种Account
类型和一种Location
类型。 我的Location
将链接回Account
。
从Play的Model类型扩展后,我得到了一些内置的免费赠品。 一方面,我得到了类似finder的方法以及典型的CRUD方法save
和delete
。
我的Account
类利用两个JPA注释。 需要清单4中所示的Table
注释指向我重命名的(小写的) account
表。
清单4.帐户类型
package models;
import play.db.jpa.Model;
import javax.persistence.Entity;
import javax.persistence.Table;
@Entity
@Table(name = "account") //required otherwise table is Account
public class Account extends Model {
public String name;
}
清单5中接下来的My Location
POJO涉及更多。 我需要为其添加两个附加注释,以在Location
和Account
之间创建多对一关系。
清单5.用JPA定义的Location类
package models;
import play.db.jpa.Model;
import javax.persistence.*;
import java.math.BigDecimal;
import java.sql.Timestamp;
@Entity
@Table(name = "location")
public class Location extends Model {
public BigDecimal latitude;
public BigDecimal longitude;
public String name;
@Column(name = "date_time")
public Timestamp timestamp;
@ManyToOne
@JoinColumn(name="account_id", nullable = false)
public Account account;
}
最后,在清单6中,我更新了我的Application
控制器的saveLocation
方法。 (请记住,在以前的Magnus实现中,我将所有HTTP PUT
路由到/location/
到此方法。) saveLocation
只是创建一个新的Location
对象(并因此创建一条对应的记录),并将该Location
实例链接到现有Account
。 因为我之前扩展了Play的Model
对象,所以我也得到了一个方便的findById
方法。
清单6.使用RDS的基于位置的更新
public static void saveLocation(String id, JsonObject body) throws Exception {
String eventname = body.getAsJsonPrimitive("name").getAsString();
double latitude = body.getAsJsonPrimitive("latitude").getAsDouble();
double longitude = body.getAsJsonPrimitive("longitude").getAsDouble();
Location loc = new Location();
loc.longitude = new BigDecimal(longitude);
loc.latitude = new BigDecimal(latitude);
loc.name = eventname;
loc.account = Account.findById(new Long(id));
loc.save();
renderJSON(getSuccessMessage());
}
使用RESTClient进行测试
我可以使用RESTClient来查看我更新的位置服务是否正常运行。 就像处理Magnus一样,我将创建一些JSON文档并将其发送。
图6.使用RESTClient进行测试
当我的方法成功保存新的Location
记录时,将发送回JSON响应以指示成功。 因为方便的图形用户界面(GUI)允许我查看RDBMS中的数据,所以只检查location
表,您知道什么? 我看到新的Magnus记录通过RDS坐在云中!
图7.哦,您去的地方!
结论
PaaS是希望快速开发和部署Web应用程序的软件开发团队的朋友。 在本文中,我介绍了Amazon RDS,这是一种PaaS解决方案,它将关系数据库(在这种情况下为MySQL,尽管RDS也支持Oracle数据库)都存储在云中。 Amazon RDS超级易于配置,并且与您多年来可能构建的各种RDBMS系统没有什么不同。 重要的区别在于,Amazon为您处理维护。
翻译自: https://www.ibm.com/developerworks/java/library/j-javadev2-19/index.html