当前位置: 首页 > 知识库问答 >
问题:

部署一个。NET Windows服务,带有Amazon Elastic Beanstalk,无Web应用程序

贺海
2023-03-14

我想创建一个弹性豆茎配置,允许我部署一个。NET Windows Service,但不部署Web应用程序。

我刚刚读了这篇解释如何使用的博客文章。eExtensions将在web应用程序旁边部署Windows服务,但是否存在以下情况:。是否可以在不部署Web应用程序的Web部署包的情况下运行ebextensions?

是创建包含的空web应用程序的唯一选项。然后部署Web部署包?

Elastic Beanstalk FAQ提到了部署非web应用程序的能力(此处),我在AWS开发者论坛(此处)上发现了一个类似的(未回答的)问题。

由于在这个问题上缺乏活动,我也无法在网上找到任何其他信息,我只是假设这个问题的答案是“不”(至少目前是这样)。

我最终创建了一个空的web应用程序,并使用它通过部署Windows服务。ebextensions YAML配置。

作为旁注,我想强调一下Amazon文档中的这一页,我发现这是创建这些特殊配置文件的非常有用的指南。

在实现上述方法之后,我发现Elastic Beanstalk没有执行我的。新Beanstalk实例的ebextensions脚本。因此,在创建新实例时无法安装Windows服务。为了最终找到一个可扩展的解决方案,我不得不再经历几个困难。如果你想知道最终解决方案的细节,请告诉我

最终,Elastic Beanstalk似乎不适合部署可伸缩的Windows服务。

我不喜欢发布源代码,因为它不是针对个人项目的,但以下是我当前部署解决方案的基本结构:

  1. 自定义EC2 AMI包含启动时运行的“引导”程序。该程序执行以下操作:
    1.1。从(可配置的)“部署”S3存储桶下载“zip”存档
    1.2。将下载的zip文件解压缩到临时目录
    1.3。找到/执行一个“install.bat”脚本(该脚本的名称也是可配置的)。此脚本安装并启动windows服务

要部署新代码,请上载安装。将压缩文件(包含windows服务和install.bat文件)压缩到S3存储桶,并终止Elastic Beanstalk应用程序的所有EC2实例。重新创建实例后,引导程序将下载/安装新更新的代码。

当然,如果我从头开始,我会跳过使用Elastic Beanstalk,使用标准的AWS自动伸缩以及类似的部署方案。底线是,如果没有web应用程序,就不要使用Elastic Beanstalk;您最好使用标准AWS自动缩放。

Amazon最近发布了几个新的代码部署/管理服务,似乎可以解决部署问题:http://aws.amazon.com/blogs/aws/code-management-and-deployment/

我还没有使用这些新服务(我甚至不确定它们是否已经发布),但它们看起来很有希望。

共有2个答案

狄兴业
2023-03-14

根据我自己的经验,使用ebextensions实现任何东西都会大大增加部署所需的时间。如此之多,以至于在自动缩放时,一个实例最多需要15分钟才能启动。几乎达不到目的。

在任何情况下,请确保将自动缩放组的“健康检查宽限期”属性配置为重要内容。例如,我们使用900(即15分钟)。任何更少的值,实例永远不会通过运行状况检查,并且放大事件失败;这就导致了一系列不断扩大规模的尝试。

寇甫
2023-03-14

由于这个问题已经存在了一段时间,仍然没有答案,但仍然吸引着人们的兴趣,让我分享一下我对一个非常类似问题的解决方案——在EC2实例上安装Windows服务。不过,我没有使用Beanstalk,因为该服务更多地是为快速部署web应用程序而设计的。相反,我直接使用Beanstalk在下面使用的CloudFormation来部署与web应用程序相关的资源。

该堆栈需要现有的VPC(我们跨越多个可用性区域)、一个存储所有服务构建工件的S3存储桶和一个EC2密钥对。该模板使用WindowsAMI和一些其他资源创建EC2实例,比如具有访问密钥的IAM用户和一个工作的S3存储桶,只是为了说明如何创建您的服务可能需要的其他资源。模板还将包含所有服务二进制文件和配置文件的压缩包的名称作为参数,这些文件已上载到build artifacts S3 bucket(我们使用TeamCity build server为我们制作,但您当然可以手动创建和上载包)。构建服务的新版本时,只需创建新包(例如service.v2.zip),用新名称更新堆栈,服务就会自动更新。模板包含4个不同区域中的AMI ID,但如果愿意,您可以始终添加其他区域。以下是堆栈模板:

{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "Service stack template.",
    "Parameters": {
        "KeyPair": {
            "Type": "String",
            "Default": "MyDefaultKeys",
            "Description": "Name of EC2 Key Pair."
        },
        "ServicePackageName": {
            "Type": "String",
            "Default": "service.zip",
            "Description": "Name of the zip package of the service files."
        },
        "DeploymentBucketName": {
            "Type": "String",
            "Default": "",
            "Description": "Name of the deployment bucket where all the artifacts are."
        },
        "VPCId": {
            "Type": "String",
            "Default": "",
            "Description": "Identifier of existing VPC."
        },
        "VPCSubnets": {
            "Default": "",
            "Description": "Commaseparated list of existing subnets within the existing VPC. Could be just one.",
            "Type": "CommaDelimitedList"
        },
        "VPCSecurityGroup": {
            "Default": "",
            "Description": "Existing VPC security group. That should be the ID of the VPC's default security group.",
            "Type": "String"
        }
    },
    "Mappings": {
        "Region2WinAMI": {
            "us-east-1": { "64": "ami-40f0d32a" },
            "us-west-1": { "64": "ami-20601740" },
            "us-west-2": { "64": "ami-ff4baf9f" },
            "eu-west-1": { "64": "ami-3367d340" }
        }
    },
    "Resources": {
        "ServiceInstance": {
            "Type": "AWS::EC2::Instance",
            "Metadata": {
                "Comment": "Install Service",
                "AWS::CloudFormation::Init": {
                    "configSets": {
                        "default": [ "ServiceConfig" ]
                    },
                    "ServiceConfig": {
                        "files": {
                            "c:\\service\\settings.config": {
                                "source": { "Fn::Join": [ "/", [ "https://s3.amazonaws.com", { "Ref": "DeploymentBucketName" }, "deployments/stacks", { "Ref": "AWS::StackName" }, "templates/settings.config.mustache" ] ] },
                                "context": {
                                    "region": { "Ref": "AWS::Region" },
                                    "accesskey": { "Ref": "IAMUserAccessKey" },
                                    "secretkey": { "Fn::GetAtt": [ "IAMUserAccessKey", "SecretAccessKey" ] },
                                    "bucket": { "Ref": "BucketName" }
                                }
                            },
                            "c:\\cfn\\cfn-hup.conf": {
                                "content": {
                                    "Fn::Join": [
                                        "",
                                        [
                                            "[main]\n",
                                            "stack=",
                                            { "Ref": "AWS::StackId" },
                                            "\n",
                                            "region=",
                                            { "Ref": "AWS::Region" },
                                            "\n",
                                            "interval=1"
                                        ]
                                    ]
                                }
                            },
                            "c:\\cfn\\hooks.d\\cfn-auto-reloader.conf": {
                                "content": {
                                    "Fn::Join": [
                                        "",
                                        [
                                            "[cfn-auto-reloader-hook]\n",
                                            "triggers=post.update\n",
                                            "path=Resources.ServiceInstance.Metadata.AWS::CloudFormation::Init\n",
                                            "action=cfn-init.exe -v -s ",
                                            { "Ref": "AWS::StackName" },
                                            " -r ServiceInstance --region ",
                                            { "Ref": "AWS::Region" },
                                            "\n"
                                        ]
                                    ]
                                }
                            }
                        },
                        "sources": {
                            "c:\\tmp\\service": { "Fn::Join": [ "/", [ "https://s3.amazonaws.com", { "Ref": "DeploymentBucketName" }, "deployments/stacks", { "Ref": "AWS::StackName" }, "artifacts/Service", { "Ref": "ServicePackageName" } ] ] }
                        },
                        "commands": {
                            "Install Service": {
                                "command": "call c:\\tmp\\service\\install.bat",
                                "ignoreErrors": "false"
                            }
                        },
                        "services": {
                            "windows": {
                                "cfn-hup": {
                                    "enabled": "true",
                                    "ensureRunning": "true",
                                    "files": [ "c:\\cfn\\cfn-hup.conf", "c:\\cfn\\hooks.d\\cfn-auto-reloader.conf" ]
                                }
                            }
                        }
                    }
                }
            },
            "Properties": {
                "ImageId": { "Fn::FindInMap": [ "Region2WinAMI", { "Ref": "AWS::Region" }, "64" ] },
                "InstanceType": "t2.micro",
                "KeyName": { "Ref": "KeyPair" },
                "SecurityGroupIds" : [{ "Ref": "VPCSecurityGroup" }],
                "SubnetId" : { "Fn::Select": [ "0", { "Ref": "VPCSubnets" } ] },
                "UserData": {
                    "Fn::Base64": {
                        "Fn::Join": [
                            "",
                            [
                                "<script>\n",
                                "if not exist \"C:\\logs\" mkdir C:\\logs \n",
                                "cfn-init.exe -v -s ",
                                { "Ref": "AWS::StackName" },
                                " -r ServiceInstance --region ",
                                { "Ref": "AWS::Region" },
                                " -c default \n",
                                "</script>\n"
                            ]
                        ]
                    }
                },
                "BlockDeviceMappings": [
                    {
                        "DeviceName": "/dev/sda1",
                        "Ebs": {
                            "DeleteOnTermination": "true",
                            "VolumeSize": "40",
                            "VolumeType": "gp2"
                        }
                    }
                ],
                "Tags": [
                    { "Key": "Name", "Value": { "Fn::Join": [ ".", [ { "Ref": "AWS::StackName" }, "service" ] ] } }
                ]
            }
        },
        "BucketName": {
            "Type": "AWS::S3::Bucket",
            "Properties": {
                "AccessControl": "PublicRead"
            },
            "DeletionPolicy": "Retain"
        },
        "IAMUser": {
            "Type": "AWS::IAM::User",
            "Properties": {
                "Path": "/",
                "Groups": [ "stack-users" ],
                "Policies": [
                    {
                        "PolicyName": "giveaccesstobuckets",
                        "PolicyDocument": {
                            "Version": "2012-10-17",
                            "Statement": [
                                {
                                    "Effect": "Allow",
                                    "Action": [ "s3:*" ],
                                    "Resource": [ { "Fn::Join": [ "", [ "arn:aws:s3:::", { "Ref": "BucketName" }, "/*" ] ] } ]
                                }
                            ]
                        }
                    }
                ]
            }
        },
        "IAMUserAccessKey": {
            "Type": "AWS::IAM::AccessKey",
            "Properties": {
                "UserName": { "Ref": "IAMUser" }
            }
        }
    }
}

如您所见,复制工件后,我们执行install.bat批处理文件(包含在zip文件中),将文件移动到正确的位置并注册服务。以下是文件的内容:

@echo off
sc query MyService > NUL
IF ERRORLEVEL 1060 GOTO COPYANDCREATE
sc stop MyService
waitfor /T 20 ServiceStop
echo D | xcopy "c:\tmp\service" "c:\service\" /E /Y /i
GOTO END
:COPYANDCREATE
echo D | xcopy "c:\tmp\service" "c:\service\" /E /Y /i
sc create MyService binpath= "c:\service\MyService.exe" start= "auto"
:END
sc start MyService

模板还创建了一个配置文件(来自同样位于artifacts bucket上的settings.config.mustache),该文件包含关于已创建供服务使用的其他资源的信息。这是:

<appSettings>
    <add key="AWSAccessKey" value="{{accesskey}}" />
    <add key="AWSSecretKey" value="{{secretkey}}" />
    <add key="AWSRegion" value="{{region}}" />
    <add key="AWSBucket" value="{{bucket}}" />
</appSettings>

您可以从AWS web控制台或CLI创建并稍后更新堆栈。

差不多就是这样。您可以访问AWS CloudFormation网站以获取有关该服务以及如何使用模板的更多信息。

附言:我意识到如果我也分享创建专有网络的模板会更好。我把它分开,因为我每个地区有一个专有网络。如果愿意,您可以将其与服务模板集成,但这意味着每次创建新堆栈时,都会创建一个新的VPC。以下是VPC模板:

{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "VPC stack template.",
    "Mappings": {
        "Region2AZ": {
            "us-east-1": { "AZ": [ "us-east-1a", "us-east-1b", "us-east-1d" ] },
            "us-west-1": { "AZ": [ "us-west-1b", "us-west-1c" ] },
            "us-west-2": { "AZ": [ "us-west-2a", "us-west-2b", "us-west-2c" ] },
            "eu-west-1": { "AZ": [ "eu-west-1a", "eu-west-1b", "eu-west-1c" ] }
        }
    },
    "Conditions": {
        "RegionHas3Zones": { "Fn::Not" : [ { "Fn::Equals" : [ { "Ref": "AWS::Region" }, "us-west-1" ] } ] }
    },
    "Resources": {
        "VPC": {
            "Type": "AWS::EC2::VPC",
            "Properties": {
                "CidrBlock": "10.0.0.0/16",
                "EnableDnsSupport" : "true",
                "EnableDnsHostnames" : "true"
            }
        },
        "VPCSecurityGroup": {
            "Type": "AWS::EC2::SecurityGroup",
            "Properties": {
                "GroupDescription": "Security group for VPC.",
                "VpcId": { "Ref": "VPC" }
            }
        },
        "Subnet0": {
            "Type": "AWS::EC2::Subnet",
            "Properties": {
                "VpcId": { "Ref": "VPC" },
                "CidrBlock": "10.0.0.0/24",
                "AvailabilityZone": { "Fn::Select": [ "0", { "Fn::FindInMap": [ "Region2AZ", { "Ref": "AWS::Region" }, "AZ" ] } ] }
            }
        },
        "Subnet1": {
            "Type": "AWS::EC2::Subnet",
            "Properties": {
                "VpcId": { "Ref": "VPC" },
                "CidrBlock": "10.0.1.0/24",
                "AvailabilityZone": { "Fn::Select": [ "1", { "Fn::FindInMap": [ "Region2AZ", { "Ref": "AWS::Region" }, "AZ" ] } ] }
            }
        },
        "Subnet2": {
            "Type": "AWS::EC2::Subnet",
            "Condition": "RegionHas3Zones",
            "Properties": {
                "VpcId": { "Ref": "VPC" },
                "CidrBlock": "10.0.2.0/24",
                "AvailabilityZone": { "Fn::Select": [ "2", { "Fn::FindInMap": [ "Region2AZ", { "Ref": "AWS::Region" }, "AZ" ] } ] }
            }
        },
        "InternetGateway": {
            "Type": "AWS::EC2::InternetGateway",
            "Properties": {
            }
        },
        "AttachGateway": {
            "Type": "AWS::EC2::VPCGatewayAttachment",
            "Properties": {
                "VpcId": { "Ref": "VPC" },
                "InternetGatewayId": { "Ref": "InternetGateway" }
            }
        },
        "RouteTable": {
            "Type": "AWS::EC2::RouteTable",
            "Properties": {
                "VpcId": { "Ref": "VPC" }
            }
        },
        "Route": {
            "Type": "AWS::EC2::Route",
            "DependsOn": "AttachGateway",
            "Properties": {
                "RouteTableId": { "Ref": "RouteTable" },
                "DestinationCidrBlock": "0.0.0.0/0",
                "GatewayId": { "Ref": "InternetGateway" }
            }
        },
        "SubnetRouteTableAssociation0": {
            "Type": "AWS::EC2::SubnetRouteTableAssociation",
            "Properties": {
                "SubnetId": { "Ref": "Subnet0" },
                "RouteTableId": { "Ref": "RouteTable" }
            }
        },
        "SubnetRouteTableAssociation1": {
            "Type": "AWS::EC2::SubnetRouteTableAssociation",
            "Properties": {
                "SubnetId": { "Ref": "Subnet1" },
                "RouteTableId": { "Ref": "RouteTable" }
            }
        },
        "SubnetRouteTableAssociation2": {
            "Type": "AWS::EC2::SubnetRouteTableAssociation",
            "Condition": "RegionHas3Zones",
            "Properties": {
                "SubnetId": { "Ref": "Subnet2" },
                "RouteTableId": { "Ref": "RouteTable" }
            }
        },
        "NetworkAcl": {
            "Type": "AWS::EC2::NetworkAcl",
            "Properties": {
                "VpcId": { "Ref": "VPC" }
            }
        },
        "AllowAllInboundTCPAclEntry": {
            "Type": "AWS::EC2::NetworkAclEntry",
            "Properties": {
                "NetworkAclId": { "Ref": "NetworkAcl" },
                "RuleNumber": "100",
                "Protocol": "6",
                "RuleAction": "allow",
                "Egress": "false",
                "CidrBlock": "0.0.0.0/0",
                "PortRange": { "From": "0", "To": "65535" }
            }
        },
        "AllowAllInboundUDPAclEntry": {
            "Type": "AWS::EC2::NetworkAclEntry",
            "Properties": {
                "NetworkAclId": { "Ref": "NetworkAcl" },
                "RuleNumber": "101",
                "Protocol": "17",
                "RuleAction": "allow",
                "Egress": "false",
                "CidrBlock": "0.0.0.0/0",
                "PortRange": { "From": "0", "To": "65535" }
            }
        },
        "AllowAllOutboundTCPAclEntry": {
            "Type": "AWS::EC2::NetworkAclEntry",
            "Properties": {
                "NetworkAclId": { "Ref": "NetworkAcl" },
                "RuleNumber": "100",
                "Protocol": "6",
                "RuleAction": "allow",
                "Egress": "true",
                "CidrBlock": "0.0.0.0/0",
                "PortRange": { "From": "0", "To": "65535" }
            }
        },
        "AllowAllOutboundUDPAclEntry": {
            "Type": "AWS::EC2::NetworkAclEntry",
            "Properties": {
                "NetworkAclId": { "Ref": "NetworkAcl" },
                "RuleNumber": "101",
                "Protocol": "17",
                "RuleAction": "allow",
                "Egress": "true",
                "CidrBlock": "0.0.0.0/0",
                "PortRange": { "From": "0", "To": "65535" }
            }
        },
        "SubnetNetworkAclAssociation0": {
            "Type": "AWS::EC2::SubnetNetworkAclAssociation",
            "Properties": {
                "SubnetId": { "Ref": "Subnet0" },
                "NetworkAclId": { "Ref": "NetworkAcl" }
            }
        },
        "SubnetNetworkAclAssociation1": {
            "Type": "AWS::EC2::SubnetNetworkAclAssociation",
            "Properties": {
                "SubnetId": { "Ref": "Subnet1" },
                "NetworkAclId": { "Ref": "NetworkAcl" }
            }
        },
        "SubnetNetworkAclAssociation2": {
            "Type": "AWS::EC2::SubnetNetworkAclAssociation",
            "Condition": "RegionHas3Zones",
            "Properties": {
                "SubnetId": { "Ref": "Subnet2" },
                "NetworkAclId": { "Ref": "NetworkAcl" }
            }
        }
    },
    "Outputs": {
        "VPC": {
            "Description": "VPC",
            "Value": { "Ref": "VPC" }
        },
        "VPCSecurityGroup": {
            "Description": "VPC Security Group Id",
            "Value": { "Fn::GetAtt": [ "VPCSecurityGroup", "GroupId" ] }
        },
        "Subnet0": {
            "Description": "Subnet0 Id",
            "Value": { "Ref": "Subnet0" }
        },
        "Subnet1": {
            "Description": "Subnet1 Id",
            "Value": { "Ref": "Subnet1" }
        },
        "Subnet2": {
            "Description": "Subnet2 Id",
            "Condition": "RegionHas3Zones",
            "Value": { "Ref": "Subnet2" }
        }
    }
}
 类似资料:
  • 我在Azure上的Linux应用服务上部署了一个响应js网站。但它没有部署在应用服务上。我使用pm2命令在linux环境下运行应用程序 pm2 serve/home/site/wwwroot/--无守护进程 但在错误日志中,未找到pm2的错误。接下来呢 容器没有响应端口: 8080上的HTTP ping,站点启动失败。 站点的容器已退出,站点启动失败

  • pom.xml我有这个用来部署 在设置中。tomcat服务器的xml我有这个 当我试图调用maven deploy时,出现了一个错误: 服务器正在运行。我试图在pom中更改tomcat插件。xml到tomcat7 maven插件,但我得到了相同的错误。据我所知,它正试图将war文件部署到http://localhost:8080/manager/ua/andrfas/SCPI/0.0.1/SCPI

  • 我已经将一个Web服务作为aar文件部署到Axis2,我使用以下教程:https://www.rukspot.com/blog/axis_2_sample_web_service_with_maven_and_eclipse 我可以进入'services'页面(http://localhost:7070/axis2/services/listservices),它正确地显示了我的web服务。我可以

  • 我期待着在tomcat 7前面的apache超文本传输协议服务器,以呈现我的静态内容,以获得更好的性能和可扩展性。 现在使用pom,我能够部署到tomcat完全战争。 但我找不到任何可以启动http服务器并向其部署静态内容的插件。 基本上,我希望过滤静态资源,并将其部署到http服务器,同时以。把war文件发给tomcat。 我寻找类似的东西与嵌入式apache超文本传输协议服务器插件或东西。 动

  • 我正在编写一个简单的RESTful Web服务,使用Java、tomcat7、jersey和IDE eclipse。 当我使用eclipse(服务器)启动web服务时,它运行良好。我测试了GET和POST方法。但当我在WAR文件中导出应用程序并使用tomcat manage UI部署时。它返回404 not found状态。 下面是一个例子: 这里是网络。xml: 有人能解释在eclipse中启动