Azure多容器Web应用程序无故停止该网站



我正在尝试在应用程序服务中设置一个带有MySQL容器的Spring Boot API。这是我正在使用的docker撰写文件:

version: '3.8'
services:
mysql:
image: mysql:8
container_name: mysql
restart: always
environment:
- MYSQL_ROOT_PASSWORD=${__dc__MYSQL_ROOT_PASSWORD}
- MYSQL_USER=${__dc__MYSQL_USERNAME}
- MYSQL_PASSWORD=${__dc__MYSQL_PASSWORD}
- MYSQL_DATABASE=${__dc__MYSQL_DATABASE}
thesisapi:
image: ${__dc__IMAGE}
container_name: thesisapi
restart: always
ports:
# Azure Web App exposes port 80
- 80:${__dc__SERVER_PORT}
depends_on:
- mysql
environment:
- SERVER_PORT=${__dc__SERVER_PORT}
- SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/${__dc__MYSQL_DATABASE}
- SPRING_DATASOURCE_USERNAME=${__dc__MYSQL_USERNAME}
- SPRING_DATASOURCE_PASSWORD=${__dc__MYSQL_PASSWORD}
- SPRING_DATASOURCE_DRIVER_CLASS_NAME=com.mysql.cj.jdbc.Driver
- SPRING_JPA_HIBERNATE_DDL_AUTO=update
- SPRING_JPA_DATABASE_PLATFORM=org.hibernate.dialect.MySQL5InnoDBDialect

注意1我在本地运行了上面的docker compose,它工作得很完美。

注意2当将文件上传到应用程序服务时,有实际值而不是变量,即${foo}。

图像的下载工作正常。MySQL服务器启动并表示等待连接,但我的应用程序会失败几次,直到MySQL服务准备就绪。根据我在ms文档中看到的内容,depends_on被忽略了。

几次失败后,我的API启动,但由于某种原因,应用程序服务决定停止容器并重试。然后它一次又一次地做同样的事情……我已经试了几天了,这让我很紧张。

我还有一个前端应用程序映像,我正在上传到应用程序服务,但它与其他服务没有依赖关系,并且可以启动并使用。

我收集的日志:

INFO 1 --- [ task-1] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.1.0.Final}
INFO 1 --- [ task-1] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
ERROR 1 --- [ task-1] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Exception during pool initialization.
com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
...
WARN 1 --- [ task-1] o.h.e.j.e.i.JdbcEnvironmentInitiator : HHH000342: Could not obtain connection to query metadata : Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
...
INFO 1 --- [         task-1] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.MySQL5InnoDBDialect
INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 5000 (http) with context path '/api'
INFO 1 --- [           main] DeferredRepositoryInitializationListener : Triggering deferred initialization of Spring Data repositories…
INFO 1 --- [         task-1] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
INFO 1 --- [         task-1] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
INFO 1 --- [           main] DeferredRepositoryInitializationListener : Spring Data repositories initialized!
INFO 1 --- [           main] my.app.MyApplication                     : Started MyApplication in 25.648 seconds (JVM running for 28.112)
INFO  - Stopping site bsdeploydev3api because it failed during startup.

更新

因此,我放弃了同时运行我的应用程序和MySQL容器,而是为MySQL创建了一个名为Azure Database for MySQL server的专用Azure资源。

在所有设置和完成后,我的应用程序仍然无法连接到数据库,这次的问题是:

java.sql.SQLException:服务器时区值"协调世界时"无法识别或表示多个时区。如果要使用时区支持,则必须配置服务器或JDBC驱动程序(通过"serverTimezone"配置属性(以使用更具体的时区值。

要解决此问题,我必须在连接字符串中设置?serverTimezone=UTC。在那之后,它开始工作了。

现在我想知道以下事情:

  • 当我在本地运行上述docker文件时,我没有遇到这个问题。我想,如果MySQL服务器和试图连接到它的应用程序位于同一系统上,则无需设置该查询参数。

  • 这可能也是部署到App Service的容器的问题吗?实际上,他们住在同一台机器上,我认为他们的行为应该和当地人一样。

所以,如果有人对此有见解,那就太好了。

我在问答中回答了你的问题;A.要点是depends_on在多容器应用程序上不受支持,它会被忽略。我建议删除对MySQL映像的启动依赖。

不确定您是否仍在寻找答案,但我已经以以下方式在api中添加了entrypoint

entrypoint: ["./wait_for.sh", "db:3306", "-t", "3600", "--", "execute", "api"]

此处./wait_for.sh取自https://github.com/vishnubob/wait-for-it

db:3306是运行在3306上的mysql数据库,我的api依赖于

最后两个参数是执行我的api的命令行。

以下是我的docker撰写文件。

version: '3.8'
services:
db:
image: mysql
volumes:
- mysql:/var/lib/mysql
environment:
- MYSQL_DATABASE=dbName
- MYSQL_ROOT_PASSWORD=MyRootPassword!
- MYSQL_USER=dbUser_1
- MYSQL_PASSWORD=dbUser_1sPassword!
restart: always
api:
depends_on:
- db
entrypoint: ["./wait_for.sh", "db:3306", "-t", "3600", "--", "execute", "api"] #waiting very long enough to set the db server up and running
image: <my registry url>/api:latest
ports:
- "80:80"
restart: always
volumes:
mysql:
driver: azure_file
driver_opts:
share_name: Azure_Share_Name
storage_account_name: Azure_Storage_Account_Name
storageaccountkey: Azure_Key

最新更新