不管是經過 JDBC 仍是經過 命令行鏈接 Trafodion ,老是偶爾出現 unable to evaluate address TCP:null 的異常。java
org.trafodion.jdbc.t4.HPT4Exception: Unable to evaluate address TCP:null:1.$Z010B5Z,null/23403:ODBC Cause: null Connecting to database... at org.trafodion.jdbc.t4.HPT4Messages.createSQLException(HPT4Messages.java:284) at org.trafodion.jdbc.t4.HPT4Messages.createSQLException(HPT4Messages.java:232) at org.trafodion.jdbc.t4.Address.validateAddress(Address.java:97) at org.trafodion.jdbc.t4.ConnectReply.fixupSrvrObjRef(ConnectReply.java:137) at org.trafodion.jdbc.t4.T4_Dcs_Connect.getConnection(T4_Dcs_Connect.java:98) at org.trafodion.jdbc.t4.InterfaceConnection.connect(InterfaceConnection.java:791) at org.trafodion.jdbc.t4.InterfaceConnection.<init>(InterfaceConnection.java:176) at org.trafodion.jdbc.t4.TrafT4Connection.makeConnection(TrafT4Connection.java:1611) at org.trafodion.jdbc.t4.TrafT4Connection.<init>(TrafT4Connection.java:1564) at org.trafodion.jdbc.t4.HPT4DataSource.getConnection(HPT4DataSource.java:132) at org.trafodion.jdbc.t4.HPT4DataSource.getConnection(HPT4DataSource.java:176) at org.trafodion.jdbc.t4.T4Driver.connect(T4Driver.java:186) at java.sql.DriverManager.getConnection(DriverManager.java:571) at java.sql.DriverManager.getConnection(DriverManager.java:215) at TrafodionConn.run(TrafodionConn.java:22) at TrafodionConn.main(TrafodionConn.java:81) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
以前一直有個錯誤的想法,認爲是 JDBC 驅動包的問題,一直在找Trafodion 的源代碼來分析,追蹤了很久都找不到問題所在node
後來聽同事說,用服務器的上的命令行鏈接也會報錯,就測試了下發現果真報錯(注意有兩個錯誤信息),錯誤信息以下:sql
Host Name/IP Address: xdata67:23400 User Name: zz *** ERROR[29111] Unable to evaluate address TCP:null:1.$Z010B5H,null/23402:ODBC Cause: null: 未知的名稱或服務 *** ERROR[29111] Unable to evaluate address TCP:null:1.$Z010B5Z,null/23403:ODBC Cause: null
瞭解到這個信息就知道了不是 JDBC 驅動的問題,應該是 Trafodion 的某個服務異常致使的。shell
經過觀察,偶然發現 $Z010B5Z 這個很熟悉,好像在以前對 Trafodion 進行管理的時候見過。數據庫
立馬在 Trafodion 安裝的集羣上 執行 sqps 命令,查看當前 Trafodion 的進程信息apache
[trafodion@xdata67 scripts]$ sqps Processing cluster.conf on local host xdata67 [$Z00152S] Shell/shell Version 1.0.1 Apache_Trafodion Release 2.0.1 (Build release [DEV], date 24Jun16) [$Z00152S] %ps [$Z00152S] NID,PID(os) PRI TYPE STATES NAME PARENT PROGRAM [$Z00152S] ------------ --- ---- ------- ----------- ----------- --------------- [$Z00152S] 000,00038200 000 WDG ES--A-- $WDG000 NONE sqwatchdog [$Z00152S] 000,00038201 000 PSD ES--A-- $PSD000 NONE pstartd [$Z00152S] 000,00038334 001 GEN ES--A-- $TSID0 NONE idtmsrv [$Z00152S] 000,00038349 001 DTM ES--A-- $TM0 NONE tm [$Z00152S] 000,00039024 001 GEN ES--A-- $ZSC000 NONE mxsscp [$Z00152S] 000,00039202 001 SSMP ES--A-- $ZSM000 NONE mxssmp [$Z00152S] 000,00045613 001 GEN ES--A-- $Z001288 NONE mxosrvr [$Z00152S] 000,00045638 001 GEN ES--A-- $Z00128Y NONE mxosrvr [$Z00152S] 000,00049097 001 GEN ES--A-- $Z00152S NONE shell [$Z00152S] 001,00008006 000 WDG ES--A-- $WDG001 NONE sqwatchdog [$Z00152S] 001,00008007 000 PSD ES--A-- $PSD001 NONE pstartd [$Z00152S] 001,00008132 001 DTM ES--A-- $TM1 NONE tm [$Z00152S] 001,00008597 001 GEN ES--A-- $ZSC001 NONE mxsscp [$Z00152S] 001,00008702 001 SSMP ES--A-- $ZSM001 NONE mxssmp [$Z00152S] 001,00013667 001 GEN ES--A-- $Z010B5H NONE mxosrvr --果真在這裏 [$Z00152S] 001,00013684 001 GEN ES--A-- $Z010B5Z NONE mxosrvr --果真在這裏 [$Z00152S] 002,00026976 000 PSD ES--A-- $PSD002 NONE pstartd [$Z00152S] 002,00026975 000 WDG ES--A-- $WDG002 NONE sqwatchdog ......
驚喜的發現了上面的信息,看信息應該是 mxosrvr 的進程名稱,發現前面有進程的 pid 號,下一步經過 pid 查找 對應的 mxosrvr 在那臺機器上,由於 Trafodion 是分佈式是系統,各進程分佈在集羣各個機器上。【文末分析爲何鏈接 Trafodion 進程 會定位鏈接到 mxosrvr 進程,這裏就不打斷】bash
[trafodion@xdata67 scripts]$ pdsh -w xdata[67-71] ps -ef | grep 13684 | grep -v grep xdata68: 503 13684 13483 0 09:31 ? 00:00:01 mxosrvr -ZKHOST xdata67:2181,xdata68:2181,xdata69:2181 -RZ null:2:1 -ZKPNODE /trafodion -CNGTO 60 -ZKSTO 180 -EADSCO 0 -TCPADD null -MAXHEAPPCT 0 -STATISTICSINTERVAL 60 -STATISTICSLIMIT 60 -STATISTICSTYPE aggregated -STATISTICSENABLE true -SQLPLAN true -PORTMAPTOSECS -1 -PORTBINDTOSECS -1 [trafodion@xdata67 scripts]$ pdsh -w xdata[67-71] ps -ef | grep 13667 | grep -v grep xdata68: 503 13667 13456 0 09:31 ? 00:00:01 mxosrvr -ZKHOST xdata67:2181,xdata68:2181,xdata69:2181 -RZ null:2:2 -ZKPNODE /trafodion -CNGTO 60 -ZKSTO 180 -EADSCO 0 -TCPADD null -MAXHEAPPCT 0 -STATISTICSINTERVAL 60 -STATISTICSLIMIT 60 -STATISTICSTYPE aggregated -STATISTICSENABLE true -SQLPLAN true -PORTMAPTOSECS -1 -PORTBINDTOSECS -1
經過定位發現兩個出錯的 mxosrvr 都在 xdata68 這臺機器上,第一時間的想法 - 難道只是巧合?服務器
因而重啓 Trafodion的 DCS服務(mxosrvr的名稱會變) 又執行上面的流程測試了一遍,發現出錯的mxosrvr 進程仍是在 xdata68 機器上,這些確定了應該不是偶然,和xdata68 這臺機器的特殊環境應該有關係。網絡
知道問題所在內心就有底多了,知道至少找對路了。這裏能夠總結一個問題定位心得 :對於偶然出現的問題必定要找出問題的規律。架構
找到了出錯的進程,就想這兩個進程和其餘機器上的正常的進程有什麼區別呢?
因而就查了下 xdata68(異常機器)的 mxosrvr 進程信息:
[trafodion@xdata68 conf]$ ps -ef | grep mxosrvr 503 13456 9801 0 09:31 ? 00:00:00 /bin/sh -c cd /home/trafodion/apache-trafodion_server;. sqenv.sh;mxosrvr -ZKHOST xdata67:2181,xdata68:2181,xdata69:2181 -RZ null:2:2 -ZKPNODE "/trafodion" -CNGTO 60 -ZKSTO 180 -EADSCO 0 -TCPADD null -MAXHEAPPCT 0 -STATISTICSINTERVAL 60 -STATISTICSLIMIT 60 -STATISTICSTYPE aggregated -STATISTICSENABLE true -SQLPLAN true -PORTMAPTOSECS -1 -PORTBINDTOSECS -1 503 13483 9801 0 09:31 ? 00:00:00 /bin/sh -c cd /home/trafodion/apache-trafodion_server;. sqenv.sh;mxosrvr -ZKHOST xdata67:2181,xdata68:2181,xdata69:2181 -RZ null:2:1 -ZKPNODE "/trafodion" -CNGTO 60 -ZKSTO 180 -EADSCO 0 -TCPADD null -MAXHEAPPCT 0 -STATISTICSINTERVAL 60 -STATISTICSLIMIT 60 -STATISTICSTYPE aggregated -STATISTICSENABLE true -SQLPLAN true -PORTMAPTOSECS -1 -PORTBINDTOSECS -1 503 13667 13456 0 09:31 ? 00:00:02 mxosrvr -ZKHOST xdata67:2181,xdata68:2181,xdata69:2181 -RZ null:2:2 -ZKPNODE /trafodion -CNGTO 60 -ZKSTO 180 -EADSCO 0 -TCPADD null -MAXHEAPPCT 0 -STATISTICSINTERVAL 60 -STATISTICSLIMIT 60 -STATISTICSTYPE aggregated -STATISTICSENABLE true -SQLPLAN true -PORTMAPTOSECS -1 -PORTBINDTOSECS -1 503 13684 13483 0 09:31 ? 00:00:02 mxosrvr -ZKHOST xdata67:2181,xdata68:2181,xdata69:2181 -RZ null:2:1 -ZKPNODE /trafodion -CNGTO 60 -ZKSTO 180 -EADSCO 0 -TCPADD null -MAXHEAPPCT 0 -STATISTICSINTERVAL 60 -STATISTICSLIMIT 60 -STATISTICSTYPE aggregated -STATISTICSENABLE true -SQLPLAN true -PORTMAPTOSECS -1 -PORTBINDTOSECS -1 503 26101 57226 0 10:14 pts/1 00:00:00 grep mxosrv
xdata70 (正常機器) 的 mxosrvr 進程信息:
[trafodion@xdata70 conf]$ ps -ef | grep mxosrvr 503 55695 52775 0 09:31 ? 00:00:00 /bin/sh -c cd /home/trafodion/apache-trafodion_server;. sqenv.sh;mxosrvr -ZKHOST xdata67:2181,xdata68:2181,xdata69:2181 -RZ xdata70:4:2 -ZKPNODE "/trafodion" -CNGTO 60 -ZKSTO 180 -EADSCO 0 -TCPADD 172.18.84.70 -MAXHEAPPCT 0 -STATISTICSINTERVAL 60 -STATISTICSLIMIT 60 -STATISTICSTYPE aggregated -STATISTICSENABLE true -SQLPLAN true -PORTMAPTOSECS -1 -PORTBINDTOSECS -1 503 55772 52775 0 09:31 ? 00:00:00 /bin/sh -c cd /home/trafodion/apache-trafodion_server;. sqenv.sh;mxosrvr -ZKHOST xdata67:2181,xdata68:2181,xdata69:2181 -RZ xdata70:4:1 -ZKPNODE "/trafodion" -CNGTO 60 -ZKSTO 180 -EADSCO 0 -TCPADD 172.18.84.70 -MAXHEAPPCT 0 -STATISTICSINTERVAL 60 -STATISTICSLIMIT 60 -STATISTICSTYPE aggregated -STATISTICSENABLE true -SQLPLAN true -PORTMAPTOSECS -1 -PORTBINDTOSECS -1 503 56060 55695 0 09:31 ? 00:00:11 mxosrvr -ZKHOST xdata67:2181,xdata68:2181,xdata69:2181 -RZ xdata70:4:2 -ZKPNODE /trafodion -CNGTO 60 -ZKSTO 180 -EADSCO 0 -TCPADD 172.18.84.70 -MAXHEAPPCT 0 -STATISTICSINTERVAL 60 -STATISTICSLIMIT 60 -STATISTICSTYPE aggregated -STATISTICSENABLE true -SQLPLAN true -PORTMAPTOSECS -1 -PORTBINDTOSECS -1 503 56135 55772 0 09:31 ? 00:00:13 mxosrvr -ZKHOST xdata67:2181,xdata68:2181,xdata69:2181 -RZ xdata70:4:1 -ZKPNODE /trafodion -CNGTO 60 -ZKSTO 180 -EADSCO 0 -TCPADD 172.18.84.70 -MAXHEAPPCT 0 -STATISTICSINTERVAL 60 -STATISTICSLIMIT 60 -STATISTICSTYPE aggregated -STATISTICSENABLE true -SQLPLAN true -PORTMAPTOSECS -1 -PORTBINDTOSECS -1 503 61947 22497 0 10:14 pts/0 00:00:00 grep mxosrvr
經過對比發現 68 機器 有個RZ參數爲null, 而 70 機器傳了準確的值
對,就是這裏了,終於找到問題了。
爲何 68 這臺機器 這個 -RZ 參數會是 null 呢?這個參數從哪裏傳過來的?
面對這兩個問題,就去繼續扒。順着 mxosrvr 的父進程ID就去找,發現 mxosrvr 是經過一個 sh 啓動的,而這個 sh 又是誰啓動的呢?
經過 sh 進程的父進程 ID 找到是以下一個進程
經過我對 Trafodion 的瞭解和對以上信息的判斷,上面找到的進程就是各個機器上的 DCS Server 進程,這個時候就必須補上Trafodion 的架構圖了,否則後面沒辦法講了
經過上面兩種圖,就能夠很清晰的明白,mxosrvr 是由各個機器上的 Dcs Server 進程來啓動的。理解了上面的信息,就來繼續回答上面的問題,爲何 啓動 mxosrvr 進程帶的 -RZ 參數是 null 呢?
要回答這個問題,就只能深刻到 Trafodion 的源代碼了。來,源代碼走起。
接下來就進入咱們的源代碼分析階段,首先申明,這裏分析的 Trafodion 源代碼只是和咱們問題相關的部分,因此你們看的時候顯得有些跳脫,不過不要緊,能解決咱們的問題就能夠。若是你們想對 Trafodion 有更深刻的瞭解,還只能系統的去分析源碼。
和本問題相關的源代碼結構大體簡化以下:
瞭解了大概結構,接下來咱們看和咱們問題具體相關的地方,咱們先找到,在代碼什麼地方會啓動上面咱們分析的 sh 命令,就下面這條,咱們的 mxosrvr 進程就是這條命令啓動的。
/bin/sh -c cd /home/trafodion/apache-trafodion_server;. sqenv.sh;mxosrvr -ZKHOST xdata67:2181,xdata68:2181,xdata69:2181 -RZ null:2:2 -ZKPNODE "/trafodion" -CNGTO 60 -ZKSTO 180 -EADSCO 0 -TCPADD null -MAXHEAPPCT 0 -STATISTICSINTERVAL 60 -STATISTICSLIMIT 60 -STATISTICSTYPE aggregated -STATISTICSENABLE true -SQLPLAN true -PORTMAPTOSECS -1 -PORTBINDTOSECS -1
經過對代碼的搜索,咱們在文件 Constants.java 文件中找到以下這行
/** Default value for DCS server user program command */ public static final String DEFAULT_DCS_SERVER_USER_PROGRAM_COMMAND = "cd ${dcs.user.program.home};. sqenv.sh;mxosrvr -ZKHOST -RZ -ZKPNODE -CNGTO -ZKSTO -EADSCO -TCPADD -MAXHEAPPCT -STATISTICSINTERVAL -STATISTICSLIMIT -STATISTICSTYPE -STATISTICSENABLE -SQLPLAN -PORTMAPTOSECS -PORTBINDTOSECS";
這就是啓動 sh 的那條命令,接下來咱們查找這個變量在哪裏使用的,咱們在 ServerManger.java 中找到了
private void featureCheck() { ...... boolean ready = false; while (!ready) { userProgEnabled = conf.getBoolean( Constants.DCS_SERVER_USER_PROGRAM, Constants.DEFAULT_DCS_SERVER_USER_PROGRAM); userProgramHome = System.getProperty("dcs.user.program.home"); userProgramCommand = conf.get( Constants.DCS_SERVER_USER_PROGRAM_COMMAND, Constants.DEFAULT_DCS_SERVER_USER_PROGRAM_COMMAND); // 就是這裏使用的 ...... } LOG.info("User program enabled"); }
咱們來理解下這裏的邏輯,從配置文件 conf(暫時就認爲它爲空,後續咱們會看到它的內容)看咱們是否配置了sh命令,若是沒有配置就取咱們上面看到的默認的命令。若是細心的讀者應該發現,上面的 sh 命令只有參數可是沒有值啊?這個值是何時加上去的? 就找到了 -RZ 這個參數的值爲何爲 null 。
咱們繼續找,就在同一個文件的上面,咱們找到了以下這段代碼
public ServerRunner(int childInstance, String registeredPath) { ...... String command = userProgramCommand .replace("-ZKHOST", "-ZKHOST " + zkc.getZkQuorum() + " ") .replace( "-RZ", // 就是這個參數,找的好辛苦啊 "-RZ " + hostName + ":" + instance + ":" + childInstance + " ") .replace("-ZKPNODE", "-ZKPNODE " + "\"" + parentZnode + "\"" + " ") .replace("-CNGTO", "-CNGTO " + connectingTimeout + " ") .replace("-ZKSTO", "-ZKSTO " + zkSessionTimeout + " ") ...... }
這段代碼是 ServerRunner的構造函數,它在這裏對 userProgramCommand 作了替換,把參數的值放上了。這裏咱們看到了牽掛已久的 -RZ 參數,咱們看到它的值是 hostName。那咱們繼續找 hostName
public ServerManager(Configuration conf, ZkClient zkc, DcsNetworkConfiguration netConf, String instance, int infoPort, int childServers) throws Exception { this.conf = conf; // 這就是咱們上面看到的是否配置 sh 命令的配置文件 this.zkc = zkc; this.netConf = netConf; this.hostName = netConf.getHostName(); // 咱們hostName 來的地方 this.instance = Integer.parseInt(instance); this.infoPort = infoPort; this.childServers = childServers;
咱們發現,兩個重要的參數值都是經過 ServerManager 的構造函數給賦值的,咱們接下來找ServerManager 調用的地方。
try { netConf = new DcsNetworkConfiguration(conf); serverName = netConf.getHostName(); ..... pool = Executors.newSingleThreadExecutor(); serverManager = new ServerManager(conf,zkc,netConf,instance,infoPort,childServers); Future future = pool.submit(serverManager); future.get(); } catch (Exception e) {
咱們在 DcsServer.java 的 run()中找到了這麼一段代碼,咱們只關心 ServerManager 的第一個和第三個參數,而且咱們發現 netConf 也是從 conf 中來的。但咱們仍是最關心 netConf.getHostName(),也就是hostName的值等於啥。
咱們繼續深刻DcsNetworkConfiguration
// Constants.java /** Configuration key for DCS DNS interface */ public static final String DCS_DNS_INTERFACE = "dcs.dns.interface"; /** Default value for DCS DNS interface */ public static final String DEFAULT_DCS_DNS_INTERFACE = "default"; ///////////// public String getHostName() { return canonicalHostName; // 真實的值 } public void getCanonicalHostName(NetworkInterface ni, InetAddress inet) throws Exception { ...... canonicalHostName = inet.getCanonicalHostName(); // 賦值 ...... } public DcsNetworkConfiguration(Configuration conf) throws Exception { ...... String dcsDnsInterface = conf.get(Constants.DCS_DNS_INTERFACE, Constants.DEFAULT_DCS_DNS_INTERFACE); if (dcsDnsInterface.equalsIgnoreCase("default")) { intHostAddress = extHostAddress = ia.getHostAddress(); canonicalHostName = ia.getCanonicalHostName(); // 有可能的賦值 ...... } else { // For all nics get all hostnames and addresses // and try to match against dcs.dns.interface property Enumeration<NetworkInterface> nics = NetworkInterface .getNetworkInterfaces(); while (nics.hasMoreElements() && !matchedInterface) { InetAddress inet = null; NetworkInterface ni = nics.nextElement(); ...... if (dcsDnsInterface.equalsIgnoreCase(ni.getDisplayName())) { ...... inet = getInetAddress(ni); getCanonicalHostName(ni, inet); // 有可能的賦值 extInterfaceName = ni.getDisplayName(); } else {
DcsNetworkConfiguration.java 在這個文件中 對 canonicalHostName 處理仍是比較複雜,咱們發現有兩處可能的賦值,決定的關鍵是 看配置文件 conf 是否配置 dcs.dns.interface 這個變量。
好了,到了這裏咱們發現,幾處很重要的地方都指向了conf 這個配置文件,那到底這個conf 文件是啥,它裏面又是什麼內容?
要找到 conf 從何時開始賦值的,還得從源頭開始找,因而就在 DcsServer.java 中找到了以下代碼
public DcsServer(String[] args) { this.args = args; conf = DcsConfiguration.create(); // 這裏 jvmShutdownHook = new JVMShutdownHook(); Runtime.getRuntime().addShutdownHook(jvmShutdownHook); thrd = new Thread(this); thrd.start(); }
找到後咱們繼續深刻 DcsConfiguration
public static Configuration addWmsResources(Configuration conf) { conf.addResource("dcs-default.xml"); //就是這裏 conf.addResource("dcs-site.xml"); //就是這裏 return conf; } /** * Creates a Configuration with Dcs resources * @return a Configuration with Dcs resources */ public static Configuration create() { Configuration conf = new Configuration(); return addWmsResources(conf); }
看到這裏,咱們就明白了原來 conf 是從這兩個文件來的,那這兩個文件在哪呢?
咱們發如今 DcsServer 啓動的時候帶了以下這麼一個參數,這就知道在哪了。
-Ddcs.conf.dir=/home/trafodion/apache-trafodion_server/dcs-2.0.1/bin/../conf
知道在哪了,那咱們就看看 xdata68 這臺機器上的配置文件的內容。打開這個目錄發現只有 dcs-site.xml 一個配置文件,內容以下
<configuration> <property> <name>dcs.zookeeper.quorum</name> <value>xdata67,xdata68,xdata69</value> </property> <property> <name>dcs.dns.interface</name> <value>eth0</value> </property> </configuration>
知道配置文件的內容,那咱們再回過頭來看看,在 DcsNetworkConfiguration 中咱們獲得 hostName 的詳細邏輯,我在這再貼下 DcsNetworkConfiguration 中處理這部分的邏輯。
// Constants.java /** Configuration key for DCS DNS interface */ public static final String DCS_DNS_INTERFACE = "dcs.dns.interface"; /** Default value for DCS DNS interface */ public static final String DEFAULT_DCS_DNS_INTERFACE = "default"; ///////////// public String getHostName() { return canonicalHostName; // 真實的值 } public void getCanonicalHostName(NetworkInterface ni, InetAddress inet) throws Exception { intHostAddress = extHostAddress = inet.getHostAddress(); canonicalHostName = inet.getCanonicalHostName(); // 賦值 ...... } public DcsNetworkConfiguration(Configuration conf) throws Exception { this.conf = conf; ia = InetAddress.getLocalHost(); // 咱們發現配置文件中恰好對 dcs.dns.interface 進行賦值了, 爲 eth0 String dcsDnsInterface = conf.get(Constants.DCS_DNS_INTERFACE, Constants.DEFAULT_DCS_DNS_INTERFACE); if (dcsDnsInterface.equalsIgnoreCase("default")) { intHostAddress = extHostAddress = ia.getHostAddress(); canonicalHostName = ia.getCanonicalHostName(); // 不可能的賦值 extInterfaceName = NetworkInterface.getByInetAddress(ia) .getDisplayName(); ...... } else { // For all nics get all hostnames and addresses // and try to match against dcs.dns.interface property Enumeration<NetworkInterface> nics = NetworkInterface .getNetworkInterfaces(); while (nics.hasMoreElements() && !matchedInterface) { InetAddress inet = null; NetworkInterface ni = nics.nextElement(); ...... if (dcsDnsInterface.equalsIgnoreCase(ni.getDisplayName())) { // 是否等於 eth0 ...... inet = getInetAddress(ni); getCanonicalHostName(ni, inet); // 真正賦值的地方 extInterfaceName = ni.getDisplayName(); } else {
經過對上面代碼的詳細分析,發現關鍵邏輯在於經過循環判斷 NetworkInterface.getNetworkInterfaces() 中獲取的項的 ni.getDisplayName() 是否 等於咱們配置文件中的配置的 eth0。因此這裏的邏輯是經過配置的網絡接口名去找 hostName
接下來咱們就看看 NetworkInterface.getNetworkInterfaces() 的結果究竟是啥,因而隨手寫了以下代碼在xdata68 上跑了下
import java.net.*; import java.util.*; public class Hello { public static void main(String[] args) throws Exception { Enumeration<NetworkInterface> nis = NetworkInterface.getNetworkInterfaces(); while (nis.hasMoreElements()) System.out.println(nis.nextElement()); } }
結果
name:eth1 (eth1) name:lo (lo)
因此從結果上來看就知道了,這個方法是獲取機器上的全部網絡接口。看到這裏咱們就有點奇怪了,爲何這裏獲取全部的網絡接口中竟然沒有咱們配置文件中配置的 eth0?
爲了再次確認 在xdata68 上執行 ifconfig 命令查看了下,再對比 正常機器 xdata70
[trafodion@xdata68 ~]$ ifconfig eth1 Link encap:Ethernet HWaddr 52:54:00:54:94:B5 inet addr:xxxxxxxx Bcast:172.18.255.255 Mask:255.255.0.0 inet6 addr: fe80::5054:ff:fe54:94b5/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:8473656440 errors:0 dropped:0 overruns:0 frame:0 TX packets:3531432078 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:1756961980786 (1.5 TiB) TX bytes:1009432619090 (940.1 GiB) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:251663643 errors:0 dropped:0 overruns:0 frame:0 TX packets:251663643 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:64908035275 (60.4 GiB) TX bytes:64908035275 (60.4 GiB) [trafodion@xdata70 conf]$ ifconfig eth0 Link encap:Ethernet HWaddr 52:54:00:A4:C5:92 inet addr:172.18.84.70 Bcast:172.18.255.255 Mask:255.255.0.0 inet6 addr: fe80::5054:ff:fea4:c592/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:7984801625 errors:0 dropped:0 overruns:0 frame:0 TX packets:3127534521 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:1740020574559 (1.5 TiB) TX bytes:956397150875 (890.7 GiB) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:74985186 errors:0 dropped:0 overruns:0 frame:0 TX packets:74985186 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:61427646458 (57.2 GiB) TX bytes:61427646458 (57.2 GiB)
看到這裏咱們豁然開朗了,原來問題致使的緣由是,xdata68 這臺機器上比較特殊,沒有配置 eth0這個網絡接口,而咱們的Trafodion dcs 的配置文件 dcs-site.xml 中統一配置的 eth0
知道了問題,解決辦法就比較簡單了,直接修改 dcs-site.xml 配置文件將 eth0 改爲 eth1 就能夠了。
這裏分析下爲何鏈接 Trafodion 進程會定位鏈接到 mxosrvr 進程
經過上面給出的 Trafodion 的架構圖瞭解到 Trafodion DCS( Database Connectivity Services)鏈接服務,是典型的分佈式架構。
Dcs Master 負責監聽鏈接(23400端口),當一個數據庫鏈接到來的時候,先鏈接到 master,master 接受到鏈接後,分配給各個機器上的 mxosrvr 進程去處理和維護這個鏈接。相信你們能夠參考官方文檔的解釋,以下:
-------------------------------------------------------------------------------------------------------------
Connectivity
The Database Connectivity Services (DCS) framework enables applications developed for ODBC/JDBC APIs to access a Trafodion SQL database server. DCS is a distributed service. It uses the underlying HBase ZooKeeper instance for its definition of a cluster. Apache ZooKeeper is a centralized service for maintaining configuration information, naming, providing distributed synchronization, and providing group services. All participating nodes and clients need to be able to access the running ZooKeeper.
DCS is a collection of components: