当前位置: 首页 > 面试题库 >

如何配置在AWS / ElasticBeanstalk / Docker上运行的GlassFish实例?

禄仲渊
2023-03-14
问题内容

我正在使用GlassFish来提供Java EE Web应用程序。在我本地的开发机器上一切正常。我有

  • 将postgres JDBC库复制到正确的位置
  • 在Glassfish管理控制台中配置了连接池和JDBC资源
  • 部署了使用上述连接的网络应用
  • 在我的浏览器中看到了结果

我正在尝试将同一应用程序部署到AWS Elastic Beanstalk托管的Glassfish实例。AWS-
EB使用Docker部署Glassfish实例。我只能执行上面的第三步(部署一个Web应用程序),而如何执行前两个完全不知所措。

我想做的是通过Web访问Glassfish管理控制台,但这似乎不适用于任何级别。一种替代方法是在本地计算机上使用玻璃鱼“
asadmin”来配置远程玻璃鱼,但是我也无法做到这一点。

如何配置托管在AWS EB上的Glassfish实例?可能吗

我已经进行了一些观察,但不胜感激确认或其他方式:

  • 看来,AWS在其CLI中有一个名为“ asadmin”的命令,该命令与自动缩放有关,并且与glassfish附带的名称为“ asadmin”。除了让Google搜寻困难外,这两者似乎与彼此无关
  • 如果我连接到包含Docker和Glassfish实例的AWS EC2实例,则会发生以下情况
    • sudo docker ps 返回端口4848 / tcp,8080 / tcp,8181 / tcp,并且没有端口被映射
    • wget localhost:8080- 连接被拒绝
    • 同样适用于8181和4848
    • wget localhost:80 返回Glassfish主页的网页
  • 在运行 docker的 同一个实例中,我得到一个内部IP地址(称为1.2.3.4),然后在该EC实例上
    • wget 1.2.3.4:8080 (和 4848、8181 )全部返回html文件
    • wget 1.2.3.4:80- 连接被拒绝
  • 如果我在docker容器中运行bash shell,则以下情况似乎是正确的
    • wget localhost:8080 (和4848、8181)全部返回格式正确的页面
    • wget localhost:80- 连接被拒绝

因此,也许我需要告诉EC2实例从本地主机转发到1.2.3.4,但是当EB负载均衡器将其扩展时,我该如何实现。

任何建议将不胜感激。


问题答案:

接下来是对我有用的东西-但我感觉自己缺少一些东西。任何编辑/评论都将受到欢迎。

EB /
Docker部署中有各种挂钩,允许执行部署后挂钩在EB实例的docker容器内的glassfish实例中运行。我使用了部署后挂钩来建立连接池。这是最终安装的样子,仅供参考:

|  | |  \_WAR_/  | | |
|  | \_Glassfish_/ | |
|  \____Docker____/  |
\____EC2 Instance____/

总体期望的结果是,在部署应用程序之后,在Docker实例内部,运行 asadmin
命令以创建JDBC连接池,并将该连接池转换为jdbc资源。在我的本地计算机上,命令是

asadmin create-jdbc-connection-pool 
    --datasourceclassname org.postgresql.ds.PGConnectionPoolDataSource 
    --restype javax.sql.ConnectionPoolDataSource 
    --property user=USERNAME:password=PASSWORD:serverName=DBHOST:portNumber=5432:databaseName=DBNAME 
    poolName

asadmin create-jdbc-resource --connectionpoolid poolName jdbc/dev

其中“ jdbc / dev”是java代码以常规方式获取连接所需的名称,即

InitialContext ctx = new InitialContext();
ds = (DataSource)ctx.lookup("jdbc/dev");

我们希望命令在docker实例中运行,因为docker实例可以访问您在AWS管理控制台中声明的环境变量,因此我可以传递配置信息,而无需在构建脚本中使用它。

为实现此结果,我们要求在安装过程中在EC2实例中创建一个文件,在我的情况下为
/opt/elasticbeanstalk/hooks/appdeploy/post/99_configure_jdbc.sh
。此文件将在EC2实例中作为根用户在部署后执行。我将其称为 ec2-post-deploy-hook

我们将使用.ebextensions / .config文件创建该文件,如此处所述

  • http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/customize-containers.html
  • http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/customize-containers-ec2.html

我的.config文件具有以下内容:

files:
  "/opt/elasticbeanstalk/hooks/appdeploy/post/99_configure_jdbc.sh":
    mode: "000755"
    owner: root
    group: root
    content: |
      #!/bin/bash
      date > /tmp/post 2>&1
      dockerid=`docker ps | grep latest | cut -d" " -f1`
      echo $dockerid >> /tmp/post 2>&1
      docker ps >> /tmp/post 2>&1
      docker exec $dockerid /var/app/WEB-INF/classes/setup_pool.sh >> tmp/post 2>&1

内容 之后的所有 内容: 最终出现在 ec2-post-deploy-hook中

我从http://junkheap.net/blog/2013/05/20/elastic-beanstalk-post-deployment-
scripts了解了这个想法。

仅需要最后一行和最后第四行,但其他行对于调试很有用。输出最终在EC2实例上的/ tmp / post中。

该文件中的一个技巧是,我们总是可以通过以下方式获取Docker容器的ID:

sudo docker ps | grep latest | cut -d" " -f1

因为部署后将仅运行一个Docker容器,并且其名称将为“ latest”。

ec2-post-deploy-hook 的最后一行使用docker在docker实例内部运行我最初想要运行的命令-
即asadmin命令。我在.war文件中部署了一个名为setup_pool.sh的文件,因此该文件最终在部署过程中位于已知位置。我的setup_pool.sh看起来像这样(我称之为
docker-post-deploy-hook ):

dbuser=$PARAM1
dbpass=$PARAM2
dbhost=$PARAM3
dbname=$PARAM4

date > /tmp/setup_connections
echo '*********' >> /tmp/setup_connections
asadmin create-jdbc-connection-pool --datasourceclassname org.postgresql.ds.PGConnectionPoolDataSource --restype javax.sql.ConnectionPoolDataSource --property user=${dbuser}:password=${dbpass}:serverName=${dbhost}:portNumber=5432:databaseName=${dbname} ei-connection-pool >>   /tmp/setup_connections 2>&1
echo '*********' >> /tmp/setup_connections
asadmin create-jdbc-resource --connectionpoolid ei-connection-pool jdbc/dev >> /tmp/setup_connections 2>&1
echo '*********' >> /tmp/setup_connections

该文件在docker实例中运行。这两个 asadmin 命令很重要,但同样,在docker实例中对/ tmp /
setup_connections进行了一些调试

密码等是从AWS环境获得的。

此时,我唯一不能做的就是在首次部署时使用AWS环境变量。我不知道为什么,但是我似乎只能在实例启动并运行后对其进行设置。这意味着我必须部署两次,分别是虚拟部署,环境编辑和真实部署。

所以总结一下

  • 部署时
    • .config文件会生成ec2-post-deploy-hook文件,
    • AWS系统将docker-post-deploy-hook部署为部署到glassfish的.war的一部分
  • 在部署后,
    • 弹性beantalk系统运行ec2-post-deploy-hook
    • ec2-post-deploy-hook运行docker-post-deploy-hook
    • docker-post-deploy-hook以管理员身份运行以设置适当的连接池
  • 在运行时,Web应用程序中的Java代码会利用连接池

而且一切正常。看得出来这有点丑陋,但是,我也是。



 类似资料:
  • 问题内容: 如何在AWS ElasticBeanstalk上安装和配置Redis?有人知道如何编写.ebextension脚本来实现这一目标吗? 问题答案: AWS Elastic Beanstalk确实通过.ebextensions文件夹提供了资源配置。本质上,除了应用程序之外,您还需要告诉Elastic Beanstalk您还希望提供什么。用于置备到默认vpc。你需要 创建一个.ebexten

  • 是否可以在lambda中运行docker? 错误:响应:{“errorType”:“Runtime.ExitError”,“errorMessage”:“RequestId:d7a7dc46-b4e2-439b-a16b-e4ee1de1f7c5错误:运行时已退出,但出现错误:退出状态127”} 请求ID:“d7a7dc46-b4e2-439b-a16b-e4ee1de1f7c5” 函数日志: S

  • 我可以在AWS Elastic Beanstek上配置Linux交换空间吗?(从2016年开始)的答案展示了如何使用配置文件为AWS Elastic Beanstek环境配置Linux交换空间。 但是,AWS 文档在 Linux 服务器上定制软件有以下说明:对于较新的 Amazon Linux 2 平台: 在 Amazon Linux 2 平台上,我们强烈建议您使用构建文件,而不是在 .eb 扩展

  • 我想通过Docker容器在AWS Lamda上运行selenium脚本。 我正在使用AWS EC2构建容器,然后通过AWS Lambda RIE在本地测试容器。一旦测试成功,容器将在ECR注册,以便馈送AWS Lambda。 尽管RIE在EC2上的本地测试总是成功的,但我无法让Lambda正常工作。Lambda测试当前总是失败,并显示以下错误消息: 在这里,您可以找到我实际使用的所有代码: 文档

  • 问题内容: 我正在运行Ubuntu 11.10,并已在该系统上安装Jenkins。 我看过一些有关如何设置反向代理(Apache,Nginx等)的教程,但是,这是专门用于jenkins的VM,我想让jenkins在端口80上运行时尽可能保持精简。 我发现了新贵的配置,并将端口修改为80 当我通过启动jenkins时,显示它运行了几秒钟然后终止。 这是因为jenkins 在特权端口上以用户身份运行吗

  • 我使用Amazon模板使用C#Dotnet3.1创建了一个AWS Lambda解决方案 这将创建一个lambda函数,其处理程序为以及一些文件和 部署它的标准方法是安装 然后运行 请注意,配置文件是可选的,但我在该配置文件下配置了AWS。这将提示输入CloudFormation堆栈名称(例如:foo)和S3 bucket(例如:my-bucket)并将其部署到自定义配置文件下配置的“真实”AWS