领先一步
VMware 提供培训和认证,助您加速进步。
了解更多一个稳固的持续集成(CI)结构带来一个有趣的副作用,那就是当一切运行可靠时,新的问题就会开始出现。在Spring的CI系统顺利运行后不久,我们在static.springframework.org上偶尔出现的空间和带宽问题变得更加突出。Colin Sampaleanu早些时候研究了如何缓解这些问题,并决定使用Amazon S3。
Amazon S3 是 Amazon Web Services 旗下的产品,提供极其廉价在线文件存储服务。什么叫“极其廉价”?嗯,从网站上看,1GB*月存储费用为 0.15 美元,1GB 流量费用为 0.20 美元。再加上一个高带宽的透明镜像服务,S3 就非常适合存储我们的夜间快照了。题外话,亚马逊内部实际上也使用完全相同的基础设施,所以你知道有一个管理员团队在保证他们“五个九”的服务承诺。
为了使用 S3 来存储我们的夜间快照,我们首先必须替换掉之前使用 scp 的旧快照上传程序。环顾四周,我没有找到任何可以上传到 S3 的 ANT 任务,于是我决定自己创建一个。我的目标配置非常简单
<aws:s3 accessKey="${s3.accessKey}" secretKey="${s3.secretKey}">
<upload bucketName="static.springframework.org"
file="${target.release.dir}/${release-with-dependencies.zip}"
toFile="SPR/spring-framework-${spring-version}-with-dependencies-${tstamp}-${build.number}.zip"
publicRead="true"/>
<upload bucketName="static.springframework.org"
file="${target.release.dir}/${release.zip}"
toFile="SPR/spring-framework-${spring-version}-${tstamp}-${build.number}.zip"
publicRead="true"/>
</aws:s3>
我希望能够定义一个单一的 S3 会话,由我们的访问密钥和秘密密钥(S3 的加密登录凭据)控制,并在该定义中执行多次上传。每次上传都进入一个“存储桶”(bucket),这是 S3 提供的唯一粒度级别。
S3 本身通常被用作 RESTful 服务,因此很容易与之交互。对于这项工作,我使用了一个名为 jets3t(发音为 jet-set)的库。对于任何使用 Java 的 S3 用户来说,这都是使用 S3 的首选方式(据我所知,这是亚马逊唯一认可的库)。Jets3t 使用与我的 XML 定义类似的范例(或者是我用了他们的?),即你创建一个服务器引用,并重复使用该引用来执行多个操作。在 ANT 任务中,我创建一组基于访问密钥和秘密密钥的凭据,并将它们绑定到服务引用中。
AWSCredentials credentials = new AWSCredentials(accessKey, secretKey);
S3Service service = new RestS3Service(credentials);
for (Upload upload : uploads) {
upload.upload(service);
}
正如你所见,我已经将上传操作进行了模块化,这样将来如果我需要扩展 s3 任务来执行其他功能(下载、设置权限等),我都可以做到。`Upload` 对象负责繁重的工作。它会根据 `bucketName` 创建一个指向存储桶的引用,根据 `toFile` 值创建一个指向新对象的引用,然后通过 HTTP 上传文件的内容。
private S3Bucket getBucket() {
return new S3Bucket(bucketName);
}
private S3Object getObject() {
S3Object object = new S3Object(toFile);
if (publicRead) {
object.setAcl(AccessControlList.REST_CANNED_PUBLIC_READ);
}
object.setDataInputFile(file);
object.setContentLength(file.length());
return object;
}
S3Bucket bucket = getBucket();
S3Object object = getObject();
service.putObject(bucket, object);
在这项任务的实际代码中,我添加了一些漂亮的输出,以便你能看到文件上传的速度以及上传速度是多少。
upload-s3:
[aws:s3] Uploading /opt/j2ee/domains/springframework.org/build/bamboo-home/xml-data/build-dir/
SPR-NIGHTLY/spring/target/release/spring-framework-2.0.5-with-dependencies.zip (65132641B)
to bucket static.springframework.org
[aws:s3] Transfer Time: 34.0s - Transfer Rate: 1915665.9B/s
[aws:s3] Uploading /opt/j2ee/domains/springframework.org/build/bamboo-home/xml-data/build-dir/
SPR-NIGHTLY/spring/target/release/spring-framework-2.0.5.zip (10752085B)
to bucket static.springframework.org
[aws:s3] Transfer Time: 6.0s - Transfer Rate: 1792014.1B/s
这项工作对我们非常成功,以至于我们已经将其扩展到了 Spring 项目组合中所有的基于 ANT 的构建。Spring Framework、Spring LDAP、Spring Web Flow 和 Spring Modules 现在都将夜间快照上传到这个 S3 存储库,我还在待办事项列表中,准备为 Maven 项目也做一些改进。这样做的好处是,我们在过去两个月里释放了超过 30GB 的空间,并大幅减少了带宽使用,而成本仅约为 4.00 美元。
由于我必须编写一些代码来实现这一切,所以我将其放入了我们的源代码控制区域。我还将其发布到了我们的内部私有 Maven 仓库,该仓库与公共 Maven 仓库进行了镜像。如果你有兴趣查看代码,可以看一下 SVN 仓库。如果你想使用 ANT 任务,你可以通过 Maven 获取它,其 `groupId` 为 `org.springframework.aws`,`artifactId` 为 `spring-aws-ant`。请注意,这是完全不受支持且未记录的代码! 它所做的事情非常有限,目前没有计划以任何方式对其进行改进或记录。如果我有一些空闲时间,情况可能会改变,但不要指望它:)
看起来我的航班现在正在降落,所以我要借此机会结束。请留意后续的帖子,其中将描述我们如何构建快照下载页面,以便你可以直接从 S3 获取快照。