MicroServe微服务

Laravel 如何设计微服务架构,及如何进行微服务间沟通?

 目前已有的一个思考方向是使用 K8S 统合各个独立的 Laravel 小服务,再开放统一对外的 API Gateway

但碰到一个问题是各个服务间要如何在不发生耦合的状况下沟通

举例来说:订单发生后需要减少库存,若库存成功扣除后要再告诉订单更新状态
我目前想到三种解决方式:

  1. 在 API Gateway 处理流程问题,等订单服务回传成功后,再呼叫库存服务。
    好处:流程简单直觉、使用者当下就可知道订单结果
    坏处:API Gateway 会发生强耦合、API Gateway 会出现状态,违反微服务的 Stateless 原则
  2. 在订单服务的建立方法中直接呼叫库存服务
    好处与坏处都跟方法一差不多,但更多的坏处是微服务本身会变复杂、与其他服务发生强耦合,且违反微服务间不能直接沟通的原则
  3. 借由某种广播机制,在订单建立完成后,由订单服务发出「订单建立成功」的广播,告诉其他服务有订单建立。库存服务接收到广播后就会扣除库存,并再次发出「库存扣除成功」的广播,由订单服务再次接收。而其他不相干的服务就会忽略广播。
    好处:各服务完全解耦,彼此只借由单次事件进行沟通,不会在双方服务留下状态,且后续有逻辑改动只需要调整事件即可,不用动服务主逻辑
    坏处:无法及时告诉使用者订单产生结果,会造成较差的使用者体验

我目前想采用的是第三种模式,因为我司目前还处于新创阶段,功能仍在快速调整,因此开发上最好能像电源一样快速插拔,若服务出现强耦合就会降低产品调整的速度。相较之下,第三种方法造成的使用者体验降低都还可以接受。
我搜寻过后似乎有「Message Queue」这种解法,但有点不明白它如何用 Laravel 实作,且有一部分文章来源表示 Message Queue 已经是过时的技术
想请问有没有人设计过微服务架构,或曾经碰过类似的状况能给我一些建议,谢谢

---------------------- 4/3 补充说明

我发现我之前对 Message Queue 的理解有错,因此上来补充说明
我之前对 Queue 的机制,是认为他注册的事件是一段程式码,等待 worker 执行
但 Laravel 的事件机制,实际上是由 Event 注册事件名称及相关资料,等 worker 空闲后,呼叫 Listener 接收事件
Event 注册的资料如下所示

array (   'displayName' => 'App\Mail\SaveAsDraft',   'job' => 'Illuminate\Queue\CallQueuedHandler@call',   'maxTries' => NULL,   'timeout' => NULL,   'timeoutAt' => NULL,   'data' =>    array (     'commandName' => 'Illuminate\Mail\SendQueuedMailable',     'command' => 'O:34:"Illuminate\Mail\SendQueuedMailable":3:{s:8:"mailable";O:20:"App\Mail\SaveAsDraft":20:{s:29:"' . "" . 'App\Mail\SaveAsDraft' . "" . 'service";O:45:"Illuminate\Contracts\Database\ModelIdentifier":3:{s:5:"class";s:18:"App\ServicePackage";s:2:"id";i:522;s:10:"connection";s:5:"mysql";}s:4:"from";a:0:{}s:2:"to";a:1:{i:0;a:2:{s:4:"name";N;s:7:"address";s:21:"mengluyange@gmail.com";}}s:2:"cc";a:0:{}s:3:"bcc";a:0:{}s:7:"replyTo";a:0:{}s:7:"subject";N;s:11:"' . "" . '*' . "" . 'markdown";N;s:4:"view";N;s:8:"textView";N;s:8:"viewData";a:0:{}s:11:"attachments";a:0:{}s:14:"rawAttachments";a:0:{}s:9:"callbacks";a:0:{}s:10:"connection";N;s:5:"queue";N;s:15:"chainConnection";N;s:10:"chainQueue";N;s:5:"delay";N;s:7:"chained";a:0:{}}s:5:"tries";N;s:7:"timeout";N;}',   ),   'id' => '1',   'attempts' => 0,   'type' => 'mail',   'tags' =>    array (     0 => 'App\ServicePackage:522',   ),   'pushedAt' => 1514296314, )

里面并无存放任何程式码,仅告诉 Listener 要做什么,用什么去做,剩下的逻辑都是在 Listener 里面

所以针对我上面提到的 Message Queue 机制,可以如下设计

  1. 以 AWS 来说,各个微服务都会有自己对应的 SQS,事件产生时,将事件发送到 SNS,SNS 就会广播到所有 SQS,并由各服务各自处理队列
  2. 若非使用 AWS,而是自架 Message Queue,就是自己架个 Message Queue Service,里面的 Redis 为集群,收到广播事件后就一次写入集群所有 Redis,再由各服务执行

Publish Comment发表评论

点击刷新验证码 点击图片可刷新验证码

Comment网友评论

詹绍乾 Jancy © 版权所有 2020

Copyright © 2010 by zhansq.cn All right reserved.