国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Alogic-FrameWork源碼分析-1.服務開發

LiveVideoStack / 1852人閱讀

摘要:介紹是一個輕量級的服務框架,源代碼位于。是的消息路由器,是具體負責每一個請求的路由過程。當執行結束后,向服務池歸還資源。在多線程模式下,同樣也是在服務線程中執行接口的三種方法。是一個接口,主要代表服務輸出的消息實例。

1.0 Alogic-FrameWork介紹

Alogic-FrameWork是一個輕量級的Java服務框架,源代碼位于Alogic-Github。具有快速開發服務的特點,在alogic-framework下,一個成熟的Java開發者可以快速的開發出實現自己業務邏輯的Restful服務。在這里我們不談具體的開發邏輯,而是專注于分析該框架的源碼。
Alogic-FrameWork的一個HelloWorld級別代碼如下:Alogic的HelloWorld-Github
其中主要包括以下幾個部分:

HelloWorld.java 服務調用的具體內容

web.xml web項目構建的配置文件

settings.xml Alogic服務目錄配置文件

servant.xml 服務描述配置文件

1.1 服務初始化入口

服務由servlet進行攔截,servlet-class對請求進行處理,并返回響應。

在一個HelloWorld級別的應用中,一個典型的web.xml配置如下:


    MessageRouter
    MessageRouter
    com.anysoft.webloader.ServletAgent
    
        handler
        com.logicbus.backend.server.http.MessageRouterServletHandler
    
    1


    MessageRouter
    /services/*

服務通過注冊ServletAgent類攔截/services/*的全部路由,其中初始化參數handler為MessageRouterServletHandler類。我們來看一下如何進行這個過程:

1.2 服務上下文的處理

ServletAgent是一個代理類,繼承自HttpServlet,主要代理了Servlet的初始化、執行和銷毀,其中重寫了init(ServletConfig servletConfig),它通過ClassLoader類加載器加載實際處理的ServletHandler,并由ServletHandler去執行它的初始化方法。

public void init(ServletConfig servletConfig) throws ServletException {
    // 獲取handler參數
    String handlerClass = servletConfig.getInitParameter("handler");
    // 獲取當前Servlet的上下文
    ServletContext sc = servletConfig.getServletContext();
    // 獲取當前web項目類加載器
    ClassLoader classLoader = (ClassLoader) sc.getAttribute("classLoader");
    if (classLoader != null) {
        try {
            //創建Handler實例
            handler = (ServletHandler) classLoader.loadClass(handlerClass)
                    .newInstance();
            //執行Handler的初始化方法
            handler.init(servletConfig);
        } catch (Exception e) {
            logger.error("Error occurs when creating handler:"
                    + handlerClass, e);
        }
    } else {
        logger.error("Can not find classLoader");
    }
}

ServletHandler是一個接口,重新封裝了關于Servlet的init、service、destory方法;在web.xml中需要配置它的實現方法,MessageRouterServletHandler是它的具體實現類,在init實現方法中,設置了一些關鍵屬性,如Http的編碼、跨域、緩存等屬性,以及獲取服務id、目錄、訪問控制等。

在doService實現方法中,將上述初始化的一些列屬性設置,達到重新封裝Http請求的目的;service方法初始化Context,并將參數作為輸入傳入到action方法中。如下:

    // 初始化HttpContext,HttpContext是Context類的一個實現,它是一個封裝后的Http請求的上下文。
    HttpContext ctx = new HttpContext(request,response,encoding,interceptMode);
    // 獲取當前服務路徑的id
    Path id = normalizer.normalize(ctx, request);
    MessageRouter.action(id,ctx,ac);

1.3 服務請求過程

上文提到過,MessageRouterServletHandler實現了ServletHandler接口,將Http上下文封裝起來,同時將doService方法中獲取得到的服務id,訪問控制給MessageRouter的action方法。MessageRouter是Alogic的消息路由器,是具體負責每一個請求的路由過程。在action方法中,包括以下邏輯:

處理路由追蹤

獲取服務實例池

通過訪問控制器分配訪問優先級

從服務實例池獲取實例

日志記錄

首先,MessageRouter根據獲取得到的服務id來獲取一個服務實例池,通過資源池模式來保證服務實例的不斷重復利用。資源池獲取代碼如下:

        // 獲取服務實例池
        ServantFactory factory = servantFactory;
        // 根據服務id獲取服務工廠
        pool = factory.getPool(id);        
        if (!pool.isRunning()){
            throw new ServantException("core.service_paused",
                "The Service is paused:service id:" + id);
        }

而接著,對于已經獲得的資源池中根據優先級獲得服務實例。在非線程模式下調用execute()方法,在多線程模式下建立服務工作線程。當執行結束后,向服務池歸還資源。

        //從服務實例池中拿服務實例,并執行
        servant = pool.borrowObject(priority);
        // 判斷是否獲取到了服務并輸出錯誤日志
        if (servant == null){
            logger.warn("Can not get a servant from pool in the limited time,check servant.queueTimeout variable.");
            ctx.setReturn("core.time_out", "Can not get a servant from pool in the limited time,check servant.queueTimeout variable.");
        }else{
               if (!threadMode){
                //在非線程模式下,不支持服務超時
                execute(servant,ctx);
            }else{
                // 構建CountDownLatch,用于等待服務工作線程建立。
                CountDownLatch latch = new CountDownLatch(1);
                //建立服務工作線程
                ServantWorkerThread thread = new ServantWorkerThread(servant,ctx,latch,tc != null ? tc.newChild() : null);
                thread.start();
                // 判斷服務工作線程是否在指定的時間內建立完成。如果超時則取消主線程阻塞狀態,并
                if (!latch.await(servant.getTimeOutValue(), TimeUnit.MILLISECONDS)){
                    ctx.setReturn("core.time_out","Time out or interrupted.");
                }
                thread = null;
            }
        }
    }catch (ServantException ex){
        ctx.setReturn(ex.getCode(), ex.getMessage());
        logger.error(ex.getCode() + ":" + ex.getMessage());
    }catch (Exception ex){
        ctx.setReturn("core.fatalerror",ex.getMessage());
        logger.error("core.fatalerror:" + ex.getMessage(),ex);
    }catch (Throwable t){
        ctx.setReturn("core.fatalerror",t.getMessage());
        logger.error("core.fatalerror:" + t.getMessage(),t);            
    }
    finally {
            ctx.setEndTime(System.currentTimeMillis());
            if (ctx != null){
                // 完成Context
                ctx.finish();
            }
            if (pool != null){
                if (servant != null){
                    // 向服務池歸還資源
                    pool.returnObject(servant);        
                }
                // 服務池訪問一次                
                pool.visited(ctx.getDuration(),ctx.getReturnCode());
                if (ac != null){
                    ac.accessEnd(sessionId,id, pool.getDescription(), ctx);
                }                
            }                        
            if (bizLogger != null){                
                //需要記錄日志
                log(id,sessionId,pool == null ? null : pool.getDescription(),ctx);
            }
            if (tracerEnable){
                boolean ok = ctx.getReturnCode().equals("core.ok");
                Tool.end(tc, "ALOGIC", id.getPath(), ok ?"OK":"FAILED", ok ? ctx.getQueryString() : ctx.getReason(), ctx.getContentLength());
            }
        }

在非線程模式下的execute方法執行了服務調用的前置方法、執行方法和后置方法。

    protected static int execute(Servant servant,Context ctx) throws Exception {
        servant.actionBefore(ctx);
        servant.actionProcess(ctx);
        servant.actionAfter(ctx);
        return 0;
    }

在多線程模式下,同樣也是在服務線程中執行Servant接口的三種方法。

    public void run(){
        TraceContext tc = null;
        if (traceCtx != null){
            tc = Tool.start(traceCtx.sn(), traceCtx.order());
        }
        boolean error = false;
        try
        {
            m_servant.actionBefore(m_ctx);
            m_servant.actionProcess(m_ctx);
            m_servant.actionAfter(m_ctx);
        }
    }
1.4 服務響應

在MessageRouter的acion方法中,服務調用的最后會調用ctx.finish(),在這個方法中調用了msg的finish方法。

    try {
            if (!isIgnore()){
                if (msg == null){
                    if (getReturnCode().equals("core.ok")){
                        response.sendError(404, "No message is found,check servant implemention.");
                    }else{
                        response.sendError(404, getReturnCode() + ":" + getReason());
                    }
                }else{
                    response.setCharacterEncoding(encoding);
                    msg.finish(this,!cometMode());
                }
            }
        }

Message是一個接口,主要代表服務輸出的消息實例。在Alogic中,Message可以有XML、JSON等協議的消息實例,如輸出為RawMessage時,finish方法如下:

    public void finish(Context ctx,boolean closeStream) {
        // 設置輸出流
        OutputStream out = null;
        try {
            // 設置返回內容格式
            ctx.setResponseContentType(contentType);
            out = ctx.getOutputStream();
            byte [] bytes = buf.toString().getBytes(ctx.getEncoding());
            contentLength += bytes.length;
            // 將字符串寫到輸出流中
            Context.writeToOutpuStream(out, bytes);
            // 輸出打印
            out.flush();
        }catch (Exception ex){
            logger.error("Error when writing data to outputstream",ex);
        }finally{
            if (closeStream)
            IOTools.close(out);
        }
    }

到此,一個服務的執行邏輯如下:

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/67378.html

相關文章

  • 區塊鏈技術學習指引

    摘要:引言給迷失在如何學習區塊鏈技術的同學一個指引,區塊鏈技術是隨比特幣誕生,因此要搞明白區塊鏈技術,應該先了解下比特幣。但區塊鏈技術不單應用于比特幣,還有非常多的現實應用場景,想做區塊鏈應用開發,可進一步閱讀以太坊系列。 本文始發于深入淺出區塊鏈社區, 原文:區塊鏈技術學習指引 原文已更新,請讀者前往原文閱讀 本章的文章越來越多,本文是一個索引帖,方便找到自己感興趣的文章,你也可以使用左側...

    Cristic 評論0 收藏0
  • Netty4.x 源碼實戰系列(一):ServerBootstrap 與 Bootstrap 初探

    摘要:而用于主線程池的屬性都定義在中本篇只是簡單介紹了一下引導類的配置屬性,下一篇我將詳細介紹服務端引導類的過程分析。 從Java1.4開始, Java引入了non-blocking IO,簡稱NIO。NIO與傳統socket最大的不同就是引入了Channel和多路復用selector的概念。傳統的socket是基于stream的,它是單向的,有InputStream表示read和Outpu...

    BakerJ 評論0 收藏0
  • 深入理解 WKWebView(入門篇)—— WebKit 源碼調試與分析

    摘要:雖然蘋果官方提供了關于的與使用說明,但這并不能滿足開發者們的需求,各類復雜場景依舊讓我們焦頭爛額,而解決方案卻不易尋找。二源碼下載編譯及調試之前我們首先需要獲取一份蘋果官方的源碼。 一、前言移動互聯網時代,網頁依舊是內容展示的重要媒介,這離不開 WebKit 瀏覽內核技術的支持與發展。在 iOS 平臺下開發者們...

    funnyZhang 評論0 收藏0
  • database

    摘要:它是第一個把數據分布在全球范圍內的系統,并且支持外部一致性的分布式事務。目的是使得開發者閱讀之后,能對項目有一個初步了解,更好的參與進入的開發中。深度探索數據庫并發控制技術并發控制技術是數據庫事務處理的核心技術。 存儲過程高級篇 講解了一些存儲過程的高級特性,包括 cursor、schema、控制語句、事務等。 數據庫索引與事務管理 本篇文章為對數據庫知識的查缺補漏,從索引,事務管理,...

    csRyan 評論0 收藏0

發表評論

0條評論

LiveVideoStack

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<