<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    空山雪林通用模塊工作室

     

    2014年5月30日

    高可用性服務(wù)端的設(shè)計與實現(xiàn)

    本文的客戶端基于我們的GQT開源項目:http://cxlh.iteye.com/blog/2021463

     

    本人拙見,如有不同意見,歡迎拍磚,同時獻(xiàn)給特別有對服務(wù)端跨語言需求的程序猿們!

    客戶端(GQT Demo V3(服務(wù)端配套版).rar)太大請挪步到QQ群下載(群號:101189702),注明:GQT或Java,C++等;

    Java工程代碼請挪步下載:http://cxlh.iteye.com/blog/2074307 


    總體設(shè)計思路: 

     

    1. 高可用性:每個業(yè)務(wù)服務(wù)端都是獨立的個體,任何一個業(yè)務(wù)服務(wù)器Crash時,都不會影響服務(wù),并且業(yè)務(wù)服務(wù)器可以按需增加,業(yè)務(wù)服務(wù)端使用Java代碼實現(xiàn),主要是為了考慮更好的數(shù)據(jù)庫操作,更好的事務(wù)支持,更好的社區(qū)支持以及可用更多的開源服務(wù),提高開發(fā)效率;
    2. 自動負(fù)載均衡:當(dāng)某個接口頻繁調(diào)用,增加的響應(yīng)服務(wù)器自動分流接口調(diào)用壓力,也就說我們的異步的請求/響應(yīng)模式下,有一個Broker仲裁程序決定客戶端發(fā)來的請求交由哪個Java業(yè)務(wù)服務(wù)器來處理,這個Broker程序我們采用C++代碼實現(xiàn);
    3. 客戶端(包括桌面或移動端)網(wǎng)關(guān):根據(jù)策略選取遠(yuǎn)程Socket服務(wù)器連接,Socket服務(wù)器與服務(wù)器之間的消息通訊通過地址尋址遠(yuǎn)程路由,以便連在不同Socket服務(wù)器上的用戶之間可以相互通訊,典型的應(yīng)用就是聊天程序;
    4. Sub/Pub類消息:客戶端訂閱服務(wù)端的服務(wù),服務(wù)端有多個Pub服務(wù)器(Java編寫),交由Socket服務(wù)器將客戶端Sub的消息Push給Client,此時Socket服務(wù)只作為Proxy用;

      好了,其實這里只有2個C++核心組件(Socket服務(wù)器,Broker仲裁程序)和N個Java業(yè)務(wù)服務(wù)器(請求處理服務(wù)器,Pub服務(wù)器),以下介紹用法(需要一定的客戶端編程知識和一些腳本只是):

    客戶端發(fā)送請求,異步收取,編寫業(yè)務(wù)代碼步驟:

     

    編寫Java服務(wù)端,比如我們編寫一個按關(guān)鍵字讀取股票列表等接口(依賴注入用的Spring):

    @Repository @CacheNamespace(implementation = org.mybatis.caches.ehcache.EhcacheCache.class, readWrite = true) public interface StockDao { 	@Select("select SYMBOL,SHORT_NAME from `master`") 	public List<Map> listStock(); 	 	@Select("select SYMBOL,SHORT_NAME from `master` where SHORT_NAME like '%${k}%' or SPELL_NAME like '%${k}%' or SYMBOL like '%${k}%' limit 0,10") 	public List<Map> listStockByKeyword(Map<String,String> map); 	 	@Select("select SYMBOL,SHORT_NAME from `master` where exch_id=8") 	public List<Map> listAllSh(Map<String,String> map); 	 	@Select("select SYMBOL,SHORT_NAME from `master` where trade_date=#dt#") 	public List<Map> listStockByDate(Map<String,String> map); }

    編寫Java服務(wù)就這么簡單:

    package com.gqt.demo;

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.InputStream;
    import java.util.Properties;
    import java.util.ResourceBundle;

    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;

    import com.gqt.server.BaseReqServer;
    import com.gqt.server.ReqCallBack;

    public class StockServer extends BaseReqServer {
        private static Logger logger = LogManager.getLogger(StockServer.class.getName());
        
        final static Properties prop = new Properties();
        static{
            InputStream is = null
            try {
                String c_path = StockServer.class.getResource("/").getPath();
                logger.info("c_path:{}",c_path);
                is = new FileInputStream(new File(c_path+"config.properties"));
                prop.load(is);
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
        public StockServer(String ip, String port, ReqCallBack callback) {
            super(ip, port, callback);
        }
        public static void main(String[] args) {
            logger.info("=============StockServer========");
            new Thread(){
                @Override
                public void run() {
                    ReqCallBack callback = new StockCallBack();
                    String ip = prop.getProperty("gqt-reqserver-ip");
                    String port = prop.getProperty("gqt-reqserver-port");
                    final StockServer ss = new StockServer(ip,port,callback);
                    ss.startServer();
                }
            }.start();
        }
    }

    編寫客戶端C++或腳本:

    gw.req("命令代碼"."命令代碼對應(yīng)的參數(shù)列表"); //回調(diào)函數(shù) gw.s_cb_gw.connect(function(trcode,msg){ 	log("-----------------------------------------------------------------"); 	log("<p>gqt server異步方式獲取數(shù)據(jù),回調(diào)信息:trcode=" + trcode + ",msg=" + msg+"</p>"); });

     

    效果如下:

     

     

     

     

    這樣做的好處:

     

    1. 桌面或移動的客戶端再也不用編寫繁瑣的網(wǎng)絡(luò)通信相關(guān)的程序,只需要發(fā)送請求/訂閱,處理響應(yīng)/訂閱數(shù)據(jù)包即可,也不用關(guān)心底層的數(shù)據(jù)分包合包,客戶端代理,網(wǎng)絡(luò)傳輸?shù)募咏饷芎蛪嚎s等;
    2. 客戶端開發(fā)人員也幾乎不用和服務(wù)端程序員溝通,通過JSON解析請求透傳給Java,Java響應(yīng)的數(shù)據(jù)帶上包頭和響應(yīng)給客戶端,客戶端解析JSON即可;
    3. 跨語言的服務(wù)端雖然會損失一定的性能,但似乎這點ZeroMQ已做的足夠好;

     

    Demo程序部署步驟:

     

    1. 創(chuàng)建一個MySQL Demo數(shù)據(jù)庫,數(shù)據(jù)庫名:stock,utf-8編碼,導(dǎo)入output下的stock.sql;
    2. 配置output下的config.properties文件,指定機(jī)器IP,配置jdbc.properties,確保數(shù)據(jù)庫配置正確;
    3. 點擊runStockServer.bat,運行stock的Java Demo服務(wù)器,可以開任意個;
    4. 配置gqt-server-communicator(cpp)下的config_ims.ini文件,IP地址全部換成機(jī)器IP;
    5. 啟動ss_server.exe,ss_zserver.exe;
    6. 點擊客戶端GQT程序,配置config_ims.ini中的IP地址,切換到gateway的標(biāo)簽頁,enjoy it!


     

    posted @ 2014-05-30 16:15 徐靈 閱讀(1234) | 評論 (0)編輯 收藏

    導(dǎo)航

    友情鏈接

    最新評論

    主站蜘蛛池模板: 91精品全国免费观看含羞草| 国产成人精品无码免费看| 波多野结衣久久高清免费| 亚洲一区二区三区免费在线观看| 久久国产色AV免费观看| 亚洲AV成人片色在线观看| 久久这里只精品热免费99| 亚洲综合久久综合激情久久| 美丽的姑娘免费观看在线播放 | 无码精品人妻一区二区三区免费看| 亚洲国产精品久久久久久| 免费jjzz在线播放国产| 久久亚洲春色中文字幕久久久| 亚洲精品av无码喷奶水糖心| 最近免费中文字幕大全免费| 亚洲人成色77777在线观看大| 亚洲人成网站影音先锋播放| 亚洲人成网亚洲欧洲无码久久| 四虎影视精品永久免费| 亚洲一级特黄大片无码毛片| 亚洲精品成人网站在线观看 | 成人毛片18女人毛片免费视频未| 亚洲人成激情在线播放| 91精品免费国产高清在线| 亚洲色偷偷综合亚洲av78 | 成人性生交大片免费看好| 久久亚洲AV成人无码国产| 免费观看的毛片大全| 亚洲AV无码成人精品区狼人影院| 国产AV日韩A∨亚洲AV电影| 亚洲网红精品大秀在线观看| 亚洲性日韩精品一区二区三区| 永久在线免费观看| 日韩av无码久久精品免费| 黄床大片免费30分钟国产精品| 亚洲AV香蕉一区区二区三区| 亚洲人成图片网站| 亚洲H在线播放在线观看H| 日产亚洲一区二区三区| 亚洲自偷自拍另类12p| 亚洲国产理论片在线播放|