日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

微服務(wù)框架Finagle介紹 Part1: Future, Service, Filter

 WindySky 2017-07-17

原文地址:http:///blog/2016/03/19/finagle1/

微服務(wù)架構(gòu)可能是時下最熱的一種架構(gòu)模式了. 這篇系列里, 我想介紹一些常用的微服務(wù)框架. 通過學(xué)習(xí)這些框架, 我們將會了解實現(xiàn)微服務(wù)的過程中會遇到哪些問題, 以及這些微服務(wù)框架是如何幫助我們解決這些問題的. 所以這是一篇關(guān)于微服務(wù)實踐的系列, 我不會討論太多概念性的東西. 系列末尾我會給出一些微服務(wù)架構(gòu)相關(guān)的鏈接, 感興趣的可以參考.

微服務(wù)不同于單一架構(gòu)應(yīng)用, 是典型的分布式場景, 各服務(wù)之間通過IPC進行通信. 實現(xiàn)微服務(wù)的過程中, 我們需要解決以下問題:
1. 服務(wù)注冊和服務(wù)發(fā)現(xiàn).
2. 根據(jù)應(yīng)用選擇合適的通信協(xié)議和數(shù)據(jù)協(xié)議. 例如可以選用thrift, protocol buffer或REST.
3. 服務(wù)負載均衡. 一個服務(wù)一般會部署多個實例. 如果使壓力均勻分布是需要考慮的問題.
4. 服務(wù)路由與限流.
5. 容錯處理. 相對于單機應(yīng)用, 分布式環(huán)境下錯誤發(fā)生的概率會大大提高, 服務(wù)宕機, 網(wǎng)絡(luò)不可用的情況時常發(fā)生.
6. 服務(wù)監(jiān)控. 各服務(wù)實例的性能指標, 例如請求響應(yīng)時間, 請求并發(fā)數(shù)量, 以及服務(wù)實例的部署數(shù)量等.
7. 事務(wù)一致性. 一般來說這個問題需要我們結(jié)合業(yè)務(wù)自己處理, 框架不會給我們太多幫助.

好的微服務(wù)框架應(yīng)該能幫助我們解決上面的全部或者大部分問題. 這里我選擇JVM上比較熱門的三個微服務(wù)框架: Finagle, spring Cloud(NetflixOSS), Dubbox. 我會從實例入手, 介紹這些框架的使用方式, 特點和適用場景.

首先來看Finagle. Finagle是Twitter在2011年開源的一款RPC框架, 在國外使用較多, 例如Pinterest, Nest, Tumblr, 感興趣的可以Google. Finagle有著較為豐富的生態(tài)圈, 例如可以使用Finch很方便的實現(xiàn)REST, 使用Finagle OAuth2實現(xiàn)OAuth認證, 使用zipkin實現(xiàn)服務(wù)監(jiān)控. Finagle使用Scala開發(fā), 官方宣稱同時支持scalaJava語言.

學(xué)習(xí)Finagle的使用之前, 首先要了解Finagle中的三個核心概念: Future, Service, Filter.

1. Future

Finagle使用的Future是com.twitter.util.Future. 由于Future非常實用, 從Scala2.10開始被加入到官方庫scala.concureent.Future. Java8中也引入了一個類似的接口java.util.concurrent.CompletableFuture. Future是對異步操作的抽象, 你可以將Future理解為一個容器, 這個容器包含一個異步操作. 一個Future容器可能處于三個狀態(tài)中的一種: 異步操作還沒有完成, 操作已經(jīng)完成了并包含了成功結(jié)果, 操作失敗并包含了異常結(jié)果. Future一種很常用的用法是可以注冊成功或失敗的回調(diào)函數(shù), 例如下面的Java代碼:

1
2
3
4
5
6
7
8
9
responseFuture.onSuccess(func(response -> {
    System.out.println(String.format("response status: %s, response string: %s",
            response.status().toString(), response.contentString()));
    return BoxedUnit.UNIT;
}));
responseFuture.onFailure(func(e -> {
    System.out.println("error: " + e.toString());
    return BoxedUnit.UNIT;
}));

我在responseFuture上注冊了一個成功的回調(diào)函數(shù)和失敗的回調(diào)函數(shù), 當Future對應(yīng)的操作完成時, 會簡單的打印出結(jié)果或異常信息. Future另外一個十分強大的用法是組合.例如下面的Java代碼:

1
2
3
4
5
Future<User> authenticatedUser = User.authenticate(email, password)
 
Future<Seq<Tweet>> lookupTweets = authenticatedUser.flatMap(user -> Tweet.findAllByUser(user))

//#1

這段代碼首先根據(jù)email和password獲取user對象, 然后獲取user對應(yīng)的所有微博. 我解釋下這段代碼的執(zhí)行邏輯. 首先調(diào)用User.authenticate(email, password)方法進行用戶認證, 返回的對象是Future, 代表這是一個異步操作. 注意我們拿到的是Future, 這個時候我們還沒有真正的拿到user對象. 接下來flatMap方法就派上用場了. 在上面代碼中, flatMap函數(shù)簽名應(yīng)該是這樣的:

1
2
3
4
5
//Java8中并沒有這個函數(shù), 這里只是用來解釋概念.
//Java8中CompletableFuture的thenCompose方法類似于flatMap
Future<Seq<Tweet>> flatMap(Function<User, Future<Seq<Tweet>>) {
  //...
}

簡單來說, flatMap的作用是將Future<A>轉(zhuǎn)換成Future<B>, 在這個例子里, 是將Future<User>轉(zhuǎn)換成Future<Seq<Tweet>>. 通過flatMap這種方式, 我們的代碼寫起來很像是同步執(zhí)行的, 但是實際上Future中的操作是由一個叫做Scheduler的組件去執(zhí)行的, 你可以將Scheduler理解為一個ExecutorService, 即我們的代碼是由其他線程異步執(zhí)行的. 上面的代碼中, 當代碼執(zhí)行到#1位置的時候, 其實認證用戶和獲取微博這兩個操作可能并沒有真正被執(zhí)行.

Future與flatMap的概念都來源于函數(shù)式編程. 在Haskell中, flatMap叫做綁定(bind), 而Future可以近似看作Monad(單子). 對函數(shù)式編程中的Monad感興趣的朋友可以參考我之前的文章.

Future還有其他一些很有用的方法, 例如從異常中恢復(fù)的rescue方法, 連接多個Future的join方法等, 這里就不展開了. Future在Finagle中無處不在, Finagle的設(shè)計哲理之一就是能異步的盡量異步, 大部分操作都不會阻塞. 例如下面我們要說的Service和Filter, 返回的結(jié)果都是Future. 如果你之前主要使用Spring或者Servlet這種技術(shù), 可能剛學(xué)習(xí)Finagle的時候覺得有些難以理解. 這很正常, 在后面的文章我會詳細介紹如何使用Future編程, 你會發(fā)現(xiàn)其實這種異步編程習(xí)慣與之前相比沒有太大的不同.只是ThreadLocal在這種環(huán)境下失效了, 不過好在我們有替代品 :)

2. Service

Service是Finagle中的核心概念. Service可以被理解為接收一個Request參數(shù), 返回一個Future對象的函數(shù). 如果定義為Java的抽象類, 原型如下:

1
2
3
4
5
6
//Service在Finagle中是用Scala代碼定義的, 這里只是用來解釋概念.
public abstract class Service<Request, Response> {

    public abstract Future<Response> apply(Request r);

}

如果用Spring MVC類比, Finagle的Service就類似于Controller的方法, 可以用來處理客戶端的請求. 例如要在Finagle中實現(xiàn)一個Echo服務(wù)器, 代碼如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Server extends Service<Request, Response> {

    @Override
    public Future<Response> apply(Request request) {
        Response response = Response.apply(Version.Http11$.MODULE$, Status.Ok());
        response.setContentString(request.getContentString());
        return Future.value(response);
    }

    public static void main(String[] args) throws Exception {
        Server service = new Server();

        ListeningServer server = Http.server().
                withLabel("echo-server").
                serve(new InetSocketAddress(8081), service);

        Await.result(server);
    }
}

注意Service的返回值是Future, 代表操作可以是異步完成的.

3. Filter

Finagle Filter類似于Servlet Filter, 可以對Service的請求和響應(yīng)進行過濾. 不過Finagle Filter使用類型參數(shù)明確定義了 輸入輸出的參數(shù)類型, Finagle Filter如果定義為Java的抽象類, 原型如下:

1
2
3
4
5
6
//Filter在Finagle中是用Scala代碼定義的, 這里只是用來解釋概念.
public abstract class Filter<ReqIn, RepOut, ReqOut, RepIn> {

     public abstract Future<RepOut> apply(ReqIn request, Service<ReqOut, RepIn> service);

}

對于ReqIn, RepOut, ReqOut, RepIn這四個類型參數(shù)的定義, 可以參考下圖. 

ReqIn和ReqOut分別是Filter的入?yún)⒑统鰠? 而RepIn和RepOut則是Service的入?yún)⒑统鰠? 我們來看看Filter在代碼中的實際用法:

1
2
3
4
5
6
7
8
9
10
val baseService = new Service[HttpRequest, HttpResponse] {
  def apply(request: HttpRequest) =
    Future(new DefaultHttpResponse(HTTP_1_1, OK))
}
 
val authorize = new RequireAuthorization()
val handleExceptions = new HandleExceptions(...)
 
val decoratedService: Service[HttpRequest, HttpResponse] =
  handleExceptions andThen authorize andThen baseService

我們定義了一個Service對象baseService, 兩個Filter對象authorize和handleExceptions. 通過filter的andThen方法, 我們能夠很簡單的將Filter和Service組裝到一起, 這有點類似于在web.xml中定義了一個Servlet, 以及兩個Filter來攔截針對Servlet的請求. 不過毫無疑問Finagle這種使用方式更加直觀, 并且不容易出錯.

現(xiàn)在我們已經(jīng)了解了Finagle的基本概念, 下一篇我將結(jié)合實例介紹如何使用Finagle進行開發(fā).


    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多