成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專(zhuān)欄INFORMATION COLUMN

Vert.x入坑須知(3)

CollinPeng / 811人閱讀

摘要:對(duì)于集成測(cè)試,直接模擬實(shí)際的環(huán)境,再加上合適的,目前看來(lái)也還不錯(cuò)。這里給出兩個(gè)例子集成測(cè)試單元測(cè)試都是基于寫(xiě)的,各位可以體驗(yàn)其酸爽度。好啦,本期內(nèi)容就此結(jié)束,請(qǐng)保持關(guān)注,期待下期繼續(xù)本系列其他文章入坑須知入坑須知

隨著Vert.x進(jìn)化到3.5.0,本系列也迎來(lái)了新篇章。

CORS的新變化

對(duì)于CORS,搞Web開(kāi)發(fā)(不論你是前端,還是后端)的同志應(yīng)該不陌生,尤其是如今微服務(wù)盛行的時(shí)代,CORS更是最常用的配置項(xiàng)之一。假若你對(duì)此還有一點(diǎn)點(diǎn)的疑問(wèn),不用問(wèn),你已經(jīng)落伍了!

Vert.x很早就支持了CORS,但到了3.5.0,出于安全性上的考慮,它增加了一個(gè)限制:

當(dāng)allowedOriginPattern為“*”時(shí),allowCredentials不允許為“true”。

這個(gè)限制其實(shí)起源自協(xié)議的限制:

The string "*" cannot be used for a resource that supports credentials.The string "*" cannot be used for a resource that supports credentials.

即:Access-Control-Allow-Origin為“*”時(shí),Access-Control-Allow-Credentials會(huì)被忽略,Credentials信息(一般是Cookie)也不會(huì)被user-agent發(fā)送。大家可以參考這篇文章(英文原版)了解如何安全地設(shè)置各個(gè)header。

在3.5.0時(shí),當(dāng)allowedOriginPattern為“*”和allowCredentials為“true”時(shí),Vert.x會(huì)產(chǎn)生一個(gè)異常,若不處理會(huì)導(dǎo)致Verticle不能正常啟動(dòng)。在之前的版本中,不會(huì)出現(xiàn)這種情況。

CB for handler

斷路器是個(gè)好東東,強(qiáng)烈建議在框架設(shè)計(jì)上就考慮它,以避免粗心的開(kāi)發(fā)者寫(xiě)的代碼擾亂其他好代碼。在我寫(xiě)dgate和dfx時(shí),對(duì)所有對(duì)外暴露的服務(wù)也都強(qiáng)加了這個(gè)限制。

既然CB這么好,是不是動(dòng)過(guò)將其應(yīng)用到普通Handler上的念頭?不過(guò)由于Vert.x CB的文檔示例中給出的都是清一色的HTTP請(qǐng)求的例子,要想將CB推而廣之應(yīng)用到普通的Handler上還得費(fèi)點(diǎn)氣力。

在dfx中我寫(xiě)了一個(gè)工具類(lèi),對(duì)此需求進(jìn)行了封裝:

public static void withCircuitBreaker(Vertx vertx, CircuitBreaker circuitBreaker
        , Accessible accessible, Map params, Handler successHandler, Handler failureHandler) {
    circuitBreaker.execute(future ->
            vertx.executeBlocking(f -> {
                        try {
                            f.complete(accessible.invoke(params));
                        } catch (Throwable throwable) {
                            f.fail(throwable);
                        }
                    }
                    , result -> {
                        if (result.succeeded()) {
                            future.complete(result.result());
                        } else {
                            future.fail(result.cause());
                        }
                    })
    ).setHandler(result -> {
        if (result.succeeded()) {
            successHandler.handle((Map) result.result());
        } else {
            logger.error("CB[{}] execution failed, cause: ", circuitBreaker.name(), result.cause());
            failureHandler.handle(result.cause());
        }
    });
}

它的使用很簡(jiǎn)單:

Utils.withCircuitBreaker(vertx, circuitBreaker, accessible, body.getMap()
               , result -> Utils.fireJsonResponse(response, 200, result)
               , throwable -> Utils.fireSingleMessageResponse(response, 500, throwable.getMessage()));

各位可依葫蘆畫(huà)瓢將其改為自己的形式,其中的重點(diǎn)在于以“vertx.executeBlocking”方式來(lái)執(zhí)行Handler的代碼。

測(cè)試

在稍微正規(guī)的隊(duì)伍中,自動(dòng)化測(cè)試應(yīng)該已經(jīng)是一個(gè)標(biāo)準(zhǔn)實(shí)踐了,并且Vert.x對(duì)于測(cè)試也提供了支持。

不過(guò),我不喜歡。原因有幾個(gè):

Vert.x Unit是基于JUnit,而我已經(jīng)有鐘情的測(cè)試框架:Spock。相比起JUnit而言,后者簡(jiǎn)直可以說(shuō)是Java測(cè)試領(lǐng)域的戰(zhàn)斗機(jī)。

好的單元測(cè)試本來(lái)就是要盡量少的依賴(lài)所用框架,注意這一點(diǎn)之后,盡力將類(lèi)設(shè)計(jì)得好測(cè)試,這樣的結(jié)果就是普通的單元測(cè)試類(lèi)編寫(xiě)。既然有讓人爽的工具用,也就沒(méi)有必要去用Vert.x Unit了。

對(duì)于集成測(cè)試,直接模擬實(shí)際的環(huán)境,再加上合適的timer,目前看來(lái)也還不錯(cuò)。而且Vert.x Unit中也一樣需要用timer,這樣一來(lái),也就沒(méi)有必要專(zhuān)門(mén)用它了。

為了證明我所言非虛,大家可以去看看dgate和dfx的測(cè)試代碼。這里給出兩個(gè)例子:

集成測(cè)試

單元測(cè)試

都是基于Spock寫(xiě)的,各位可以體驗(yàn)其酸爽度。

運(yùn)行時(shí)外部配置

在本系列第一篇里,我就提出了一個(gè)鐘意的工程結(jié)構(gòu)組成,但里面沒(méi)有提到“運(yùn)行時(shí)外部配置文件”這一常見(jiàn)的實(shí)踐。

經(jīng)過(guò)若干項(xiàng)目的錘煉之后,目前對(duì)于這種運(yùn)行時(shí)的外部配置文件,我基本形成了一個(gè)固定套路:Groovy DSL + Groovy ConfigSlurper。它倆簡(jiǎn)直是完成這一任務(wù)的絕配,比起Vert.x的提供的json配置文件要爽太多。

看看Gradle的build文件,你就可以知道這種DSL的靈活度可以到什么程度,更何況Groovy的語(yǔ)法對(duì)于Java開(kāi)發(fā)者極其友好。

或許有人會(huì)覺(jué)得Groovy不酷,甚至有點(diǎn)鄙夷,言必稱(chēng)Scala、Clojure、Kotlin、Go或者Rust。對(duì)此,哥只想說(shuō):作為開(kāi)發(fā)者,最讓人鄙夷的是交不出活,客戶才不關(guān)心你用什么語(yǔ)言呢!

配置DSL的例子:dgate配置

dgate是我寫(xiě)的一個(gè)基于vertx的輕量級(jí)網(wǎng)關(guān),所有的配置全部通過(guò)配置文件來(lái)定義,無(wú)需數(shù)據(jù)庫(kù)。關(guān)于它的詳細(xì)介紹,可以參見(jiàn)其文檔。為了說(shuō)明上一節(jié)采用Groovy DSL的靈活度,這里展示幾個(gè)dgate的配置例子。

靜態(tài)Mock

利用dgate的mock功能,分離開(kāi)的前后端開(kāi)發(fā)人員可以并行工作,只需將mock響應(yīng)配置到dgate的配置文件中就好。

"/summary" {
    expected {
        statusCode = 200
        payload {
            eqLocations = []
            opRateInLast30Days = []
            myOrgs = [
                ["name": "org1", "admin": false]
            ]
        }
    }
}
動(dòng)態(tài)Mock

動(dòng)態(tài)Mock為那些返回動(dòng)態(tài)結(jié)果(如某些情況下成功,某些情況下失敗)的URL模擬提供了便利。

"/login" {
    required = ["sub", "password"]
    methods = [HttpMethod.GET, HttpMethod.POST]
    expected {
        statusCode = 200
        payload = {
            JWTAuth jwtAuth = Utils.createAuthProvider(Vertx.vertx())
            JWTTokenGenerator tokenGenerator = new JWTTokenGenerator(jwtAuth)
            [token: tokenGenerator.token(["sub": "……", "name": "……", "role": "normal"], 200)]
        }
    }
}

上例將模擬一個(gè)實(shí)際的動(dòng)態(tài)JWT,這樣的好處在于,方便前端/移動(dòng)端開(kāi)發(fā)直接去完成刷新token或重新登錄的過(guò)程,而不需要再針對(duì)此場(chǎng)景做其他特殊處理。

請(qǐng)注意,為了產(chǎn)生動(dòng)態(tài)結(jié)果,此處的payload使用的是閉包,而不像前一例用的是Map。此時(shí),閉包的返回值為Mock響應(yīng)的結(jié)果。

以上的例子已經(jīng)充分展現(xiàn)了將Groovy DSL作為運(yùn)行時(shí)外部配置的能力,可以說(shuō)是完勝Vert.x自帶的json配置方式。

好啦,本期內(nèi)容就此結(jié)束,請(qǐng)保持關(guān)注,期待下期繼續(xù)!


本系列其他文章:

Vert.x入坑須知(1)

Vert.x入坑須知(2)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/70756.html

相關(guān)文章

  • Vert.x入坑須知(4)

    摘要:主要是避免引入太多的復(fù)雜性,并且出于靈活部署的需要。以應(yīng)用為例,由于實(shí)際上是在上執(zhí)行,若它被阻塞,即導(dǎo)致后續(xù)請(qǐng)求全部無(wú)法得到處理。因此,最合適的做法就是對(duì)于簡(jiǎn)單業(yè)務(wù),采用異步庫(kù)。本系列其他文章入坑須知入坑須知入坑須知 最開(kāi)始覺(jué)得這個(gè)系列也就最多3篇了不起了(因?yàn)槭虏贿^(guò)三嘛),沒(méi)曾想居然迎來(lái)了第四篇! Kotlin 由于最近決定投身到區(qū)塊鏈的學(xué)習(xí)當(dāng)中的緣故,出于更好的理解它的基本概念,自...

    summerpxy 評(píng)論0 收藏0
  • Vert.x入坑須知(1)

    摘要:輕量級(jí),部署簡(jiǎn)單。此外,本文也不是入門(mén)文檔,而是為了預(yù)防陷坑而給出的指導(dǎo)意見(jiàn),故在閱讀本文之前還請(qǐng)先仔細(xì)閱讀的文檔??梢曌鞯囊粋€(gè)最小部署和運(yùn)行單元,簡(jiǎn)單的說(shuō),可類(lèi)比為。,主,負(fù)責(zé)部署程序中其他的。嚴(yán)格來(lái)講,之后,上述第一點(diǎn)并不完全正確。 一直以來(lái)早有將這些年用Vert.x的經(jīng)驗(yàn)整理一下的想法,奈何天生不是勤快人,直到最近扶墻老師問(wèn)起,遂成此文。 選擇理由 現(xiàn)在想想,我們應(yīng)該算是國(guó)內(nèi)用V...

    Turbo 評(píng)論0 收藏0
  • Vert.x入坑須知(2)

    摘要:這一點(diǎn)其實(shí)是非常不妥的,有潛在的安全問(wèn)題。這次,在項(xiàng)目中終于采用了以它為基礎(chǔ)的集群方案。相反,使用一個(gè)周期,但針對(duì)每個(gè)生成一個(gè)一次性的,模擬隨機(jī)發(fā)送。同時(shí),要記得用完之后立即釋放。 當(dāng)初創(chuàng)建簡(jiǎn)書(shū)賬號(hào)的時(shí)候曾立下宏愿,希望保持周更,無(wú)奈現(xiàn)實(shí)殘酷,整個(gè)5月都處于忙忙碌碌的狀態(tài),居然令這個(gè)本來(lái)并不算太宏偉的目標(biāo)難以為繼,最終導(dǎo)致5月份交了白卷!【好吧,我承認(rèn),是我意志不夠堅(jiān)定,太懶了,;)】...

    xialong 評(píng)論0 收藏0
  • 使用Vert.x構(gòu)建Web服務(wù)器和消息系統(tǒng)

    摘要:而不是開(kāi)始,將服務(wù)使用多線程的請(qǐng)求重量級(jí)的容器。是啟動(dòng)多個(gè)輕便單線程的服務(wù)器和流量路由到他們。亮點(diǎn)應(yīng)用程序是事件驅(qū)動(dòng),異步和單線程的。通過(guò)使用事件總線傳遞消息通信。為了建立一個(gè)消息系統(tǒng),則需要獲得該事件總線。 摘要 如果你對(duì)Node.js感興趣,Vert.x可能是你的下一個(gè)大事件:一個(gè)建立在JVM上一個(gè)類(lèi)似的架構(gòu)企業(yè)制度。 這一部分介紹Vert.x是通過(guò)兩個(gè)動(dòng)手的例子(基于Vert.x...

    DrizzleX 評(píng)論0 收藏0
  • Vert.x Blueprint 系列教程(二) | Vert.x Kue 教程(Web部分)

    摘要:上部分藍(lán)圖教程中我們一起探索了如何用開(kāi)發(fā)一個(gè)基于消息的應(yīng)用。對(duì)部分來(lái)說(shuō),如果看過(guò)我們之前的藍(lán)圖待辦事項(xiàng)服務(wù)開(kāi)發(fā)教程的話,你應(yīng)該對(duì)這一部分非常熟悉了,因此這里我們就不詳細(xì)解釋了。有關(guān)使用實(shí)現(xiàn)的教程可參考藍(lán)圖待辦事項(xiàng)服務(wù)開(kāi)發(fā)教程。 上部分藍(lán)圖教程中我們一起探索了如何用Vert.x開(kāi)發(fā)一個(gè)基于消息的應(yīng)用。在這部分教程中,我們將粗略地探索一下kue-http模塊的實(shí)現(xiàn)。 Vert.x Kue ...

    Kerr1Gan 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

CollinPeng

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<