跳坑之java链接oracle的集群

跳坑之java链接oracle的集群

1570发表于2017-09-14

前段时间遇到问题,记录一下。也为和我一样入坑的同学共勉。

本地开发环境完全没问题,测试环境也没问题。发布到线就不行,项目启动成功但是spring mvc始终报404。刚开始就猜是不是数据库问题,但是运维的同事说同一台服务器上其它项目运行的好好,很快就排除了这个原因。

接下来就是痛苦的各种找问题,各种排查无果,后来打开spring日志。我用的logback日志框架,在logback配置文件中加入了如下代码:

<logger name="org.springframework" additivity="false" level="DEBUG">
	<appender-ref ref="DATELOG"/>
	<appender-ref ref="DATELOG_ERROR"/>
	<appender-ref ref="STDOUT" />
</logger>
DATELOG,DATELOG_ERROR,STDOUT是我自己定义的appender,修改后启动tomcat,让人激动的错误出现了。
exception: Listener refused the connection with the following error:
ORA-12505, TNS:listener does not currently know of SID given in connect descriptor
The Connection descriptor used by the client was:
192.168.11.88:1521:mydb

从上面错误信息可以很容易的猜到是数据库链接出问题了。

问一下同事原来线上是oracle集群rac,运维的同事在部署的时候也没有注意数据库链接的问题。

我们都知道j2ee开发java链接oracle一般都采用thin的形式链接oracle,因为这样不用依赖oracle的客户端。细心的同学可能会注意到有三种写法,但是三者的区别是什么呢?

方法一、

jdbc:oracle:thin:@192.168.100.217:1521/prod

/<service_name> 这种格式是Oracle 推荐的格式,因为对于集群来说,每个节点的SID 是不一样的,但是SERVICE_NAME 确可以包含所有节点。如果使用了oracle集群要使用这种方式。

方法二、

jdbc:oracle:thin:@192.168.100.217:1521:prod

:<SID> 


方法三、

jdbc:oracle:thin:@prod

@<TNSName> 

我报错的项目就采用了第二种方法,线上是采用了oracle集群rac,因为service_name和sid是有区别的,通过sid来链接集群的就出问题。

把项目中数据库链接中的“:”改成"/"就完美解决了。


ps===============================坑里学到的东东

Oracle 实例名服务名 请问SID和Service_Name有什么区别啊?

可以简单的这样理解:一个公司比喻成一台服务器,数据库是这个公司中的一个部门。


1.SID:一个数据库可以有多个实例(如RAC),SID是用来标识这个数据库内部每个实例的名字,就好像一个部门里,每个人都有一个自己的名字。

2.SERVICE_NAME:是这个数据库对外宣称的名字,外面的人要想连接我这个数据库,你就在客户端的连接串里写上service_name。它就像一个部门的名字,这个部门的名称在看门大爷(listener)那里有登记,

看门大爷一看你是要找SERVICE_NAME这个部门,就告诉你我们公司确实有这个部门,于是你就找到了,连接就建立了。


一句话来说就是:SID是对内的,是实例级别的一个名字,用来内部之间称呼用。SERVICE_name是对外的,

是数据库级别的一个名字,用来告诉外面的人,我数据库叫"SERVICE_NAME"。

你可以通过service_name参数指定这个名字是什么,可以有多个名字,名字随便起,叫狗蛋,翠花都没关系。

如果你不指定,默认的是Db_name. Db_domain,也就是global_name。

数据库里,还有ORACLE_SID,是告诉OS系统,我这个实例叫做什么。这些易混淆的名字,你要记住,

他们不是指数据库,就是指实例,就这两个东西,别无其它。他们具体用哪个名字,是要看对谁而言,

是什么场合。是对数据库,还是对操作系统,还是对外部链接。就像你对父母而言,你有小名叫幺儿;

对同学而言,你有外号叫灯泡;对办事机构,你有正规的名字叫王小明。但归根到底,是一回事。分清楚这点,就不容易混了。


oracel怎么查询是否打开oracle rac

查看数据库参数
SQL> show parameter cluster

NAME                                 TYPE       VALUE
------------------------------------ ---------- ------------------------------
cluster_database                     boolean    TRUE
cluster_database_instances           integer    2
cluster_interconnects                string

cluster_database 是true 证明也是rac模式

如何查看oracle的sid

ps -ef|grep pmon

可以从进程名字里看到

也可以通过
sqlplus / as sysdba
show parameter instance_name



小编蓝狐