【问题标题】:How do I configure data files in a Autoscaled (multi-instance) Elastic Beanstalk (Tomcat) Application (AWS)?如何在自动缩放(多实例)Elastic Beanstalk (Tomcat) 应用程序 (AWS) 中配置数据文件?
【发布时间】:2014-08-17 08:12:51
【问题描述】:

我目前有一个 Elastic Beanstalk 实例运行部署到 Tomcat 的 Java 应用程序。我使用 Web 界面部署应用程序,但应用程序使用 web.xml 中引用的数据文件(Lucene 索引),我通过 ssh-ing 到 EC2 并从我的 S3 存储桶中获取数据文件,将其复制到底层 EC2 实例。

到目前为止一切顺利。

但是如果我将我的 EB 更改为可自动扩展的环境,以便它根据需要自动创建新实例,那么这些 EC2 实例将没有数据文件,我该如何处理。

  1. 我可以在每个 EC2 实例实际使用之前预先配置数据文件吗??
  2. 我可以有一个共享的 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


    【解决方案1】:

    有多种方法可以实现这一目标。您无需 ssh 到实例并复制您的文件。

    我会在您的“更新 3”中推荐这种方法。

    您可以将 Elastic Beanstalk 环境配置为在部署应用程序之前执行命令。您可以使用 ebextensions 执行此操作。阅读有关命令 here 的文档。

    基本上,您在应用源中创建一个名为 .ebextensions 的文件夹。此文件夹可以包含一个或多个扩展名为 .config 的文件。这些文件按其名称的字典顺序进行处理。您可以使用 ebextensions 执行 shell 命令。例如,您可以执行以下操作:

    commands:
      02_download_index: 
        command: aws s3 cp s3://mybucket/test.txt test2.txt
    

    您需要先在您的 EC2 实例上安装 aws cli。这可以再次使用与上述类似的命令来完成。 here 提供了有关如何使用捆绑安装程序安装 AWS CLI 的说明。您可以运行多个命令。配置文件中的命令将按字典顺序执行,因此您可以将命令命名为 01_install_awcli、02_download_index 等。

    现在,如果您计划在 EC2 实例上使用 AWS CLI,您还需要凭证。如果您正在使用 IAM 实例配置文件(如果没有阅读过它here,您很可能是)。您可以授予实例配置文件权限以使用 IAM 访问您的 S3 对象。这样,您的实例将拥有一个与之关联的 IAM 实例配置文件,并且能够从 S3 下载该文件。或者,您也可以使用here 所示的环境属性直接获取 ACCESS_KEY_ID 和 SECRET_KEY。

    出现的所有新实例都应执行您的 ebextensions 中的命令。因此,您的实例可以使用您想要的软件进行预配置。

    【讨论】:

    • 感谢您给了我可以完成的信心 - 我开始怀疑这是否可能是由于缺乏回复。因为我是一名 Java 开发人员,所以我接受了你的想法,但现在正尝试用标准 Java 来实现它。
    • 我让它在单个实例中的 Java 中工作,但发现 EB 不尊重 servlet init() 方法并在第一个实例完成初始化之前开始启动其他实例,所以看起来我会有使用您建议的 .ebextensions 方法
    猜你喜欢
    • 2014-06-30
    • 2016-05-10
    • 2017-01-30
    • 2018-04-14
    • 2013-04-11
    • 2018-05-19
    • 1970-01-01
    • 2018-04-01
    • 2015-05-14
    相关资源
    最近更新 更多