1. 程式人生 > >用 http-proxy架設 Cmpage 的微服務閘道器

用 http-proxy架設 Cmpage 的微服務閘道器

Cmpage的微服務化

         Cmpage前端是個典型的單頁結構,每個業務模組從後端返回的是HTML片段,然後進行組裝渲染。假設現在有3個團隊分別開發了使用者中心(UC),客戶管理系統(CRM),人事考勤系統(HR),每個系統會有若干業務模組,系統內外的資料有關聯,一般也都是用WebAPI的方式進行互相呼叫,但由於Cmpage的業務模組是高度配置型的,因此我們先不考慮WebAPI,而以公共類組成的框架專案為依託進行系統間相互呼叫(本方案耦合度較高,主要是基於開發成本的考慮,大團隊或不差錢的或穩定性要求很高的專案還是採用現在流行的方案如SpringCloud等較好),因此可採用資料集中存放,應用分開部署,分別由不同的團隊開發和運維,

C#或Java版的可以建立框架專案,供業務子系統呼叫和解決方案整合,NodeJs版可以做成多個Npm模組(有待實現),主系統一般為UC,負責許可權系統,其他業務系統通過框架公共類和方法來進行系統間呼叫(可採用 ServiceV1 和Proxy的方式來管理版本),這中間很多細節就不展開討論了。

        可以看出,整個系統要從大的單體系統拆分成多個可獨立開發和運維的子系統,主要有三部分重要工作,1、閘道器和服務發現,2、框架專案的開發和維護,3、各業務子系統的開發和維護,這裡我們主要看閘道器的實現。

服務如何發現

  1. 常規的方案需要有地方去註冊服務、統一管理,但Cmpage的業務模組配置是集中存放於配置資料庫中的,這自然就成了註冊中心,而對外服務的介面可以寫成帶版本的公共服務類,放置於框架專案(也可以單獨建立專案維護)供其他系統呼叫。
  2. Cmpage的前後端呼叫大部分都是通過統一URL介面,帶上modulename引數來進行的,這樣就可以方便地進行處理了, 在閘道器處配置業務模組所在地址就行了,然後通過簡單的HTTP代理機制就可以實現該網關了

閘道器的實現

  1. 安裝http-proxy模組,npm install http-proxy;
  2. 配置業務模組和部署地址的對應關係,也可以從UC的介面取下列結構的JSON資料:
    const moduleTargets = [{
            modules:',DocuListLookup,DocuList,DcouRecArrive,DocuRecBill,DocuRecOrder,DocuRecOrderApply,DocuRecPick,',       //列出了部分模組
            target: 'http://10.9.35.41:8380'
        },{
            modules:',ExamMarker,Exam,ExamRec,ExamStudent,Crontab,',       //列出了部分模組
            target: 'http://127.0.0.1:8380'
        }
    ];
    function getTarget(modulename){
        for(let mod of moduleTargets){
            if(mod.modules.indexOf(','+modulename+',') >-1){
                return {target: mod.target };
            }
        }
        return { target: 'http://10.9.35.41:8380' };  
    }

    3、這樣可以根據配置進行簡單的路由轉發就行了

    let server = http.createServer(function(req, res) {
            // 在這裡可以自定義你的路由分發  
            let parms = querystring.parse(url.parse(req.url).query);
            console.log(parms);        
            //var host = req.headers.host, ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;  
            visitCnt ++;
            console.log("cnt: "+visitCnt+", cookie: " + req.headers.cookie);    
            if(parms['modulename'] ){
                proxy.web(req, res, getTarget(parms['modulename']));
            }else{
                proxy.web(req, res, { target: 'http://10.9.35.41:8380' });
            }
    
        }
    );

    Cmpage的適應性改造

         由於閘道器代理轉發的時候 req中是帶有統一的cookie資訊的,因此後端各業務系統如果能從同一個地方取Session資訊的話,單點登入就實現了。因此session的配置改為 think-session-mysql 方式進行,大致如下:

  1. 增加NPM模組 think-session-mysql: npm install think-session-mysql
  2. 在存放session資訊的資料庫中新建資料表:
    CREATE TABLE `think_session` (
      `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
      `cookie` varchar(255) NOT NULL DEFAULT '',
      `data` text,
      `expire` bigint(11) NOT NULL DEFAULT '0',
      `maxage` int(11) NOT NULL DEFAULT '0',
      PRIMARY KEY (`id`),
      UNIQUE KEY `cookie` (`cookie`),
      KEY `expire` (`expire`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

經測試,閘道器加兩個系統是可以正常工作的,即兩個系統可以通過代理閘道器結合成一個統一的系統提供給使用者。