解決的問題
docker中的springboot項目訪問docker中的mysql和mongo
-
MongoDB連接報錯
org.springframework.data.mongodb.UncategorizedMongoDbException: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-256, userName='admin', source='pet', password=<hidden>, mechanismProperties=<hidden>}; nested exception is com.mongodb.MongoSecurityException: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-256, userName='admin', source='pet', password=<hidden>, mechanismProperties=<hidden>} at com.zxmt.app.AppApplicationTests.contextLoads(AppApplicationTests.java:72) Caused by: com.mongodb.MongoSecurityException: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-256, userName='admin', source='pet', password=<hidden>, mechanismProperties=<hidden>} at com.zxmt.app.AppApplicationTests.contextLoads(AppApplicationTests.java:72) Caused by: java.lang.IllegalArgumentException: Prohibited character at position 0 at com.zxmt.app.AppApplicationTests.contextLoads(AppApplicationTests.java:72)
跳過SpringBoot打包測試
先看一下最開始的配置
-
application.yml
spring: datasource: url: jdbc:mysql://localhost:3306/pet?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false driver-class-name: com.mysql.cj.jdbc.Driver username: root password: 123456 data: mongodb: host: localhost port: 27017 username: admin password: 123456 database: pet
將項目打包成為jar包拿穴,并上傳到服務器
? 打包的時候,項目會進行測試祈争,然后會出現(xiàn)一個問題稼虎。就是mongodb連接報錯,這個問題是由于我們使用分開寫配置文件选调,host,port,database這種造成的夹供,具體原因我也不太清楚灵份,有人說是jdk版本問題仁堪,所以直接換成uri模式
org.springframework.data.mongodb.UncategorizedMongoDbException: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-256, userName='admin', source='pet', password=<hidden>, mechanismProperties=<hidden>}; nested exception is com.mongodb.MongoSecurityException: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-256, userName='admin', source='pet', password=<hidden>, mechanismProperties=<hidden>}
at com.zxmt.app.AppApplicationTests.contextLoads(AppApplicationTests.java:72)
Caused by: com.mongodb.MongoSecurityException: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-256, userName='admin', source='pet', password=<hidden>, mechanismProperties=<hidden>}
at com.zxmt.app.AppApplicationTests.contextLoads(AppApplicationTests.java:72)
Caused by: java.lang.IllegalArgumentException: Prohibited character at position 0
at com.zxmt.app.AppApplicationTests.contextLoads(AppApplicationTests.java:72)
spring:
datasource:
url: jdbc:mysql://localhost:3306/pet?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 123456
data:
mongodb:
# 重點:mongodb://用戶名:密碼@localhost:27017/數(shù)據(jù)庫名
uri: mongodb://admin:123456@localhost:27017/pet
在jar文件同級目錄新建Dockerfile,內(nèi)容如下
FROM java:8-alpine
ADD app-0.0.1-SNAPSHOT.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar"]
然后在當前目錄執(zhí)行(最后有一個點,表示上下文 ):docker build -t pet-app .
因為docker中運行著mysql和mongo填渠,所以我們直接開始運行pet-app這個自己打包的鏡像
dokcer run -d -p 8080:8080 --name pet-app pet-app
-d 表示后臺運行, --name 表示取一個別名 ,最后一個pet-app表示剛才的鏡像名稱
OK問題來了
你以為一切很順利弦聂,但是你訪問接口會發(fā)現(xiàn)錯誤
Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is java.sql.SQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up.\n### The error may exist in com/zxmt/app/mapper/AgreementMapper.java (best guess)\n### The error may involve com.zxmt.app.mapper.AgreementMapper.selectById\n### The error occurred while executing a query\n### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is java.sql.SQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up."
這個問題就是,docker中的springboot沒能通過localhost:3306訪問到數(shù)據(jù)庫氛什,同時mongo也是訪問不到
解決方案1:直接將localhost改為服務器地址就可以了莺葫,相當于docker中的服務通過網(wǎng)絡訪問服務器端口,服務器再訪問docker枪眉。(⊙o⊙)…這個決絕辦法有點low
解決方案2:使用docker中的--link參數(shù)
-
先修改配置文件捺檬。將原來的主機地址都取一個別名例如下面的mysql,mongo
spring: datasource: url: jdbc:mysql://mysql:3306/pet?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false driver-class-name: com.mysql.cj.jdbc.Driver username: root password: 123456 data: mongodb: uri: mongodb://admin:123456@mongo:27017/pet
-
因為改了這個配置文件,打包的時候會進行測試贸铜,(你想你都寫成jdbc:mysql://mysql:3306這樣了堡纬,測試能通過嗎)所以現(xiàn)在需要配置跳過測試(在pom的properties中加代碼)
<properties> <skipTests>true</skipTests> </properties>
還是Dockerfile打包成鏡像
-
最后是通過鏡像啟動容器的代碼!!!!重點
docker run -p 8080:8080 -d --link=mysql:mysql --link=mongo:mongo --name pet-app pet-app
--link:前面的mysql表示啟動的容器的名稱,后面是別名名稱對應上面的配置文件中的mysql
jdbc:mysql://mysql:3306/pet?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false
當然mongo也是一樣蒿秦。烤镐。
再把之前的錯誤啟動方式貼一次對比一下
# 錯誤的 dokcer run -d -p 8080:8080 --name pet-app pet-app #正確的 docker run -p 8080:8080 -d --link=mysql:mysql --link=mongo:mongo --name pet-app pet-app