Solon 框架如何方便獲取每個請求的響應時間?

劉之西東 發表於 2021-10-21
框架

經常會有同學問 Solon 怎樣才能獲取每個請求的響應時間?要求是不需要給每個函式加註解。故此,整理了一下。

不給每個函式加註解,主要有兩種方式可以獲取請求響應時間:

方式1:基於全域性過濾器

public class DemoApp{
    public static void main(String[] args){
        SolonApp app = Solon.start(DemoApp.class, args);

        //全域性過濾器
        app.filter((ctx, chain) -> {
            //記錄開始時間
            long start = System.currentTimeMillis();
            try {
                chain.doFilter(ctx);
            } finally {
                //獲得耗時
                long elapsed = (System.currentTimeMillis() - start);
            }
        });
    }
}

方式2:基於處理鏈 + 上下文特性

public class DemoApp{
    public static void main(String[] args){
        SolonApp app = Solon.start(TestApp.class, args);

        //前置處理
        app.before(c -> c.attrSet("start", System.currentTimeMillis()));

        //後置處理
        app.after(c -> {
            long start = c.attr("start", 0L);
            long elapsed = (System.currentTimeMillis() - start);
        });
    }
}

其實也還有第三種,基於控制器基類;以及第四種基於輕閘道器。

方式3:基於控制器基類(和方式1 有點兒像)

//1.定義基類(增加包圍攔截注入)
@Around(TimeInterceptor.class)
public class ControllerBase {
}

//2.定義攔截器
public class TimeInterceptor implements Interceptor {
    @Override
    public Object doIntercept(Invocation inv) throws Throwable {
        long start = System.currentTimeMillis();
        try {
            return inv.invoke();
        } finally {
            long elapsed = (System.currentTimeMillis() - start);
        }
    }
}

//3.應用
@Controller
public class DemoController extends ControllerBase{
    @Mapping("/hell")
    public void hello(){
        
    }
}

方式4:基於輕閘道器的處理鏈

//輕一點的示例
@Mapping("/API/V1/**")
@Controller
public class ApiGateway extends Gateway {
    @Override
    protected void register() {
        before(new StartHandler()); //開始計時

        after(new OutputBuildHandler());//構建輸出內容
        after(new OutputHandler());//輸出
        after(new EndBeforeLogHandler());//記錄日誌
        after(new EndHandler("API"));//結束計時,並上報

        addBeans(bw -> "api".equals(bw.tag()));
    }
}

//重一點的示例(平時我搭介面專案框架,用的是這一例)
@Mapping("/API/V2/**")
@Controller
public class ApiGatewayOfApp extends UapiGateway {
    @Override
    protected void register() {
        filter(new BreakerFilter()); //融斷

        before(new StartHandler()); //開始計時
        before(new ParamsParseHandler()); //引數解析
        before(new ParamsSignCheckHandler(new Md5Encoder())); //引數簽名較驗
        before(new ParamsRebuildHandler(new AesDecoder())); //引數重構
        before(new ParamsNeedCheckHandler("g_lang"));//引數必要性檢查//即公共引數
        before(new ParamsLocaleHandler());

        after(new OutputBuildHandler(new AesEncoder())); //輸出構建
        after(new OutputSignHandler(new Md5Encoder())); //輸出簽名
        after(new OutputHandler()); //輸出
        after(new EndBeforeLogHandler()); //日誌
        after(new EndHandler("app.v1")); //結束計時

       addBeans(bw -> "api".equals(bw.tag()));
    }
}

有這方面困惑的同學,希望能看到此文。

關於 Solon ?

Solon 是一個輕量的Java基礎開發框架。強調,剋制 + 簡潔 + 開放的原則;力求,更小、更快、更自由的體驗。支援:RPC、REST API、MVC、Job、Micro service、WebSocket、Socket 等多種開發模式。短小而精悍!

關於 Solon Cloud ?

Solon Cloud 是一系列的介面標準和配置規範,相當於DDD模式裡的防腐層概念。是 Solon 的微服務架構模式開發解決方案。

專案地址 ?