将 Spring Boot 应用程序连接到 Docker 容器中的 Oracle 数据库 12.2.0.1

Posted

技术标签:

【中文标题】将 Spring Boot 应用程序连接到 Docker 容器中的 Oracle 数据库 12.2.0.1【英文标题】:Connecting Spring boot application to Oracle database 12.2.0.1 in Docker container 【发布时间】:2019-07-19 19:38:37 【问题描述】:

我将 Oracle 数据库作为 Docker 容器运行,以下是容器详细信息。

Config: 
        "Hostname": "8ad016675bd2",
        "Domainname": "",
        "User": "oracle",
        "AttachStdin": true,
        "AttachStdout": true,
        "AttachStderr": true,
        "ExposedPorts": 
            "1521/tcp": ,
            "5500/tcp": 
        ,
        "Tty": true,
        "OpenStdin": true,
        "StdinOnce": true,
        "Env": [
            "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
            "ORACLE_HOME=/u01/app/oracle/product/12.2.0/dbhome_1",
            "ORACLE_SID=ORCL"
        ],
        "Cmd": [
            "/bin/sh",
            "-c",
            "/bin/bash /home/oracle/setup/dockerInit.sh"
        ],
        "Healthcheck": 
            "Test": [
                "CMD-SHELL",
                "/bin/bash /home/oracle/setup/healthcheck.sh"
            ],
            "Interval": 60000000000,
            "Timeout": 10000000000
        
    ,
    "NetworkSettings": 
        "Bridge": "",
        "SandboxID": "c13a0ee218e9245d7916c7ffb078adf4191a14e100221274f3125975fc6cb5b7",
        "HairpinMode": false,
        "LinkLocalIPv6Address": "",
        "LinkLocalIPv6PrefixLen": 0,
        "Ports": 
            "1521/tcp": [
                
                    "HostIp": "0.0.0.0",
                    "HostPort": "32773"
                
            ],
            "5500/tcp": [
                
                    "HostIp": "0.0.0.0",
                    "HostPort": "32772"
                
            ]
        ,
        "SandboxKey": "/var/run/docker/netns/c13a0ee218e9",
        "SecondaryIPAddresses": null,
        "SecondaryIPv6Addresses": null,
        "EndpointID": "782fa0c989db7f58643416fea7b60165ad00ce3067b7bb7a6af72c0619c31e5a",
        "Gateway": "172.17.0.1",
        "GlobalIPv6Address": "",
        "GlobalIPv6PrefixLen": 0,
        "IPAddress": "172.17.0.2",
        "IPPrefixLen": 16,
        "IPv6Gateway": "",
        "MacAddress": "02:42:ac:11:00:02",
        "Networks": 
            "bridge": 
                "IPAMConfig": null,
                "Links": null,
                "Aliases": null,
                "NetworkID": "486e58b051b36eb20838e5f9edcb6fe205407e583e75fedf86460ecec41dd9c5",
                "EndpointID": "782fa0c989db7f58643416fea7b60165ad00ce3067b7bb7a6af72c0619c31e5a",
                "Gateway": "172.17.0.1",
                "IPAddress": "172.17.0.2",
                "IPPrefixLen": 16,
                "IPv6Gateway": "",
                "GlobalIPv6Address": "",
                "GlobalIPv6PrefixLen": 0,
                "MacAddress": "02:42:ac:11:00:02",
                "DriverOpts": null
            
        

我正在尝试使用以下凭据通过 Flyway 连接到 Oracle 数据库

spring.jpa.database=oracle
spring.datasource.url=jdbc:oracle:thin:@172.17.0.2:32773/ORCLPDB1
spring.datasource.username=sys
spring.datasource.password=Oradoc_db1

但我收到以下错误

Caused by: oracle.net.ns.NetException: The Network Adapter could not establish the connection
at oracle.net.nt.ConnStrategy.execute(ConnStrategy.java:523) ~[ojdbc8-12.2.0.1.jar:12.2.0.1.0]
at oracle.net.resolver.AddrResolution.resolveAndExecute(AddrResolution.java:521) ~[ojdbc8-12.2.0.1.jar:12.2.0.1.0]
at oracle.net.ns.NSProtocol.establishConnection(NSProtocol.java:660) ~[ojdbc8-12.2.0.1.jar:12.2.0.1.0]
at oracle.net.ns.NSProtocol.connect(NSProtocol.java:286) ~[ojdbc8-12.2.0.1.jar:12.2.0.1.0]
at oracle.jdbc.driver.T4CConnection.connect(T4CConnection.java:1438) ~[ojdbc8-12.2.0.1.jar:12.2.0.1.0]
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:518) ~[ojdbc8-12.2.0.1.jar:12.2.0.1.0]
... 35 common frames omitted
Caused by: java.io.IOException: Connection timed out: connect, socket connect lapse 21030 ms. /172.17.0.2 32773 30000 1 true
at oracle.net.nt.TcpNTAdapter.connect(TcpNTAdapter.java:209) ~[ojdbc8-12.2.0.1.jar:12.2.0.1.0]
at oracle.net.nt.ConnOption.connect(ConnOption.java:161) ~[ojdbc8-12.2.0.1.jar:12.2.0.1.0]
at oracle.net.nt.ConnStrategy.execute(ConnStrategy.java:470) ~[ojdbc8-12.2.0.1.jar:12.2.0.1.0]
... 40 common frames omitted

Unable to obtain connection from database: IO Error: The Network Adapter 
could not establish the connection
---------------------------------------------------------------------------- 
-------------------------------
SQL State  : 08006
Error Code : 17002
Message    : IO Error: The Network Adapter could not establish the 
connection

谁能指出我在这里遗漏了什么?以及如何解决这个问题。

【问题讨论】:

我猜是oracle从1521的容器暴露出来的,你正在尝试连接32773,请确认oracle暴露在32773的端口是不是? @BalajiSrinivasan 端口号似乎没问题。运行docker port 命令给出1521/tcp -> 0.0.0.0:32773 5500/tcp -> 0.0.0.0:32772 你能通过任何 SQL 客户端连接到 oracle 吗? 【参考方案1】:

首先你需要检查容器暴露的正确端口是否为 1521/tcp 端口:

docker port your_containerID 1521/tcp

然后确保容器中的数据库已启动: docker ps (* 在容器状态不健康时检查)

1.- 连接sqlplus

docker exec -it your_containerID bash -c "source /home/oracle/.bashrc; sqlplus /nolog"

2.- 使用例如 SQL Developer IDE 连接 jdbc 并创建一个方案:

create user "MYUSER" identified by  admin123 default tablespace "USERS" temporary tablespace "TEMP";
grant "DBA" to "MYUSER";
grant "RESOURCE" to "MYUSER";

grant SELECT ANY DICTIONARY to "MYUSER";
grant CREATE SEQUENCE to "MYUSER";
grant CREATE SYNONYM to "MYUSER";
grant CREATE SESSION to "MYUSER";
grant CREATE TYPE to "MYUSER";
grant CREATE PROCEDURE to "MYUSER";
grant CREATE DATABASE LINK to "MYUSER";
grant CREATE ANY DIRECTORY to "MYUSER";
grant CREATE TABLE to "MYUSER";
grant EXPORT FULL DATABASE to "MYUSER";
grant UNLIMITED TABLESPACE to "MYUSER";
grant CREATE JOB to "MYUSER";
grant CREATE VIEW to "MYUSER";
grant ALTER SESSION to "MYUSER";

grant EXECUTE on "SYS"."SYS_PLSQL_FAA5F685_2385_1" to "MYUSER";
grant EXECUTE on "SYS"."SYS_PLSQL_D9B1149D_9_1" to "MYUSER";

最后一步在你的 application.yml 中:

datasource:
    username: MYUSER
    password: admin123
    driver-class-name: oracle.jdbc.OracleDriver
    url: jdbc:oracle:thin:@(description=(address=(host=your_docker_ip)(protocol=tcp)(port=your_port_number))(connect_data=(service_name=ORCLPDB1.localdomain)))

【讨论】:

以上是关于将 Spring Boot 应用程序连接到 Docker 容器中的 Oracle 数据库 12.2.0.1的主要内容,如果未能解决你的问题,请参考以下文章

无法将 Spring Boot 应用程序连接到 IBM Informix 数据库

如何将我的 Spring Boot 应用程序连接到 Docker 上的 Redis 容器?

如何将 Docker 内部的 Spring Boot 应用程序连接到 PostgreSQL 外部

如何将 Angular 9 登录页面连接到 Spring Boot 应用程序?

无法将 dockerized spring boot 应用程序连接到 dockerized postgresql

将 Spring Boot Web 应用程序连接到 postgresql 服务器