1.1 基本概念html
1.1.1 什麼是微服務?python
微服務架構是SOA思想某一種具體實現。是一種將單應用程序做爲一套小型服務開發的方法,每種應用程序都在其本身的進程中運行,並採用輕量級的通信機制(TCP)進行通訊。這些服務是圍繞業務功能構建的,能夠經過全自動部署機制進行獨立部署。這些服務的集中化管理已是最少的,它們能夠用不一樣的編程語言編寫,並使用不一樣的數據存儲技術。linux
1.1.2 爲何要用微服務?git
1.1.2.1 微服務解決了什麼問題?github
在微服務的最佳實踐中都提到若是一個項目以微服務做爲起點,則大機率會陷入項目失敗。微服務的本質是解決了團隊分工的問題,當項目團隊的開發人員沒法解決大型單體應用的問題或雖然能夠解決問題但成本高昂的時候,微服務每每纔是最佳實踐。經過從外圍不斷拆分單體架構的業務,以細粒度的單項服務的形式發佈服務,最終將單體架構微服務化。web
1.1.2.2 微服務帶來了什麼挑戰?算法
微服務首先是對組織架構的調整提出的新的挑戰,微服務要求每個服務儘量的獨立和內聚,這要求這個團隊符合2pizza風格,也就是說每個團隊都儘量的包含從開發到測試到運維人員組成的獨立項目組。而不是傳統大型企業中以橫向切割的形式讓開發、運維、測試各是一個獨立部門。spring
微服務的第二個挑戰是帶來了分佈式下開發、測試與運維的複雜性。微服務本質上並非什麼銀彈,它解決了團隊面對單體架構疲於奔命的開發和部署問題,可是也引來了新的問題。在單體開發過程當中,開發人員不會想到方法調用會失敗、會重試、要冪等。測試人員不會考慮幾十個應用怎麼一塊兒集成測試,運維人員不會考慮下游應用掛了對我有什麼影響。意識到分佈式下開發、測試與運維的複雜性,並掌握這些複雜問題的方法纔是更主要的。docker
1.2 架構設計shell
1.2.1 服務註冊/發現
服務治理解決了分佈式應用中服務依賴複雜度的問題,當數十個應用須要統一的管理進行服務發現、負載均衡、服務降級、服務下線時。沒有一個統一的管理方式是沒法實現的,服務治理的概念也應運而生。服務治理中最重要的部分就是服務的註冊和發現,以dubbo爲例,服務提供者啓動後向註冊中心註冊本身提供的服務。消費者(有多是其餘服務、也有多是網關)啓動,向註冊中心訂閱本身須要的服務。註冊中心返回服務提供者的健康檢查(心跳)列表,消費者根據軟負載算法(輪詢/隨機/hash一致/最小壓力優先)選擇一臺發起請求。
1.2.2 分佈式通信
1.2.2.1 REST API/RPC
通常在微服務架構中,服務和服務之間因爲進程隔離甚至物理機隔離,每每會採用一種通用的網絡通信模式,以目前主流的設計來講有兩種方案,一種是基於HTTP協議的rest api方式。這種方式下每個生產者以rest api的形式暴露本身的接口到註冊中心。消費者從註冊中心拉取到生產者列表後經過httpclient的形式發起請求並得到結果。Rpc協議也是基於網絡的請求協議,rpc經過TCP的形式(如dotnetty)採用遠程過程調用的方式,讓本地應用調用遠程應用就和調用本地過程同樣方便(new remoteprocessserver().get({id=1}))。
1.2.2.2 事件總線
微服務中因爲服務和服務之間採用了物理級的數據隔離機制,而在單體架構中很容易實現的事務在微服務中成了複雜的分佈式問題,目前的解決辦法是引入事件總線(event bus)的機制來實現分佈式環境下的事務問題,事件總線採用了觀察者模式,經過訂閱發佈到事件總線來實現消息的最終一致性。訂閱者訂閱消息,發佈者產生消息後發佈到事件總線,事件總線異步通知(基於第三方的消息隊列,如rabbitmq)訂閱者,訂閱者處理消息。訂閱者能夠經過一些機制好比重試和冪等機制保證消費的消息必定可以被消費一次。若是稍微複雜則須要引入TCC這樣的機制保證消息消費失敗能夠及時回滾(.netcore目前國內有開源的CAP能夠實現eventbus並內置的tcc,無需開發者實現複雜的應用層tcc)
1.2.3 網關
微服務中,網關是全部服務對外提供的一個統一窗口。網關本質就是一個路由器,經過這個路由器,咱們能夠將外界(PC/APP/IOT/CLOUD)的請求進行統一的鑑權、限流、監控後對內調用服務,從而起到了保護內部服務接口安全的目的。
1.2.3.1 服務鑑權
用戶調用的某一個接口須要進行權限身份驗證時,能夠經過網關集成identity進行統一的鑑權管理,而無需每個應用本身去實現鑑權。也能夠經過獨立的受權服務器來處理,網關將每個須要鑑權的請求經過受權服務器作校驗,再由受權服務器受權後通知網關調用具體的服務
1.2.3.2 服務限流
網關能夠經過對每一個服務進行限流來保障在高併發中服務由於沒法及時處理請求而掛掉,好比當某個服務的請求在單位時間內超過了設定閾值,則網關能夠直接返回給調用者一個友好的回調或者經過緩存的形式返回以前的結果。
1.2.3.3 熔斷降級
網關能夠經過熔斷的機制來保障某一個服務的可用性,好比當某個服務變得不可用的時候,好比當調用者屢次請求某個服務都超時,當超時次數超過設定閾值的時候,網關能夠對該類型的服務進行熔斷,全部對該服務的請求都會收到網關的友好回調或舊緩存。網關會在熔斷時啓動一個定時做業定時檢查該服務的可用性,直到該服務從新能夠被訪問時才能從新接入網關
1.2.4 配置中心
單體式應用中,通常採用傳統的配置文件的形式進行本地化配置,方便統一管理或熱更新。可是在分佈式環境下若是沒有一個分佈式的配置中心做爲支撐,動輒幾百個微服務應用是沒辦法及時進行統一配置的。因此一個統一的分佈式配置中心是有必要存在的。經過統一的配置中心管理全部應用的配置,應用經過初始化拉取的形式作更新。應用內部依舊採用熱更新的形式讀取配置數據。
1.2.5 下一代微服務架構
1.2.5.1 Service Mesh
這一套解決方案提供了一套基於基礎設施的,對語言和應用自己無依賴的服務網格來提供上一代微服務中心化的網關/註冊中心/緩存/負載均衡等等功能。好比基於k8s實現的istio。本質上是經過對容器注入sidercar的形式無感知的實現服務治理。而無需關注服務自己是用何種語言編寫的何種服務。Service fabric也是提供相似的功能的平臺。
1.2.5.2 Serverless
Serverless 是提供微服務的一種簡化開發、自動化運維、資源分時複用的解決方案,好比Flink(略)
1.3 具體實踐
1.3.1 如何經過.netcore+surging+DDD實現微服務?
surging 是一個分佈式微服務框架,提供高性能RPC遠程服務調用,服務引擎支持http、TCP、WS協議,採用Zookeeper、Consul做爲surging服務的註冊中心,集成了哈希,隨機,輪詢、壓力最小優先做爲負載均衡的算法,RPC集成採用的是netty框架,採用異步傳輸。項目地址https://github.com/dotnetcore/surging
在surging的基礎上我進行了一些本地化實現,好比受權服務分離。併爲應用提供了一套ddd的基礎設施以及自動發佈以及運維監控部分的集成。項目地址https://gitee.com/gmmy/Microservices
2.1 基本概念
2.1.1 什麼是容器?
容器基於Linux Container技術,它是一種內核輕量級的操做系統層虛擬化技術。最單純的理解就是經過容器技術,你能夠很方便的將你的應用打包到某一個指定的環境(centos/ubuntu/alpine)構建特定的鏡像,這個鏡像能夠經過世界上任意一臺安裝了docker的服務器進行拉取併成功運行,解決了以往應用在不一樣環境中表現不一致的問題。
2.1.2 容器和虛擬機的區別?
容器和虛擬機最大的區別在於容器自己是依賴於linux操做系統的的半獨立系統而虛擬機則是擁有獨立操做系統的沙箱。容器又在此的基礎上提供了進程級的隔離和文件數據隔離,基本作到了虛擬機的體驗而資源佔用又比虛擬機少了不少。
2.1.3 鏡像/容器/自動化構建
2.1.3.1 容器
容器就是docker中的獨立最小化單元,是一個運行起來的鏡像。內部包含一個操做系統+環境+應用程序。好比(centos+jvm+spring boot)/又或者(Ubuntu+python+flaskwebapp)。雖然容器自己對應用並未有安裝限制,但實際開發時必須根據關注點分離的原則一個容器只運行1個應用。
2.1.3.2 鏡像
鏡像就是容器的原始文件。當咱們經過命令構造一個鏡像後,能夠經過run很方便的把這個鏡像啓動成一個或一組容器(集羣)。有點相似於編程中的類定義文件和運行時的類實例,一個類定義文件在運行時能夠建立1個或多個內存中運行的實例,由應用來管理它的生命週期。咱們也能夠經過容器快照的方式將某個容器在某個時間點的快照導出成鏡像。該鏡像會保留容器快照時的全部狀態。
2.1.3.3 自動化構建
容器能夠經過docker build和docker compose的方式進行自動化構建。前者主要經過dockerfile的形式將本地的應用配合倉庫中的鏡像進行一組打包操做造成一個鏡像。後者則能夠直接經過調用多個dockerfile/命令的方式啓動一組鏡像(好比一個微服務項目含有多個應用。能夠經過此方式一次性所有運行起來)
2.1.4 鏡像倉庫/市場
鏡像倉庫/市場就是存放鏡像的雲平臺,docker官方提供了(https://hub.docker.com)做爲鏡像市場能夠免費(2018.11)上傳您的本地倉庫中的鏡像,可是因爲國內已知的緣由,仍是推薦使用國內雲提供商提供的免費(2018.11)鏡像市場(https://www.aliyun.com/product/acr?utm_co
ntent=se_1000088670)或者私有化部署本身的鏡像倉庫(https://www.cn
blogs.com/Javame/p/7389093.html)。
2.1.5 容器編排
Docker自己提供了基於shell的方式對單個服務器的容器集合進行簡單的管理,可是在實際的生產過程當中,咱們依然須要更增強大的集中式管理工具來管理咱們跨數個服務的容器集羣,k8s就是基於這樣一個容器管理編排平臺,能夠經過它很方便的管理容器的生命週期,從應用建立、部署、擴容、更新、調度都可以在一個平臺上完成,而無需建立複雜的腳本進行運維管理。
2.2 具體實踐
2.2.1 如何經過容器進行asp.netcore應用的發佈?
2.2.1.1 準備工做
2.2.1.1.1 環境
Linux/windows
Docker/docker for windows
Docker-compose(非必須,需單獨安裝)
Asp.net core app(咱們假設應用已經發布並打包好了)
2.2.1.2 發佈流程
打包鏡像通常咱們推薦採用dockerfile的形式來完成。
首先在應用所在目錄建立一個沒有後綴的名稱叫Dockerfile的文件,用vim或者txt打開並編輯它(取決於您採用什麼操做系統)
命令以下:
#咱們須要從本地倉庫拉取一個基礎鏡像(dotnetcore runtime)
FROM microsoft/dotnet:2.1-runtime
#設置咱們的工做目錄,後面的操做包括文件複製,命令啓動如無必要均默認在該目錄執行
WORKDIR /app
#將當前dockerfile所在文件夾全部文件複製到鏡像對應的workdir目錄中
COPY . .
#設置容器的默認啓動命令
ENTRYPOINT ["dotnet", "Web.dll"]
這樣一個簡單的dockerfile就建立好了。接下來你能夠經過docker build . –t ‘imagename’ 來構建鏡像並經過docker run 的形式來運行它,或採用docker-compose的方式來直接構建並運行它.
Docker-compose 方式
在剛纔的目錄中能夠建立一個docker-compose.yml文件進行容器編排(此處的編排僅僅指打包運行一組容器非k8s)
內容以下
version: '3.4'
services:
#名稱,可隨意
servicename:
#環境變量,根據應用實際須要指定傳入
environment:
- Register_Conn=192.168.0.171:80
#是否默認啓動
restart: always
#指定鏡像名稱,經過build打包後的鏡像名稱
image: servicename:latest
#指定打包,若沒有則會直接根據上一步的鏡像名稱構建容器
build:
#打包路徑
context: .
dockerfile: Dockerfile
#構建的容器名稱
container_name: servicename
#對外映射端口,左側是服務器對外開放的端口,右側是容器內開放的端口,假設個人asp.netcore指定了80端口映射到服務器提供的8080端口
ports:
- "8080:80"
經過簡單的執行 docker-compose up –d –-build 就能夠很方便的將應用運行起來了。
3.1 基本概念
3.1.1 什麼是CI/CD&CD?
CI/CD&CD字面意思就是指持續集成,持續部署,持續交付。指出在軟件研發過程當中須要經過自動化構建的方式將產品可以快速的高質量的進行交付和迭代,區別於以往小做坊式的手工方式打包部署,避免了人爲緣由形成的軟件部署失敗以及提高了部署效率。
3.2 具體實踐
3.2.1 Gitlab+gitlabCI+gitlabRunner
軟件安裝
Gitlab: http://www.javashuo.com/article/p-ssstonyj-dr.html
gitlab-runner: http://www.javashuo.com/article/p-akriurix-dn.html
ci&cd具體落地依賴於版本管控軟件以及自動化構建工具以及容器技術,我這裏採用的例子是gitlab自帶的gitlabci工具。
其發佈流程以下:push代碼到gitlab->gitlab根據根目錄的.gitlab-ci.yml文件發佈ci命令,若當前項目部署了對應的gitlabci,則ci工具會啓動對應的gitlabrunner這個進程開始執行對應的命令並推送構建好的鏡像到遠程服務器,大體的流程以下圖:
3.2.2 單元測試(xtest)與質量管控(SonarQube)
單元測試對於軟件開發來講是必要的,因此須要接入單元測試。.netcore推薦xunit做爲單元測試工具。
https://www.cnblogs.com/ccccc05/archive/2017/08/01/7266914.html
代碼質量管控也是一個必要的過程,經過對上傳代碼的分析,能夠找出一些人爲忽略掉的質量問題,方便後續版本的改進。
http://www.cnblogs.com/qiumingcheng/p/7253917.html
4.1 基本概念
4.1.1 APM
Apm致力於監控管理應用軟件性能和可用性,單體應用時代APM的需求並不是特別強烈。可是基於微服務的分佈式架構下,多個服務的性能穩定可用必須統一檢測和管控起來。
4.1.2 日誌與異常
以往的單體應用每每採用日誌文件或者數據庫記錄的方式來管理日誌和異常(好比知名的log4j),和其餘單體應用轉分佈式同樣的問題就是每個應用的異常數據和日誌都須要統一的進行管理
4.2 具體實踐
4.2.1 Skywalking+ Elasticsearch + Exceptionless
默認已經集成到個人微服務體系裏了,可直接運行docker版本
4.2.2 Elasticsearch+ Logstash + Kibana
JAVA體系下的分佈式監控與日誌框架,可自行了解