日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關咨詢
選擇下列產(chǎn)品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關閉右側工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
微服務框架相關技術整理

微服務整體框架

  • 開發(fā)前后臺分離:前臺與后臺之間,通過 Restful 風格接口通信(HTTP協(xié)議)
  • 內(nèi)部服務: Dubbo ( RPC框架)
  • 外部服務: SpringCloud Zuul (提供Restful API接口)
     

    錦江網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)建站!從網(wǎng)頁設計、網(wǎng)站建設、微信開發(fā)、APP開發(fā)、響應式網(wǎng)站等網(wǎng)站項目制作,到程序開發(fā),運營維護。創(chuàng)新互聯(lián)建站2013年至今到現(xiàn)在10年的時間,我們擁有了豐富的建站經(jīng)驗和運維經(jīng)驗,來保證我們的工作的順利進行。專注于網(wǎng)站建設就選創(chuàng)新互聯(lián)建站。

  • 微服務應用開發(fā)  

API Gateway

  • API Gateway :網(wǎng)關,統(tǒng)一應用請求接口.API 網(wǎng)關在微服務們的最前端,讓 API 網(wǎng)關變成由應用所發(fā)起的每個請求的入口,簡化客戶端實現(xiàn)和微服務應用程序間的溝通方式。

API Gateway兩種方式:

  • 單節(jié)點API Gateway
     

  • BFF (Backends for frontends) Gateway
     

API Gateway的作用

  • 請求路由,版本控制: API Gateway 是微服務的入口,可以根據(jù)不同的請求路由到不同的服務上. 也可以進行路由的版本控制,這樣即使后服務發(fā)生了變化,Gateway 的路徑依然可以不改變
  • 用戶登錄,權限認證: 客戶端在與我們后端服務進行交互之前,由API Gateway先進行登錄鑒權操作,這是后端所有的服務都需要有的共有邏輯
  • 數(shù)據(jù)聚合: 由于不同的客戶端往往需要的數(shù)據(jù)完全不同,而這些數(shù)據(jù)又是不同的 service 提供的,可以借助 Gateway 方便完成來自不同 service 的數(shù)據(jù)聚合
  • 協(xié)議轉換: 在項目實踐中,CS(Client to Server)協(xié)議和SS(Server to Server)協(xié)議是不一樣的,為了保證數(shù)據(jù)傳輸?shù)目煽啃?,CS協(xié)議會有鑒權以及加密解密的邏輯,而在內(nèi)部的SS協(xié)議則不需要這些邏輯,因此在 Gateway 我們需要有一個協(xié)議轉換的過程
  • 熔斷,降級,限流: 通過API Gateway可以在監(jiān)測到某個服務發(fā)生異常,或者當服務的流量超過服務的承載能力等情況時,可以采取相應的措施. 提高整個系統(tǒng)的容錯性、穩(wěn)定性
  • 負載均衡: API Gateway知道所有服務實例的地址,可以根據(jù)不同服務采取不同的負載均衡策略
  • 灰度發(fā)布: 灰度發(fā)布允許直接只導入指定量的流量請求到新的版本

API Gateway的架構

  • 多網(wǎng)關集群(Backends for frontends): 針對不同的客戶端,都有相應的網(wǎng)關層來接入.功能主要有:用戶登錄,鑒權,服務發(fā)現(xiàn)注冊,協(xié)議轉換,接口版本控制等以及監(jiān)控,APM調(diào)用鏈,日志,流控策略等
  • 聚合服務(Merge Service): 在某些客戶端的需求中,需要從多個服務拉取數(shù)據(jù),為了減少客戶端的復雜度,以及加快客戶端的訪問速度,可以加一個聚合層,用來做聚合查詢,在某些接口中可以把多個服務的數(shù)據(jù)一次性返回給客戶端
  • 儀表盤管理端(Dashboard): Dashboard 提供可視化的分析平臺,包括服務的管理,監(jiān)控數(shù)據(jù)報警配置,日志查詢,灰度發(fā)布操作,API文檔管理等

Eureka(服務發(fā)現(xiàn)框架)

  • Eureka是一個基于REST的服務,主要用于定位運行在AWS域中的中間層服務,以達到負載均衡和中間層服務故障轉移的目的. SpringCloud將它集成在其子項目spring-cloud-netflix中,以實現(xiàn)SpringCloud的服務發(fā)現(xiàn)功能

Eureka的兩個組件

  • Eureka Server: Eureka Server提供服務注冊服務,各個節(jié)點啟動后,會在Eureka Server中進行注冊,這樣EurekaServer中的服務注冊表中將會存儲所有可用服務節(jié)點的信息,服務節(jié)點的信息可以在界面中看到. Eureka Server之間通過復制的方式完成數(shù)據(jù)的同步
  • Eureka Client: 是一個java客戶端,用于簡化與Eureka Server的交互,客戶端同時也就是一個內(nèi)置的、使用輪詢(round-robin)負載算法的負載均衡器
  • Eureka通過心跳檢查、客戶端緩存等機制,確保了系統(tǒng)的高可用性、靈活性和可伸縮性
    • 在應用啟動后,將會向Eureka Server發(fā)送心跳, 如果Eureka Server在多個心跳周期內(nèi)沒有接收到某個節(jié)點的心跳,Eureka Server將會從服務注冊表中把這個服務節(jié)點移除。
    • Eureka還提供了客戶端緩存機制,即使所有的Eureka Server都掛掉,客戶端依然可以利用緩存中的信息消費其他服務的API。Eureka通過心跳檢查、客戶端緩存等機制,確保了系統(tǒng)的高可用性、靈活性和可伸縮性

RPC框架

RPC定義

  • RPC(Remote Procedure Call Protocol): 遠程過程調(diào)用協(xié)議,一種通過網(wǎng)絡從遠程計算機程序上請求服務,而不需要了解底層網(wǎng)絡技術的協(xié)議.也就是

客戶端在不知道調(diào)用細節(jié)的情況下,調(diào)用存在于遠程計算機上的某個對象,就像調(diào)用本地應用程序中的對象一樣

  • RPC是協(xié)議: 協(xié)議就是一套規(guī)范,目前典型的RPC實現(xiàn)包括:Dubbo,Thrift,GRPC,Hetty等.從目前技術的發(fā)展趨勢來看,實現(xiàn)了RPC協(xié)議的應用工具往往都會附加其他重要功能
  • 網(wǎng)絡協(xié)議和網(wǎng)絡IO模型對其透明: 既然RPC的客戶端認為自己是在調(diào)用本地對象。那么傳輸層使用的是TCP/UDP還是HTTP協(xié)議,又或者是一些其他的網(wǎng)絡協(xié)議它就不需要關心了。既然網(wǎng)絡協(xié)議對其透明,那么調(diào)用過程中,使用的是哪一種網(wǎng)絡IO模型調(diào)用者也不需要關心
  • 信息格式對其透明: 我們知道在本地應用程序中,對于某個對象的調(diào)用需要傳遞一些參數(shù),并且會返回一個調(diào)用結果。至于被調(diào)用的對象內(nèi)部是如何使用這些參數(shù),并計算出處理結果的,調(diào)用方是不需要關心的。那么對于遠程調(diào)用來說,這些參數(shù)會以某種信息格式傳遞給網(wǎng)絡上的另外一臺計算機,這個信息格式是怎樣構成的,調(diào)用方是不需要關心的
  • 應該有跨語言能力: 調(diào)用方實際上也不清楚遠程服務器的應用程序是使用什么語言運行的。那么對于調(diào)用方來說,無論服務器方使用的是什么語言,本次調(diào)用都應該成功,并且返回值也應該按照調(diào)用方程序語言所能理解的形式進行描述
     

RPC主要組成部分

  • Client: RPC協(xié)議的調(diào)用方.最理想的情況是RPC Client在完全不知道有RPC框架存在的情況下發(fā)起對遠程服務的調(diào)用.但實際情況來說Client或多或少的都需要指定RPC框架的一些細節(jié)
  • Server: 在RPC規(guī)范中,這個Server并不是提供RPC服務器IP,端口監(jiān)聽的模塊。而是 遠程服務方法的具體實現(xiàn)(在JAVA中就是RPC服務接口的具體實現(xiàn)) .其中的代碼是最普通的和業(yè)務相關的代碼,甚至其接口實現(xiàn)類本身都不知道將被某一個RPC遠程客戶端調(diào)用
  • Stub/Proxy: RPC代理存在于客戶端,因為要實現(xiàn)客戶端對RPC框架“透明”調(diào)用,那么客戶端不可能自行去管理消息格式、不可能自己去管理網(wǎng)絡傳輸協(xié)議,也不可能自己去判斷調(diào)用過程是否有異常。這一切工作在客戶端都是交給RPC框架中的“代理”層來處理的
  • Message Protocol: 一次完整的client-server的交互肯定是攜帶某種兩端都能識別的,共同約定的消息格式. RPC的消息管理層專門對網(wǎng)絡傳輸所承載的消息信息進行編碼和解碼操作 .目前流行的技術趨勢是不同的RPC實現(xiàn),為了加強自身框架的效率都有一套(或者幾套)私有的消息格式
  • Transfer/Network Protocol: 傳輸協(xié)議層負責管理RPC框架所使用的網(wǎng)絡協(xié)議,網(wǎng)絡IO模型. 傳輸層還需要統(tǒng)一RPC客戶端和RPC服務端所使用的IO模型
  • Selector/Processor: 存在于RPC服務端,用于服務器端某一個RPC接口的實現(xiàn)的特性(它并不知道自己是一個將要被RPC提供給第三方系統(tǒng)調(diào)用的服務).所以在RPC框架中應該有一種 " 負責執(zhí)行RPC接口實現(xiàn) " 的角色.包括: 管理RPC接口的注冊,判斷客戶端的請求權限,控制接口實現(xiàn)類的執(zhí)行在內(nèi)
  • IDL: IDL(接口定義語言)并不是RPC實現(xiàn)中所必須的.但是需要跨語言的RPC框架一定會有IDL部分的存在.這是因為要找到一個 各種語言能夠理解的消息結構、接口定義的描述形式 . 如果RPC實現(xiàn)沒有考慮跨語言性,那么IDL部分就不需要包括 ,例如JAVA RMI因為就是為了在JAVA語言間進行使用,所以JAVA RMI就沒有相應的IDL

不同的RPC框架實現(xiàn)都有一定設計差異。例如生成Stub的方式不一樣,IDL描述語言不一樣、服務注冊的管理方式不一樣、運行服務實現(xiàn)的方式不一樣、采用的消息格式封裝不一樣、采用的網(wǎng)絡協(xié)議不一樣。但是基本的思路都是一樣的,上圖中的所列出的要素也都是具有的

影響RPC框架性能的因素

  • 使用的網(wǎng)絡IO模型: RPC服務器可以只支持傳統(tǒng)的阻塞式同步IO,也可以做一些改進讓RPC服務器支持非阻塞式同步IO,或者在服務器上實現(xiàn)對多路IO模型的支持.這樣的RPC服務器的性能在高并發(fā)狀態(tài)下,會有很大的差別.特別是單位處理性能下對內(nèi)存,CPU資源的使用率
  • 基于的網(wǎng)絡協(xié)議: 一般來說可以選擇讓RPC使用應用層協(xié)議,例如HTTP或者HTTP/2協(xié)議,或者使用TCP協(xié)議.讓RPC框架工作在傳輸層.工作在哪一層網(wǎng)絡上會對RPC框架的工作性能產(chǎn)生一定的影響,但是對RPC最終的性能影響并不大.但是至少從各種主流的RPC實現(xiàn)來看,沒有采用UDP協(xié)議做為主要的傳輸協(xié)議的
  • 消息封裝格式: 選擇或者定義一種消息格式的封裝,要考慮的問題包括: 消息的易讀性,描述單位內(nèi)容時的消息體大小,編碼難度,解碼難度,解決半包/粘包問題的難易度. 當然如果您只是想定義一種RPC專用的消息格式,那么消息的易讀性可能不是最需要考慮的.消息封裝格式的設計是目前各種RPC框架性能差異的最重要原因,這就是為什么幾乎所有主流的RPC框架都會設計私有的消息封裝格式的原因. dubbo 中消息體數(shù)據(jù)包含 dubbo版本號,接口名稱,接口版本,方法名稱,參數(shù)類型列表,參數(shù),附加信息
  • 序列化和反序列化(Schema & Data Serialization): 序列化和反序列化,是對象到二進制數(shù)據(jù)的轉換,程序是可以理解對象的,對象一般含有 schema 或者結構,基于這些語義來做特定的業(yè)務邏輯處理.

序列化框架一般會關注以下幾點:

  1. Encoding format:是human readable(是否能直觀看懂 json)還是binary(二進制)
  2. Schema declaration:也叫作契約聲明,基于IDL,比如 Protocol Buffers/Thrift.還是自描述的,比如 JSON、XML.另外還需要看是否是強類型的
  3. 語言平臺的中立性:比如Java的Native Serialization就只能自己玩,而Protocol Buffers可以跨各種語言和平臺
  4. 新老契約的兼容性:比如IDL加了一個字段,老數(shù)據(jù)是否還可以反序列化成。
  5. 和壓縮算法的契合度 :運行benchmark(基準)和實際應用都會結合各種壓縮算法,例如gzip,snappy
  6. 性能 :這是最重要的,序列化,反序列化的時間,序列化后數(shù)據(jù)的字節(jié)大小是考察重點。
  7. 序列化方式非常多,常見的有Protocol Buffers,Avro,Thrift,XML,JSON,MessagePack,Kyro,Hessian,Protostuff,Java Native Serialize,FST
  • 實現(xiàn)的服務處理管理方式: 在高并發(fā)請求下,如何管理注冊的服務也是一個性能影響點.可以讓RPC的Selector/Processor使用單個線程運行服務的具體實現(xiàn)(這意味著上一個客戶端的請求沒有處理完,下一個客戶端的請求就需要等待). 也可以為每一個RPC具體服務的實現(xiàn)開啟一個獨立的線程運行(可以一次處理多個請求,但是操作系統(tǒng)對于“可運行的最大線程數(shù)”是有限制的). 也可以線程池來運行RPC具體的服務實現(xiàn)(目前看來,在單個服務節(jié)點的情況下,這種方式是比較好的). 還可以通過注冊代理的方式讓多個服務節(jié)點來運行具體的RPC服務實現(xiàn)

工業(yè)界的 RPC 框架

  • 國內(nèi)
    • Dubbo: 來自阿里巴巴 http://dubbo.I/O/
    • Motan: 新浪微博自用 https://github.com/weibocom/motan
    • Dubbox: 當當基于 dubbo 的 https://github.com/dangdangdotcom/dubbox
    • rpcx: 基于 Golang 的 https://github.com/smallnest/rpcx
  • 國外
    • Thrift from facebook: https://thrift.apache.org
    • Avro from hadoop: https://avro.apache.org
    • Finagle by twitter: https://twitter.github.I/O/finagle
    • gRPC by Google: http://www.grpc.I/O (Google inside use Stuppy)
    • Hessian from cuacho: http://hessian.caucho.com
    • Coral Service inside amazon: not open sourced

如何選擇RPC框架

選擇一個rpc框架會基于多方面的考慮: 框架特性、性能、成熟度、技術支持、社區(qū)活躍度等 多個方面.最重要一點,這也是往往很多技術人員進入的誤區(qū), "對于技術,不要為了使用而使用, 用最簡單合適的技術實現(xiàn)解決問題才是正道 " . 架構是服務于業(yè)務的,能快速方便的滿足業(yè)務需求的架構才是好的架構 .沒有最好的,只有適合自己的

Dubbo

  • Dubbo是一個開源分布式服務框架,阿里巴巴公司開源的一個高性能優(yōu)秀的服務框架,使得應用可通過高性能的 RPC 實現(xiàn)服務的輸出和輸入功能,可以和Spring框架無縫集成.
  • Dubbo是一款高性能,輕量級的開源Java RPC框架,它提供了三大核心能力: 面向接口的遠程方法調(diào)用,智能容錯和負載均衡,以及服務自動注冊和發(fā)現(xiàn)

核心組件

  • Remoting: 網(wǎng)絡通信框架,實現(xiàn)了 sync-over-async 和 request-response 消息機制
  • RPC: 一個遠程過程調(diào)用的抽象.支持負載均衡,容災和集群功能
  • Registry: 服務目錄框架,用于服務的注冊和服務事件發(fā)布和訂閱

工作原理

Provider:暴露服務方稱之為“服務提供者”

Consumer:調(diào)用遠程服務方稱之為“服務消費者”

Registry:服務注冊與發(fā)現(xiàn)的中心目錄服務稱之為“服務注冊中心”

Monitor:統(tǒng)計服務的調(diào)用次數(shù)和調(diào)用時間的日志服務稱之為“服務監(jiān)控中心”

連通性:

注冊中心負責服務地址的注冊與查找,相當于目錄服務,服務提供者和消費者只在啟動時與注冊中心交互,注冊中心不轉發(fā)請求,壓力較小

監(jiān)控中心負責統(tǒng)計各服務調(diào)用次數(shù),調(diào)用時間等,統(tǒng)計先在內(nèi)存匯總后每分鐘一次發(fā)送到監(jiān)控中心服務器,并以報表展示

服務提供者向注冊中心注冊其提供的服務,并匯報調(diào)用時間到監(jiān)控中心,此時間不包含網(wǎng)絡開銷

服務消費者向注冊中心獲取服務提供者地址列表,并根據(jù)負載算法直接調(diào)用提供者,同時匯報調(diào)用時間到監(jiān)控中心,此時間包含網(wǎng)絡開銷

注冊中心,服務提供者,服務消費者三者之間均為長連接,監(jiān)控中心除外

注冊中心通過長連接感知服務提供者的存在,服務提供者宕機,注冊中心將立即推送事件通知消費者

注冊中心和監(jiān)控中心全部宕機,不影響已運行的提供者和消費者,消費者在本地緩存了提供者列表

注冊中心和監(jiān)控中心都是可選的,服務消費者可以直連服務提供者

健壯性:

監(jiān)控中心宕掉不影響使用,只是丟失部分采樣數(shù)據(jù)

數(shù)據(jù)庫宕掉后,注冊中心仍能通過緩存提供服務列表查詢,但不能注冊新服務

注冊中心對等集群,任意一臺宕掉后,將自動切換到另一臺

注冊中心全部宕掉后,服務提供者和服務消費者仍能通過本地緩存通訊

服務提供者無狀態(tài),任意一臺宕掉后,不影響使用

服務提供者全部宕掉后,服務消費者應用將無法使用,并無限次重連等待服務提供者恢復

伸縮性:

注冊中心為對等集群,可動態(tài)增加機器部署實例,所有客戶端將自動發(fā)現(xiàn)新的注冊中心

服務提供者無狀態(tài),可動態(tài)增加機器部署實例,注冊中心將推送新的服務提供者信息給消費者

Dubbo特性

  • 面向接口代理的高性能RPC調(diào)用: 提供高性能的基于代理的遠程調(diào)用能力,服務以接口為粒度,為開發(fā)者屏蔽遠程調(diào)用底層細節(jié)
  • 智能負載均衡: 內(nèi)置多種負載均衡策略,智能感知下游節(jié)點健康狀況,顯著減少調(diào)用延遲,提高系統(tǒng)吞吐量
  • 服務自動注冊與發(fā)現(xiàn): 支持多種注冊中心服務,服務實例上下線實時感知
  • 高度可擴展能力: 遵循微內(nèi)核+插件的設計原則,所有核心能力如 Protocol,Transport,Serialization 被設計為擴展點,平等對待內(nèi)置實現(xiàn)和第三方實現(xiàn)
  • 運行期流量調(diào)度: 內(nèi)置條件,腳本等路由策略.通過配置不同的路由規(guī)則,輕松實現(xiàn)灰度發(fā)布,同機房優(yōu)先等功能
  • 可視化的服務治理與運維: 提供豐富服務治理,運維工具:隨時查詢服務元數(shù)據(jù),服務健康狀態(tài)及調(diào)用統(tǒng)計,實時下發(fā)路由策略,調(diào)整配置參數(shù)

使用示例

Zuul

  • Zuul是netflix開源的一個API Gateway 服務器, 本質(zhì)上是一個web servlet應用

    Zuul 是一個基于JVM路由和服務端的負載均衡器,提供動態(tài)路由,監(jiān)控,彈性,安全等邊緣服務的框架,相當于是設備和 Netflix 流應用的 Web 網(wǎng)站后端所有請求的前門

Zuul工作原理

  • 過濾器機制
    • Zuul提供了一個框架,可以對過濾器進行動態(tài)的加載,編譯,運行
    1.Zuul的過濾器之間沒有直接的相互通信,他們之間通過一個RequestContext的靜態(tài)類來進行數(shù)據(jù)傳遞的。RequestContext類中有ThreadLocal變量來記錄每個Request所需要傳遞的數(shù)據(jù)
    2.Zuul的過濾器是由Groovy寫成,這些過濾器文件被放在Zuul Server上的特定目錄下面,Zuul會定期輪詢這些目錄,修改過的過濾器會動態(tài)的加載到Zuul Server中以便過濾請求使用
    • 標準過濾器類型:
      Zuul大部分功能都是通過過濾器來實現(xiàn)的。Zuul中定義了四種標準過濾器類型,這些過濾器類型對應于請求的典型生命周期
      • PRE: 在請求被路由之前調(diào)用,利用這種過濾器實現(xiàn)身份驗證、在集群中選擇請求的微服務、記錄調(diào)試信息等
      • ROUTING: 請求路由到微服務,用于構建發(fā)送給微服務的請求,使用Apache HttpClient或Netfilx Ribbon請求微服務
      • POST: 在路由到微服務以后執(zhí)行,用來為響應添加標準的HTTP Header、收集統(tǒng)計信息和指標、將響應從微服務發(fā)送給客戶端等
      • ERROR: 在其他階段發(fā)生錯誤時執(zhí)行該過濾器
    • 內(nèi)置的特殊過濾器:
      • StaticResponseFilter: StaticResponseFilter允許從Zuul本身生成響應,而不是將請求轉發(fā)到源
      • SurgicalDebugFilter: SurgicalDebugFilter允許將特定請求路由到分隔的調(diào)試集群或主機
    • 自定義的過濾器:
      除了默認的過濾器類型,Zuul還允許我們創(chuàng)建自定義的過濾器類型。如STATIC類型的過濾器,直接在Zuul中生成響應,而不將請求轉發(fā)到后端的微服務
  • 過濾器的生命周期
    Zuul請求的生命周期詳細描述了各種類型的過濾器的執(zhí)行順序

  • 過濾器調(diào)度過程
     

  • 動態(tài)加載過濾器
     

Zuul的作用

Zuul可以通過加載動態(tài)過濾機制實現(xiàn)Zuul的功能:

  • 驗證與安全保障: 識別面向各類資源的驗證要求并拒絕那些與要求不符的請求
  • 審查與監(jiān)控: 在邊緣位置追蹤有意義數(shù)據(jù)及統(tǒng)計結果,得到準確的生產(chǎn)狀態(tài)結論
  • 動態(tài)路由: 以動態(tài)方式根據(jù)需要將請求路由至不同后端集群處
  • 壓力測試: 逐漸增加指向集群的負載流量,從而計算性能水平
  • 負載分配: 為每一種負載類型分配對應容量,并棄用超出限定值的請求
  • 靜態(tài)響應處理: 在邊緣位置直接建立部分響應,從而避免其流入內(nèi)部集群
  • 多區(qū)域彈性: 跨越AWS區(qū)域進行請求路由,旨在實現(xiàn)ELB使用多樣化并保證邊緣位置與使用者盡可能接近

Zuul與應用的集成方式

  • ZuulServlet - 處理請求(調(diào)度不同階段的filters,處理異常等)
    • 所有的Request都要經(jīng)過ZuulServlet的處理,
    • Zuul對request處理邏輯的三個核心的方法: preRoute(),route(), postRoute()
    • ZuulServletZuulServlet交給ZuulRunner去執(zhí)行。由于ZuulServlet是單例,因此ZuulRunner也僅有一個實例。ZuulRunner直接將執(zhí)行邏輯交由FilterProcessor處理,F(xiàn)ilterProcessor也是單例,其功能就是依據(jù)filterType執(zhí)行filter的處理邏輯
    • FilterProcessor對filter的處理邏輯:
      1.首先根據(jù)Type獲取所有輸入該Type的filter:List list
      2.遍歷該list,執(zhí)行每個filter的處理邏輯:processZuulFilter(ZuulFilter filter)
      3.RequestContext對每個filter的執(zhí)行狀況進行記錄,應該留意,此處的執(zhí)行狀態(tài)主要包括其執(zhí)行時間、以及執(zhí)行成功或者失敗,如果執(zhí)行失敗則對異常封裝后拋出
      4.到目前為止,Zuul框架對每個filter的執(zhí)行結果都沒有太多的處理,它沒有把上一filter的執(zhí)行結果交由下一個將要執(zhí)行的filter,僅僅是記錄執(zhí)行狀態(tài),如果執(zhí)行失敗拋出異常并終止執(zhí)行
    • ContextLifeCycleFilter - RequestContext 的生命周期管理:
      • ContextLifecycleFilter的核心功能是為了清除RequestContext;請求上下文RequestContext通過ThreadLocal存儲,需要在請求完成后刪除該對象RequestContext提供了執(zhí)行filter Pipeline所需要的Context,因為Servlet是單例多線程,這就要求RequestContext即要線程安全又要Request安全。context使用ThreadLocal保存,這樣每個worker線程都有一個與其綁定的RequestContext,因為worker僅能同時處理一個Request,這就保證了Request Context 即是線程安全的由是Request安全的。
    • GuiceFilter - GOOLE-IOC(Guice是Google開發(fā)的一個輕量級,基于Java5(主要運用泛型與注釋特性)的依賴注入框架(IOC).Guice非常小而且快.)
    • StartServer - 初始化 zuul 各個組件(ioc,插件,filters,數(shù)據(jù)庫等)
    • FilterScriptManagerServlet - uploading/downloading/managing scripts, 實現(xiàn)熱部署
      Filter源碼文件放在zuul 服務特定的目錄, zuul server會定期掃描目錄下的文件的變化,動態(tài)的讀取\編譯\運行這些filter,如果有Filter文件更新,源文件會被動態(tài)的讀取,編譯加載進入服務,接下來的Request處理就由這些新加入的filter處理

React前端框架

React定義

  • React前端框架是Facebook開源的一個js庫,用于動態(tài)構建用戶界面.
  • React解決的問題:
    • 數(shù)據(jù)綁定的時候,大量操作真實dom,性能成本太高
    • 網(wǎng)站的數(shù)據(jù)流向太混亂,不好控制
  • React 把用戶界面抽象成一個個組件.如按鈕組件 Button,對話框組件 Dialog,日期組件 Calendar.開發(fā)者通過組合這些組件,最終得到功能豐富,可交互的頁面.通過引入 JSX 語法,復用組件變得非常容易,同時也能保證組件結構清晰.有了組件這層抽象,React 把代碼和真實渲染目標隔離開來,除了可以在瀏覽器端渲染到 DOM 來開發(fā)網(wǎng)頁外,還能用于開發(fā)原生移動應用

React核心

虛擬DOM是React的基石,React的核心是 組件 ,React的精髓是 函數(shù)式編程 ,在React中是 單向響應的數(shù)據(jù)流

組件的設計目的是提高代碼復用率,降低測試難度和代碼復雜度:

  1. 提高代碼復用率:組件將數(shù)據(jù)和邏輯封裝,類似面向?qū)ο笾械念?/li>
  2. 降低測試難度:組件高內(nèi)聚低耦合,很容易對單個組件進行測試
  3. 降低代碼復雜度:直觀的語法可以極大提高可讀性

React特點

  • JSX: JSX 是 JavaScript 語法的擴展
  • 組件: 通過 React 構建組件,使得代碼更加容易得到復用,能夠很好的應用在大項目的開發(fā)中
  • 單向響應的數(shù)據(jù)流: React 實現(xiàn)了單向響應的數(shù)據(jù)流,從而減少了重復代碼,這也是它為什么比傳統(tǒng)數(shù)據(jù)綁定更簡單
  • Declarative(聲明式編碼): React采用聲明范式,可以輕松描述應用(自動dom操作)
  • Component-Based(組件化編碼)
  • Learn Once,Write Anywhere(支持客戶端與服務器渲染)
  • 高效:React通過對DOM的模擬(虛擬dom),最大限度地減少與DOM的交互

1.虛擬(virtual)DOM, 不總是直接操作DOM,減少頁面更新次數(shù);
2.高效的DOM Diff算法, 最小化頁面重繪;

  • 靈活:React可以與已知的庫或框架很好地配合

React的虛擬DOM

  • 傳統(tǒng)DOM更新
    真實頁面對應一個 DOM 樹.在傳統(tǒng)頁面的開發(fā)模式中,每次需要更新頁面時,都要手動操作 DOM 來進行更新

虛擬DOM
DOM操作非常昂貴.我們都知道在前端開發(fā)中,性能消耗最大的就是DOM操作,而且這部分代碼會讓整體項目的代碼變得難以維護.React把真實DOM樹轉換成JavaScript對象樹,也就是Virtual DOM

  • 虛擬DOM定義:
    • 一個虛擬DOM(元素)是一個一般的js對象,準確的說是一個對象樹(倒立的)
    • 虛擬DOM保存了真實DOM的層次關系和一些基本屬性,與真實DOM一一對應
    • 如果只是更新虛擬DOM, 頁面是不會重繪的
  • Virtual DOM算法步驟:
    • 用JS對象樹表示DOM樹的結構.然后用這個樹構建一個真正的DOM樹插入到文檔中
    • 當狀態(tài)變更的時候,重新構造一棵新的對象樹.然后用新的樹和舊的樹進行比較,記錄兩棵樹差異
    • 把差異應用到真實DOM樹上,視圖就更新了
  • 進一步理解:
    • Virtual DOM 本質(zhì)上就是在 JS 和 DOM 之間做了一個 緩存

可以類比CPU和硬盤,既然硬盤這么慢,我們就在它們之間加個緩存:既然 DOM 這么慢,
我們就在它們JS和DOM之間加個緩存.CPU(JS)只操作內(nèi)存(Virtual DOM,最后的時候再
把變更寫入硬盤(DOM)

  • React提供了一些API來創(chuàng)建一種特別的一般js對象
 
 
 
 
  1. //創(chuàng)建的就是一個簡單的虛擬DOM對象 
  2. var element = React.createElement('h1', {id:'myTitle'}, 'hello'); 
  • 虛擬DOM對象最終都會被React轉換為真實的DOM
  • 我們編碼時基本只需要操作react的虛擬DOM相關數(shù)據(jù),react會轉換為真實DOM變化而更新界面
  • 創(chuàng)建虛擬DOM的2種方式
    • JSX方式
 
 
 
 
  1. //  jsx方式創(chuàng)建虛擬dom元素對象 
  2. const vDOM2 = {msg.toLowerCase()} 

還有一種是純JS,一般不使用:

 
 
 
 
  1. //  純JS方式 
  2. const msg = 'I like you'; 
  3. const myId = 'atguigu'; 
  4. const vDOM1 = React.createElement('h2',{id:myId},msg); 
  • 渲染虛擬DOM(元素)
    • 語法: ReactDOM.render(virtualDOM,containerDOM)
    • 作用: 將虛擬DOM元素渲染到真實容器DOM中顯示
    • 參數(shù)說明:
      • 參數(shù)一: 純js或jsx創(chuàng)建的虛擬DOM對象
      • 參數(shù)二: 用來包含虛擬DOM元素的真實dom元素對象(一般是一個div)
 
 
 
 
  1. //  渲染到真實的頁面中 
  2.  ReactDOM.render(vDOM1,document.getElementById('example1')); 
  3.  ReactDOM.render(vDOM2,document.getElementById('example2')); 

使用示例:

 
 
 
 
  1.  
  2.  
  3.  
  4.  
  5. 02_JSX_DEMO 
  6.  
  7.  
    •  
    • A
    •  
    • B
    •  
    • C
    •  
     

  8.  
  9.  
 
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  • React的組件

    • 模塊
      • 什么是模塊: 向外提供特定功能的js程序, 一般就是一個js文件
      • 為什么要用模塊: js代碼越多越復雜了
      • 使用模塊的優(yōu)勢: 簡化js的編寫, 閱讀, 提高運行效率
      • 模塊化: 當應用的js都以模塊來編寫的, 這個應用就是一個模塊化的應用
    • 組件
      • 什么是組件: 用來實現(xiàn)特定功能效果的代碼集合(html/css/js)
      • 為什么要用組件: 單個界面的功能更復雜
      • 使用組件的優(yōu)勢: 復用, 簡化項目編碼, 提高運行效率
      • 組件化: 當應用是以多組件的方式實現(xiàn)功能, 這樣應用就是一個組件化的應用
    • 自定義組件:
      1. 定義組件
     
     
     
     
    1. 1.工廠(無狀態(tài))函數(shù)(簡單組件,推薦使用) 
    2.     
    3.     //  方式一:工廠函數(shù),推薦使用 
    4.   function MyComponent() { 
    5.   return 

      工廠函數(shù)

       
    6.   } 
    7.  
    8. 2.ES6類語法 
    9. //  方式二:ES6類語法(復雜組件,推薦使用) 
    10. class MyComponent2 extends React.Component{ 
    11.      render(){ 
    12.          return 

      ES6的語法

       
    13.      } 
    14.  } 

    2. 渲染組件標簽

     
     
     
     
    1. //語法規(guī)則 
    2. ReactDOM.render(, document.getElementById('example')); 
    • ==注意==
      • 返回的組件類必須首字母大寫
      • 虛擬DOM元素必須只有一個根元素
      • 虛擬DOM元素必須有結束標簽
    • ReactDOM.render()渲染組件標簽的基本流程:
     
     
     
     
    1. 1.React內(nèi)部會創(chuàng)建組件實例對象; 
    2. 2.得到包含的虛擬DOM并解析為真實DOM; 
    3. 3.插入到指定的頁面元素內(nèi)部; 

    組件的三大屬性

    props屬性

    1.每個組件對象都會有props(properties的簡寫)屬性

    2.組件標簽的所有屬性都保存在props中

    3.內(nèi)部讀取某個屬性值:this.props.propertyName

    4. 作用: 通過標簽屬性從組件外向組件內(nèi)傳遞數(shù)據(jù)(只讀)

    5.對props中的屬性值進行類型限制和必要性限制:

     
     
     
     
    1. //  對標簽屬性進行限制 
    2. Person.propTypes = { 
    3.     name:React.PropTypes.string.isRequired, 
    4.     sex:React.PropTypes.string, 
    5.     age:React.PropTypes.number 

    6. 擴展屬性: 將對象的所有屬性通過props傳遞

     
     
     
     
    1.  
    2.  //具體如下: 
    3.  ReactDOM.render(,document.getElementById('example')) 

    7.默認屬性值

     
     
     
     
    1. //  指定屬性的默認值 
    2. Person.defaultProps = { 
    3.      sex:'男', 
    4.      age:18 
    5.  } 

    8.組件類的構造函數(shù)

     
     
     
     
    1. constructor (props) { 
    2.   super(props) 
    3.   console.log(props) // 查看所有屬性 

    refs屬性

    1.組件內(nèi)的標簽都可以定義ref屬性來標識本身

    2.在組件中可以通過this.refs.refName來得到對應的真實DOM對象

    3. 作用: 用于操作指定的ref屬性的dom元素對象(表單標簽居多)

    • 事件處理
      • 通過onXxx屬性指定組件的事件處理函數(shù)(注意大小寫)
        • React使用的是自定義(合成)事件, 而不是使用的DOM事件
        • React中的事件是通過委托方式處理的(委托給組件最外層的元素)
      • 通過event.target得到發(fā)生事件的DOM元素對象
     
     
     
     
    1.  
    2.       handleFocus(event) { 
    3.  event.target  //返回input對象 
    4.       } 
    • ==強烈注意==
     
     
     
     
    1. this.change = this.change.bind(this); 

    箭頭函數(shù)(ES6模塊化編碼時才能使用)

    • 組件內(nèi)置的方法中的this為組件對象
    • 在組件中自定義的方法中的this為null
      1.強制綁定this

    state屬性

    • 組件被稱為 "狀態(tài)機" ,通過更新組件的狀態(tài)值來更新對應的頁面顯示(重新渲染)
    • 初始化狀態(tài):
     
     
     
     
    1. constructor (props) { 
    2.    super(props) 
    3.    this.state = { 
    4.      stateProp1 : value1, 
    5.      stateProp2 : value2 
    6.    } 
    • 讀取某個狀態(tài)值:
     
     
     
     
    1. this.state.statePropertyName 
    • 更新狀態(tài)->組件界面更新
     
     
     
     
    1. this.setState({ 
    2. stateProp1 : value1, 
    3. stateProp2 : value2 
    4. }) 

    組件的生命周期

    • 組件的三個生命周期狀態(tài):
      • Mount: 插入真實 DOM
      • Update: 被重新渲染
      • Unmount: 被移出真實 DOM
    • React 為每個狀態(tài)都提供了兩種勾子(hook)函數(shù),will 函數(shù)在進入狀態(tài)之前調(diào)用,did 函數(shù)在進入狀態(tài)之后調(diào)用:
      • componentWillMount()
      • componentDidMount(): 已插入頁面真實DOM,在render之后才會執(zhí)行
      • componentWillUpdate(object nextProps,object nextState)
      • componentDidUpdate(object prevProps,object prevState)
      • componentWillUnmount()
    • 生命周期流程:
      • 第一次初始化渲染顯示:render()
        • constructor(): 創(chuàng)建對象初始化state
        • componentWillMount(): 將要插入回調(diào)函數(shù)
        • render(): 用于插入虛擬DOM回調(diào)函數(shù)
        • componentDidMount(): 已經(jīng)插入回調(diào)函數(shù).在此方法中啟動定時器,綁定監(jiān)聽,發(fā)送Ajax請求
      • 每次更新state:this.setSate()
        • componentWillUpdate(): 將要更新回調(diào)函數(shù)
        • render(): 更新,重新渲染
        • componentDidUpdate(): 已經(jīng)更新回調(diào)
        • 刪除組件
          • ReactDOM.unmountComponentAtNode(div):移除組件
          • componentWillUnmount():組件將要被移除回調(diào)
    • 常用的方法
      • render(): 必須重寫,返回一個自定義的虛擬DOM
      • constructor(): 初始化狀態(tài),綁定this(可以箭頭函數(shù)代替)
      • componentDidMount(): 只執(zhí)行一次,已經(jīng)在DOM樹中,適合啟動,設置一些監(jiān)聽
    • ==注意==
      • 一般會在 componentDidMount() 中: 開啟監(jiān)聽 , 發(fā)送ajax請求
      • 可以在 componentWillUnmount() 做一些收尾工作: 停止監(jiān)聽
      • 生命周期還有一個方法: componentWillReceiveProps()

    React的函數(shù)式編程

    • 函數(shù)式編程: 結構化編程的一種,主要思想是把運算過程盡量寫成一系列嵌套的函數(shù)調(diào)用
    • 聲明式編程: 只關注做什么,而不關注怎么做(流程),類似于填空題,數(shù)組中常見聲明式方法: map() , forEach() ,find() ,findIndex()
    • 命令式編程: 要關注做什么和怎么做(流程), 類似于問答題
     
     
     
     
    1. var arr = [1, 3, 5, 7] 
    2. // 需求: 得到一個新的數(shù)組, 數(shù)組中每個元素都比arr中對應的元素大10: [11, 13, 15, 17] 
    3. // 命令式編程 
    4. var arr2 = [] 
    5. for(var i =0;i
    6.     arr2.push(arr[i]+10) 
    7. console.log(arr2) 
    8. // 聲明式編程 
    9. var arr3 = arr.map(function(item){ 
    10.     return item +10 
    11. }) 
    12. // 聲明式編程是建立命令式編程的基礎上 

    React的JSX

    • JSX定義: JavaScript XML,react定義的一種類似于XML的JS擴展語法:XML+JS,用來創(chuàng)建react虛擬DOM(元素)對象.
      • 注意:

        1.它不是字符串, 也不是HTML/XML標簽

        2.它最終產(chǎn)生的就是一個JS對象

      •     
            
            
            
        1. var ele = 

          Hello JSX!

    • JSX編碼:
      • 基本語法規(guī)則:
        • 遇到 < 開頭的代碼, 以標簽的語法解析 :==html同名標簽轉換為html同名元素,其它標簽需要特別解析==
        • 遇到以 { 開頭的代碼, 以JS的語法解析 :==標簽中的js代碼必須用{}包含==
      • js中直接可以套標簽, 但標簽要套js需要放在 { } 中
      • 在解析顯示js數(shù)組時,會自動遍歷顯示
      • 把數(shù)據(jù)的數(shù)組轉換為標簽的數(shù)組
     
     
     
     
    1. var liArr = dataArr.map(function(item, index){ 
    2.               return {item}
    3.  
    4.           }) 
    • babel.js的作用
      • 瀏覽器的js引擎是不能直接解析JSX語法代碼的,需要babel轉譯為純JS的代碼才能運行
      • 只要用了JSX,都要加上 type="text/babel" ,聲明需要babel來處理
    • ==注意:==
      • 標簽必須有結束
      • 標簽的class屬性必須改為className屬性
      • 標簽的style屬性值必須為: {{color:'red', width:12}}

    React的其它操作

    雙向綁定

    • React是一個單向數(shù)據(jù)流
    • 可以自定義雙向數(shù)據(jù)流組件(受控組件),需要通過onChange監(jiān)聽手動實現(xiàn)
     
     
     
     
    1.  

    React發(fā)送ajax請求

    • React沒有ajax模塊,所以只能集成其它的js庫(如jQuery/axios/fetch), 發(fā)送ajax請求
      • axios
        • 封裝XmlHttpRequest對象的ajax
        • promise
        • 可以用在瀏覽器端和服務器
      • fetch
        • 不再使用XmlHttpRequest對象提交ajax請求
        • fetch就是用來提交ajax請求的函數(shù),只是新的瀏覽才內(nèi)置了fetch
        • 為了兼容低版本的瀏覽器,可以引入fetch.js
    • 在哪個方法去發(fā)送ajax請求:
      • 只顯示一次(請求一次): componentDidMount()
      • 顯示多次(請求多次): componentWillReceiveProps()
     
     
     
     
    1. //做一個跳轉頁面 
    2.  
    3.  
    4.  
    5.  
    6.  

    RESTful

    • RESTful是一種軟件架構風格、設計風格,而不是標準,只是 提供了一組設計原則和約束條件 . 它主要用于客戶端和服務器交互類的軟件. 可以使軟件更簡潔,更有層次,更易于實現(xiàn)緩存等機制
    • REST原則:
      • 客戶端和服務器之間的交互在請求之間是無狀態(tài)的
      • 分層系統(tǒng)

    RESTful的關鍵

    • 定義可表示流程元素或資源的對象: 在REST中,每一個對象都是通過URL來表示的,對象用戶負責將狀態(tài)信息打包進每一條消息內(nèi),以便對象的處理總是無狀態(tài)的
    • 組合管理及流程綁定

    RESTful與 RPC

    • RPC 樣式的 Web 服務客戶端將一個裝滿數(shù)據(jù)的信封:包括方法和參數(shù)信息, 通過 HTTP 發(fā)送到服務器。服務器打開信封并使用傳入?yún)?shù)執(zhí)行指定的方法。方法的結果打包到一個信封并作為響應發(fā)回客戶端。客戶端收到響應并打開信封。每個對象都有自己獨特的方法以及僅公開一個 URI 的 RPC 樣式 Web 服務,URI 表示單個端點。它忽略 HTTP 的大部分特性且僅支持 POST 方法

    RESTful Web 服務的Java框架

    • Restlet
      • 客戶端和服務器都是組件, 組件通過連接器互相通信
      • 該框架最重要的類是抽象類 Uniform 及其具體的子類 Restlet,該類的子類是專用類,比如 Application、Filter、Finder、Router 和 Route。這些子類能夠一起處理驗證、過濾、安全、數(shù)據(jù)轉換以及將傳入請求路由到相應資源等操作。Resource 類生成客戶端的表示形式
      • RESTful Web 服務也是 多層架構 :數(shù)據(jù)存儲層,數(shù)據(jù)訪問層,業(yè)務層,表示層

    RESTful API

    • RESTful:

    URL定位資源,用HTTP動詞(GET,POST,PUT,DELETE)描述操作

    • RESTful API 就是一套協(xié)議來規(guī)范多種形式的前端和同一個后臺的交互方式.由SERVER來提供前端來調(diào)用,前端調(diào)用API向后臺發(fā)起HTTP請求,后臺響應請求將處理結果反饋給前端

    RESTful API設計原則

    • 資源: 首先是弄清楚資源的概念,資源總是要通過一種載體來反應它的內(nèi)容.JSON是現(xiàn)在最常用的資源表現(xiàn)形式
    • 統(tǒng)一接口: RESTful 風格的數(shù)據(jù)元操 CRUD(create,read,update,delete) 分別 對應HTTP方法 : GET 用來 獲取資源 , POST 用來 新建資源 (也可以用于 更新資源 ), PUT 用來 更新資源 , DELETE 用來 刪除資源 ,統(tǒng)一數(shù)據(jù)操作的接口
    • URI: 可以用一個URI(統(tǒng)一資源定位符)指向資源,即每個URI都對應一個特定的資源.要獲取這個資源訪問它的URI就可以,因此URI就成了每一個資
      網(wǎng)頁名稱:微服務框架相關技術整理
      網(wǎng)址分享:http://www.5511xx.com/article/cdgojcg.html