2017年3月20日
#
組織樹報表中由id與父id來實現組織樹報表,若層級數較多時,對每個單元格設置過濾條件和形態會比較繁瑣,因此FineReport提供了一種特殊的數據集——樹數據集,只需要簡單的設置就能自動遞歸出層級,方便的實現如下圖組織樹報表:
圖一

圖二

構建樹
新建工作薄,添加數據集ds1取出原始數據,SQL語句為SELECT * FROM 公司部門。
1)根據父字段構建樹
使用情形:原始表結構中符合ID、parentID結構,我們可以通過父ID這個字段生成樹,添加樹數據集,如下圖:


2)根據數據長度構建樹
使用情形:原始表結構中所有ID都在一列中,且沒有父ID字段,但是ID是有規律的,每組的長度相同,且子級的前N位就是父級編號,添加樹數據集,如下圖:


預覽樹數據集,可看到已自動生成遞歸樹數據,FR_GEN_0為最高層,依次往下,如下:

縱向組織樹編輯
按照下圖所示將對應的數據列拖入到單元格中,并將A2單元格的左父格設置為A1,A3單元格的左父格設置為A2:

有上面預覽數據可以看到從二層FR_GEN_1開始,就會有空白數據,這是因為數據庫中存儲的數據有上一級部門本身的部門名稱和部門ID,其上一級部門的部門級數會低一級,比如說上述數據的第一行為總部,雖然總部下面有子部門,但是數據庫中還是要存儲總部這個部門的部門名稱和部門ID的,總部對應的級數為一級,那么其對應的數據記錄行里面就只有FR_GEN_0層,下面的FR_GEN_1和FR_GEN_2這兩層就會沒有數據,顯示為空白。
在模板制作過程中,從第二層級開始就會有空白數據,需要將空白數據隱藏掉,選中A2和A3單元格,添加條件屬性,當數據為空時隱藏該行,如下圖: 
如果組織結構的層級結構不確定,即有的層級有子層,有的層級沒有子層時,其組織樹報表的實現方式請查看不規范組織樹報表
由于自動生成的字段是編碼,可以使用數據字典將其轉為對應的部門名稱,如下圖:
保存模板,點擊分頁預覽,效果如圖一。
橫向組織樹編輯
按照下圖所示將對應的數據列拖入到單元格中,在右側單元格屬性表-擴展屬性中將B1、C1單元格的擴展方向設為橫向,
并將B1單元格的左父格設置為A1,C1單元格的左父格設置為B1:
有上面預覽數據可以看到從二層FR_GEN_1開始,就會有空白數據,這是因為數據庫中存儲的數據有上一級部門本身的部門名稱和部門ID,其上一級部門的部門級數會低一級,比如說上述數據的第一列為總部,雖然總部下面有子部門,但是數據庫中還是要存儲總部這個部門的部門名稱和部門ID的,總部對應的級數為一級,那么其對應的數據記錄列里面就只有FR_GEN_0層,下面的FR_GEN_1和FR_GEN_2這兩層就會沒有數據,顯示為空白。
在模板制作過程中,從第二層級開始就會有空白數據,需要將空白數據隱藏掉,選中B1和C1單元格,添加條件屬性,當數據為空時隱藏該列,如下圖:

如果組織結構的層級結構不確定,即有的層級有子層,有的層級沒有子層時,其組織樹報表的實現方式請查看不規則組織樹報表
由于自動生成的字段是編碼,可以使用數據字典將其轉為對應的部門名稱,如下圖:
保存模板,點擊分頁預覽,效果如圖二。
在企業應用中,通常單個計算機的配置是有限的,而企業應用又是高并發的需求,這個時候會通過計算機集群的方式來提高并發數,從而提高整體應用服務的性能。集群是將多臺計算機作為一個整體來提供相關應用的服務。FineBI支持多計算機服務的集群部署,通過集群部署利用有限的計算機資源來有效提高整體應用的并發性能。本文主要介紹整體FineBI集群的思路。
FineBI采用負載均衡集群的模式,將多臺服務器創建為一個集群服務器。這里碰到這幾個問題:1)web工程的存儲問題:FineBI在集群中,由于自身的問題需要多臺服務器讀取同一個web工程。因此要實現web工程分享。2)系統數據一致性:在FineBI的運行過程中,存在讀寫的操作,同時有部分的數據的配置文件要寫入數據庫。需要保證集群的情況下,系統數據的一致性。3)負載均衡:一方面通過負載均衡來處理session的問題,另一方面達成負載均衡的集群環境,使用代理服務器可以將請求轉發給集群內部的服務器,可以將負載均衡和代理服務器的高速緩存技術結合在一起,提供有益的性能。4)FS平臺集群:如FineBI使用FS平臺,則FS平臺的各種配置也需要進行集群配置。
如下圖是一個FineBI進去的架構的案例示意圖,這種方式通過NFS文件共享來處理web工程。

Web工程存儲問題
Web工程的存儲,我們要解決的是多個服務器保證讀取同一個web工程。我們可以通過ceph做到多塊物理硬盤組件一塊邏輯硬盤,從而實現所有節點都是在訪問同一地址;也可以通過linux本身帶有的nfs共享文件服務來達成訪問同一web工程。無論使用哪一種方式,我們要保證:
<!--[if !supportLists]-->1)<!--[endif]-->訪問同一web工程
<!--[if !supportLists]-->2)<!--[endif]-->Cube存儲地址是一致的
因為同一個web工程下,要求cube的存儲地址是一致的,因此要求cube存儲地址一定要一樣。
而真正使用的時候,ceph的實現需要至少三臺計算機來實現,而實際企業應用中,比較少使用三臺;而nfs均可以且是linux本身的,因此使用“nfs”方案。
系統數據配置
單節點的情況下,利用緩存和通過操作系統的文件系統來保存數據的方式,在集群模式下不再合適。主要原因在于數據的一致性問題,多個節點可能進行同時讀寫,更改系統數據,最終勢必會造成整體數據不一致。最好的解決方案是系統配置數據全部交給MySQL等關系型數據庫來管理。但由于這樣工程量好大,更主要的原因為許多代碼缺少維護,貿然更改可能帶來意想不到的bug。于是我們采用一種折中的做法。在集群中選出一臺幾點作為主節點,簡稱M。其余節點擔當子節點,簡稱S。當S上所有與更改系統配置相關的操作,全部發送到M上進行處理。M負責來更改系統狀態,維護整個系統到底一致的狀態。S節點放棄全部的緩存數據,讀取狀態的時候,不再通過讀取自身數據,而是通過向M發送讀取請求,獲得M上的數據。M節點自身可以存在緩存數據。其他數據S節點與M節點時等同的,不存在從屬關系。

因此按上述原由我們提供如下解決方案:
<!--[if !supportLists]-->1)<!--[endif]-->mysql數據庫:原web工程中存在finedb的配置信息轉存到mysql數據庫中。因為finedb數據庫只能有一個連接,無法多節點同時讀取,而mysql數據庫則不存在。Logdb也需遷移;
<!--[if !supportLists]-->2)<!--[endif]-->主子節點:我們使用主子節點的方式來配置集群,系統數據的更改均在主節點上進行,子節點只讀取主節點上的數據;
<!--[if !supportLists]-->3)<!--[endif]-->Zookeeper:為了保證讀寫情況下,主子節點保證數據一致性,還需要zookeeper進行通信,充當文件鎖的功能。
負載均衡
在FineBI的集群環境中,我們可以使用任何支持負載均衡的服務器來完成輪發的任務,并保證session粘滯。此處我們使用的是nginx反向代理,使用IP標識輪發,保證同一個用戶在同一個session。(在一個服務器一個節點的情況下,同一個IP就保證session粘滯)。
FS平臺集群
使用FS平臺集群插件,將FS平臺配置能夠滿足集群需求。在FS平臺集群中,FS平臺的所有操作都是發到主節點上來操作;子節點只是作計算服務器。