Laravel 如何设计微服务架构,及如何进行微服务间沟通? | Laravel China 社区
如题,我目前有需要用 Laravel 设计微服务架构的需求,但能找到的相关资料不多
目前已有的一个思考方向是使用 K8S 统合各个独立的 Laravel 小服务,再开放统一对外的 API Gateway
但碰到一个问题是各个服务间要如何在不发生耦合的状况下沟通
举例来说:订单发生后需要减少库存,若库存成功扣除后要再告诉订单更新状态
我目前想到三种解决方式:
- 在 API Gateway 处理流程问题,等订单服务回传成功后,再呼叫库存服务。
好处:流程简单直觉、使用者当下就可知道订单结果
坏处:API Gateway 会发生强耦合、API Gateway 会出现状态,违反微服务的 Stateless 原则 - 在订单服务的建立方法中直接呼叫库存服务
好处与坏处都跟方法一差不多,但更多的坏处是微服务本身会变复杂、与其他服务发生强耦合,且违反微服务间不能直接沟通的原则 - 借由某种广播机制,在订单建立完成后,由订单服务发出「订单建立成功」的广播,告诉其他服务有订单建立。库存服务接收到广播后就会扣除库存,并再次发出「库存扣除成功」的广播,由订单服务再次接收。而其他不相干的服务就会忽略广播。
好处:各服务完全解耦,彼此只借由单次事件进行沟通,不会在双方服务留下状态,且后续有逻辑改动只需要调整事件即可,不用动服务主逻辑
坏处:无法及时告诉使用者订单产生结果,会造成较差的使用者体验
我目前想采用的是第三种模式,因为我司目前还处于新创阶段,功能仍在快速调整,因此开发上最好能像电源一样快速插拔,若服务出现强耦合就会降低产品调整的速度。相较之下,第三种方法造成的使用者体验降低都还可以接受。
我搜寻过后似乎有「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:"' . "\0" . 'App\\Mail\\SaveAsDraft' . "\0" . '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:"' . "\0" . '*' . "\0" . '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 机制,可以如下设计
- 以 AWS 来说,各个微服务都会有自己对应的 SQS,事件产生时,将事件发送到 SNS,SNS 就会广播到所有 SQS,并由各服务各自处理队列
- 若非使用 AWS,而是自架 Message Queue,就是自己架个 Message Queue Service,里面的 Redis 为集群,收到广播事件后就一次写入集群所有 Redis,再由各服务执行
思路上大概如上,但未经过实作,待实作过后会再上来补充说明
簡永哲 Leo Chien IT Director | 大師鏈 MasterChain E: s950329@hotmail.com
赞 (0)