如何处理 AWS 中的大型 WAR 文件?

Posted

技术标签:

【中文标题】如何处理 AWS 中的大型 WAR 文件?【英文标题】:How to deal with large WAR files in AWS? 【发布时间】:2016-05-19 02:08:42 【问题描述】:

我做了什么?

使用 JSP 开发了一个 Web 应用程序,允许用户注册、登录和上传文件到 AWS S3。我通过上传应用程序的war文件使用Elastic Beanstalk将此应用程序部署到aws。 对于登录和注册模块,我使用了 RDS,它工作正常。

问题

当我想将文件上传到 S3 时,我需要在 WEB 应用程序中使用 AWS SDK jar 及其支持的 JAR 文件。 当我完成开发部分并导出战争文件时,它大约是 75 MB。所以问题是,如果我对 app 进行任何更改,我需要将这个大型战争上传到 aws。由于 AWS SDK 的 JAR 文件,war 文件的大小会受到影响。

应对这种情况有哪些选择?

【问题讨论】:

您应该在服务器配置中更改上传的内容大小 这可能是一个想法:***.com/questions/14368629/… 【参考方案1】:

使用 Elastic Beanstalk 部署部分(因此更小的)war 文件的步骤:

    使用正在使用的外部库创建一个单独的包(例如dist-lib.zip) 将此包上传到 S3 创建 Elastic Beanstalk 部署 config 文件以下载和提取 EC2 节点上的外部库 创建没有外部库的 war 文件 照常部署war文件

1。 dist-lib.zip

摘自web模块的build.gradle(版本号已从zip中的路径中删除):

apply plugin: 'java-library-distribution'

distTar.enabled = false
distZip.enabled = hasProperty('dist') // 

def subPrjs = rootProject.subprojects.collect  it.name  - project.name

//...

distributions.main 
    contents.exclude subPrjs.collect  "$it*.jar" 
    contents.exclude "tomcat-embed-*"
    contents.exclude "tomcat-annotations-api-*"
    contents.exclude "spring-boot-starter-tomcat-*"


distZip 
    baseName += '-lib'
    version = null
    doLast 
        def f0 = archivePath;
        version = props.ver; // replace w/ your version number
        if (archivePath.exists()) 
            archivePath.delete()
        
        f0.renameTo(archivePath.path)
    

使用gradle distZip -Pdist=true 创建 zip 文件。

2。上传dist-lib.zip到S3

来自 aws-cli:aws s3 cp YOUR_MODULE/build/distributions/YOUR_MODULE-lib-YOUR_VERSION.zip s3://YOUR_BUCKET/dist/dist-lib.zip

我建议保护存储桶:

    它不会为您产生额外的外部流量; 如果出现问题,您不小心上传了一些敏感数据,也不会造成任何损害。

3。 EB 配置

访问私有 S3 存储桶的配置详细信息在Storing Private Keys Securely in Amazon S3 中进行了描述。

在将您的应用程序复制到Tomcat的webapps之前,您需要以下文件来自动下载、提取并将外部库添加到提取的war包中。

deploy/eb/app-res.config:

Resources:
  # Use instance profile to authenticate to S3 bucket that contains the private key
  AWSEBAutoScalingGroup:
    Metadata:
      AWS::CloudFormation::Authentication:
        S3Auth:
          type: "s3"
          buckets: ["elasticbeanstalk-us-east-1-169305339676"]
          roleName:
            "Fn::GetOptionSetting":
              Namespace: "aws:autoscaling:launchconfiguration"
              OptionName: "IamInstanceProfile"
              DefaultValue: "aws-elasticbeanstalk-ec2-role-dev"

files:
  # distribution libs
  /tmp/dist-lib.zip:
    mode: "000644"
    owner: tomcat
    group: tomcat
    authentication: "S3Auth"
    source: https://s3.amazonaws.com/YOUR_BUCKET/dist/dist-lib.zip

deploy/eb/dist-lib.config:

files:
  /opt/elasticbeanstalk/hooks/appdeploy/pre/10_lib_extr.sh:
    mode: "000755"
    owner: root
    group: root
    content: |
      #!/usr/bin/env bash
      rm -rf /tmp/dist-lib
      unzip  /tmp/dist-lib.zip -d /tmp/
      mv     /tmp/dist-lib/lib /tmp/deployment/application/ROOT/WEB-INF/lib 

4。 war

另一部分来自build.gradle的web模块(子模块(子项目)类直接包含在WEB-INF/classes中):

apply plugin: 'war'

jar.enabled = false

def env = project.hasProperty('env') ? project.getProperty('env') : 'lcl' // profile: set w/ "-Penv=..."
def ebDirs = ["$rootDir/deploy/eb-$env", "$rootDir/deploy/eb", "$rootDir/deploy/eb/_nginx"] // env. specific config first

// ...

war 
    duplicatesStrategy = 'fail'
    //rootSpec.exclude subPrjs.collect  "**/$it*.jar"  // exclude subproject jars only
    rootSpec.exclude "**/*.jar" // exclude dependencies => they must be downloaded and extracted during deployment
    from(subPrjs.collect  project(":$it").sourceSets.main.output ) 
        duplicatesStrategy = 'exclude' // in case of one output dir for multiple sourceSets
        into "WEB-INF/classes"
    
    from(ebDirs) 
        duplicatesStrategy = 'exclude' // in case of env. spec. config
        exclude "**/_*"
        into ".ebextensions"
    

5。部署

上述解决方案已使用gradle v4.10.2aws-cli v1.16.44(均使用eb createeb deploy)进行了测试。

【讨论】:

【参考方案2】:

使用 Maven 等构建工具。这将确保在服务器的本地 maven 存储库中下载依赖文件。因此,它可以减少项目的上传大小。 Here 是官方快速指南

【讨论】:

如果战争是在 AWS 服务器上构建的,那将起作用,但情况似乎并非如此...... 由于用户希望经常更新代码,我建议这样做。如果战争只在发布时间部署,问题所有者就不会担心大文件上传 @Thanga 我对 Maven 不了解,根据您的建议,我已经尝试过并且它有效。谢谢人..

以上是关于如何处理 AWS 中的大型 WAR 文件?的主要内容,如果未能解决你的问题,请参考以下文章

AWS DMS:如何处理 Presto/Athena 中的 TIMESTAMP_MICROS parquet 字段

在 C# 中,如何处理具有多个线程/任务但有条件的大型文本文件?

如何处理 AWS 中的开发和生产环境? [关闭]

如何处理 aws-appsync 中的关系?

GreenPlum 如何处理多个大型连接和同时工作负载?

如何处理 AWS Redshift 卸载命令中的引用值?