小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

美利好車的微服務實踐

 xujin3 2018-06-17
前言

美麗好車的微服務實踐是基于 Spring Cloud 體系來做的,在具體的開發(fā)過程中遇到了不少問題,踩了不少坑,對于微服務也有了實際的切身體會和理解,而不再是泛泛而談。在整個 Spring Cloud 技術棧中,基于不同職責需要,我們選擇了相應組件來支持我們的服務化,同時配合 Swagger 和 Feign 實現(xiàn)接口的文檔化和聲明式調用,在實際開發(fā)過程中極大地降低了溝通成本,提高了研發(fā)聯(lián)調和測試的效率。

從應用架構來看,正是由于基于 Spring Cloud 來實現(xiàn),整個系統(tǒng)完全秉承了微服務的原則,無論是 Spring Cloud 組件還是業(yè)務系統(tǒng),都體現(xiàn)了服務即組件、獨立部署、去中心化的特性,由此提供了快速交付和彈性伸縮的能力。

接下來我們基于各個組件具體介紹一下美利好車的微服務實踐,首先最基本的就是 Eureka,其承載著微服務中的服務注冊和服務發(fā)現(xiàn)的職責,是最基礎的組件,必然有高可用的要求。

基于高可用的 Eureka 集群實現(xiàn)服務發(fā)現(xiàn)

美利好車在生產(chǎn)實踐中部署了一個三節(jié)點的 Eureka Server 的集群,每個節(jié)點自身也同時基于 Eureka Client 向其它 Server 注冊,節(jié)點之間兩兩復制,實現(xiàn)了高可用。在配置時指定所有節(jié)點機器的 hostname 既可,即做到了配置部署的統(tǒng)一,又簡單實現(xiàn)了 IP 解耦,不需要像官方示例那樣用 profile 機制區(qū)分節(jié)點配置。這主要是由于 Eureka 節(jié)點在復制時會剔除自身節(jié)點,向其它節(jié)點復制實例信息,保證了單邊同步原則:只要有一條邊將節(jié)點連接,就可以進行信息傳播和同步。在生產(chǎn)環(huán)境中并不要過多調整其它配置,遵循默認的配置既可。


 服務發(fā)現(xiàn)

作為服務提供者的 Eureka Client 必須配置 register-with-eureka 為 true,即向 Eureka Server 注冊服務,而作為服務消費者的 Eureka Client 必須配置 fetch-registry=true,意即從 Eureka Server 上獲取服務信息。如果一個應用服務可能既對外提供服務,也使用其它領域提供的服務,則兩者都配置為 true,同時支持服務注冊和服務發(fā)現(xiàn)。由于 Ribbon 支持了負載均衡,所以作為服務提供者的應用一般都是采用基于 IP 的方式注冊,這樣更靈活。


 健康檢查

在開發(fā)測試環(huán)境中,常常都是 standlone 方式部署,但由于 Eureka 自我保護模式以及心跳周期長的原因,經(jīng)常會遇到 Eureka Server 不剔除已關停的節(jié)點的問題,而應用在開發(fā)測試環(huán)境的啟停又比較頻繁,給聯(lián)調測試造成了不小的困擾。為此我們調整了部分配置讓 Eureka Server 能夠迅速有效地踢出已關停的節(jié)點,主要包括在 Server 端配置關閉自我保護 (eureka.server.enableSelfPreservation=false),同時可以縮小 Eureka Server 清理無效節(jié)點的時間間隔(eureka.server.evictionIntervalTimerInMs=1000)等方式。

另外在 Client 端開啟健康檢查,并同步縮小配置續(xù)約更新時間和到期時間 (eureka.instance.leaseRenewalIntervalInSeconds=10 和 eureka.instance.leaseExpirationDurationInSeconds=20)。

健康檢查機制也有助于幫助 Eureka 判斷 Client 端應用的可用性。沒有健康檢查機制的 Client 端,其應用狀態(tài)會一直是 UP,只能依賴于 Server 端的定期續(xù)約和清理機制判斷節(jié)點可用性。配置了健康檢查的 Client 端會定時向 Server 端發(fā)送狀態(tài)心跳,同時內(nèi)置支持了包括 JDBC、Redis 等第三方組件的健康檢查,任何一個不可用,則應用會被標為 DOWN 狀態(tài),將不再提供服務。在生產(chǎn)環(huán)境下也是開啟了客戶端健康檢查的機制,但沒有調節(jié)配置參數(shù)。


 Eureka 的一致性

在 CAP 原則中,Eureka 在設計時優(yōu)先保證 AP。Eureka 各個節(jié)點都是平等的,幾個節(jié)點掛掉不會影響正常節(jié)點的工作,剩余的節(jié)點依然可以提供注冊和查詢服務。而 Eureka 的客戶端在向某個 Eureka 注冊時如果發(fā)現(xiàn)連接失敗,則會自動切換至其它節(jié)點,只要有一臺 Eureka 還在,就能保證注冊服務可用 (保證可用性),只不過查到的信息可能不是最新的 (不保證強一致性)。除此之外,Eureka 還有一種自我保護機制:如果在 15 分鐘內(nèi)超過 85% 的節(jié)點都沒有正常的心跳,那么 Eureka 就認為客戶端與注冊中心出現(xiàn)了網(wǎng)絡故障,開啟自我保護,支持可讀不可寫。

Eureka 為了保證高可用,在應用存活、服務實例信息、節(jié)點復制等都采用了緩存機制及定期同步的控制策略,比如客戶端的定期獲取(eureka.client.registryFetchIntervalSeconds),實例信息的定期復制(eureka.client.instanceInfoReplicationIntervalSeconds),Server 的定期心跳檢查 (eureka.instance.leaseExpirationDurationInSeconds),客戶端定期存活心跳(eureka.instance.leaseRenewalIntervalInSeconds)等等,加強了注冊信息的不一致性。服務消費者應用可以選擇重試或者快速失敗的方式,但作為服務提供者在基于 Spirng Cloud 的微服務機制下應當保證服務的冪等性,支持重試。因此如果對一致性的要求較高,可以適當調整相應參數(shù),但明顯這樣也增加了通信的頻率,這種平衡性的考慮更多地需要根據(jù)生產(chǎn)環(huán)境實際情況來調整,并沒有最優(yōu)的設置。

Config 的高可用及實時更新


 高可用方案

Config 的高可用方案比較簡單,只需將 Config Server 作為一個服務發(fā)布到注冊中心上,客戶端基于 Eureka Client 完成服務發(fā)現(xiàn),既可實現(xiàn)配置中心的高可用。這種方式要求客戶端應用必須在 bootstrap 階段完成發(fā)現(xiàn)配置服務并獲取配置,因此關于 Eureka Client 的配置也必須在 bootstrap 的配置文件中存在。同時我們引入了 Spring Retry 支持重試,可多次從 Server 端拉取配置,提高了容錯能力。另外,在啟動階段,我們配置了 failFast=true 來實現(xiàn)快速失敗的方式檢查應用啟動狀態(tài),避免對于失敗的無感知帶來應用不可用的情況。


 配置實時同步

在實際的生產(chǎn)中,我們同時基于 Spring Cloud Bus 機制和 Kafka 實現(xiàn)了實時更新,當通過 git 提交了更新的配置文件后,基于 webhook 或者手動向 Config Server 應用發(fā)送一個 /bus/refresh 請求,Config Server 則通過 Kafka 向應用節(jié)點發(fā)送了一個配置更新的事件,應用接收到配置更新的事件后,會判斷該文件的 version 和 state,如果任一個發(fā)生變化,則從 Config Server 新拉取配置,內(nèi)部基于 RefreshRemoteApplicationEvent 廣播更新 RefreshScope 標注的配置。默認的 Kafka 的 Topic 為 springCloudbus,同時需要注意的是應用集群的節(jié)點不能采用 consumer group 的方式消費,應采用廣播模式保證每個節(jié)點都消費配置更新消息。Spring CloudBus 又是基于 Spring Cloud Stream 機制實現(xiàn)的,因此配置需要按照 Steam 的方式設置。具體為:

spring.cloud.stream.kafka.binder.brokers=ip:portspring.cloud.stream.kafka.binder.zk-nodes=ip:portspring.cloud.stream.bindings.springCloudBusInput.destination=springCloudbus.dev

如果需要重定義 Topic 名稱,則需要如上所示進行調整,由于多套開發(fā)環(huán)境的存在,而 Kafka 只有一套,我們對 Topic 進行了不同環(huán)境的重定義。

但需要注意的一點是,這種實時刷新會導致拒絕任務的異常 (RejectedExecutionException),必現(xiàn)(當前 Edgware.RELEASE 版本)但不影響實際刷新配置,已被證實是個 Bug,具體參見 https://github.com/spring-cloud/spring-cloud-netflix/issues/2228,可簡單理解為在刷新時會關閉 context 及關聯(lián)的線程池重新加載,但刷新事件又同時提交了一個新的任務,導致拒絕執(zhí)行異常。

Zuul 的網(wǎng)關的安全及 session

 安全處理

針對外網(wǎng)請求,必然需要一個網(wǎng)關系統(tǒng)來進行統(tǒng)一的安全校驗及路由請求,Zuul 很好地支持了這一點,在實際生產(chǎn)中,我們盡量讓 gateway 系統(tǒng)不集成任何業(yè)務邏輯,基于 EnableZuulProxy 開啟了服務發(fā)現(xiàn)模式實現(xiàn)了服務路由。且只做安全和路由,降低了網(wǎng)關系統(tǒng)的依賴和耦合,也因此使 gateway 系統(tǒng)可以線性擴展,無壓力和無限制地應對流量和吞吐的擴張。

需要注意的是,重定向的問題需要配置 add-host-header=true 支持;為了安全保障,默認忽略所有服務(ignored-services='*'),基于白名單進行路由,同時開啟 endpoints 的安全校驗,以避免泄露信息,還要通過 ignored-patterns 關閉后端服務的 endpoints 訪問請求。


 Session 管理

Zuul 支持自定義 Http Header,我們借助于該機制,實現(xiàn)了 Session 從網(wǎng)關層向后端服務的透傳。主要是基于 pre 類型的 ZuulFilter,通過 RequestContex.addZuulRequestHeader 方法可實現(xiàn)請求轉發(fā)時增加自定義 Header,后端基于 SpringMVC 的攔截器攔截處理即可。

ZuulFilter 不像 SpringMVC 的攔截器那么強大,它是不支持請求路徑的過濾的。Zuul 也沒有集成 SpringMVC 的攔截器,這就需要我們自己開發(fā)實現(xiàn)類似的功能。如果需要支持 SpringMVC 攔截器,只需要繼承 InstantiationAwareBeanPostProcessorAdapter 重寫初始化方法 postProcessAfterInstantiation,向 ZuulHandlerMapping 添加攔截器既可。為了支持請求的過濾,還可以將攔截器包裝為 MappedInterceptor,這就可以像 SpringMVC 的攔截器一樣支持 include 和 exclude。具體代碼示例如下:

1.       public static class ZuulHandlerBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {  2.      3.        @Value('${login.patterns.include}')  4.        private String includePattern;  5.        @Value('${login.patterns.exclude}')  6.        private String excludePattern;  7.      8.        @Autowired  9.        private AuthenticateInterceptor authenticateInterceptor;  10.          11.      12.        public MappedInterceptor pattern(String[] includePatterns, String[] excludePatterns, HandlerInterceptor interceptor) {  13.            return new MappedInterceptor(includePatterns, excludePatterns, interceptor);  14.        }  15.      16.        @Override  17.        public boolean postProcessAfterInstantiation(final Object bean, final String beanName) throws BeansException {  18.            if (bean instanceof ZuulHandlerMapping) {  19.                ZuulHandlerMapping zuulHandlerMapping = (ZuulHandlerMapping) bean;  20.                String[] includePatterns = Iterables.toArray(Splitter.on(',').trimResults().omitEmptyStrings().split(includePattern), String.class);  21.                String[] excludePatterns = Iterables.toArray(Splitter.on(',').trimResults().omitEmptyStrings().split(excludePattern), String.class);  22.                zuulHandlerMapping.setInterceptors(pattern(includePatterns, excludePatterns, authenticateInterceptor));  23.            }  24.            return super.postProcessAfterInstantiation(bean, beanName);  25.        }  26.      27.    }


 關閉重試機制

Zuul 底層是基于 Ribbon 和 Hystrix 實現(xiàn)的,因此超時配置需要注意,如果基于服務發(fā)現(xiàn)的方式,則超時主要受 Ribbon 控制。另外由于 Spring Config 引入了 Spring Retry 導致 Zuul 會至少進行一次失敗請求的重試,各種開關配置都不生效,最后通過將 Ribbon 的 MaxAutoRetries 和 MaxAutoRetriesNextServer 同時設置為 0,避免了重試。在整個微服務調用中,由于不能嚴格保證服務的冪等性,我們是關閉了所有的重試機制的,包括 Feign 的重試,只能手動進行服務重試調用,以確保不會產(chǎn)生臟數(shù)據(jù)。

基于 Sleuth 的服務追蹤

Zipkin 是大規(guī)模分布式跟蹤系統(tǒng)的開源實現(xiàn),基于 2010 年 Google 發(fā)表的 Dapper 論文開發(fā)的,Spring Cloud Sleuth 提供了兼容 Zipkin 的實現(xiàn),可以很方便地集成,提供了較為直觀的可視化視圖,便于人工排查問題。美利好車系統(tǒng)在實際的生產(chǎn)實踐中,將日志同步改為適用于 Zipkin 格式的 pattern,這樣后端 ELK 組件日志的收集查詢也兼容,基于 traceId 實現(xiàn)了服務追蹤和日志查詢的聯(lián)動。

在日志的上報和收集上我們?nèi)匀换?spring-cloud-starter-bus-kafka 來實現(xiàn)。

Swagger 支持的接口文檔化和可測性

在前后端分離成為主流和現(xiàn)狀的情況下,前后端就接口的定義和理解的不一致性成為開發(fā)過程中效率的制約因素,解決這個問題可以幫助前后端團隊很好地協(xié)作,高質量地完成開發(fā)工作。我們在實際開發(fā)過程中使用了 Swagger 來生成在線 API 文檔,讓 API 管理和使用變得極其簡單,同時提供了接口的簡單測試能力。雖然這帶來了一定的侵入性,但從實際生產(chǎn)效率來說遠超出了預期,因此也特別予以強調和推薦。

實際開發(fā)過程中,我們?nèi)匀惶峁┝?API 的 SDK 讓調用方接入,雖然這個方式是微服務架構下不被推崇的,但現(xiàn)階段我們認為 SDK 可以讓調用 API 更簡單、更友好。版本問題基于 Maven 的 snapshot 機制實現(xiàn)實時更新,唯一需要注意的是要保證向后兼容。

以上就是美利好車系統(tǒng)微服務實施的一些實踐,有些地方可能不是特別恰當和正確,但在當前階段也算基本滿足了開發(fā)需要,而且我們秉承擁抱變化的態(tài)度,對整個體系結構也在持續(xù)進行改善和優(yōu)化,積極推動美利好車架構的演進,希望能更好地支持美利好車的業(yè)務需求。


 作者介紹

王文堯,曾在京東等多家知名互聯(lián)網(wǎng)電商領域公司任職,也創(chuàng)業(yè)做過垂直電商平臺,現(xiàn)任美利金融好車技術部架構師。對電商領域的業(yè)務比較了解,同時對敏捷、領域建模、高并發(fā)高可用的分布式系統(tǒng)設計及服務化等方面有較為深入的研究和實踐。


 More

P2P如何將視頻直播帶寬降低75%?

阿里盒馬領域驅動設計實踐

 其它

2017 年軟件研發(fā)領域有很多新的變化,比如 Java 9 正式發(fā)布;Kotlin 得到 Google Android 正式支持;Spark、Kafka 等框架紛紛引入流式計算能力;AI 技術蓬勃發(fā)展等等。

新一年的技術新趨勢 QCon 全球軟件開發(fā)大會也與你一同關注。目前,我們已經(jīng)確認多位技術專家:Netflix 工程總監(jiān) Katharina Probst、Kotlin 團隊工程師 Roman Elizarov、Apache Spark Structured Streaming 的核心開發(fā)人員朱詩雄、愛奇藝科學家李典等老師將在現(xiàn)場分享前沿技術案例,共呈技術盛宴。

2018 北京站現(xiàn)在報名享 7 折優(yōu)惠,立減 2040 元。有任何問題可咨詢購票經(jīng)理 Hanna,電話:15110019061,微信:qcon-0410。


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

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多