squbs-5.Akka HTTP客戶端上的類固醇(Steroids)

原文地址:Accessing Other Services using HTTP or HTTPS

概貌

squbs-httpclient 項目在保持Akka Http API的同時谱俭,向Akka HTTP Host-Level Client-Side API添加了可操作化方面昆著,以下是它添加的功能的列表

依賴

在你的build.sbt或scala構(gòu)建文件中加入如下依賴:

"org.squbs" %% "squbs-httpclient" % squbsVersion

用法

squbs-httpclient項目堅持 Akka HTTP API接谨。唯一的例外時在創(chuàng)建主機連接池期間塘匣。代替 Http().cachedHostConnectionPool,它使用一組參數(shù)定義 ClientFlow(和一些可選參數(shù))跑揉。

implicit val system = ActorSystem()
implicit val materializer = ActorMaterializer()
// construct a pool client flow with context type `Int`
val poolClientFlow = ClientFlow[Int]("sample") // Only this line is specific to squbs

val responseFuture: Future[(Try[HttpResponse], Int)] =
  Source.single(HttpRequest(uri = "/") -> 42)
    .via(poolClientFlow)
    .runWith(Sink.head)

同時,類似在Akka HTTP Host-Level Client-Side API中的例子现拒,ClientFlow在JAVA中的使用如下:

final ActorSystem system = ActorSystem.create();
final ActorMaterializer mat = ActorMaterializer.create(system);

final Flow<Pair<HttpRequest, Integer>, Pair<Try<HttpResponse>, Integer>, HostConnectionPool>
    clientFlow = ClientFlow.create("sample", system, mat);

CompletionStage<Pair<Try<HttpResponse>, Integer>> =
    Source
        .single(Pair.create(request, 42))
        .via(clientFlow)
        .runWith(Sink.head(), mat);

HTTP 模型

Scala

以下是一個HttpRequest Scala的創(chuàng)建例子望侈,更多請查閱 HTTP Model Scala documentation

import HttpProtocols._
import MediaTypes._
import HttpCharsets._
val userData = ByteString("abc")
val authorization = headers.Authorization(BasicHttpCredentials("user", "pass"))

HttpRequest(
  PUT,
  uri = "/user",
  entity = HttpEntity(`text/plain` withCharset `UTF-8`, userData),
  headers = List(authorization),
  protocol = `HTTP/1.0`)
Java

以下是一個HttpRequest Java的創(chuàng)建例子脱衙,更多請查看Http Model Java documentation :

import HttpProtocols.*;
import MediaTypes.*;

Authorization authorization = Authorization.basic("user", "pass");
HttpRequest complexRequest =
    HttpRequest.PUT("/user")
        .withEntity(HttpEntities.create(ContentTypes.TEXT_PLAIN_UTF8, "abc"))
        .addHeader(authorization)
        .withProtocol(HttpProtocols.HTTP_1_0);

服務(wù)發(fā)現(xiàn)鏈

在創(chuàng)建池的時候,squbs-httpclient不需要提供主機名/端口的組合退唠。取而代之的是,它允許注冊服務(wù)發(fā)現(xiàn)鏈瞧预,通過注冊服務(wù)發(fā)現(xiàn)機制仅政,允許通過string識別符來解析端點(endpoint)。舉個例子滩愁,在上面的例子中, "sample"是客戶端想要訪問的服務(wù)的邏輯名稱硝枉,配置的服務(wù)發(fā)現(xiàn)鏈會將它解析成一個包含主機名和端口的端點(endpoint)倦微,例如: http://akka.io:80.。

這里有兩個不同的注冊端點解釋器如下弧可。閉包的風(fēng)格允許更加緊湊和可讀的代碼。然而棕诵,這個子類擁有保持狀態(tài)和基于這個狀態(tài)做解決決定的能力凿将。

Scala

注冊函數(shù)類型 (String, Env) => Option[Endpoint]:

EndpointResolverRegistry(system).register("SampleEndpointResolver", { (svcName, env) =>
  svcName match {
    case "sample" => Some(Endpoint("http://akka.io:80"))
    case "google" => Some(Endpoint("http://www.google.com:80"))
    case _ => None
})

注冊類繼承于 EndpointResolver:

class SampleEndpointResolver extends EndpointResolver {
  override def name: String = "SampleEndpointResolver"

  override def resolve(svcName: String, env: Environment): Option[Endpoint] = svcName match {
    case "sample" => Some(Endpoint("http://akka.io:80"))
    case "google" => Some(Endpoint("http://www.google.com:80"))
    case _ => None
  }
}

// Register EndpointResolver
EndpointResolverRegistry(system).register(new SampleEndpointResolver)
Java

注冊BiFunction<String, Env, Optional<Endpoint>>:

EndpointResolverRegistry.get(system).register("SampleEndpointResolver", (svcName, env) -> {
    if ("sample".equals(svcName)) {
        return Optional.of(Endpoint.create("http://akka.io:80"));
    } else if ("google".equals(svcName))
        return Optional.of(Endpoint.create("http://www.google.com:80"));
    } else {
        return Optional.empty();
    }
});

注冊類繼承AbstractEndpointResolver:

class SampleEndpointResolver extends AbstractEndpointResolver {
    String name() {
        return "SampleEndpointResolver";
    }

    Optional<Endpoint> resolve(svcName: String, env: Environment) { 
        if ("sample".equals(svcName)) {
        return Optional.of(Endpoint.create("http://akka.io:80"));
    } else if ("google".equals(svcName))
        return Optional.of(Endpoint.create("http://www.google.com:80"));
    } else {
        return Optional.empty();
    }
}

// Register EndpointResolver
EndpointResolverRegistry.get(system).register(new SampleEndpointResolver());

你可以注冊多個EndpointResolver牧抵。這個鏈是根據(jù)注冊的逆序執(zhí)行侨把。如果一個解析器返回None,這就意味著它無法解釋秋柄,下一個解釋器嘗試解釋。
如果解釋的端點(endpoint)是安全的骇笔,例如(https)嚣崭,可以將SSLContext傳遞給Endpoint

每個客戶端的配置(Per Client Configuration)

Akka HTTP Configuration 定義了配置的默認值芦劣。你可以在application.conf中重寫這些默認值;然而這樣會影響所有的客戶端持寄。做一個特定客戶端的重寫娱俺,在HostConnectionPool流創(chuàng)建時荠卷,Akka HTTP允許在HostConnectionPool流創(chuàng)建期間傳遞ConnectionPoolSettings。這也是由squbs支持油宜。

除了以上之外怜姿,squbs還允許客戶端特定重寫 application.conf。你僅需要通過客戶端名稱提出一個有 type = squbs.httpclient的配置部分沧卢。然后,你可以在這個部分提出任何的客戶端配置披诗。例如立磁,如果我們只想要重寫上面"sample"客戶端中的 max-connections 設(shè)置,我們可以如下做:

sample {
  type = squbs.httpclient
  
  akka.http.host-connection-pool {
    max-connections = 10
  }
}

管道(Pipeline)

我們通常需要公用的基礎(chǔ)功能或不同客戶端的組織標準唱歧。這些基礎(chǔ)設(shè)施包括而不限于粒竖,日志蕊苗、指標手機、請求跟蹤岁歉、認證\授權(quán)膝蜈,跟蹤,cookie管理饱搏,A/B測試等等。正因squbs促成關(guān)注分離备绽,這樣的邏輯將屬于基礎(chǔ)設(shè)置鬓催,而非客戶端實現(xiàn)。 squbs pipeline 允許基礎(chǔ)設(shè)施提供組件宇驾,安裝在客戶端,客戶端所有者不需要擔心這些方面塌西。更多詳細可查看 squbs pipeline筝尾。

一般來說,一個pipeline是一個雙向流筹淫,構(gòu)建了squbs客戶端和Akka HTTP 層的橋梁。squbs-httpclient允許為所有或個別的客戶端注冊全局雙向流(默認 pipeline)庵寞。注冊一個特定客戶端pipeline,設(shè)置 pipeline配置捐川。你可以通過defaultPipeline設(shè)置開啟/關(guān)閉默認pipeline(如果未指定逸尖,則設(shè)置為on)瘸右。

sample {
  type = squbs.httpclient
  pipeline = metricsFlow
  defaultPipeline = on
}

請參照 squbs pipeline來查看如何創(chuàng)建pipeline和配置默認pipeline

指標(Metrics)

squbs帶有預(yù)編譯pipeline指標集岩齿,squbs激活模板將這些設(shè)為默認。因此盹沈,不需要任何代碼變更或配置,每個squbs http客戶端可以收集Codahale Metrics即開即用做裙。默認情況下肃晚,JMX提供以下指標:

  • 請求計時器(Request Timer)
  • 請求計數(shù)儀表(Request Count Meter)
  • 為每個http相應(yīng)狀態(tài)歸類的儀表:2xx, 3xx, 4xx, 5xx
  • ClientFlow.返回的每個異常類型的儀表

JMX Beans

故障排除問題時,可視化系統(tǒng)配置是非常重要的关串。squbs-httpclient為每個客戶端注冊了JMX bean。JMX bean發(fā)布所有的配置吧碾,例如端點(endpoint)墓卦,主機連接池設(shè)置等。bean的名稱設(shè)置如 org.squbs.configuration.${system.name}:type=squbs.httpclient,name=$name趴拧。所以著榴,如果actor系統(tǒng)名稱是 squbs 屁倔,客戶端名稱為 sample,那么JMX bean的名稱為org.squbs.configuration.squbs:type=squbs.httpclient,name=sample锐借。

Circuit Breaker

// TODO In progress

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末钞翔,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子布轿,更是在濱河造成了極大的恐慌来颤,老刑警劉巖稠肘,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件项阴,死亡現(xiàn)場離奇詭異,居然都是意外死亡环揽,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進店門撞芍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來跨扮,“玉大人,你說我怎么就攤上這事衡创。” “怎么了哟玷?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵一也,是天一觀的道長。 經(jīng)常有香客問我椰苟,道長,這世上最難降的妖魔是什么谦絮? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任洁仗,我火速辦了婚禮,結(jié)果婚禮上赠潦,老公的妹妹穿的比我還像新娘。我一直安慰自己臭家,他們只是感情好疲陕,可當我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布蹄殃。 她就那樣靜靜地躺著你踩,像睡著了一般。 火紅的嫁衣襯著肌膚如雪带膜。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天式廷,我揣著相機與錄音芭挽,去河邊找鬼。 笑死袜爪,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的俺陋。 我是一名探鬼主播,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼腊状,長吁一口氣:“原來是場噩夢啊……” “哼苔可!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起醇疼,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤法焰,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后埃仪,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體陕赃,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡颁股,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年甘有,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片亏掀。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡泛释,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出怜校,到底是詐尸還是另有隱情,我是刑警寧澤魂贬,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布胰丁,位于F島的核電站,受9級特大地震影響锦庸,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜甘萧,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望牙言。 院中可真熱鬧,春花似錦咱枉、人聲如沸徒恋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春障陶,著一層夾襖步出監(jiān)牢的瞬間聊训,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工带斑, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人侄刽。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓朋凉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親杂彭。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,614評論 2 353

推薦閱讀更多精彩內(nèi)容