Java 从jdbc连接到oracle服务器获取活动主机和端口(不解析url)

Java 从jdbc连接到oracle服务器获取活动主机和端口(不解析url),java,oracle,jdbc,Java,Oracle,Jdbc,有没有办法将JDBC连接的主机和端口连接到Oracle DB服务器 我知道,我可以解析URL。但我们使用故障转移,我想知道我实际连接的是哪台服务器。由于我们使用的格式不同,URL解析是静态的并且容易出错 在连接元数据中找不到它 使用“从全局_name中选择*”可以获得servicename。但是我还没有找到一种方法来获取我们连接到的主机和端口 有什么想法吗?以下是您可以通过连接获得的一些信息: Connection dbConnection = null;

有没有办法将JDBC连接的主机和端口连接到Oracle DB服务器

我知道,我可以解析URL。但我们使用故障转移,我想知道我实际连接的是哪台服务器。由于我们使用的格式不同,URL解析是静态的并且容易出错

在连接元数据中找不到它

使用“从全局_name中选择*”可以获得servicename。但是我还没有找到一种方法来获取我们连接到的主机和端口


有什么想法吗?

以下是您可以通过连接获得的一些信息:

            Connection dbConnection = null;
        try {
            dbConnection = dataSource.getConnection();
            DatabaseMetaData dbMetaData = dbConnection.getMetaData();
            getLogger().debug("DB Product Name   = " + dbMetaData.getDatabaseProductName());
            getLogger().debug("DB Product Version= " + dbMetaData.getDatabaseProductVersion());
            getLogger().debug("DB Driver Name    = " + dbMetaData.getDriverName());
            getLogger().debug("DB Driver Version = " + dbMetaData.getDriverVersion());
            getLogger().debug("DB Username         = " + dbMetaData.getUserName());
            getLogger().debug("DB URL            = " + dbMetaData.getURL());
        } catch (Exception e) {
            getLogger().debug("Failed to recover DatabaseMetaData: "+e.getMessage(), e);
        } finally {
            if (dbConnection != null) {
                try {
                    dbConnection.close();
                } catch (Exception ex) {
                    getLogger().error("Failed to close the DB connection: "+ex.getMessage(), ex);
                }
            }
        }
如果需要更多/不同的信息,请检查数据库元数据。 输出示例:

DB Product Name   = Oracle
DB Product Version= Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production
With the Partitioning, Automatic Storage Management, OLAP, Data Mining
and Real Application Testing options
DB Driver Name    = Oracle JDBC driver
DB Driver Version = 11.2.0.2.0
DB Schema         = XXXXX
DB URL            = jdbc:oracle:thin:@XXX.XXX.XXX.XXX:11010:MYSID

不确定该端口实际上是侦听器上的端口,但对于主机,您可以尝试:

select utl_inaddr.get_host_name, utl_inaddr.get_host_address from dual;
在数据库端还有其他选项,例如查询v$instance,请参阅。例如,您可能使用的SID:

select sys_context('userenv','instance_name') from dual;
希望有帮助。还请注意,我使用utl_inaddr,但仅用于日志记录和电子邮件/警报目的

编辑:


另外,请注意,对欺骗Oracle会话信息存在一些顾虑,这也是我注意到我只使用它向警报和日志添加上下文的部分原因。我并不假装知道所有的细节,但基本上这个问题涉及一个客户假装是某人或来自其他地方。由于您是通过java应用程序控制连接的,因此这不应该是一个问题,但如果您在意,请参阅了解更多信息。

这将为您提供正在运行的实例的主机名:

从v$instance中选择主机名

select sys_context('userenv','instance_name') from dual;
select sys_context('userenv','instance') from dual;
select sys_context('userenv','server_host') from dual;

文档:

为什么您需要知道应用程序连接到哪个主机?您想要满足什么用例?我们有几个应用服务器可以连接到几个db服务器。可以通过不同的URL访问应用程序服务器。如果我们发现一个错误,我们需要一个简单的方法来知道我们正在寻找的是应用服务器和数据库服务器的组合。为了实现这一点,我们希望在web gui上显示应用程序服务器和db服务器。对于故障转移测试,最好知道我们实际连接到了哪个db服务器。thx是答案。但这不是我需要的信息。我需要我们实际连接的主机、端口和sid。我已经用一个输出示例编辑了我的文章。如果您想获得url的单个组件,您可能必须对其进行解析,因为我认为这些元素不是单独可用的,但无论哪种方式,都很简单:搜索char@然后在char上拆分:format is…@HOSTNAME:PORT:SIDI已经完成了元数据和url解析。但是在我们的例子中,URL有点复杂,并且经常变化。e、 g.jdbc:oracle:thin:@DESCRIPTION\u LIST=DESCRIPTION=CONNECT\u TIMEOUT=10RETRY\u COUNT=3ADDRESS\u LIST=ADDRESS=PROTOCOL=tcpHOST=xyz1.abc.递解=6778CONNECT\u DATA=SERVICE\u NAME=Service2.oracle.db.deDESCRIPTION=CONNECT\u TIMEOUT=60RETRY\u COUNT=1ADDRESS\u LIST=ADDRESS=PROTOCOL=tcpHOST=xyz2.abc.abc.递解=6777CONNECT\u DATA=SERVICE\u NAME=Service2.oracle.db.de解析这种url和您提到的类型。可能有两个以上的服务器,我想知道,我实际上连接到了哪个服务器,但我无法从url中找到。可能有一个系统表或函数提供了这些信息。我不是oracle专家,我想知道是否有可能获得此信息。似乎连接池是由db本身管理的。在这种情况下,像下面tbone指定的那样的直接查询将是一种解决方案,假设db实例可用并回答查询,如果得不到识别哪个db实例失败的答案,这显然会违背您的目的。我将环顾四周,看看是否有一种方法可以用jdbc驱动程序实现不同的操作。Thx提供安全提示!我们正在考虑使用密码保护此信息。只有具有适当权限的登录用户才能看到此信息。您需要让DBA设置ACL,以便在Oracle 11g中运行上述查询,以避免以下ORA-24247:访问控制列表拒绝的网络访问ACL ORA-06512:at SYS.UTL_INADDR,第4行ORA-06512:at SYS.UTL_INADDR,第35行see不适用于我:执行SQL命令时出错:从v$instance ORA-00942中选择主机名:表或视图不存在[SQL State=42000,DB Errorcode=942]如果在sqlplus中运行此查询,是否也会出现此错误?要运行此查询,需要dba权限。然后它也应该在我的JDBC工具中工作。但是我们决定显示“select*from global_name”中的服务名称,该名称在我们的网络中应该是唯一的+感谢你的努力。