【发布时间】:2014-08-17 08:12:51
【问题描述】:
我目前有一个 Elastic Beanstalk 实例运行部署到 Tomcat 的 Java 应用程序。我使用 Web 界面部署应用程序,但应用程序使用 web.xml 中引用的数据文件(Lucene 索引),我通过 ssh-ing 到 EC2 并从我的 S3 存储桶中获取数据文件,将其复制到底层 EC2 实例。
到目前为止一切顺利。
但是如果我将我的 EB 更改为可自动扩展的环境,以便它根据需要自动创建新实例,那么这些 EC2 实例将没有数据文件,我该如何处理。
- 我可以在每个 EC2 实例实际使用之前预先配置数据文件吗??
- 我可以有一个共享的 fs 供每个服务器引用吗(数据文件是只读的)?
* 更新 *
我认为我原则上已经得出了答案。我从本地机器上传我的应用程序,然后从亚马逊添加大数据文件。我需要做的是在我的数据处理 EC2 实例上构建我的战争,将数据文件添加到某处的战争中,然后将此战争放到 S3 上,然后当我创建我的 EB 时,我需要从 S3 存储桶加载 WAR。
所以只需要弄清楚数据文件在 War 中应该放在哪里以及如何通过 Maven 构建过程来创建。
* 更新 2 *
实际上并不清楚数据文件应该放在 WAR 文件中,我看不到将它们放在哪里,并且应用程序希望它们是真实文件,因此如果包含在 WAR 中并且 WAR 没有展开/解压缩(我不知道什么 EB) 应用程序无论如何都无法工作。
* 更新 3 *
我当然可以将数据放在 S3 中(实际上它可能会在那里开始)所以我想知道在服务器初始化时我是否可以获取 s3 数据并将其放在某个地方然后使用它? 请指导。
* 更新 4 *
所以使用 s3 的想法,我几乎可以让它工作,在 servlet init() 方法中,我得到压缩文件,将它保存到当前工作目录 (/usr/share/tomcat7/),然后解压缩它。问题是压缩文件是2.7GB,解压后的文件夹是5GB,EB使用的小实例提供8GB,其中使用了2GB。所以我有 6GB 足够的空间来存放未压缩的文件,但不要保存压缩文件然后解压缩,因为在解压缩过程中我需要 2.7 GB + 5 GB。
我将压缩版本加载到 S3,因为原始数据不是单个文件,而是一个充满文件的文件夹,很难将其作为文件列表进行管理。我无法更改 EB 中根目录的大小,我可以尝试更改为功能强大的实例,但这会不必要地更加昂贵,并且不清楚 ECB 使用的实例提供了哪些磁盘空间。有什么想法吗?
这些是我添加到我的 maven 存储库中的依赖项
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>1.8.2</version>
</dependency>
<dependency>
<groupId>org.rauschig</groupId>
<artifactId>jarchivelib</artifactId>
<version>0.6.0</version>
</dependency>
这是代码
@Override
public void init()
{
try
{
log.severe("Retrieving Indexes from S3");
AWSCredentials credentials = new BasicAWSCredentials("***********", "***********");
AmazonS3Client ac = new AmazonS3Client(credentials);
log.severe("datalength-testfile:"+ac.getObjectMetadata("widget","test.txt").getContentLength());
File testFile = new File("test.txt");
ac.getObject(new GetObjectRequest("widget", "test.txt"), testFile);
log.severe("datalength-testfile:retrieved");
log.severe("datalength-largefile:"+ac.getObjectMetadata("widget","indexes.tar.gz").getContentLength());
File largeFile = new File("indexes.tar.gz");
ac.getObject(new GetObjectRequest("widget", "indexes.tar.gz"), largeFile);
log.severe("datalength-largefile:retrieved");
log.severe("Retrieved Indexes from S3");
log.severe("Unzipping Indexes");
File indexDirFile = new File(indexDir).getAbsoluteFile();
indexDirFile.mkdirs();
Archiver archiver = ArchiverFactory.createArchiver(largeFile);
archiver.extract(largeFile, indexDirFile);
log.severe("Unzipped Indexes");
}
catch(Exception e)
{
log.log(Level.SEVERE, e.getMessage(), e );
}
}
* 更新 5 *
意识到微型 EC2 实例只提供 0.6GB 而不是 6GB,我无论如何都需要更新到更大的机器,并且它提供了两个磁盘,所以我可以将压缩文件复制到一个磁盘,然后成功解压缩到根磁盘,所以准备好了.
* 更新 6 *
EB 不尊重 init() 方法,因此在自动缩放的 EB 配置中,它会启动其他 EC2 实例,认为第一个实例会过载,而实际上它刚刚准备好。而且我怀疑如果它在真正忙碌时启动新的负载均衡器,负载均衡器会在这些实例准备好之前开始向这些实例提供请求,从而导致请求失败。
* 更新 7 *
尝试将索引直接放入 WEB-INF/classes 并在 web.xml 中引用该位置。这适用于本地测试 Tomcat 部署,但不幸的是在 EB 中失败,因为抱怨 所以似乎 EB 不响应 init()。因此,我没有尝试在 init() 方法中从 S3 获取索引,而是将索引直接放入 WEB-INF/classes 下的 War 文件中,并将我的 web.xml 中的参数指向那里。虽然它们实际上不是类,但这不会对 Tomcat 造成问题,我已经针对本地 Tomcat 安装进行了部署测试,没有问题。
不幸的是,将这个包含索引的较大 war 文件上传到 S3 尝试将其从 S3 位置部署到 EB 失败:
无法启动环境:源包为空或超过允许的最大大小:524288000。
为什么亚马逊要强加这个任意限制?
* 更新 8 *
所以可能的选择是
- ebextensions
- Docker 部署
- 创建用于 EB 的自定义 Amazon 映像
第三个选项似乎很老套,并不是所有人都热衷于此,或者真的很热衷于其他选项。
* 更新 9 **
最后我得到了它与 ebextensions 一起使用,还不错,我在这里记录以备不时之需
如果使用 maven 在 src/main/resources 中创建文件夹 ebextensions 将以下内容添加到 pom.xml (在最终战争中 ebextensions 放在正确的位置)
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webResources>
<resource>
<directory>src/main/ebextensions</directory>
<targetPath>.ebextensions</targetPath>
<filtering>true</filtering>
</resource>
</webResources>
</configuration>
</plugin>
在 ebextensions 文件夹中创建 .config 文件(我叫我的 copyindex.cfg),我的有这些信息
commands:
01_install_cli:
command: wget https://s3.amazonaws.com/aws-cli/awscli-bundle.zip; unzip awscli-bundle.zip; ./awscli-bundle/install -b ~/bin/aws
02_get_index:
command:
aws s3 cp --region eu-west-1 s3://jthink/release_index.tar.gz /dev/shm/release_index.tar.gz;
cd /usr/share/tomcat7; tar -xvf /dev/shm/release_index.tar.gz
转到 IAM 控制台 (https://console.aws.amazon.com/iam/home?#home) 并将角色策略超级用户附加到 Elastic Beanstalk 角色用户
部署您的应用程序
【问题讨论】:
标签: tomcat amazon-web-services amazon-elastic-beanstalk