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

資訊專欄INFORMATION COLUMN

Vert.x入坑須知(4)

summerpxy / 3231人閱讀

摘要:主要是避免引入太多的復(fù)雜性,并且出于靈活部署的需要。以應(yīng)用為例,由于實際上是在上執(zhí)行,若它被阻塞,即導(dǎo)致后續(xù)請求全部無法得到處理。因此,最合適的做法就是對于簡單業(yè)務(wù),采用異步庫。本系列其他文章入坑須知入坑須知入坑須知

最開始覺得這個系列也就最多3篇了不起了(因為事不過三嘛),沒曾想居然迎來了第四篇!

Kotlin

由于最近決定投身到區(qū)塊鏈的學(xué)習(xí)當(dāng)中的緣故,出于更好的理解它的基本概念,自己動手參考文章寫了一個迷你區(qū)塊鏈的例子。采用了kotlin + vertx的工具選擇。這次嘗試再次驗證了我在本系列一開篇所說:建議以Java語言開發(fā)為主。原因很簡單,因為這個是基礎(chǔ),所以各方面支持(包括文檔和功能方面)肯定是Java語言優(yōu)先。

在做這個區(qū)塊鏈的例子時,Vertx Kotlin的文檔讓我有極為糟糕的體驗:從整篇文檔中,你找不到一個完整的用kotlin書寫Verticle的例子,閱讀的時候就感覺內(nèi)容有跳躍。雖然你可以猜出應(yīng)該是繼承AbstractVerticle,但你肯定還是希望文檔中明確指出來。

當(dāng)然啦,盡管有這樣的問題,寫代碼的體驗還是不錯的。就build.gradle而言,跟Java + Groovy組合的差別不大。唯一需要注意的是,你可能需要將kotlin的jvmTarget設(shè)置為“1.8”。具體的配置可以參考工程的build.gradle。

總之,發(fā)現(xiàn)文檔有問題,就先查Java文檔。

靜態(tài)資源

上面的區(qū)塊鏈的例子由兩部分組成:前端靜態(tài)頁面 + 后端的Verticle,前端靜態(tài)頁面通過Ajax請求與后端的Verticle交互。這其實就是通過Vertx-Web的StaticHandler來實現(xiàn)的,很簡單。這里只提兩個需要留心的小地方。

首先,靜態(tài)資源的根路徑默認(rèn)情況下是:src/main/resources/webroot。即當(dāng)你請求“http://localhost:8080/index.html”時,其實對應(yīng)的是:src/main/resources/webroot/index.html。

其次,目前的Web應(yīng)用的URL很少會直接出現(xiàn)“……/xxx.html”。按照向Spring MVC或Grails這里框架的做法,一般是經(jīng)過一個action,然后將瀏覽器導(dǎo)向某個頁面。在做這個例子時,其實沒有這么復(fù)雜的邏輯,讓瀏覽器直接去加載某個頁面(如configure.html)就可以了。但這樣會出現(xiàn)一個讓人很不爽的Path:“/configure.html”,而其他的路徑因為主要是負(fù)責(zé)處理Ajax請求,都是形如“/mine”這樣的路徑。

為了統(tǒng)一路徑風(fēng)格,這里采用了一個小技巧:RoutingContext.reroute。參考代碼如下:

router.get("/configure").handler({ rc: RoutingContext -> rc.reroute("/configure.html") })
JDBC連接池

Vert.x JDBC client缺省的連接池提供者是c3p0,但它也支持其他其他的連接池,比如大名鼎鼎的Hikari。但遺憾的是,文檔中沒有給出一個完整的代碼示例。對于想換用其他連接池的同學(xué),可以參考下面的代碼:

JDBCClient.createShared(vertx, new JsonObject()
                .put("provider_class", "io.vertx.ext.jdbc.spi.impl.HikariCPDataSourceProvider")
                .put("driverClassName", "org.postgresql.Driver")
                .put("jdbcUrl", jdbcUrl)
                .put("username", username)
                .put("password", password)
                .put("maximumPoolSize", maximumPoolSize)
                .put("minimumIdle", minimumIdle)
                .put("cachePrepStmts", true)
                .put("prepStmtCacheSize", 250)
                .put("prepStmtCacheSqlLimit", 2048));

對于用Postgresql的同學(xué),還可以看看Reactive Postgres Client,一個高性能的輕量級jdbc client同時自帶連接池,作者也是vertx的貢獻(xiàn)者。

回調(diào)的線程安全性

使用Vert.x的最大好處就是極大簡化了多線程編程的復(fù)雜性,大部分時候你幾乎不需要去操心,這部分內(nèi)容分別在文檔的Standard verticles和Worker verticles有描述。

但文檔中并沒有專門闡述這一原則是否對于回調(diào)函數(shù)也適用,畢竟回調(diào)函數(shù)執(zhí)行的時機不確定并且典型的Vert.x程序充斥著回調(diào)。對于這個問題,簡單地說:同樣適用。下面的示例代碼可以驗證這一點:

public class Vert1 extends AbstractVerticle {

    long count = 0;

    @Override
    public void start() {
        HttpClient httpClient = vertx.createHttpClient();

        for (int i = 0; i < 20; i++) {
            httpClient.getAbs("http://www.baidu.com/", response -> {
                count++;
                System.out.println(count);
            }).end();
        }
    }

}

從輸出來看,完全正確。作為對比,你可以在groovyConsole中運行下面的代碼(多按幾次ctrl - r):

int count = 0
def c = { 
    10.times { 
        count++
        println count }
}
def t1 = new Thread(c)
def t2 = new Thread(c)
t1.start()
t2.start()

并且,通過調(diào)研Vert.x源代碼,你可以(在HttpClientRequestBase中)發(fā)現(xiàn):

  void handleResponse(HttpClientResponseImpl resp) {
    synchronized (getLock()) {
      // If an exception occurred (e.g. a timeout fired) we won"t receive the response.
      if (exceptionOccurred == null) {
        long timeoutMS = currentTimeoutMs;
        cancelOutstandingTimeoutTimer();
        try {
          doHandleResponse(resp, timeoutMS);
        } catch (Throwable t) {
          handleException(t);
        }
      }
    }
  }

很明顯,Vert.x內(nèi)部已經(jīng)為你提前預(yù)防了,這就是框架的力量!如果你還在用Netty,不妨考慮Vert.x這個建構(gòu)于它之上的高層工具吧。

Unmount Subrouters

Subrouter是個好東東,可API設(shè)計有個問題:只有mount,沒有unmount!一般情況下,unmount的確用不上,但你一旦想實現(xiàn)動態(tài)路由時,它就是萬萬不可缺少的了。

好在我自己摸索出了下面的方法:

public static void unMountSubRouter(Router router, String root) {
    router.getRoutes().stream()
            .filter(route -> route.getPath() != null && route.getPath().startsWith(root))
            .forEach(route -> route.remove());
}

有趣的是,Vert.x的開發(fā)者曾經(jīng)覺得subrouter用處不大,并動了把它在未來拿掉的念頭。當(dāng)這個想法被提出來征求社區(qū)意見時,立馬有人跳出來說:“subrouter的設(shè)計非常好,哥的程序嚴(yán)重依賴它,請繼續(xù)保留。”

應(yīng)用架構(gòu)

我曾經(jīng)不止一次看到初學(xué)者在問類似這樣的問題:

應(yīng)該創(chuàng)建多少Verticle實例?

Vert.x的應(yīng)用該怎么去設(shè)計?

怎么跟現(xiàn)有的框架結(jié)合?

……

要回答這些問題,需要首先搞清楚幾個事實。

不要將Verticle和Thread混為一談,它們不是一類東西。簡單的說,可以這樣理解:Verticle由Thread來執(zhí)行。

Vert.x中的Verticle由種類之分,不同類型的Verticle適用于不同場景,這一點在文檔中已經(jīng)有詳細(xì)的闡述。

Vert.x本身是一個庫,并不妨礙它跟其他框架(如Grails)的結(jié)合。只不過就我個人而言,更偏好將Vert.x應(yīng)用多帶帶使用。主要是避免引入太多的復(fù)雜性,并且出于靈活部署的需要。

并且,通過觀察其他人寫的Vert.x代碼(包括Vert.x自己的那些子項目),可以總結(jié)出來幾個套路。

Master - Worker

這是最常見的結(jié)構(gòu):

標(biāo)準(zhǔn)Verticle,負(fù)責(zé)接收外部請求,完成請求分派和結(jié)果收集

Worker Verticle,負(fù)責(zé)臟活累活

標(biāo)準(zhǔn)Verticle和Worker Verticle之間通過eventbus進(jìn)行交互,整個架構(gòu)其實也很簡單:

request <---> standard verticles <---> worker verticle

這里的一個典型反模式,尤其是初學(xué)者會大概率犯的錯誤:將本該worker干的活,交給了標(biāo)準(zhǔn)verticle,即將圖中后兩個組件合二為一。這種情況在寫Vertx Web時非常容易出現(xiàn),尤其受傳統(tǒng)MVC框架的影響,無意識地將原來的編程套路給照搬過來了:在Handler中進(jìn)行了大量操作。我自己也不例外,走過這段彎路。

Don"t block me!

以Vert.x Web應(yīng)用為例,由于Handler實際上是在eventloop上執(zhí)行,若它被阻塞,即導(dǎo)致后續(xù)請求全部無法得到處理。因此,最合適的做法就是:

對于簡單業(yè)務(wù),采用異步庫。

對于復(fù)雜業(yè)務(wù),干脆交給worker去處理。

異步工具庫

利用Vert.x的特點,將IO操作封裝成異步庫。

微服務(wù)

用Vert.x將業(yè)務(wù)功能封裝成微服務(wù),然后利用現(xiàn)成的基礎(chǔ)設(shè)施與其他應(yīng)用交互:

利用kafka隊列實現(xiàn)服務(wù)間的交互

利用TCP Bridge實現(xiàn)與tcp client的交互

利用Eventbus Bridge實現(xiàn)與頁面的交互

利用數(shù)據(jù)庫實現(xiàn)與應(yīng)用的簡單交互

……

這也是我最喜歡用的模式,輕量,簡單,部署方便。我不太喜歡在一個本來就已經(jīng)含有復(fù)雜業(yè)務(wù)邏輯的Grails應(yīng)用中再包含一個Vert.x Verticle了。

或許有同學(xué)對于上面的最后一項,感到疑惑。其實這個很簡單,以Postgresql為例,可以采用兩種模式:

簡單的“定時任務(wù)+表”的方式,通過表的某個字段實現(xiàn)服務(wù)間的集成

利用PG自身支持的pub/sub功能

行了,本篇寫到這里也差不多了。最后給大家推薦一個網(wǎng)頁:Awesome Vert.x,上面有不少不錯的資源。

本系列其他文章:

Vert.x入坑須知(1)

Vert.x入坑須知(2)

Vert.x入坑須知(3)

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

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/69249.html

相關(guān)文章

  • Vert.x入坑須知(3)

    摘要:對于集成測試,直接模擬實際的環(huán)境,再加上合適的,目前看來也還不錯。這里給出兩個例子集成測試單元測試都是基于寫的,各位可以體驗其酸爽度。好啦,本期內(nèi)容就此結(jié)束,請保持關(guān)注,期待下期繼續(xù)本系列其他文章入坑須知入坑須知 隨著Vert.x進(jìn)化到3.5.0,本系列也迎來了新篇章。 CORS的新變化 對于CORS,搞Web開發(fā)(不論你是前端,還是后端)的同志應(yīng)該不陌生,尤其是如今微服務(wù)盛行的時代,...

    CollinPeng 評論0 收藏0
  • Vert.x入坑須知(1)

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

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

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

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

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

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

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

    Kerr1Gan 評論0 收藏0

發(fā)表評論

0條評論

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