基於Spring Cloud的微服務實踐
移動醫療公司順能網路從單體服務拆分成微服務的實戰經驗分享,內容包含微服務框架選型、CI/CD、容器編排的經驗,旨在幫助大家低成本、快速落地微服務,在刀刀見血的互聯網大潮中,快速迭代,快速交付。
相關趨勢圖
首先給大家看一張百度指數上,關於微服務、Spring Boot、Spring Cloud、Dubbo的趨勢圖:
從圖中可見,Dubbo的搜索量增勢放緩,Spring Boot從16年中下旬開始發力,一路高漲。學習了Spring Boot再學習Spring Cloud幾乎順理成章。
Spring Boot旨在解決Spring越來越臃腫的全家桶方案的配置地獄(諷刺的是,Spring剛出道是扯著輕量化解決方案大旗一路衝殺,現在自己也開始慢慢胖起來了),提供了很多簡單易用的starter。特點是預定大於配置。
Dubbo放緩是源於,阿里巴巴中間斷更將近三年(dubbo-2.4.11 2014-10-30, dubbo-2.5.4 2017-09-07),很多依賴框架和技術都較為陳舊,也不接納社區的PR(當然,最近開始恢復更新,後面會有說到),導致噹噹另起爐灶,fork了一個:https://github.com/dangdangdotcom/dubbox(現在已斷更)。
而且Dubbo僅相當於Spring Cloud的一個子集,可參考文章《微服務架構的基礎框架選擇:Spring Cloud還是Dubbo?》:http://blog.csdn.net/kobejayandy/article/details/52078275
另外我們可以看看k8s、kubernetes 、docker的搜索趨勢:
上面兩圖意在說明,微服務相關和容器相關越來越流行了,不再是一個特別新的、不成熟的技術。那單體服務和微服務的對比如何呢?
微服務 vs. 單體應用
單體應用好處:
開發簡單
容易測試
易於部署
事務回滾容易
無分散式管理,調用開銷
重複功能/代碼較少
單體應用缺點:
迭代緩慢
維護困難
持續部署困難:微小改動,必須重啟,不相干功能無法提供服務
牽一髮而動全身:依賴項衝突,變更後,需要大量測試,防止影響其他功能
基礎語言、框架升級緩慢
框架語言單一,無法靈活選用
微服務好處:
敏捷性:按功能拆分,快速迭代
自主性:團隊技術選型靈活(PHP、python、java、C#、nodejs、golang),設計自主
可靠性:微服務故障隻影響此服務消費者,而單體式應用會導致整個服務不可用
持續集成持續交付
可擴展性:熱點功能容易擴展
微服務的缺點:
性能降低:服務間通過網路調用
管理難度增大:增加了項目的複雜性
事務一致性
擴展閱讀《Introduction to Microservices》:https://www.nginx.com/blog/introduction-to-microservices/
框架選型
下面分享一下我司在落地微服務時的框架選型方面的一些經驗。
我們公司主要使用java,所以決定使用Spring框架中的Spring Cloud作為微服務基礎框架,但是原生Spring Cloud學習曲線比較陡峭,需要學習feign、zuul、eureka、hystrix、zipkin、ribbon…需要老司機坐副駕駛,不然容易翻車。
從JHipster官方資料看,登記在冊的使用 jhipster的企業有224家,其中不乏Google、Adobe一類的大廠。可參見http://www.jhipster.tech/companies-using-jhipster/
此處列舉一下JHipster的技術棧(開箱即用):
客戶端技術棧:
angular4,5 or angularv1.x
Bootstrap
HTML5 Boilerplate
兼容IE11+及現代瀏覽器
支持國際化
支持sass
支持spring websocket
支持yarn、bower管理js庫
支持webpack、gulp.js構建,優化,應用
支持Karma、Headless Chrome 和 Protractor 進行前端單元測試測試
支持Thymeleaf 模板引擎,從服務端渲染頁面
服務端技術棧:
支持spring boot 簡化spring配置
支持maven、gradle,構建、測試、運行程序
支持多配置文件(默認dev,prod)
spring security
spring mvc REST + jackson
spring websocket
spring data jpa + Bean Validation
使用liquibase管理資料庫表結構變更版本
支持elasticsearch,進行應用內搜素
支持mongoDB 、Couchbase、Cassandra等NoSQL
支持h2db、pgsql、mysql、meriadb、sqlserver、oracle等關係型sql
支持kafka mq
使用 zuul或者traefik作為http理由
使用eureka或consul進行服務發現
支持ehcache、hazelcast、infinispan等緩存框架
支持基於hazelcast的httpsession集群
數據源使用HikariCP連接池
生成Dockerfile、docker-compose.yml
支持雲服務商AWS、Cloud Foundry、Heroku、Kubernetes、Openshift、Docker …
支持統一配置中心
不過真正用了後,就會發現,這個列表不全,JHipster支持的不止列表中描述的這些,大家也可以參考我以前寫的《JHipster開發筆記》:https://jh.jiankangsn.com/
JHipster是基於yoman的一個快速開發的腳手架(國內前幾年流行的名字叫代碼生成器),需要nodejs 環境 ,並且使用yarn搭建環境。當然不會也沒事,它非常簡單,如果實在想用,可以用《JHipster Online》:https://start.jhipster.tech/。類似Spring的http://start.spring.io/
值得一提的是JHipster也支持通過JHipster rancher-compose命令來生成rancher-compose.yml和docker-compose.yml,具體可參考《[BETA] Deploying to Rancher》:http://www.jhipster.tech/rancher/
對於小團隊落地微服務,可以考慮使用JHipster來生成項目,能夠極大的提高效率。基本上可以視作JHipster是一套基於Spring Boot的最佳實踐(不僅支持微服務,也支持單體式應用)。對於想學習Spring Boot或者Spring Cloud的也建議了解一下JHipster,好過獨自摸索。
JHipster依賴的技術框架版本基本都是最新穩定版,版本更新比較及時,基本上一月一個版本,對GitHub上的issues和PR響應比較及時(一般在24小時內)。
10分鐘搭建微服務
下面我將分享如何10分鐘搭建一套微服務(不含下載nodejs、安裝maven等準備環境的時間)。
安裝nodejs、yarn的指南可參見我在《JHipster開發筆記》中的一篇【安裝】:https://jh.jiankangsn.com/install.html
需要注意的是,如果是windows nodejs,需要安裝v7.x,因為註冊中心和網關需要用到node-sass@4.5.0,但是github上的node-sass的rebuild只有v7.x(process 51) 版本的,而自己構建太反人類了。如果是linux,可以嘗試高版本的,建議裝nodejs v7.x,除非你想玩刺激,自己build一個node-sass。
為了加速下載,建議用npm的淘寶鏡像:
安裝jdk8、maven、maven加速這些就不說了,可自行百度。
下載註冊中心
JHipster-registry github地址 :https://github.com/jhipster/jhipster-registry)
瀏覽器訪問 http://localhost:8761,初始用戶名密碼均為admin。
註冊中心的頁面
Spring Config Server,統一配置中心,可以統一管理不同環境的資料庫地址、用戶名、密碼等敏感數據。
JHipster Registry對應SC(Spring Cloud)的eurake+spring config server。
創建網關
創建api網關,參見
【Creating an application】:http://www.jhipster.tech/creating-an-app/
【The JHipster API Gateway】:http://www.jhipster.tech/api-gateway/
訪問http://localhost:8080/,默認用戶名密碼均為admin。
創建服務
創建服務可參考:http://www.jhipster.tech/creating-an-app/
訪問http://localhost:8080/#/docs 默認用戶名密碼均為 admin ,使用swagger管理api文檔,開發時,僅需要添加對應的註解,即可自動生成文檔,解決了傳統通過word、pdf等管理介面時,文檔更新不及時等問題。並且可以通過try it直接調用介面,避免了介面調試時使用curl、postman等工具。
至此,已經創建了一個簡單微服務(JHipster-registry是註冊中心,gateway是網關,foo是具體的功能模塊)。
創建實體
JHipster支持通過命令行創建實體,也支持uml或jdl生成實體,為了省事,此處使用官方jdl-studio的默認jdl文件https://start.jhipster.tech/jdl-studio/。
重啟foo服務,再次訪問http://localhost:8080/#/docs,發現多了很多介面
通過swagger ui,找到region-resource,找到POST /api/regions,創建一個名為test的regison。
點try it out! ,然後瀏覽器打開h2 資料庫http://localhost:8081/h2-console
查詢REGION表,數據已經插入成功。
至此,一個雖然簡單、但是可用的微服務已經弄好。
將服務發布到Rancher
JHipster支持發布到Cloud Foundry、Heroku、Kubernetes、Openshift、Rancher、AWS、Boxfuse。
我們建議使用Rancher,因為Cloud Foundry 、Heroku、AWS、Boxfuse都是雲環境,而k8s和openshift origin太複雜了,而Rancher則很容易上手,功能完備,也是完全開源,其聯合創始人還是CNCF的理事會成員。
服務發布可以參見文檔:http://www.jhipster.tech/rancher/
RANCHER-COMPOSE.YML
DOCKER-COMPOSE.YML
docker-compose.yml中給的JHipster-registry是本地模式的,可以根據注釋部分內容,改成從Git拉。好處是維護方便,壞處是容易造成單點故障。使用Git模式,就可以將registry-config-sidekick 部分去掉。
JHipster使用liquibase進行資料庫版本管理,便於資料庫版本變更記錄管理和遷移。(rancher server也用的liquibase)
把docker-compose.yml和rancher-compose.yml貼到rancher上,就能創建一個應用stack了。
不過,好像漏了點啥?少了CICD。Rancher和docker的compsoe.yml有了,但是,還沒構建鏡像呢,鏡像還沒push到registry呢,對吧?
CI/CD
自建GitLab
我司用GitLab管理源碼,我在Docker Hub上發布了一個漢化的GitLab:https://hub.docker.com/r/gitlab/gitlab-ce/tags/
如果要用官方鏡像,參見https://hub.docker.com/r/gitlab/gitlab-ce/tags/
GitLab CI
我們的CI用的是GitLab-CI,參見【GitLab Continuous Integration (GitLab CI)】:https://docs.gitlab.com/ce/ci/README.html
為啥不用Jenkins?這個蘿蔔白菜各有所愛,我是出於壓縮技術棧的考慮:
GitLab-CI夠簡單,也夠用
它和GitLab配套,不用多學習Jenkins,畢竟多一套,就多一套的學習成本
搭建鏡像伺服
老牌sonatype nexus oss可以管理 Bower、Docker、Git LFS、Maven、npm、NuGet、PyPI、Ruby Gems、Yum Proxy,功能豐富:https://www.sonatype.com/download-oss-sonatype
GitLab Container Registry administration,GitLab Registry跟GitLab集成,不需要額外安裝服務:https://docs.gitlab.com/ce/administration/container_registry.html#gitlab-container-registry-administration
Harbor應用商店就有,安裝方便,號稱企業級registry,功能強大:http://vmware.github.io/harbor/rancher
如何選擇?還是那句話,看需求。我司有部署maven和npm的需要,所以用了nexus oss,順便管理docker registry。
Service Mesh——下一代微服務
我司是從16年八九月份開始拆分單體服務,彼時國內Spring Cloud,微服務等相關資料較少,國內流行dubbo(那會已經斷更1年多了,雖然現在復更,但是對其前景不太看好)。
從17年開始,圈內討論Spring Cloud的漸漸多起來了,同時市面上也有了介紹Spring Cloud的書籍,比如周立的《Spring Cloud與Docker微服務架構實戰》, 翟永超的《Spring Cloud微服務實戰》等。
但是用了Spring Cloud後,感覺Spring Cloud太複雜了(如果用了JHipster情況會好點),並沒有實現微服務的初衷:
跟語言,框架無關:局限於java
隱藏底層細節,需要學習zuul路由,eureka註冊中心,configserver配置中心,需要熔斷,降級,需要實現分散式跟蹤…
在這種情況下,16年,國外buoyant公司提出Service Mesh概念,基於scala創建了linkerd項目。Service Mesh 的設想就是,讓開發人員專註於業務,不再分心於基礎設施。
目前主流框架:
istio:背靠google,ibm,後台硬,前景廣闊
conduit:跟linkerd是一個公司的,使用Rust語言開發,proxy消耗不到10M內存,p99控制在毫秒內
linkerd:商用企業較多,國內我知道的有豆瓣
envoy:國內騰訊在用
其中istio和conduit都不太成熟,而linkerd和envoy都有商用案例,較為成熟。長遠來看,我更看好istio和conduit。
對Dubbo的老用戶來說也有個好消息,據說 Dubbo3 將兼容2,並且支持Service Mesh,支持反應式編程。
結語
建議大家根據公司、團隊實際情況理性選擇框架,目前Service Mesh還處於墾荒階段,而Spring Cloud或者Dubbo還沒到徹底過時的程度,建議持續關注,不建議立刻上馬。
如果已經落地了相關的微服務技術,不要盲目跟風,在可接受學習成本和開發成本情況下,可以考慮研究一下Service Mesh。
如果使用的是Spring框架的話,建議拋開Spring Cloud,直接Spring Boot + Service Mesh,更清爽一些。
TAG:RancherLabs |