[微服務架構 】微服務簡介,第1部分
- 2019 年 10 月 4 日
- 筆記
每個人都在談論微服務。行業資深人士可能會記住單片或基於SOA的解決方案是做事的方式。時代變了。新工具使開發人員能夠專註於特定問題,而不會給部署或通常與隔離服務相關的其他管理任務增加過多的複雜性。選擇使用合適的工具來解決正確的問題變得越來越容易。
在本系列文章中,我們將探討微服務的世界,它如何幫助解決現實問題,以及為什麼行業越來越多地將其作為標準的做事方式。在本系列中,我們將嘗試解決與此方法相關的常見問題,並提供方便簡單的示例。在本系列的最後,我們應該有一個完整的基於微服務的架構的框架實現。今天,我們將關注微服務以及它們與替代方案的比較。我們還將列出我們計劃在以下帖子中討論的問題。
更新:在第2部分中,我們討論了API網關。
什麼是微服務?
微服務是一個孤立的,鬆散耦合的開發單元,可以解決一個問題。這類似於舊的「Unix」做事方式:做一件事,做得好。諸如如何「組合」服務提供的任何事項的事項留給更高層或政策。這通常意味著微服務往往避免相互依賴:如果一個微服務對其他微服務有一個硬性要求,那麼你應該問自己是否有意義將它們全部放在同一個單元中。
"A microservice is an isolated, loosely-coupled unit of development that works on a single concern."
「微服務是一個孤立的,鬆散耦合的開發單元,可以解決一個問題。」

微服務對開發團隊特別有吸引力的是他們的獨立性。團隊可以自己處理問題或一組問題。這創造了許多開發人員青睞的有吸引力的品質:
- 自由選擇合適的工具:您一直想要使用的是新的庫或開發平台嗎?你可以(如果它是適合這項工作的工具)。
- 快速迭代:第一個版本不是最理想的嗎?沒問題,版本2可以立即出門。由於微服務往往很小,因此可以相對快速地實現更改。
- 重寫是一種可能性:與單片解決方案相比,由於微服務很小,重寫是可能的。技術堆棧是錯誤的選擇嗎?沒問題,切換到正確的選擇。
- 程式碼品質和可讀性:隔離開發單元的品質往往更高,新開發人員可以非常輕鬆地使用現有程式碼。
生產品質的微服務
現在我們知道微服務是什麼,這裡列出了在設計基於微服務的架構時需要記住的事項。如果這看起來太抽象,不要擔心;我們將在整個系列文章中系統地處理所有這些問題。
必須以這樣的方式實施跨領域關注,即微服務不需要處理有關其特定範圍之外的問題的細節。例如,身份驗證可以作為任何API網關或代理的一部分來實現。
數據共享很難。微服務傾向於支援可以直接更新的每服務或每組資料庫。在為您的應用程式進行數據建模時,請注意這種處理方式是否適合您的應用程式。為了在資料庫之間共享數據,可能需要實現處理資料庫之間的內部更新和事務的內部過程。可以在許多微服務之間共享單個資料庫;請記住,如果您需要在將來進行擴展,這可能會限制您的選擇。
可用性:由於隔離和獨立,需要對微服務進行監控,以儘早檢測故障。在一個大型軟體堆棧中,一個伺服器可能會被忽視一段時間。在選擇用於管理服務的軟體堆棧時考慮到這一點。
進化:微服務往往快速發展。當專門團隊處理特定問題時,可以快速找到新的更好的解決方案。因此,有必要考慮服務的版本控制。只要有客戶需要使用舊版本,舊版本通常可用。較新版本以特定於應用程式的方式公開。例如,使用HTTP / REST API,微服務的版本可以是自定義標頭的一部分,或嵌入在返回的數據中。說明這一點。
自動部署:現在微服務如此方便的全部原因是,從完全乾凈的環境部署新服務非常容易。請參閱Heroku,Amazon Web Services,Webtask.io或其他PaaS提供商。如果您要採用自己的內部方法,請記住,部署新服務或預先存在的服務版本的複雜性對於解決方案的成功至關重要。如果不以方便,自動的方式處理部署,您最終可能會達到一定程度的複雜性,這超出了該方法最初帶來的好處。
相互依賴性:將它們保持在最低限度。處理服務之間的依賴關係有不同的方法。我們將在稍後的部落格文章系列中進一步探討它們。現在,請記住,依賴性是這種方法的最大問題之一,因此尋求將它們保持在最低限度的方法。
傳輸和數據格式:微服務適用於任何傳輸和數據格式;但是,它們通常通過HTTP上的RESTful API公開公開。任何適合您的資訊的數據格式。 HTTP + JSON現在非常流行,但是沒有什麼可以阻止你使用協議緩衝區而不是AMQP。
把事情做正確
所有這些問題都可以系統地處理。我們將探索本系列文章中的技巧和模式來處理它們。以下是我們將來在帖子中討論的內容:
- API代理
- 記錄
- 服務發現和註冊
- 服務依賴性
- 數據共享和同步
- 優雅的失敗
- 自動部署和實例化
保持真實:樣品微服務
現在,這應該很容易。如果微服務從開發團隊的腦海中掏出這麼多的包袱,寫一個應該是小菜一碟,對吧?是的,在某種程度上。雖然我們可以編寫一個簡單的RESTful HTTP服務並將其稱為微服務,但在本文中我們將通過考慮上面列出的一些事情來做到這一點(不要擔心:在以下帖子中,我們將擴展此示例包括上面列出的所有問題的解決方案。
對於我們的示例,我們將從Sandrino Di Mattia的關於使用Flux進行調試的優秀帖子中選擇後端程式碼。在Sandrino的帖子中,一個簡單的express.js應用程式為React.js應用程式製作了後端。我們將採用後端並對其進行調整。您可以在此處查看原始後端程式碼。
Sandrino示例中的後端處理許多不同的問題:登錄,身份驗證,CORS,票證更新操作和查詢。對於我們的微服務,我們將專註於一項任務:查詢門票。看看這個:
var express = require('express'); var morgan = require('morgan'); var http = require('http'); var mongo = require('mongodb').MongoClient; var winston = require('winston'); // Logging winston.emitErrs = true; var logger = new winston.Logger({ transports: [ new winston.transports.Console({ timestamp: true, level: 'debug', handleExceptions: true, json: false, colorize: true }) ], exitOnError: false }); logger.stream = { write: function(message, encoding){ logger.debug(message.replace(/ $/, '')); } }; // Express and middlewares var app = express(); app.use( //Log requests morgan(':method :url :status :response-time ms - :res[content-length]', { stream: logger.stream }) ); var db; if(process.env.MONGO_URL) { mongo.connect(process.env.MONGO_URL, null, function(err, db_) { if(err) { logger.error(err); } else { db = db_; } }); } app.use(function(req, res, next) { if(!db) { //Database not connected mongo.connect(process.env.MONGO_URL, null, function(err, db_) { if(err) { logger.error(err); res.sendStatus(500); } else { db = db_; next(); } }); } else { next(); } }); // Actual query app.get('/tickets', function(req, res, next) { var collection = db.collection('tickets'); collection.find().toArray(function(err, result) { if(err) { logger.error(err); res.sendStatus(500); return; } res.json(result); }); }); // Standalone server setup var port = process.env.PORT || 3001; http.createServer(app).listen(port, function (err) { if (err) { logger.error(err); } else { logger.info('Listening on http://localhost:' + port); } });
- 只有一件事:我們的微服務的唯一問題是查詢完整的門票清單。而已。身份驗證,CORS和其他問題將由我們架構中的上層處理。
- 記錄:我們使用'winston'庫保持記錄。現在我們只需登錄到控制台,但在以後的版本中,我們會將預定義格式的日誌推送到集中位置進行分析。
- 沒有依賴:我們的微服務與其他微服務沒有依賴關係。
- 輕鬆擴展:沒有依賴關係,單獨的流程,只需一個操作,我們的微服務就可以輕鬆擴展。
- 小巧可讀:我們的微服務小巧可讀。新開發人員可以立即修改或重寫它。
- 數據共享:現在我們的微服務從自己的資料庫中讀取數據。我們將在以後的帖子中探討當其他微服務需要更新或創建票證時會發生什麼。
- 註冊和失敗:我們的微服務獨立存在。在以後的文章中,我們將探討如何管理服務發現以及在微服務失敗的情況下您可以做些什麼。
獲取https://github.com/sebadoom/auth0/blob/master/microservices/microservice-1-webtask/server.js。
旁白:對微服務感興趣?你會喜歡webtasks!
微服務是Auth0堆棧的重要組成部分,我們提出了一種使它更容易使用的好方法。查看webtask.io。
- 輕量且簡單的開發工作流程。
- 簡化部署。
- 強大的安全模型,方便HTML5和移動應用程式。
- 適用於HTML和數據API的Web友好編程模型。
我們已將上面的示例轉換為webtask,看看它有多簡單:
npm install wt-cli -g # This will send an activation link to your email. One time only. wt init [email protected] # This will return a new endpoint for your webtask wt create https://raw.githubusercontent.com/sebadoom/auth0/master/microservices/microservice-1-webtask/server.js # Use the endpoint here (we have setup a sample DB for this example) curl https://webtask.it.auth0.com/api/run/wt-sebastian_peyrott-auth0_com-0/0214e081084da52e5dd32915232242d8/tickets?webtask_no_cache=1&MONGO_URL=mongodb://test:[email protected]:35553/microservices -v
看程式碼。 將它與我們之前的版本進行比較,看看我們有多少變化。
結論
微服務是進行分散式計算的新方法。 部署和監控工具的進步緩解了管理許多獨立服務所帶來的痛苦。 好處很明顯:使用正確的工具來解決正確的問題,並讓團隊使用他們的專有技術來解決每個問題。 困難的部分是處理共享數據。 在處理共享數據和服務間依賴關係時,必須考慮特殊注意事項。 數據建模是任何設計中必不可少的步驟,在基於微服務的架構中更是如此。 我們將在以下文章中詳細探討其他常見模式和實踐。