整套平臺采用Nginx的proxy_pass和DNS解析作為核心,即反向代理功能與域名解析功能,整體網絡拓撲如圖1所示,其中服務器集群分布式部署在各縣區機房,防火墻與DNS服務統一放置在市級機房。
單位網內擁有多臺互為備份的服務器,當公網用戶訪問網內設備時,通過兩臺暴露在公網環境的服務器與防火墻互備組合,利用反向代理提供負載均衡服務。網內用戶訪問公網設備時,使用另外兩臺部署在公網NAT后面的服務器與防火墻互備組合,除了提供反向代理外,還設計了緩存機制,加快訪問速度。
除了上述公網、內網互訪機制,我們還部署了自己的DNS服務,通過定向解析的方式加速服務,即:我們平臺的全部域名,在公網上正常解析公網地址;內網用戶使用我們自己的DNS服務,訪問其他域名時正常轉發公網地址,訪問我們這些域名時直接解析內網地址。

圖1 網絡結構拓撲圖
平臺采用Centos6.8系統,使用常規安裝的方法即可。兩塊系統磁盤使用RAID1部署,剩下的存儲磁盤使用RAID5部署;磁盤使用GPT分區方式,勿用MBR分區;內存為96GB,CPU使用E5-2650v3兩顆。
注意:centos在自動分區時,會自動分配/,/boot、/boot/efi三個數百兆字節的分區和swap分區,然后剩下的全部磁盤空間自動分配給/home。
本平臺具有緩存功能,緩存文件存儲在/usr/local/nginx/proxy_cache/中,因此可以簡單的將/home并入根目錄,或者修改分區方式,或者直接修改本文提供的源代碼。

表1 分區格式表
筆者分區格式如表1,供參考([root@LeniyTsan ~]#df-h,RAID5的大硬盤分區用來保存Nginx緩存)。
Centos服務器本身倉庫中有編譯好的nginx,但是部署本平臺需要定制化,因此需要從源碼開始調試。



通過.user.ini中聲明open_basedir等參數限制基本目錄層級,并設置此文件為chmod 644和chattr +i屬性。
除了上述核心部分外,搭建Nginx服務還有很多細節需要調整。我編寫了一個自動部署項目,已經以Leniy Tsan為昵稱開源發布到了GitHub上,項目名為Leniy/Install_Nginx,供參考。
完整的配置文件同樣開源了,需要注意的是緩存部分的配置:

當內網訪問公網服務的時候,需要將一些大文件緩存,加快訪問速度,因此我將名為content的緩存創建在了服務器的/usr/local/nginx/proxy_cache目錄中,即RAID5的六塊1.2TB SAS硬盤,并設計了二層緩存目錄,文件超過1年未使用自動刪除,最大緩存空間5TB。
當公網訪問內網時,不使用緩存策略,單獨進行負載均衡轉發。
智慧社區中有多種服務需要能夠在公網訪問,如黨員管理后臺、集群可用性監控、用戶醫療檔案訪問等業務。暴露在公網環境的服務器與防火墻互備組合,具有相同的配置,由DNS同域名多IP解析進行負載均衡。服務器利用反向代理連接內網中的各個雙機熱備系統進行負載均衡。
以某個服務為例,某一臺公網服務器的nginx配置文件如下(為保證服務安全,這里寫的端口和IP僅為示例,不是本平臺的真實端口):


這個nginx配置文件,會將全部訪問公網服務器9090端口的請求,輪詢的轉發到內網100和200兩臺服務器的8080端口,并將這兩臺的響應數據原路發回給用戶。
內網訪問公網的時候,為了加速,將相應的大文件緩存在服務器中。
為了防止公網網站出現訪問故障,整個網站默認情況下僅僅轉發不緩存,配置文件與上述類似,不使用upstream負載均衡的方法,如下所示(每個配置文件中都有三個與上面相同的proxy_set_header參數,為節省篇幅略過):對于幾乎很難更改的文件,則使用前文中定義的content緩存空間:


以本項目為例,需要加速數十個政府網站,如果每個域名寫一個配置文件,將會極大地加重維護成本,故而可以在配置文件中設置正則表達式批量匹配:

當我在測試服務器上測試時,發現服務器直接返回502錯誤。經過查詢日志,發現告警信息為:
2016/05/17 20:45:52[error] 25452#17756:*6 no resolver defined toresolveleniy.org, client:127.0.0.1,server:leniy.org,request:"GET / HTTP/1.1",host:"leniy.org"
翻看官方document后得知,新版本的Nginx多了一個配置參數,當proxy_pass使用變量的時候,server name會首先到服務器組upstream中搜索,找不到的時候,會使用resolver解析而不是直接查詢域名的IP地址。
本項目的服務加速不使用upstream負載均衡,因此,直接設置resolver 114.114.114.114即 可,當然,DNS的IP地址盡量使用本地ISP提供的服務,解析速度相對于互聯網上的公共DNS較為迅速。
為了讓公網用戶正常訪問業務,我們在域名注冊商的NS服務器中,為服務器集群配置了雙聯路,以portal-1域名為例:
> portal-1.leniy.org
服務器:public1.114dns.com
Address:114.114.114.114
非權威應答:
名稱:portal-1.leniy.org
Addresses:1.1.1.1
1.1.1.2
當用戶訪問portal-1的時候,NS會輪詢的解析某一個公網地址,一旦某地址不可訪問,則僅僅解析另外一個地址。為了減少切換時間,同時考慮到服務器與電腦的DNS緩存,我將TTL設為了120。
2.Windows Server部署
第一部分概述中提到的三個目標中,內網加速與外網負載均衡第三部分已經講到了,現在只需要讓內網用戶直接訪問內網服務器即可。
用戶訪問的業務全部通過域名提供服務,如`portal-1.leniy.org A 1.1.1.1`表 示 將`portal-1`這個二級域名綁定了`1.1.1.1`這個公網地址,域名的NS服務發布在公網上,則公網上的用戶可以直接解析。
但是,為了防止內網用戶解析出來公網地址,我們給用戶DHCP推送的DNS服務器是在內網專門建立的。
DNS服務器使用Windows Server 2008 R2自帶的DNS服務,直接添加正向查找zone區域,然后在里面添加需要解析的次級域名。
為了防止配置一個二級域名導致本域名下其他的三級域名無法轉發解析,我們可以將各個多級域名分別單獨添加為一個zone,然后解析其@地址即可。因為域名太多,我同樣寫了一個腳本進行批量添加,核心代碼為:

其中192.168.100.50即為前面提到的1.1.1.1這個公網地址的內網地址。
本平臺的DNS需要讓全部用戶能夠自動獲取到。我們使用BRAS進行用戶身份認證與IP池的分配,采用vbui用戶虛接口。
以平臺集群中我們某地市的分節點為例,在BRAS上創建名為zhihuishequ的地址 池 :ip-pool pool-name zhihuishequ pool-id 3,然后設置接入域accessdomain yzzhihui。 本 地址池可以直接DHCP獲取,不需要撥號,因此不用配置VCC和AAA認證,只需要設置member 1 startip 10.0.0.1 end-ip 10.255.255.254。
假設我們內網的DNS服務器的內網ip地址是192.168.100.60,則設 置pppoe-dns-server 192.168.100.60即可實現目標。
本項目上線以來,業務量快速增加,特別是服務器集群中存儲的數據量越來越大。截止投稿時,平臺網內流量已經達到8Gbps,出口雙方向流量300Mbps。隨著本平臺的上線,網內用戶直接走內網線路,訪問直連公網網站大文件走緩存,節省了約1Gbps的帶寬,外網用戶通過Portal訪問,降低了業務宕機的風險并加強了安全防護。對整個項目的提升效果顯著。