2015年5月11日

snmp4j table view

在 SNMP 中,如果要查詢多個 oid 的資料,就只能一個一個查詢,不然就是用 walk 的方式,將所有 oid 的節點都走過一次。但是在 oid 的定義 tree 中,有時後會遇到某個節點,下面有數十個都一樣類型的資料,例如 traffic 流量,可能一次就有十幾個連續的 oid,必須要一次將這些 oid 的結果都查出來,我們可以使用 table view 的方式,來進行這類型的資料查詢。

延續先前的 SNMPClient class,我們可以增加一個 getTable 的 method,SNMP4j 提供了 TableUtils 這個 class,當我們進行一連串的 oid 查詢後,結果會存在 List snmpList 回傳回來。

    public List<TableEvent> snmpGetTable(String oid, String lowerBound,
            String upperBound) throws Exception {
        try {
            int maxRepetitions = 100;

            PDUFactory pF = new DefaultPDUFactory(PDU.GETNEXT);

            TableUtils tableUtils = new TableUtils(snmp, pF);
            tableUtils.setMaxNumRowsPerPDU(maxRepetitions);

            OID[] columns = new OID[1];
            columns[0] = new VariableBinding(new OID(oid)).getOid();
            OID lowerBoundIndex = new OID(lowerBound);
            OID upperBoundIndex = new OID(upperBound);

            logger.debug("Vector Bulk SNMP oid= " + columns[0]);
            logger.debug("Vector Bulk SNMP lower= " + lowerBoundIndex);
            logger.debug("Vector Bulk SNMP upper= " + upperBoundIndex);

            List<TableEvent> snmpList = tableUtils.getTable(target, columns,
                    lowerBoundIndex, upperBoundIndex);

            logger.debug("snmpList size : " + snmpList.size());

            for (int j = 0; j < snmpList.size(); j++) {
                logger.debug("snmpList : " + snmpList.get(j));
            }

        } catch (Exception e) {
            logger.error("Error", e);
            throw e;
        }
        return null;
    }

至於要如何使用這個 method,以下這個呼叫,會得到 .1.3.6.1.4.1.119.2.3.76.2.4.6.1 .2.1 ~ .1.3.6.1.4.1.119.2.3.76.2.4.6.1 .2.21 的所有資料。

tester.snmpGetTable(".1.3.6.1.4.1.119.2.3.76.2.4.6.1", "2.0",
                    "2.21");

在做 SNMP Client 的程式時,如果是在做一般類似 mib browser 功能的 stand alone client,SNMP get/set 程式當然就得放在 client 裡面。但如果是在做 web browser 為使用者界面的 SNMP client 網頁應用程式時,我們就得要注意,每一個頁面會產生多少 SNMP Query,網頁前端點擊一個動作後,要等待多久,網頁的回應要等待多久這些問題。

當我們考慮到網頁的快速回應時,就不能以同步的方式,等待 server 將所有 query 都查完,再把結果回傳給前端的網頁,當 agent 存在,且能快速回應時,系統不會有什麼問題,但這種方式的缺點是,如果 query 時,SNMP Agent 剛好不存在時,網頁就必須等待所有 snmp request timeout 之後,才會回應給前端,使用者就會覺得網頁怎麼用起來卡卡的。

尤其如果在同樣的頁面,而且是多人同時查詢時,這種情況會更糟糕,而且相同的資料,會因為多人同時查詢而需要查詢好幾次。以這種狀況為前提來考量,我們必須要考慮使用 server cache 來暫存查詢的結果,而且在網頁進行查詢時,實際上是去查詢這個 cache。

然而這種設計雖然保障了使用者前端的高可用性,但卻讓資料的正確性降低了,因為系統並不是一直取得最新的資料,傳送給前端使用。因此這樣的設計方式必須要用在使用者頁面的高可用性為前提的頁面上,而且使用者不需要隨時都看到最新的資料,只需要資料可以一直更新就好了,幾分鐘的誤差不造成特別的影響。

系統設計時,除了要注意使用者的使用感受,還要注意 server 端要如何儲存資料,如果用到 cache 的機制,就要注意多執行緒修改資料的問題,還要知道多久要更新一次資料。綜合許多的考量,才能得到一個最佳調適沒有偏頗的資訊系統。