首頁>技術>

分散式架構發展史:

單機小型機時代:

  1969年,阿帕網誕生,最初是為了軍事目的,後來衍變成Internet。2000年左右,網際網路在中國開始盛行起來,但是那時候網民數較少,所以多數企業服務單一,採用集中式部署的方式就能滿足需求

  但是這樣的部署方式帶來了一定的問題,一旦小型機或者資料庫出現問題,會導致整個系統的故障,而且功能修改釋出也不方便,所以不妨把大系統拆分成多個子系統,比如“使用者”,“商品”,“論壇“等,也就是”垂直拆分“,並且每個子系統都有各自的硬體

叢集化負載均衡時代:

  使用者量越來越大,就意味著需要更多的小型機,價格昂貴,操作維護成本高,不妨把小型機換成普通的PC機,採用多臺PC機部署同一個應用的方案,但是此時就需要對這些應用做負載均衡,因為客戶端不知道請求哪一個。

  負載均衡可以分為硬體和軟體,硬體比如F5,軟體比如LVS(Linux Virtual Server),nginx,haproxy。負載均衡的思路是對外暴露一個統一的介面,然後根據使用者的請求進行對應規則的轉發。同時負載均衡還可以做健康檢查、限流等有了負載均衡,後端的應用就可以根據流量的大小進行動態的擴縮容了,也就是“水平擴充套件”。

服務化時代:

  此時發現在使用者,商品和訂單等中有重複的功能,比如登入、註冊、郵件等。一旦專案大了,叢集部署多了,這些重複的功能無疑是浪費資源,不妨把重複的功能抽取出來,起個名字叫“服務Service”。其實對於“服務”現在已經比較廣泛了,比如“基礎設施即服務IaaS”、“平臺即服務PaaS”、“軟體即服務SaaS“等。這時候急需解決的就是服務之間的呼叫問題,RPC(Remote Procedure Call),同時這種呼叫關係得維護起來,比如某個服務在哪裡,是不是得知道?所以不僅僅要解決服務呼叫的問題,還要解決服務治理的問題,比如像Dubbo,預設採用Zookeeper作為註冊中心,Spring Cloud使用Eureka作為註冊中心當然,要關注的還有很多,比如限流、降級、負載均衡、容錯等

分散式微服務時代:

  在分散式架構下,服務可能拆分的沒那麼細,可以進一步的拆分 Microservices。Java中微服務主流解決方案Spring Cloud,Spring Cloud可以透過引入幾個註解,寫少量程式碼完成微服務架構中的開發,相比Dubbo而言方便很多。並且使用的是HTTP協議,所以對多語言也可以很好地支援。

Service Mesh(服務網格)時代:

  微服務時代有了Spring Cloud就完美了嗎?不妨想一想會有哪些問題

最初是為了業務而寫程式碼,比如登入功能、支付功能等,到後面會發現要解決網路通訊的問題,雖然有Spring Cloud裡面的元件幫我們解決了,但是細想一下它是怎麼解決的?引入以來dependency,加註解,寫配置,最後將這些非業務功能的程式碼打包一起部署,和業務程式碼在一起,稱為“侵入式框架”;微服務中的服務支援不同語言開發,維護不同語言和非業務程式碼的成本;業務程式碼開發者應該把更多的精力投入到業務熟悉度上,而不應該是非業務上,Spring Cloud雖然能解決微服務領域的很多問題,但是學習成本還是較大的;對於Spring Cloud而言,並不是微服務領域的所有問題都有對應的解決方案,也就是功能有限,比如Content Based Routing和Version Based Routing。當然可以將Spring Cloud和Service Mesh結合起來使用,也就是對SC的補充、擴充套件和加強等;網際網路公司產品的版本升級是非常頻繁的,為了維護各個版本的相容性、許可權、流量等,因為SpringCloud是“程式碼侵入式的框架”,這時候版本的升級就註定要讓非業務程式碼一起,一旦出現問題,再加上多語言之間的呼叫,工程師會非常痛苦;其實大家有沒有發現,服務拆分的越細,只是感覺上輕量級解耦了,但是維護成本卻越高了,那麼怎麼辦呢?網路的問題當然還是要交給網路本身來解決

  從微服務發展的角度上來說,我們所面臨的首要的問題就是網路問題,TCP/IP協議解決了計算機之間的通訊問題。微服務的出現帶來了服務與服務之間的通訊問題,我們應該知道,對於開發者而言,最好的方式是能實現服務與服務之間就好比計算機與計算機之間的通訊一樣,是無感知的。

問題解決思路:

  本質上是要解決服務之間通訊的問題,不應該將非業務的程式碼融合到業務程式碼中,也就是從客戶端發出的請求,要能夠順利到達對應的服務,這中間的網路通訊的過程要和業務程式碼儘量無關

  通訊的問題:服務發現、負載均衡、版本控制、藍綠部署等

  那就不妨把這些通訊的問題都交給計算機網路模型組織去解決咯?別人肯定不會答應,怎麼辦?既然不答應,那我們就自己想辦法解決通訊問題,搞一些產品豈不快哉?沒錯,代理嘛

一些公司對於代理的探索Sidecar:

  很多公司借鑑了Proxy模式,推出了Sidecar的產品,比如像14年Netflix的Prana、15年唯品會的local proxy其實Sidecar模式和Proxy很類似,但是Sidecar功能更全面,也就是Sidecar功能和侵入式框架的功能對應

  這種Sidecar是為特定的基礎設施而設計的,也就是跟公司原有的框架技術繫結在一起,不能成為通用性的產品,所以還需要繼續探索。

Service Mesh之Linkerd:

  2016年1月,離開Twitter的基礎設施工程師William Morgan和Oliver Gould,在github上釋出了Linkerd 0.0.7版本,從而第一個Service Mesh專案由此誕生。並且Linkerd是基於Twitter的Finagle開源專案,實現了通用性。後面又出現了Service Mesh的第二個專案Envoy,並且在17年都加入了CNCF專案。

  Linkerd解決了通用性問題,在Linkerd思想要求所有的流量都走Sidecar,而原來的Sidecar方式可以走可以直連,這樣一來Linkerd就幫業務人員遮蔽了通訊細節,也不需要侵入到業務程式碼中,讓業務開發者更加專注於業務本身。

  但是Linkerd的設計思想在傳統運維方式中太難部署和維護了,所以就後來沒有得到廣泛的關注,其實主要的問題是Linkerd只是實現了資料層面的問題,但沒有對其進行很好的管理。

Service Mesh之Istio:

  由Google、IBM和Lyft共同發起的開源專案,17年5月釋出0.1 release版本,17年10月釋出0.2 release版本,18年7月釋出1.0 release版本。很明顯Istio不僅擁有“資料平面(Data Plane)”,而且還擁有“控制平面(Control Plane),也就是擁有了資料接管與集中控制能力。

  官網:https://istio.io/docs/concepts/what-is-istio

What is a service mesh?

  隨著單片應用程式向分散式微服務體系結構的轉變,Istio解決了開發人員和操作人員面臨的挑戰。要了解如何做到這一點,請更詳細地檢視Istio的服務網格。術語ServiceMesh(服務網格)用於描述組成這些應用程式的微服務網路以及它們之間的互動。隨著服務網格的規模和複雜性的增長,它會變得更加難以理解和管理。它的需求可以包括髮現、負載平衡、故障恢復、度量和監視。服務網格通常還有更復雜的操作需求,比如A/B測試、canary推出、速率限制、訪問控制和端到端身份驗證。Istio提供了對整個服務網格的行為洞察和操作控制,提供了一個完整的解決方案來滿足微服務應用程式的各種需求。

  為何Service Mesh能夠迅速走紅?隨著微服務和容器化技術的發展,使得開發和運維的方式變得非常方便。從而讓服務能夠方便地遷移到不同的雲平臺上。回顧一下Service Mesh的發展歷程

借鑑反向代理,對Proxy模式進行探索,讓非業務的程式碼下沉使用Sidecar彌補Proxy模式功能的不足,解決“侵入式框架”中非業務程式碼的問題Linkerd解決傳統Sidecar模式中通用性的問題Istio增加了控制平面,解決整個系統中的流量完全控制的問題

what is Istio ?

  基於Sidecar模式、資料平面和控制平臺、主流Service Mesh解決方案

  雲平臺為使用它們的組織提供了大量的好處。然而,不可否認採用雲會給DevOps團隊帶來壓力。開發人員必須使用微服務來構建可移植性,同時運營商也在管理非常大的混合和多雲部署。Istio允許您連線、保護、控制和觀察服務。在高層次上,Istio有助於降低這些部署的複雜性,並減輕開發團隊的壓力。它是一個完全開源的服務網格,透明地分層到現有的分散式應用程式上。它也是一個平臺,包括一些api,可以將其整合到任何日誌平臺、遙測技術或策略系統中。Istio的多樣化特性集使您能夠成功、高效地執行分散式微服務體系結構,並提供統一的方式來保護、連線和監視微服務。

Why use Istio ?

  透過負載平衡、service-to-service身份驗證、監視等方法,Istio可以輕鬆地建立部署的服務網路,而服務程式碼中的程式碼更改很少或沒有更改。透過在整個環境中部署一個特殊的sidecar代理來攔截微服務之間的所有網路通訊,從而向服務新增Istio支援,然後使用其控制平面功能來配置和管理Istio,其中包括:

HTTP、gRPC、WebSocket和TCP流量的自動負載平衡。透過豐富的路由規則、重試、故障轉移和故障注入對流量行為進行細粒度控制。支援訪問控制、速率限制和配額的可插拔策略層和配置API。叢集內所有流量的自動度量、日誌和跟蹤,包括叢集入口和出口。在具有強大的基於身份的身份驗證和授權的叢集中實現安全的服務到服務通訊。

  Istio是為可擴充套件性而設計的,可以滿足不同的部署需求。Sidecar的方式解決了資料通訊的問題,而在Istio中還加入了控制平面,所有的流量都能夠有效地被控制,也就是透過控制平面可以控制整個系統。

  在Istio中到底能解決哪些問題:

針對HTTP、gRPC、WebSocket等協議的自動負載均衡故障的排查、應用的容錯、眾多路由流量控制、全鏈路安全訪問控制與認證請求遙測、日誌分析以及全鏈路跟蹤應用的升級釋出、頻率限制和配合等Istio Architecture:

  有了感性的認知和功能瞭解之後,接下來就要考慮落地的問題了,也就是Istio的架構圖該如何設計。說白了就是根據資料平面和控制平面的理念,該怎麼設計架構圖,這個官方已經幫我們考慮好了。

  Architecutre :https://istio.io/docs/ops/deployment/architecture/

  Istio服務網格在邏輯上分為資料平面和控制平面。資料平面由一組部署為邊車(Sidecar)的智慧代理(Envoy)組成。這些代理負責協調和控制微服務之間的所有網路通訊,以及一個通用策略和遙測中心。控制平面管理並將代理配置為路由流量。此外,控制平面配置混頻器來執行策略和收集遙測資料。下圖顯示了組成每個平面的不同元件:

Envoy:

  Istio使用Envoy代理的擴充套件版本。Envoy是用c++開發的高效能代理,用於協調服務網格中所有服務的所有入站和出站流量。特使代理是唯一與資料飛機通訊互動的Istio元件。Envoy代理被部署為服務的sidecars,在邏輯上增加了Envoy的許多內建特性,例如:

動態服務發現負載平衡TLS終止HTTP/2和gRPC代理斷路器健康檢查分階段推出基於%的流量分割故障注入豐富的指標

  這種sidecar部署允許Istio提取大量關於流量行為的訊號作為屬性。反過來,Istio可以在混合器中使用這些屬性來執行策略決策,並將它們傳送到監控系統以提供關於整個網格的行為的資訊。sidecar代理模型還允許您向現有部署新增Istio功能,而不需要重新架構或重寫程式碼。您可以閱讀更多關於為什麼我們在設計目標中選擇這種方法的資訊。由Envoy代理啟用的一些Istio功能和任務包括:

流量控制功能:透過豐富的HTTP、gRPC、WebSocket和TCP流量路由規則來執行細粒度的流量控制。網路彈性特性:設定重試、故障轉移、斷路器和故障注入。安全性和身份驗證特性:執行安全性策略和透過配置API定義的訪問控制和速率限制。Kubernetes CRD(K8s資源拓展):

  官網:https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/

  Kubernetes平臺對於分散式服務部署的很多重要的模組都有系統性的支援,藉助如下一些平臺資源可以滿足大多數分散式系統部署和管理的需求。

  但是在不同應用業務環境下,對於平臺可能有一些特殊的需求,這些需求可以抽象為Kubernetes的擴充套件資源,而Kubernetes的CRD(CustomResourceDefinition)為這樣的需求提供了輕量級的機制,保證新的資源的快速註冊和使用。在更老的版本中,TPR(ThirdPartyResource)是與CRD類似的概念,但是在1.9以上的版本中被棄用,而CRD則進入的beta狀態。Istio就是使用CRD在Kubernetes上建構出一層Service Mesh的實現

  這裡就是需要建立 istio-1.0.6/install/kubernetes/helm/istio/templates/crds.yaml 這個資源.

安裝 Istio:

  官網:https://istio.io/docs/setup/getting-started/ 需要Kuberbetes 叢集做支撐

  Before you can install Istio, you need a cluster running a compatible version of Kubernetes. Istio 1.4 has been tested with Kubernetes releases 1.13, 1.14, 1.15.Create a cluster by selecting the appropriate platform-specific setup instructions.

1.下載 istio-1.0.6-linux.tar.gz

2.解壓 tar -zxvf istio-1.x.y.tar.gz,進入到istio檔案目錄下

3.將itsioctl新增到環境變數中

export PATH=$PWD/bin:$PATH

4.進入檢視 istio-1.0.6/install/kubernetes/istio-demo.yaml 檔案 。提前準備好映象,所有節點

docker pull registry.cn-hangzhou.aliyuncs.com/wuzz-istio-k8s/proxy_init:1.0.6docker pull registry.cn-hangzhou.aliyuncs.com/wuzz-istio-k8s/hyperkube:v1.7.6_coreos.0docker pull registry.cn-hangzhou.aliyuncs.com/wuzz-istio-k8s/galley:1.0.6docker pull registry.cn-hangzhou.aliyuncs.com/wuzz-istio-k8s/proxyv2:1.0.6docker pull registry.cn-hangzhou.aliyuncs.com/wuzz-istio-k8s/grafana:5.2.3docker pull registry.cn-hangzhou.aliyuncs.com/wuzz-istio-k8s/mixer:1.0.6docker pull registry.cn-hangzhou.aliyuncs.com/wuzz-istio-k8s/pilot:1.0.6docker pull registry.cn-hangzhou.aliyuncs.com/wuzz-istio-k8s/prometheus:v2.3.1docker pull registry.cn-hangzhou.aliyuncs.com/wuzz-istio-k8s/citadel:1.0.6docker pull registry.cn-hangzhou.aliyuncs.com/wuzz-istio-k8s/servicegraph:1.0.6docker pull registry.cn-hangzhou.aliyuncs.com/wuzz-istio-k8s/sidecar_injector:1.0.6docker pull registry.cn-hangzhou.aliyuncs.com/wuzz-istio-k8s/all-in-one:1.5

5.把阿里雲映象倉庫的映象打成原有的tag

docker tag registry.cn-hangzhou.aliyuncs.com/wuzz-istio-k8s/proxy_init:1.0.6            docker.io/istio/proxy_init:1.0.6docker tag registry.cn-hangzhou.aliyuncs.com/wuzz-istio-k8s/hyperkube:v1.7.6_coreos.0   quay.io/coreos/hyperkube:v1.7.6_coreos.0docker tag registry.cn-hangzhou.aliyuncs.com/wuzz-istio-k8s/galley:1.0.6                docker.io/istio/galley:1.0.6docker tag registry.cn-hangzhou.aliyuncs.com/wuzz-istio-k8s/proxyv2:1.0.6               docker.io/istio/proxyv2:1.0.6docker tag registry.cn-hangzhou.aliyuncs.com/wuzz-istio-k8s/grafana:5.2.3               grafana/grafana:5.2.3docker tag registry.cn-hangzhou.aliyuncs.com/wuzz-istio-k8s/mixer:1.0.6                 docker.io/istio/mixer:1.0.6docker tag registry.cn-hangzhou.aliyuncs.com/wuzz-istio-k8s/pilot:1.0.6                 docker.io/istio/pilot:1.0.6docker tag registry.cn-hangzhou.aliyuncs.com/wuzz-istio-k8s/prometheus:v2.3.1           docker.io/prom/prometheus:v2.3.1docker tag registry.cn-hangzhou.aliyuncs.com/wuzz-istio-k8s/citadel:1.0.6               docker.io/istio/citadel:1.0.6docker tag registry.cn-hangzhou.aliyuncs.com/wuzz-istio-k8s/servicegraph:1.0.6          docker.io/istio/servicegraph:1.0.6docker tag registry.cn-hangzhou.aliyuncs.com/wuzz-istio-k8s/sidecar_injector:1.0.6      docker.io/istio/sidecar_injector:1.0.6docker tag registry.cn-hangzhou.aliyuncs.com/wuzz-istio-k8s/all-in-one:1.5              docker.io/jaegertracing/all-in-one:1.5

6.刪除阿里雲映象倉庫下載的映象

docker rmi registry.cn-hangzhou.aliyuncs.com/wuzz-istio-k8s/proxy_init:1.0.6docker rmi registry.cn-hangzhou.aliyuncs.com/wuzz-istio-k8s/hyperkube:v1.7.6_coreos.0docker rmi registry.cn-hangzhou.aliyuncs.com/wuzz-istio-k8s/galley:1.0.6docker rmi registry.cn-hangzhou.aliyuncs.com/wuzz-istio-k8s/proxyv2:1.0.6docker rmi registry.cn-hangzhou.aliyuncs.com/wuzz-istio-k8s/grafana:5.2.3docker rmi registry.cn-hangzhou.aliyuncs.com/wuzz-istio-k8s/mixer:1.0.6docker rmi registry.cn-hangzhou.aliyuncs.com/wuzz-istio-k8s/pilot:1.0.6docker rmi registry.cn-hangzhou.aliyuncs.com/wuzz-istio-k8s/prometheus:v2.3.1docker rmi registry.cn-hangzhou.aliyuncs.com/wuzz-istio-k8s/citadel:1.0.6docker rmi registry.cn-hangzhou.aliyuncs.com/wuzz-istio-k8s/servicegraph:1.0.6docker rmi registry.cn-hangzhou.aliyuncs.com/wuzz-istio-k8s/sidecar_injector:1.0.6docker rmi registry.cn-hangzhou.aliyuncs.com/wuzz-istio-k8s/all-in-one:1.5

7.安裝istio核心元件,根據istio-1.0.6/install/kubernetes/istio-demo.yaml建立資源

  kubectl apply -f istio-demo.yaml

  第一次創建出現:unable to recognize "install/kubernetes/istio.yaml": no matches for config.istio.io/, Kind=attributemanifest 。耐心等待一下就行,資源較多,速度沒那麼快。

  kubectl get pods -n istio-system

  kubectl get svc -n istio-system 可以給某個service配置一個ingress規則,訪問試試

  大家都知道,K8s中是透過Pod來部署業務,流量的進出是直接跟Pod打交道的那在Istio中如何體現sidecar的作用呢?在Pod中除了業務的container,再增加一個container為sidecar豈不是快哉?

手動注入sidecar:

  準備一個資源 first-istio.yaml:

apiVersion: apps/v1kind: Deploymentmetadata:  name: first-istiospec:  selector:    matchLabels:      app: first-istio  replicas: 1  template:    metadata:      labels:        app: first-istio    spec:      containers:      - name: first-istio        image: registry.cn-hangzhou.aliyuncs.com/wuzz-docker/test-docker-image:v1.0        ports:        - containerPort: 8080  ---apiVersion: v1kind: Servicemetadata:  name: first-istiospec:  ports:  - port: 80    protocol: TCP    targetPort: 8080  selector:    app: first-istio  type: ClusterIP

  kubectl apply -f first-istio.yaml

  kubectl get pods -> # 注意該pod中容器的數量 可以看到這裡只有一個。

  kubectl get svc

  curl 10.103.54.200:8080/dockerfile

  kubectl delete -f first-istio.yaml

  istioctl kube-inject -f first-istio.yaml | kubectl apply -f -

  可以看到這裡產生了2個容器,那麼我們看看這生成的另一個容器是什麼?

  kubectl describe pod pod-name -n istio-system

  很明顯,這個新的容器就是Envoy-proxy

  這樣一來,就手動給pod中注入了sidecar的container,也就是envoy sidecar。其實這塊是先改變了yaml檔案的內容,然後再建立的pod:kubectl get pod pod-name -o yaml

自動注入sidecar:

  上述每次都進行手動建立肯定不爽咯,一定會有好事之者來做這件事情。這塊需要名稱空間的支援,比如有一個名稱空間為istio-demo,可以讓該名稱空間下建立的pod都自動注入sidecar。

1.建立名稱空間 :kubectl create namespace istio-demo

2.給名稱空間加上label :kubectl label namespace istio-demo istio-injection=enabled

3.建立資源 :kubectl apply -f first-istio.yaml -n istio-demo

4.檢視資源。這個時候達到的效果跟上面是一致的,只不過已經自動建立了 Envoy-proxy

kubectl get pods -n istio-demokubectl describe pod pod-name -n istio-demokubectl get svc -n istio-demo

5.刪除資源:kubectl delete -f first-istio.yaml -n istio-demo

Istio 與 prometheus和grafana:

  其實istio已經預設幫我們安裝好了grafana和prometheus,只是對應的Service是ClusterIP,我們按照之前K8s的方式配置一下Ingress訪問規則即可,但是要提前有Ingress Controller的支援哦

1.尋找prometheus的yaml配置(搜尋istio-demo.yaml檔案)找到下面這個:

# Source: istio/charts/prometheus/templates/service.yamlapiVersion: v1kind: Servicemetadata:  name: prometheus    # 主要是為了定位到prometheus的Service  namespace: istio-system

2.配置prometheus的Ingress規則 :

#ingressapiVersion: extensions/v1beta1kind: Ingressmetadata:  name: prometheus-ingress  namespace: istio-systemspec:  rules:  - host: prometheus.istio.wuzz.com    http:      paths:      - path: /        backend:          serviceName: prometheus          servicePort: 9090

3.訪問grafana的配置(istio-demo.yaml檔案)

apiVersion: v1kind: Servicemetadata:  name: grafana  namespace: istio-system

4.配置grafan的Ingress規則 :

#ingressapiVersion: extensions/v1beta1kind: Ingressmetadata:  name: grafana-ingress  namespace: istio-systemspec:  rules:  - host: grafana.istio.wuzz.com    http:      paths:      - path: /        backend:          serviceName: grafana          servicePort: 3000

5.根據兩個ingress建立資源

  kubectl get ingress -n istio-system

  訪問 prometheus

  訪問 grafana:

23
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • Java檔案上傳是如何實現的?