我有一个 spring-boot 应用程序,我需要为其指定石墨服务器和端口(以发送指标)。为此,我必须安装并配置
statsd
。我使用 ebextensions
文件来做到这一点。
commands:
01_nodejs_install:
command: sudo yum -y install nodejs npm --enablerepo=epel
ignoreErrors: true
02_mkdir_statsd:
command: mkdir /home/ec2-user/statsd
ignoreErrors: true
03_fetch_statsd:
command: git clone https://github.com/etsy/statsd.git /home/ec2-user/statsd
ignoreErrors: true
04_change_example_config:
command: "cat exampleConfig.js | sed 's/2003/<graphite-port>/g' | sed 's/graphite.example.com/<my-graphite-server>/g' > config.js"
cwd: /home/ec2-user/statsd
05_run_statsd:
command: setsid node stats.js config.js >/dev/null 2>&1 < /dev/null &
cwd: /home/ec2-user/statsd
此配置的问题是我只能为所有环境指定 1 个石墨服务器。
所以我决定将命令 04 和 05 移至
container_commands
。我正在考虑使用 beanstalk 控制台/UI定义一个名为
ENV_NAME
的环境变量,并根据环境将其设置为 dev
、qa
或 prod
。然后我可以使用test
的container_commands
选项仅针对基于此ENV_NAME
的特定环境运行04和05命令。
所以我的问题是 - 如何使用 AWS 控制台定义环境变量?我尝试使用 Beanstalk 控制台来定义我的变量,如文档here中所述,但它不起作用。我还发现(参见有 5 个赞成票的答案)该方法仅设置 JVM 属性,而不设置 ENV 变量。
我无法使用
ebextensions
定义环境变量,因为那样我就会遇到同样的问题 - 无法为不同的环境定义不同的环境变量:)
所以我需要以下方面的帮助:
ENV_NAME
环境变量。或者
ENV_NAME
中的 container_commands
系统属性来根据 ENV_NAME
的值来决定是否运行命令的方法。如果您知道更简单/更好的方法来为不同环境指定不同的 Graphite 服务器,请随时参与。
我解决这个问题的方法是在开发和生产环境中分别将
ENV_NAME
定义为dev
和prod
,并使用以下ebextensions
配置。
commands:
01_nodejs_install:
command: sudo yum -y install nodejs npm --enablerepo=epel
ignoreErrors: true
02_mkdir_statsd:
command: mkdir /home/ec2-user/statsd
ignoreErrors: true
03_fetch_statsd:
command: git clone https://github.com/etsy/statsd.git /home/ec2-user/statsd
ignoreErrors: true
container_commands:
04a_container_change_example_config:
command: "cat exampleConfig.js | sed 's/2003/<graphite-dev-port>/g' | sed 's/graphite.example.com/<graphite-dev-host>/g' > config.js"
cwd: /home/ec2-user/statsd
test: '[ "${ENV_NAME}" == "dev" ]'
04b_container_change_example_config:
command: "cat exampleConfig.js | sed 's/2003/<graphite-prod-port>/g' | sed 's/graphite.example.com/<graphite-prod-host>/g' > config.js"
cwd: /home/ec2-user/statsd
test: '[ "${ENV_NAME}" == "prod" ]'
05_run_statsd:
command: setsid node stats.js config.js >/dev/null 2>&1 < /dev/null &
cwd: /home/ec2-user/statsd
使用
test
我可以在我已经在 beanstalk 环境中定义的 container command
属性上调节 ENV_NAME
的执行。
除了@Nik的回答:
您还可以获取实际的环境名称并将其自动存储在
ENV_NAME
中,而不是手动添加环境变量ENV_NAME
。这是通过在 option_settings
配置文件中使用 ebextensions
来实现的。
例如:
option_settings:
aws:elasticbeanstalk:application:environment:
# assign the actual env name to ENV_NAME
ENV_NAME: '`{ "Ref" : "AWSEBEnvironmentName" }`'
container_commands:
0100_execute_only_in_dev:
# this will turn up in ebactivity.log
command: echo "this is the development environment"
test: '[[ $ENV_NAME = "dev" ]]'
附注,对于那些不太熟悉 shell 脚本的人来说,比如我:测试表达式中的空格很重要(示例)。
自 2021 年起,Amazon Linux 2 成为新标准。 Amazon Linux 2 使用 platform hooks 而不是
container_commands
中的 .ebextensions
。
这是一个相当于上面定义的
0100_execute_only_in_dev
容器命令的 bash 脚本,可用作 Amazon Linux 2 上的平台挂钩:
0100_execute_only_in_dev.sh
#!/bin/bash
if [ $ENV_NAME = "dev" ]
# the following output will end up in "/var/log/eb-hooks.log"
then echo "this is the development environment"
fi
shell 脚本需要执行权限,如此处所述,并且可以放置在源包中
.platform/hooks
和/或.platform/confighooks
的任何子目录中,具体取决于适用的部署阶段(prebuild
, predeploy
,或postdeploy
)。有关更多信息,请参阅部署工作流程。它还有助于检查 /var/log/eb-engine.log
,了解部署期间到底发生了什么。
请注意,平台挂钩还可以访问 EB 环境属性。
答案就在这个 Spring 文档中,但我会用我的话来说: 由于您正在运行 spring-boot 应用程序,因此您可以创建不同的“application.properties”文件,如下所示:
在每个文件中,您可以放置石墨(或其他)配置:
在我的应用程序-dev.yml中:
在我的应用程序-prod.yml中:
如您所见,每个环境都有一个配置。
您可以使用不同的 maven 配置文件运行您的应用程序,在这种情况下,假设:dev 和 prod...在我的例子中,我的“dev”配置文件是默认设置的,因此当应用程序启动时,它将加载 dev 配置文件,因此,application-dev.yml 配置。
我的 pom.xml 的片段
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
...
然后,当您使用每个配置文件运行应用程序时,它将加载所需的 .yml 文件
让我们看看,如果我跑步:
java -jar mywar.war
我的控制台加载开发配置文件(因为记住这是我的默认配置文件)
但是如果我指定产品配置文件,例如:
java -jar mywar.war --spring.profiles.active=prod
我的控制台将显示:
要在 Elastic Beanstalk 中设置环境变量,请转到配置 -> 软件配置:
并设置
spring.profile.active
,如下所示:
最后一条评论:不要将环境属性与环境标签混淆!