浅谈基于 Laravel 开发的 MeEdu 的微服务架构设计

MeEdu 是基于 Laravel 开发的在线教育点播收费系统。您可以通过 MeEdu 开启您的在线教育事业。

https://github.com/Qsnh/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的微服务设计中,也存在着服务治理的影子。我们将视线再次移到上面的服务注册代码中,我们可以看到 CourseVideo 的注册服务后面都带有 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 协议》,转载必须注明作者和本文链接
开源教育系统https://meedu.vip
本帖由系统于 4年前 自动加精
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 1

可以讲解一下meedu登陆原理吗?

3年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!