近段時(shí)間離職,跟同事們講解我之前所做的微服務(wù)相關(guān)產(chǎn)品,對(duì)于同事們提出的問題,做了如下整理出來(lái),加上自己的理解,分享出來(lái)跟大家一起探討下:
問題預(yù)覽
- 我為什么要換微服務(wù)?能給我?guī)?lái)什么好處?
- 從交互上來(lái)看,單體應(yīng)用在處理業(yè)務(wù)實(shí)體之間的關(guān)系,直接由框架搞定,如java的hibernate等,而使用微服務(wù),還要去花時(shí)間去重新整理甚至重構(gòu)業(yè)務(wù)結(jié)構(gòu).
- 微服務(wù)測(cè)試起來(lái)比較麻煩:首先微服務(wù)根據(jù)不同的業(yè)務(wù)實(shí)體劃分資源服務(wù),那么也許有些業(yè)務(wù)的操作,會(huì)涉及多個(gè)微服務(wù),那么測(cè)試微服務(wù)的話,就需要將所有的相關(guān)服務(wù)都啟動(dòng)完成,才可以進(jìn)行測(cè)試。
- 微服務(wù)一般對(duì)外是restful服務(wù),為了保證安全性,開銷也是比較大的:一方面服務(wù)內(nèi)部可能每次訪問都需要安全檢查,會(huì)降低效率;另一方面內(nèi)部訪問開啟https,在證書部署維護(hù)方面也會(huì)增加壓力
- 一般情況下,很多服務(wù)都存在類似session等數(shù)據(jù)存儲(chǔ)在內(nèi)存中,而這些session只在同一WebServer中存在,一般無(wú)法進(jìn)行多實(shí)例共享(當(dāng)然也有共享的方案,但是需要相對(duì)復(fù)雜的集群設(shè)計(jì)),該如何解決這些數(shù)據(jù)的問題呢?
- 接著上個(gè)問題,微服務(wù)的使用場(chǎng)景中,基本都需要實(shí)現(xiàn)單個(gè)服務(wù)多個(gè)實(shí)例的場(chǎng)景,以實(shí)現(xiàn)高可用,那么問題來(lái)了,我對(duì)單個(gè)服務(wù)運(yùn)行了10個(gè)實(shí)例,那么該如何知道服務(wù)該向哪個(gè)服務(wù)發(fā)起訪問呢?
- 接著上個(gè)問題,當(dāng)我運(yùn)行10個(gè)WebServer的時(shí)候,在主機(jī)上需要使用10個(gè)端口進(jìn)行對(duì)應(yīng),而服務(wù)多了以后,對(duì)于端口的消耗和管理也是個(gè)比較大的麻煩
- 接著上個(gè)問題,一般的應(yīng)用,我們可以使用haproxy來(lái)做代理,那么就需要每增加或者修改一次實(shí)例,就需要修改haproxy的配置,管理上的消耗也會(huì)成為比較大的麻煩,并且還有可能出錯(cuò)
- 對(duì)于眾多的微服務(wù)實(shí)例,服務(wù)較多的至少可以達(dá)到數(shù)百個(gè)甚至數(shù)千個(gè),監(jiān)控和管理上,也將比較大的挑戰(zhàn)
- 上面提到的很多軟件,都是比較零散的軟件堆疊出來(lái)的服務(wù),有沒有比較好的成套的解決方案?
問題及自己的理解
1. 我為什么要換微服務(wù)?能給我?guī)?lái)什么好處?
可以解決復(fù)雜性的問題,在功能不變的情況下,分解為多個(gè)相互協(xié)作的微服務(wù),通過(guò)rest API定義邊界,這樣極大易于開發(fā)、理解和維護(hù)。
微服務(wù)架構(gòu)是的每個(gè)服務(wù)可以由專門的開發(fā)團(tuán)隊(duì)或者個(gè)人開發(fā)者進(jìn)行開發(fā),開發(fā)者可以自由選擇技術(shù),不必受制于規(guī)定的技術(shù)和框架,只要API服務(wù)協(xié)議好交互方式即可(如restful)。這樣即使重新技術(shù)過(guò)時(shí)的微服務(wù)模塊兒或者重寫以前的代碼,也不是很困難。
微服務(wù)架構(gòu)模式使得每個(gè)微服務(wù)獨(dú)立部署,且每個(gè)服務(wù)獨(dú)立擴(kuò)展,開發(fā)者不再需要協(xié)調(diào)其它服務(wù)部署對(duì)本服務(wù)的影響。微服務(wù)架構(gòu)模式使得持續(xù)化部署成為可能。
2. 從交互上來(lái)看,單體應(yīng)用在處理業(yè)務(wù)實(shí)體之間的關(guān)系,直接由框架搞定,如java的hibernate等,而使用微服務(wù),還要去花時(shí)間去重新整理甚至重構(gòu)業(yè)務(wù)結(jié)構(gòu).
首先,在使用框架的同時(shí),也已經(jīng)受制于框架,甚至是開發(fā)語(yǔ)言的選擇,單體應(yīng)用下,看似方便,可是業(yè)務(wù)實(shí)體之間的關(guān)系太過(guò)于固化,當(dāng)有一個(gè)業(yè)務(wù)實(shí)體需要改變,則整個(gè)應(yīng)用相當(dāng)于發(fā)布了一個(gè)新的版本。這種情況對(duì)于不care更新停止程序的客戶來(lái)說(shuō)是無(wú)所謂,可是對(duì)于服務(wù)更新停止程序敏感性比較強(qiáng)甚至不允許停止程序的公司來(lái)說(shuō),無(wú)疑是個(gè)災(zāi)難。所以使用微服務(wù)不是必須的,而是在適當(dāng)?shù)膶?shí)際,架構(gòu)適應(yīng)應(yīng)用場(chǎng)景的一種改變。
3. 微服務(wù)測(cè)試起來(lái)比較麻煩:首先微服務(wù)根據(jù)不同的業(yè)務(wù)實(shí)體劃分資源服務(wù),那么也許有些業(yè)務(wù)的操作,會(huì)涉及多個(gè)微服務(wù),那么測(cè)試微服務(wù)的話,就需要將所有的相關(guān)服務(wù)都啟動(dòng)完成,才可以進(jìn)行測(cè)試。
微服務(wù)測(cè)試起來(lái)麻煩是沒有任何疑問的,不過(guò)微服務(wù)大多采用restful服務(wù),這為微服務(wù)的測(cè)試提供了相對(duì)的便利性(測(cè)試restful接口的工具還是挺多的)。對(duì)于微服務(wù)帶來(lái)的便利性,增加這點(diǎn)壓力還是可以容忍的。
4. 微服務(wù)一般對(duì)外是restful服務(wù),為了保證安全性,開銷也是比較大的:一方面服務(wù)內(nèi)部可能每次訪問都需要安全檢查,會(huì)降低效率;另一方面內(nèi)部訪問開啟https,在證書部署維護(hù)方面也會(huì)增加壓力
首先,一般微服務(wù)外部都是需要有API GateWay的,由API GateWay來(lái)保證外部訪問的安全性,而內(nèi)部訪問,可以省去https和安全檢查,僅保留必要的用戶信息即可。
5. 一般情況下,很多服務(wù)都存在類似session等數(shù)據(jù)存儲(chǔ)在內(nèi)存中,而這些session只在同一WebServer中存在,一般無(wú)法進(jìn)行多實(shí)例共享(當(dāng)然也有共享的方案,但是需要相對(duì)復(fù)雜的集群設(shè)計(jì)),該如何解決這些數(shù)據(jù)的問題呢?
一般情況下,對(duì)于絕大部分有狀態(tài)服務(wù),在設(shè)計(jì)之初,就會(huì)考慮有狀態(tài)服務(wù)的狀態(tài)轉(zhuǎn)移等工作,假設(shè)我們有服務(wù)存在session,那么這些session信息,可以轉(zhuǎn)嫁存儲(chǔ)在一套redis集群中,這樣子就可以多個(gè)實(shí)例都訪問redis,相當(dāng)于狀態(tài)由redis進(jìn)行處理了。
6. 接著上個(gè)問題,微服務(wù)的使用場(chǎng)景中,基本都需要實(shí)現(xiàn)單個(gè)服務(wù)多個(gè)實(shí)例的場(chǎng)景,以實(shí)現(xiàn)高可用,那么問題來(lái)了,我對(duì)單個(gè)服務(wù)運(yùn)行了10個(gè)實(shí)例,那么該如何知道服務(wù)該向哪個(gè)服務(wù)發(fā)起訪問呢?
一般情況下,我們可以使用haproxy之類的服務(wù),將當(dāng)期服務(wù)的所有實(shí)例進(jìn)行代理,可以先對(duì)單個(gè)服務(wù)單點(diǎn)訪問,其他服務(wù)做備份,又可以使用haproxy的負(fù)載均衡,使請(qǐng)求平均分發(fā)到各個(gè)服務(wù)中
7. 接著上個(gè)問題,當(dāng)我運(yùn)行10個(gè)WebServer的時(shí)候,在主機(jī)上需要使用10個(gè)端口進(jìn)行對(duì)應(yīng),而服務(wù)多了以后,對(duì)于端口的消耗和管理也是個(gè)比較大的麻煩
可以使用docker來(lái)解決,在docker的使用中,一個(gè)服務(wù)對(duì)應(yīng)一個(gè)鏡像,而基于一個(gè)鏡像可以啟動(dòng)多個(gè)容器,而每個(gè)容器都可以使用統(tǒng)一的內(nèi)部端口,不同的容器名稱,我們使用的haproxy也在docker中運(yùn)行,通過(guò)docker內(nèi)部網(wǎng)絡(luò)訪問各個(gè)服務(wù),這樣就解決了端口問題。
8. 接著上個(gè)問題,一般的應(yīng)用,我們可以使用haproxy來(lái)做代理,那么就需要每增加或者修改一次實(shí)例,就需要修改haproxy的配置,管理上的消耗也會(huì)成為比較大的麻煩,并且還有可能出錯(cuò)
對(duì)于這個(gè)問題,也有解決方案:首先我們可以去嘗試使用如下一套解決方案“docker-swarm-consul-haproxy”,Swarm是一個(gè)用于創(chuàng)建Docker主機(jī)(運(yùn)行Docker守護(hù)進(jìn)程的服務(wù)器)集群的工具,consul用來(lái)服務(wù)發(fā)現(xiàn)及配置中心,haproxy則用來(lái)進(jìn)行代理服務(wù)
9. 對(duì)于眾多的微服務(wù)實(shí)例,服務(wù)較多的至少可以達(dá)到數(shù)百個(gè)甚至數(shù)千個(gè),監(jiān)控和管理上,也將比較大的挑戰(zhàn)
無(wú)論是做以往的單體應(yīng)用、SOA還是微服務(wù),服務(wù)監(jiān)控和管理都是必不可少的,對(duì)于監(jiān)控,目前有比較好的容器監(jiān)控開源程序,如:Prometheus、 cAdvisor等;管理方案可以使用簡(jiǎn)單的shipyard,復(fù)雜的可以使用kubernetes的
10. 上面提到的很多軟件,都是比較零散的軟件堆疊出來(lái)的服務(wù),有沒有比較好的成套的解決方案?
整體的解決方案是有的,就是個(gè)人感覺略重(我個(gè)人搭建的一些服務(wù),沒有用kubernetes,而是使用了非常簡(jiǎn)單compose+swarm)。這個(gè)方案就是使用kubernetes(基于Docker),下面可以簡(jiǎn)單描述下我這邊是怎么使用kubernetes來(lái)實(shí)現(xiàn)微服務(wù)的:
- 首選我的微服務(wù)程序都是無(wú)狀態(tài)的或者經(jīng)過(guò)狀態(tài)轉(zhuǎn)移過(guò)的
- 對(duì)于服務(wù)發(fā)現(xiàn),以往我們用consul,這里我沒有去做服務(wù)發(fā)現(xiàn)和服務(wù)注冊(cè),而是使用kubernetes的ReplicationController來(lái)保證我的微服務(wù)實(shí)例數(shù)量(系統(tǒng)會(huì)自動(dòng)維護(hù))
- 對(duì)外的代理以前用haproxy,而現(xiàn)在使用kubernetes的service來(lái)替代,kubernetes自動(dòng)處理各個(gè)微服務(wù)實(shí)例的負(fù)載及請(qǐng)求的分發(fā),我們只需要保證業(yè)務(wù)穩(wěn)定即可。
by 劉迎光@螢火蟲工作室
OpenBI交流群:495266201
MicroService 微服務(wù)交流群:217722918
mail: liuyg#liuyingguang.cn
博主首頁(yè)(==防止爬蟲==):http://blog.liuyingguang.cn