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

时间:2016-02-09 07:24:01

标签: java amazon-web-services amazon-s3 amazon-elastic-beanstalk

我做了什么?

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

问题

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

有哪些方法可以解决这种情况?

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

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

  1. 使用正在使用的外部库创建一个单独的程序包(例如dist-lib.zip
  2. 将此软件包上载到S3
  3. 创建Elastic Beanstalk部署config文件,以下载和提取EC2节点上的外部库
  4. 不使用外部库创建war文件
  5. 像往常一样部署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

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

我建议固定水桶:

  1. 它不会为您带来额外的外部流量;
  2. 如果出现问题,并且您不小心上传了一些敏感数据,则不会造成任何损害。

3。 EB配置

Storing Private Keys Securely in Amazon S3中描述了用于访问私有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程序包

Web模块build.gradle的另一部分(子模块(子项目)类直接包含在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)进行了测试。