Moqui 在 Elastic Beanstalk Tomcat 实例上部署到 AWS
Posted
技术标签:
【中文标题】Moqui 在 Elastic Beanstalk Tomcat 实例上部署到 AWS【英文标题】:Moqui deployment to AWS on Elastic Beanstalk Tomcat instance 【发布时间】:2019-10-03 03:24:54 【问题描述】:背景
我们已经使用 Java 环境在 Elastic Beanstalk 上使用嵌入式 Jetty 服务器运行 Moqui 2.0 大约一年了。出于安全原因,我们让应用程序与 Postgres 数据库一起在私有子网中运行,并通过 *** 访问它。因此,我们从不费心启用 HTTPS 访问。
我们现在想在公共子网中部署 Moqui,这样就可以在没有 *** 的情况下访问它,因此我们需要 HTTPS 访问。
旁注:请记住,我已经阅读了部署选项here!。
独立 Moqui 上的 HTTPS
我的第一个问题是,您能否仅使用嵌入式服务器通过 HTTPS 运行 Moqui?我查看了 MoquiStart 类,main 似乎默认只支持在端口 8080 上初始化 HTTP。有一整节被注释掉了,其中还包含使用注释初始化 HTTPS 和 HTTP/2 的代码:
// Possible code to handle HTTPS, HTTP/2 (h2, h2c):
所以我假设 Moqui 不支持 HTTPS 作为独立应用程序?
Web 应用服务器中的 Moqui
假设 Moqui 没有将 Jetty 配置为服务 HTTPS 请求,使用 Java 环境在公共子网中运行 Moqui 显然是不可接受的。这给我们留下了两个选择。诸如 Docker 之类的容器化(这超出了我的技能范围)或在诸如 Tomcat 之类的应用程序服务器中运行(这也超出了我的技能范围,但我至少在概念上可以理解)。这将我引向issue! 上的 *** 线程。
我不熟悉 J2EE 架构,但我假设一旦在 Tomcat 中运行,Catalina 会绕过 MoquiStart 中的 Jetty 端口初始化不知何故? [希望对我自己的理解进行简要说明]
不管怎样,上面的帖子证实了我在 HTTPS 解决方案的正确轨道上。
问题
问题是,Moqui 不工作。我知道 Tomcat 工作正常,因为当我创建环境时,我使用示例应用程序,我可以通过 HTTP 访问它。一旦我部署了 ROOT.war 文件(我在 ../apache-tomcat-8.5.6/webapps 中找到),我既不能通过 HTTP 也不能通过 HTTPS 访问 Moqui。 (我的安全组完全开放)它尝试连接并最终超时。
我检查了 EB 日志,可能的罪魁祸首记录在 catalina.YYYY-MM-DD.log 文件中。
14-May-2019 21:21:07.101 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/var/lib/tomcat8/webapps/ROOT]
14-May-2019 21:21:23.946 SEVERE [localhost-startStop-1] org.apache.catalina.core.StandardContext.startInternal One or more listeners failed to start. Full details will be found in the appropriate container log file
14-May-2019 21:21:23.956 SEVERE [localhost-startStop-1] org.apache.catalina.core.StandardContext.startInternal Context [] startup failed due to previous errors
14-May-2019 21:21:23.965 WARNING [localhost-startStop-1] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [ROOT] appears to have started a thread named [AsyncAppender-AsyncLog] but has failed to stop it. This is very likely to create a memory leak.
堆栈跟踪如下:
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
java.util.concurrent.ArrayBlockingQueue.take(ArrayBlockingQueue.java:403)
org.apache.logging.log4j.core.appender.AsyncAppender$AsyncThread.run(AsyncAppender.java:282)
直接的下游错误是:
14-May-2019 21:21:23.989 SEVERE [localhost-startStop-1] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks The web application [ROOT] created a ThreadLocal with key of type [com.hazelcast.internal.util.ThreadLocalRandom$1] (value [com.hazelcast.internal.util.ThreadLocalRandom$1@4379b697]) and a value of type [com.hazelcast.internal.util.ThreadLocalRandom] (value [com.hazelcast.internal.util.ThreadLocalRandom@37d77b2b]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
14-May-2019 21:21:24.006 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/var/lib/tomcat8/webapps/ROOT] has finished in [16,904] ms
MoquiActualConf 的相关部分是:
...
<default-property name="webapp_http_host" value="[OUR_IP_HERE]"/>
<default-property name="webapp_http_port" value="80"/>
<default-property name="webapp_https_port" value="443"/>
<default-property name="webapp_https_enabled" value="true"/>
<default-property name="entity_ds_db_conf" value="h2"/>
<default-property name="entity_ds_host" value="localhost"/>
<default-property name="entity_ds_port" value=""/>
<default-property name="entity_ds_database" value="moqui"/>
<default-property name="entity_ds_url" value="jdbc:h2:$moqui_runtime/db/h2/$entity_ds_database;lock_timeout=30000"/>
<default-property name="entity_ds_schema" value=""/>
<default-property name="entity_ds_user" value="sa"/>
<default-property name="entity_ds_password" value="sa"/>
...
<webapp name="webroot" http-port="80" http-host="[OUR_IP_HERE]" https-port="443" https-host="[OUR_IP_HERE]" https-enabled="true" require-session-token="true" websocket-timeout="600000">
<root-screen host=".*" location="component://webroot/screen/webroot.xml"/>
<error-screen error="unauthorized" screen-path="error/Unauthorized"/>
<error-screen error="forbidden" screen-path="error/Forbidden"/>
<error-screen error="not-found" screen-path="error/NotFound"/>
<error-screen error="too-many" screen-path="error/TooMany"/>
<error-screen error="internal-error" screen-path="error/InternalError"/>
<listener class="org.moqui.impl.webapp.MoquiSessionListener"/>
<servlet name="MoquiServlet" class="org.moqui.impl.webapp.MoquiServlet" load-on-startup="1">
<url-pattern><![CDATA[/*]]></url-pattern>
</servlet>
<servlet name="MoquiFopServlet" class="org.moqui.impl.webapp.MoquiFopServlet" load-on-startup="1">
<url-pattern><![CDATA[/fop/*]]></url-pattern>
</servlet>
<session-config timeout="60"/>
<endpoint path="/notws" class="org.moqui.impl.webapp.NotificationEndpoint" timeout="3600000" enabled="true"/>
...
我已经在 EC2 实例的 Tomcat 内部挖掘了 3 天,但一无所获,因此非常感谢一些帮助。
PS:在不相关的说明中,由于某种原因,MoquiActualConf 被 MoquiProductionConf 覆盖,而不是 Procfile 中指定的 MoquiTestConf。
web: java -Xmx1024M -cp . MoquiStart port=8080 conf=conf/MoquiTestConf.xml
我认为这不是问题的原因,但在指向生产数据库等时会导致问题。
【问题讨论】:
【参考方案1】:我通过设置 ec2 负载均衡器设法使 AWS EB 中的 Moqui 实例可以通过 HTTPS 访问。很明显,Moqui 的 jetty 监听端口 5000,ec2 nginx 监听端口 80(并将其转发到端口 5000),ec2 负载均衡器监听端口 80 和 443(并将其转发到 ec2 Nginx 端口 80)。 如果您不想使用负载均衡器,您可以设置 ec2 Nginx 以侦听 HTTPS 并将其转发到 Moqui 的码头端口 5000,就像 Nginx HTTP 一样。 最不推荐的方法是通过环境变量传递一些 https 码头的参数,在 MoquiStart 中可能需要进行一些小的更改。那是几年前的事了,我不记得细节了,但 Jetty 能够以这种方式提供 HTTPS。
【讨论】:
【参考方案2】:webapp 元素上的 http* 属性用于配置 URL 写入,而不是用于配置 Moqui 外部的 Web 服务器。 Moqui 在 Tomcat 或 Jetty 等 Java Servlet 容器中运行,即使使用嵌入式 Jetty 方法也是如此,并且 Servlet 容器的配置是配置 HTTP 接口的地方。
通常,终止 HTTPS 的最佳方法是使用基于 httpd 或 nginx 的反向代理。即使是 ElasticBeanstalk 映像默认情况下也会执行此操作(使用 httpd),如果您通过 AWS EB 配置 HTTPS 证书,则由 httpd 处理它。 Docker Compose 示例中的 nginx-proxy 使用了相同的方法。
【讨论】:
嗯,好的。好吧,让我受过教育!那么我应该坚持使用 Java SE 部署并阅读有关通过 AWS 配置 HTTPS 证书的内容吗?会给你一个狂欢,让你知道我是怎么过的。感谢您的回复! David,我终于成功地获得了一个 .ebextensions 文件夹,以便在 Java SE 单实例上成功地将 HTTP 重定向到 HTTPS。我现在唯一的问题是 Moqui 在屏幕上用 http 写出 URL。根据您之前的反馈,我在 Moqui*Conf.xml 的 web-app 元素上尝试了各种关闭 http-host、http-port、https-port 和 https-enabled 的组合,但无济于事。有小费吗?请记住,反向代理配置为在端口 5000 上与 Moqui 通信。谢谢。 更新:修改 http-host 正确更改返回 html 中的域,并添加 http-port="5000" 将端口号添加到域。 https-port 和 https-enabled 似乎没有做任何事情。以上是关于Moqui 在 Elastic Beanstalk Tomcat 实例上部署到 AWS的主要内容,如果未能解决你的问题,请参考以下文章
Amazon Elastic BeanStalk 错误:无法创建 AWS Elastic Beanstalk 应用程序版本
text 在Elastic Beanstalk上安装telegraf代理
如何在 elastic-beanstalk 中应用 ruby 版本补丁