MeEdu 是基於 Laravel 開發的線上教育點播收費系統。您可以通過 MeEdu 開啟您的線上教育事業。
本篇文章主要給小夥伴們介紹下MeEdu的微服務架構設計。首先,來看下MeEdu服務層的目錄結構:
# ./app/Services
.
├── Base
│ ├── Interfaces
│ │ ├── CacheServiceInterface.php
│ │ ├── ConfigServiceInterface.php
│ │ └── RenderServiceInterface.php
│ ├── Providers
│ │ └── BaseServiceRegisterProvider.php
│ └── Services
│ ├── CacheService.php
│ ├── ConfigService.php
│ └── RenderService.php
├── Course
│ ├── Interfaces
│ │ ├── CourseCommentServiceInterface.php
│ │ ├── CourseServiceInterface.php
│ │ ├── VideoCommentServiceInterface.php
│ │ └── VideoServiceInterface.php
│ ├── Models
│ │ ├── Base.php
│ │ ├── Course.php
│ │ ├── CourseChapter.php
│ │ ├── CourseComment.php
│ │ ├── Video.php
│ │ └── VideoComment.php
│ ├── Providers
│ │ └── CourseServiceRegisterProvider.php
│ ├── Proxies
│ │ ├── CourseServiceProxy.php
│ │ └── VideoServiceProxy.php
│ └── Services
│ ├── CourseCommentService.php
│ ├── CourseService.php
│ ├── VideoCommentService.php
│ └── VideoService.php
├── Member
└── README.md
由於篇幅,上面省略掉了部分服務,不過重點的已經在裡面了。微服務的架構設計從目錄上面就能看出很多東西。
微服務
首先,我們先來了解下微服務到底是什麼?下面是百度百科給出的解釋:
微服務可以在“自己的程式”中執行,並通過“輕量級裝置與HTTP型API進行溝通”。關鍵在於該服務可以在自己的程式中執行。通過這一點我們就可以將服務公開與微服務架構(在現有系統中分佈一個API)區分開來。在服務公開中,許多服務都可以被內部獨立程式所限制。如果其中任何一個服務需要增加某種功能,那麼就必須縮小程式範圍。在微服務架構中,只需要在特定的某種服務中增加所需功能,而不影響整體程式的架構。
總結來說,微服務就是講複雜的應用進行拆分獨立部署,高內聚,低耦合,配合DevOps實現快速敏捷迭代開發。
高內聚,低耦合
我想大家應該都有遇到過某些專案,這些專案的程式碼緊密的結合在一起,當看到程式碼之後,你腦子裡面想的第一個詞:“重構”。如果在專案開始之初,沒有嚴格的規範和約束,隨著業務範圍的擴張和開發人員的變動,專案會越來越複雜,越來越臃腫,經過一段時間的積累之後,後來接手專案的人就苦逼了。
為了避免出現這樣的問題,我們在設計專案的時候,就要考慮一個問題:“如何做到高內聚,低耦合?”
為了解決這個為,在傳統的MVC架構下,引入了很多的解決方案,對程式碼進行分割,對系統程式碼和業務程式碼進行分離,但是啊,我們可以看到的是,這些其實作用並不是很大,隨著產品需求的變更,原來一開始或許不錯的程式碼會變得越來越糟糕,為什麼會這樣呢?是因為設計的不合理嗎?其實也不是,我覺得最主要的原因就是程式碼寫在一起了!沒有做徹底的分離!
微服務的出現就不一樣了,對系統進行服務服務劃分之後,相應的開發人員負責自己的服務,它的程式碼範圍就侷限在自己的服務裡面,這樣就做到了高內聚,低耦合。更嚴格的情況下,不同的服務的資料庫也是不一樣的,這樣就更加獨立和自主了。
服務劃分
微服務最重要的一點就是對系統進行服務劃分,那怎麼樣的劃分最為合理呢?服務的界限以什麼為標準呢?
這其實沒有具體的標準,服務劃分的界限要考慮到很多東西,專案的架構,產品的業務範圍,技術人員,維護等。所以,這個界限標準,只要你的團隊都覺得合理,就可以了。但是有一點需要注意的是,服務並不是越細越好!
在MeEdu中,基於現有的功能,主要劃分了下面幾個服務:
| 服務 | 說明 |
| --- | --- |
| Base
| 系統底層服務,主要有:快取,配置服務等 |
| Member
| 會員服務,負責 MeEdu 系統的會員註冊/登入/找回密碼/會員等級等 |
| Course
| 課程服務,主要提供課程/視訊線上觀看 |
| Order
| 訂單服務,主要提供課程/視訊/會員的線上購買服務 |
| Other
| 其它服務,主要是系統的一些小功能,包括像:上傳,簡訊傳送等 |
服務註冊/釋出
微服務的架構當中,每個服務需要將自己註冊到註冊中心,這樣消費者才可以消費服務。
MeEdu雖然是微服務的架構,但是畢竟沒有做到徹底的服務分離,所以,所有的服務還是寫在一個系統裡面的。那麼MeEdu的服務是怎麼註冊的呢?請看下下面的程式碼:
class CourseServiceRegisterProvider extends ServiceProvider
{
public function register()
{
$this->app->instance(CourseServiceInterface::class, $this->app->make(CourseServiceProxy::class));
$this->app->instance(VideoServiceInterface::class, $this->app->make(VideoServiceProxy::class));
$this->app->instance(CourseCommentServiceInterface::class, $this->app->make(CourseCommentService::class));
$this->app->instance(VideoCommentServiceInterface::class, $this->app->make(VideoCommentService::class));
}
}
MeEdu是基於Laravel開發的,在這裡,我們將容器當做了服務的註冊中心,在需要用到的服務的時候,我們在容器裡面拿到我們想要的服務!
服務的治理
服務治理也是微服務架構設計中的一個必不可少的環節。在MeEdu的微服務設計中,也存在著服務治理的影子。我們將視線再次移到上面的服務註冊程式碼中,我們可以看到 Course
和 Video
的註冊服務後面都帶有 Proxy
這個關鍵字!這裡的 Proxy
就是實現服務治理的目的!來看下 CourseServiceProxy
的程式碼:
class CourseServiceProxy extends ServiceProxy implements CourseServiceInterface
{
public function __construct(CourseService $service)
{
parent::__construct($service);
$this->cache['getLatestCourses'] = function ($limit) {
return new CacheInfo('c:cs:lc:'.$limit, $this->configService->getCacheExpire());
};
$this->cache['chapters'] = function ($courseId) {
return new CacheInfo('c:cs:cc:'.$courseId, $this->configService->getCacheExpire());
};
}
}
CourseServiceProxy
實現了 CourseServiceInterface
介面,所以,它可以被註冊到註冊中心。這裡我們需要關注下 ServiceProxy
:
由於篇幅的原因,這裡僅貼出核心的程式碼,全部程式碼可以到meedu的倉庫檢視。
public function __call($name, $arguments)
{
// 鎖控制
if (isset($this->lock[$name])) {
return $this->lockHandlerBefore($name, $arguments);
}
// 限流
$this->limitHandler($name, $arguments);
// 快取
$response = $this->cacheHandler($name, $arguments);
return $response;
}
上面的核心程式碼就是採用AOP設計思想實現了鎖控制,限流,快取等治理功能。
服務呼叫
這是最重要的一個環節,如果這個環節做不好,那麼微服務的架構設計就沒有意義了。許多專案就是因為程式碼之間的互相呼叫導致了程式碼越來越複雜,越來越看不懂。所以,限制服務之間的呼叫是必須要考慮的一點。
-
在MeEdu的微服務架構設計中,我們規定,
Base
服務可以被其它任何服務呼叫,除了Base
服務之外,禁止呼叫其它任何服務。只有這樣嚴格的規定,才能做到真正的高內聚,低耦合。 -
服務之外的任何地方都可以任意的呼叫各種服務的方法,沒有限制。
-
所有的服務禁止手動初始化,必須通過容器的方式拿到服務的例項物件。
總結
微服務架構遠不止這麼簡單,真正做到微服務架構設計需要更多的專業知識和人力成本。MeEdu的微服務架構設計,目前僅僅是程式碼層面實現的架構設計,不過,在這個基礎上,後期如果切換真正的微服務架構也是非常簡單的。因為,路已經鋪好了!
本作品採用《CC 協議》,轉載必須註明作者和本文連結