終於等到你---訂餐系統之負載均衡(nginx+memcached+ftp上傳圖片+iis)

又見畢業

     對面工商大學的畢業生叕在拍畢業照了,一個個臉上都掛滿了笑容,也許是滿意自己四年的修行,也許是期待步入繁華的社會...
  恰逢其時的連綿細雨與滿天柳絮,似乎也是在映襯他們心中那些離別的憂傷,與對未來的憧憬和彷徨。
  想起當年畢業時,來去匆匆,只留下一張全班合影照和寢室好友的一句:再見,珍重!有點小遺憾!
  又見畢業,又是一年,感慨兩句,珍惜時間,好好加油,廢話完結,回到主題。

 

背景

 

   自畢業以來,一直在現在公司做訂餐系統的開發,那會兒沒有口碑,沒有餓了麼,更別說美團外賣,百度外賣了...因爲規模都比較小,都是一個服務器包含數據庫,iis...然後就完事兒了。終於等到給窩窩團開發訂餐系統時,以爲可以瞭解更多服務器相關東西時,生產環境我又接觸不了,但還是瞭解了好些內容:session怎麼用數據庫保存,圖片如何用單獨服務器之類,雖然都是小兒科,但是第一次接觸這些時,還是感慨良多:覺得之前都白過了。

  再到後來,終於,我們的一個客戶日均訂單在5K時(12年時,還是蠻不錯的了),我以爲機會又來了,正當我滿心歡喜的搗鼓兩個服務器時,然後,他們告訴我們,他們用別人的系統了,然後,訂單就開始少了,然後,美團到了他們的城市,然後,就沒有然後了。

  沒有觀衆,再好的表演也沒意義了,雖然有時也會一時興起,搭個環境玩下,但一有問題就放棄了,畢竟沒有用武之地。

  終於,一個做配送的客戶,每天有2K的訂單了,我覺得是時候學習下《負載均衡》了,於是有了下文,鄙人也是第一次真正使用這個,不正之處,歡迎斧正。

 

nginx安裝與配置

  這部分基本操作都是差不多的,博客園也有很多文章講解得非常詳細了, 我之前也是參考這片文章,寫得蠻詳細的, nginx+iis實現負載均衡

    配置方面,我就是 server 結節下增加了配置 server_name  www.xxx.com a.xxx.com; 方便用域名訪問而已。

外網無法訪問?

  配置完成後,在服務器上訪問非常正常,用ip,域名訪問也都正常,防火牆端口中也添加了例外,正當山重水複疑無路之時,纔想起,早些時間配置server-u時,(如果安裝時沒開防火牆)要選擇程序添加例外,其實,域名解析早就完成了,ping 測試正常,兩個服務器單獨訪問也是正常,所以只有可能是防火牆的問題了,配置很簡單,控制面板---windows防火牆---高級設置---入站規則---新建規則---程序---選擇nginx---下一步 ....完成

    

  設置後外網域名訪問正常了

 

session數據庫配置

   使用兩臺服務器後,要考慮session共享的問題,之前開發時,也是使用數據庫保存,稍微瞭解些,所以這次也使用數據庫保存。

   要使用數據庫保存session,首先要配置數據庫(廢話了),其次是要在web.config中進行相關配置。

   配置數據庫比較簡單,定位到指定.net版本,執行以下命令就可以,比如我的服務器是64位操作系統,用的.net 4.0的,以下命令如下

  定位指定文件夾: cd  C:\Windows\Microsoft.NET\Framework64\v4.0.30319

      執行命令: aspnet_regsql.exe -S xx\sql2008 -U user -P passward  -d Sessiondb -ssadd -sstype c 

     上面這個命令 -S 表示服務器名稱,也可寫ip, -U 表示用戶名,-P 表示密碼 -d 表示要生成的數據庫名稱

      執行命令時,可能有些服務器會提示要在命令前加  .\ 直接加就可以了, 提示如下表示OK了,這時你發現已經自動生成了一個數據爲,名稱爲-d 後面的名稱。

  

   接下來就是web.config配置了 在<system.web> 結點下增加如下內容

   數據庫鏈接串部分爲上面生成的數據庫相關信息,具體如下圖

   

 

     完成以上操作,就可以正常訪問了,然後,搜索商家,添加購物車,提交訂單等一系列訂餐流程就完成了,爲了方便查看,我在一個服務器上首頁標題上加了一個“1”,來區分兩個服務器,因爲沒有配置weight

   所以基本是平均每個服務器請求一次。

 

   

       

  確實訂餐一系列流程都正常了,但是真的就完成了嗎?其實還早着呢!

  

圖片上傳

  以前單個服務器時,上傳圖片自己到根目錄/uplpad/,路徑保存成  ~/upload/201601/xxx.png,前臺顯示時使用 Server.MapPath(圖片路徑)就可以了。 

  分成多個服務器後,以前的方式只能把圖片保存到本服務器,別的服務器就無法訪問了,我參考了原來 discuz 的代碼,使用ftp方式上傳到遠程服務器,具體操作如下:

  1,選擇某個服務器做爲圖片服務器,選擇一個文件夾比如images 做爲所有圖片的存放的位置。

  2,在IIS裏搭建一個站點,根目錄就是第一步中創建  images 文件夾,綁定幾個域名如:img0.ihangjing.com,img1.ihangjing.com ... 圖片保存時,隨機選擇0-x中的一個數據,這個圖片最後保存的路徑就是 img(n).ihangjing.com/upload/yyyyMM/xxx.png了。

  3,創建一個ftp站點,根目錄也是第一步中創建  images 文件夾,設置好用戶名如:ftpuser,密碼如:ftppwd。

  4,配置ftp相關信息,具體如下圖:

    

  5,上傳圖片時,調用實現ftp的代碼,保存文件就可以了。

      FTPs ftps = new FTPs();

      ftps.UpLoadFile("/"+strDay, DirUrl + "/" + tempFileName, FTPs.FTPUploadEnum.WebImg);

 

  6,經過上面的過程,圖片路徑都是保存的絕對路徑,這樣請求圖片時,不管是哪個服務器,顯示都正常了。

  

      注: ftps的代碼基本是參考 discuz,做了一些調整,這裏就不貼代碼了,有興趣的自己下載哈。

 

緩存配置 memcached

  以前緩存是使用的類 System.Web.Caching.Cache 這個是保存本服務器內存的,準確的說應該是(對於每個應用程序域均創建該類的一個實例),多個服務器時,每個服務器都緩存在自己內存裏,如果某個服務器數據更新,不能通知到別的服務器,那別的數據庫的數據就是“髒數據”

  之前微信站點,與 pc 站點就有緩存更新不及時,後來偷懶用來一個比較簡單的方法處理了:pc端更新緩存時,通過http接口更新微信站點的緩存。所以,以前更新緩存要做兩步:

  UpdateCacheByKey("WebPromotionConfig"); //更新其他站點緩存
  EasyEatCache.GetCacheService().RemoveObject("/WebPromotionConfig");//更新本站點緩存

  雖然這樣確實可以解決大部分的問題,但是麻煩,於是決定用 memcached 做緩存服務器,具體操作如下:

  1,下載安裝文件,爲了大家方便我這裏上傳一個文件。點我下載

  2,至於安裝,啓動這些有很多文章都寫得很多詳細了,大家自行搜索,我是參考的這這個文章:http://www.tuicool.com/articles/VjEvQb

     其實基本也有兩個操作

     安裝服務: memcached.exe -d install

     啓動服務:memcached.exe -m 1024 -d start 

       進入服務列表,看到服務正常運行就OK了,如下圖:

 

    

 

   因爲我使用了兩個服務器,所以兩個服務器都安裝好,並啓動服務。

    

  3,實現客戶端,我使用的是 Memcached Providers,原來是用的 Memcached.ClientLibrary.dll,網站就一直無法打開,也不出錯,後來查了,原來這只能在.net 2.0中使用,才果斷放棄了, 通過配置文件配置使用本地緩存,還是Memcached (我們多數客戶還是隻用一個服務器,有這個配置主方便多了),最後代碼緩存層結構如下:

    

 

  4,web.config 配置 Memcached Providers,寫法都差不多,以下是我自己的配置文件(親自測試是可用的,請放心使用)

    

    

   5,經過以上操作,原來項目的緩存就切換到了Memcached了。 步驟是就這幾個,實際操作中還是有碰到不少問題,比如:從 Memcached.ClientLibrary 換成 Memcached Providers 後,數據一直緩存不了,最後

   實在沒辦法了,才重起了服務,然後就好了,具體什麼原因也沒弄明白,重起真是個好方法。看數據緩存的日誌後,心裏總算踏實些了,本想弄個 memcached manager 監控下具體的數據,添加服務器已經提示用戶名密碼不正確

     ,這個就暫且放一下,後面有空了再好好研究下。如有哪個朋友瞭解的,請不吝賜教下哈。

   

訂單通知商家,配送員

   我們訂單通知商家,配送員app是通過iis調用wcf通知到socket服務器,再由服務器推送給相應app, 有興趣的可以看下,我之前的一個篇文章 《基於SuperSocket的IIS主動推送消息給android客戶端》

   現在變成多個服務器後,我只要修改下wcf的服務器ip就可以了。如下圖

    

 

   目前socket服務器,還是用的一個服務器,如果商家和配送員達到一定的量,單個服務器是無法支持的了,我想下一步就要考慮下socket負載均衡方面的東西了,如有哪個朋友瞭解的,也請不吝賜教下哈。

 

結語

  我是第一次這樣部署,在這之前真是不確定自己是否能完成這個事兒,中途也想放棄(世上無難事,只要肯放棄嘛),最後還是靠着不甘心的勁兒:有困難我們要上,沒困難製造困難也要上。

  雖然整理結構已經部署完成了,使用也正常了,但還有相當多的問題等着,比如,session共享用數據庫好呢,還是用 Memcached 呢;這樣部署後是否能支持現在的我們的客戶的訂單量呢...

  文章到這裏就完成了,覺得有幫助呢,動動手指點個贊,圖個高興;覺得寫得不好,也接受拍磚哈;寫得不正確的地方,請不吝賜教下哈,共同進步。

  最後再吐槽一下:上次寫了一篇文章 《訂餐系統之同步餓了麼商家訂單》 被拿出首頁了,一開始說是弄錯了,放回去了,後來又說又弄錯了,又拿出去了,我也是醉了。如果也有做這塊的,大家交流下哦。

 

   成爲一名優秀的程序員!

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章