針對這個架構圖我分層介紹一下:nginx
一、是web服務器的選型,這個我選擇的是nginx+keepalived,haproxy也是一個選擇,可是haproxy在反向代理處理跨域訪問的時候問題不少。因此咱們nginx有些地方作了keep-alive模式處理,減小了三次握手的次數,提升了鏈接效率。keepalived作nginx的負載,虛擬一個vip對外,兩個nginx作高可用,nginx自己反向代理zuul集羣。git
二、api gateway,這裏的zuul不少人詬病,說是速度慢推薦直接用nginx,這裏我仍是推薦使用zuul的,畢竟zuul含有攔截器和反向代理,在權限管理、單點登陸、用戶認證時候仍是頗有用的,並且zuul自帶ribbon負載均衡,若是你直接用nginx,還須要單獨作一個feign或者ribbon層,用來作業務集羣的負載層,畢竟直接把接口暴露給web服務器太危險了。這裏zuul帶有ribbon負載均衡和hystrix斷路器,直接反向代理serviceId就能夠代理整個集羣了。web
三、業務集羣,這一層我有些項目是分兩層的,就是上面加了一個負載層,下面是從service開始的,底層只是單純的接口,controller是單獨一層由feign實現,而後內部不一樣業務服務接口互調,直接調用controller層,只能說效果通常,多了一次tcp鏈接。因此我推薦合併起來,由於作過spring cloud項目的都知道,feign是含有ribbon的,而zuul也含有ribbon,這樣的話zuul調用服務集羣,和服務集羣間接口的互調都是高可用的,保證了通信的穩定性。Hystrix仍是要有的,沒有斷路器很難實現服務降級,會出現大量請求發送到不可用的節點。固然service是能夠改造的,若是改形成rpc方式,那服務之間互調又是另一種狀況了,那就要作成負載池和接口服務池的形式了,負載池調用接口池,接口池互相rpc調用,feign client只是經過實現接口達到了仿rpc的形式,不過速度表現仍是不錯的。redis
四、redis緩存池,這個用來作session共享,分佈式系統session共享是一個大問題。同時呢,redis作二級緩存對下降整個服務的響應時間,而且減小數據庫的訪問次數是頗有幫助的。固然redis cluster仍是redis sentinel本身選擇。spring
五、eurake註冊中心這個高可用集羣,這裏有不少細節,好比多久刷新列表一次,多久監測心跳什麼的,都很重要。docker
六、spring admin,這個是很推薦的,這個功能很強大,能夠集成turbine斷路器監控器,並且能夠定義全部類的log等級,不用單獨去配置,還能夠查看本地log日誌文件,監控不一樣服務的機器參數及性能,很是強大。它加上elk動態日誌收集系統,對於項目運維很是方便。數據庫
七、zipkin,這個有兩種方式,直接用它本身的功能界面查看方式,或者用stream流的方式,由elk動態日誌系統收集。可是我必需要說,這個對系統的性能損害很是大,由於鏈路追蹤的時候會形成響應等待,並且等待時間很是長接近1秒,這在生產環境是不能忍受的,因此生產環境最好關掉,有問題調試的時候再打開。json
八、消息隊列,這個必須的,分佈式系統不可能全部場景都知足強一致性,這裏只能由消息隊列來做爲緩衝,這裏我用的是Kafka。後端
九、分佈式事物,我認爲這是分佈式最困難的,由於不一樣的業務集羣都對應本身的數據庫,互相數據庫不是互通的,互相服務調用只能是相互接口,有些甚至是異地的,這樣形成的結果就是網絡延遲形成的請求等待,網絡抖動形成的數據丟失,這些都是很可怕的問題,因此必需要處理分佈式事物。我推薦的是利用消息隊列,採起二階段提交協議配合事物補償機制,具體的實現須要結合業務,這裏篇幅有限就不展開說了。api
十、config配置中心,這是頗有必要的,由於服務太多配置文件太多,沒有這個很難運維。這個通常利用消息隊列創建一個spring cloud bus,由git存儲配置文件,利用bus總線動態更新配置文件信息。
十一、實時分佈式日誌系統,logstash收集本地的log文件流,傳輸給elasticsearch,logstash有兩種方式,一、是每一臺機器啓動一個logstash服務,讀取本地的日誌文件,生成流傳給elasticsearch。二、logback引入logstash包,而後直接生產json流傳給一箇中心的logstash服務器,它再傳給elasticsearch。elasticsearch再將流傳給kibana,動態查看日誌,甚至zipkin的流也能夠直接傳給elasticsearch。這個配合spring admin,一個查看動態日誌,一個查看本地日誌,同時還能遠程管理不一樣類的日誌級別,對集成和運維很是有利。
最後要說說,spring cloud的不少東西都比較精確,好比斷路器觸發時間、事物補償時間、http響應時間等,這些都須要好好的設計,並且能夠優化的點很是多。好比:http通信可使用okhttp,jvm優化,nio模式,數據鏈接池等等,均可以很大的提升性能。
還有一個docker問題,不少人說不用docker就不算微服務。其實我我的意見,spring cloud自己就是微服務的,只須要jdk環境便可。編寫dockerfile也無非是集成jdk、添加jar包、執行jar而已,或者用docker compose,將多個不一樣服務的image組合run成容器而已。可是帶來的問題不少,好比通信問題、服務器性能損耗問題、容器進程崩潰問題,固然若是你有一套成熟的基於k8s的容器管理平臺,這個是沒問題的,若是沒有可能就要斟酌了。而spring cloud自己就是微服務分佈式的架構,因此我的仍是推薦直接機器部署的,固然好的DevOps工具將會方便不少。
服務註冊到eureka
請求統一經過API網關(Zuul)來訪問內部服務.
網關接收到請求後,從註冊中心(Eureka)獲取可用服務
由Ribbon進行均衡負載後,分發到後端具體實例
微服務之間經過Feign進行通訊處理業務
Hystrix負責處理服務超時熔斷