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

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

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

方式1:基於全局過濾器

SolonApp app = Solon.start(TestApp.class, args);

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

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

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 的微服務架構模式開發解決方案。

項目地址 ?