tomcat - 如何在自动缩放(多实例)Elastic Beanstalk (Tomcat) 应用程序 (AWS) 中配置数据文件?

标签 tomcat amazon-web-services amazon-elastic-beanstalk

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

到现在为止还挺好。

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

  • 我可以在实际使用之前使用数据文件预先配置每个 EC2 实例吗?
  • 我可以有一个每个服务器都可以引用的共享文件系统吗(数据文件是只读的)?

  • * 更新 *

    我想我已经在原则上找到了答案。我从本地机器上传我的应用程序,然后从亚马逊添加大型数据文件。我需要做的是在我的数据处理 EC2 实例上构建我的 war ,将数据文件添加到 war 的某个地方,然后将此 war 放到 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 的自定义亚马逊镜像

  • 第 3 个选项似乎很笨拙,并非所有人都热衷于此,或者真的非常热衷于其他人。

    * 更新 9 **

    最后我让它与 ebextensions 一起工作,还不错,我在这里记录以防万一

    如果使用 maven 在 src/main/resources 中创建文件夹 ebextensions
    将以下内容添加到 pom.xml (sao that ebextensions 在最终 war 中出现在正确的位置)
                <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 角色用户

    部署您的应用程序

    最佳答案

    有多种方法可以实现这一点。您无需通过 ssh 连接到实例并复制您的文件。

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

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

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

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

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

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

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

    关于tomcat - 如何在自动缩放(多实例)Elastic Beanstalk (Tomcat) 应用程序 (AWS) 中配置数据文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24431130/

    相关文章:

    http - 在 Apache Tomcat 6.0 中禁用 PUT TRACE DELETE 请求

    amazon-web-services - 当我收到 'services has reached steady state'时,是否在Amazon ECS中停止了某些任务?

    mysql - 通过 SSH 在 AWS RDS MySQL 数据库实例上执行查询

    amazon-web-services - Elastic Beanstalk 上 New Relic 的 nrsysmond 的唯一主机名

    python - Amazon Elastic Beanstalk 中的 Django Collectstatic 不工作

    eclipse - 如何禁用 Hibernate 泛洪日志

    java - Tomcat 集群 6 和 ContextListener

    java - 如何在 AWS CodeBuild 标准镜像上安装不同的 Java OpenJDK 版本

    amazon-web-services - AWS 云观察 : how to fetch custom metrics from AWS Elastic Beanstalk

    spring - FAIL - 上下文路径/icescrum 中的应用程序无法启动