运行时获取oracle数据库主机名

Sye*_*din 6 java oracle spring spring-boot

有一个 Springboot 应用程序连接到 Oracle 数据。数据库的 URL 配置为

spring.datasource.url=jdbc:oracle:thin:@(DESCRIPTION=\
  (LOAD_BALANCE=OFF)(FAILOVER=ON)\
  (ADDRESS=(PROTOCOL=TCP)(HOST=domainName1.com) (PORT=1521))\
  (ADDRESS=(PROTOCOL=TCP)(HOST=domainName2.com)(PORT=1521))\
  (CONNECT_DATA=(SERVICE_NAME=xyz)))
Run Code Online (Sandbox Code Playgroud)

配置此 URL 后,当一台主机关闭时,应用程序将连接到第二个数据库。数据库的 URL 打印在应用程序运行状况检查中,如下所示

Hello 
version    : 4.0.0
build      : 2022-03-3 
datasource :    oracle.jdbc.OracleDriver
db url     :    jdbc:oracle:thin:@(DESCRIPTION=(LOAD_BALANCE=OFF)(FAILOVER=ON)(ADDRESS=(PROTOCOL=TCP)(HOST=domainName1.com) (PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=domainName2.com)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=xyz)))
db status  :    ok 
Run Code Online (Sandbox Code Playgroud)

我的问题是如何获取正在使用的数据库的主机名,这意味着如何获取应用程序当前正在使用的主机(domainName1 或domainName2)并将其显示在运行状况检查上?例如如下所示。

Hello 
version    : 4.0.0
build      : 2022-03-3
datasource :    oracle.jdbc.OracleDriver
db url     :    jdbc:oracle:thin:@domainName1.com: 1521/coldv1
db status  :    ok (LVZ count = 379)
Run Code Online (Sandbox Code Playgroud)

我用于此健康检查的 java 代码如下所示。

@GetMapping(path = "/healthcheck",
            produces = MediaType.APPLICATION_JSON_VALUE
    )
    public String getServiceStatus(){
        String[] activeProfiles = environment.getActiveProfiles();
        final BeanWrapper accessor = PropertyAccessorFactory.forBeanPropertyAccess(dataSource);
        final String driverClassName = String.valueOf(accessor.getPropertyValue("driverClassName"));
        String url = null;

        if(activeProfiles[1].equals("external_tomcat")) {
            url = String.valueOf(accessor.getPropertyValue("url"));
        }else{
            try {
                String[] dataSourceProperties = nameService.getDataSource();
                url = dataSourceProperties[0];
            } catch (SQLException ex) {
//                throwables.printStackTrace();
                log.error(ex.getMessage(), ex);
            }
        }

        String version = buildProperties.getVersion();
        String buildTimestamp = String.valueOf(buildProperties.getTime());
        BigDecimal count = nameService.getCount("Table_name_of_database");

        StringBuilder result = new StringBuilder("Hello")
                .append("\nversion    :\t")
                .append(version)
                .append("\nbuild      :\t")
                .append(buildTimestamp)
                .append("\ndatasource :\t")
                .append(driverClassName)
                .append("\ndb url     :\t")
                .append(url)
                .append("\ndb status  :\tok  ")
                .append(count.intValue())
                .append(")");
        return result.toString();
    }
Run Code Online (Sandbox Code Playgroud)

名称服务.java

 @Override
    public String[] getDataSource() throws SQLException {
        return getDataSourceProperties();
    }


   

    public String[] getDataSourceProperties() {
        String[] dataSourceProperties = new String[2];
        HikariDataSource dataSource = getDataSourceFromHibernateEntityManager();
        if(dataSource.getJdbcUrl() != null){
            dataSourceProperties[0] = dataSource.getJdbcUrl();
            dataSourceProperties[1] = dataSource.getDataSourceClassName();
        }
        return dataSourceProperties;
    }
Run Code Online (Sandbox Code Playgroud)

Sye*_*din 3

@Olivier 和 @ik_zelf 这两个答案都适合我。我在 Spring Boot 应用程序中实现的方式是使用以下代码片段。

public String getHostNameFromUrl() {
        String sql = "SELECT host_name FROM v$instance";
//        String sql = "SELECT sys_context('USERENV','SERVER_HOST') server_host FROM dual"; this also works
        Query query = entityManager.createNativeQuery(sql);
        return query.getSingleResult().toString();
}
Run Code Online (Sandbox Code Playgroud)

稍后在控制器中我调用此方法以在运行状况检查中显示。