构建基于Lagom的微服务项目实践
立即解锁
发布时间: 2025-08-19 00:05:43 阅读量: 1 订阅数: 3 


Scala 2.13编程实战与进阶
### 构建基于 Lagom 的微服务项目实践
#### 1. 面包师服务(BakerService)的定义与实现
面包师服务(BakerService)定义了处理生面团(RawCookies)并返回烘焙好的饼干(ReadyCookies)的功能。以下是其定义与实现的详细内容:
- **服务定义**:
```scala
trait BakerService extends Service {
def bake: ServiceCall[Source[RawCookies, NotUsed], Future[Source[ReadyCookies, NotUsed]]]
override def descriptor: Descriptor =
named("BakerService").withCalls(call(bake))
}
```
这里定义了 `BakerService` 接收 `Source[RawCookies, NotUsed]` 类型的请求,并返回 `Future[Source[ReadyCookies, NotUsed]]` 类型的响应。这允许我们在生面团可用时写入,并在烘焙后得到成品饼干。
- **服务实现**:
```scala
import play.api.Logger
class BakerServiceImpl extends BakerService {
private val logger = Logger("Baker")
override def bake: ServiceCall[Source[RawCookies, NotUsed], Source[ReadyCookies, NotUsed]] =
ServiceCall { dough =>
logger.info(s"Baking: $dough")
Future.successful(dough.via(bakerFlow))
}
private val bakerFlow: Flow[RawCookies, ReadyCookies, NotUsed] =
Baker.bakeFlow.join(Oven.bakeFlow)
}
```
实现部分复用了 `Baker` 和 `Oven` 的流程定义,并将组合后的流程作为调用结果返回。同时,还展示了如何使用底层 Play 框架提供的日志记录器。
#### 2. 厨师服务(ChefService)的持久化实现
厨师服务在混合食材的过程中可能会花费一些时间,为了防止服务重启时工作丢失,我们使用 Lagom 框架提供的持久化功能。具体步骤如下:
- **导入必要的包**:
```scala
import ch15.model._
import java.util.UUID
import akka.Done
import com.lightbend.lagom.scaladsl.persistence._
import PersistentEntity.ReplyType
import com.lightbend.lagom.scaladsl.playjson.JsonSerializer
import play.api.libs.json._
```
- **定义命令**:
```scala
sealed trait ChefCommand
final case class MixCommand(groceries: Groceries) extends ChefCommand with ReplyType[Done]
final case class DoneCommand(id: UUID) extends ChefCommand with ReplyType[Done]
```
`MixCommand` 表示混合食材的请求,`DoneCommand` 表示混合完成的状态转换。
- **定义事件**:
```scala
sealed trait ChefEvent
final case class Mixing(id: UUID, groceries: Groceries) extends ChefEvent
final case class MixingDone(id: UUID, dough: Dough) extends ChefEvent with AggregateEvent[MixingDone] {
override def aggregateTag: AggregateEventTag[MixingDone] = ChefModel.EventTag
}
```
`Mixing` 事件响应 `MixCommand`,`MixingDone` 事件响应 `DoneCommand`。
- **定义状态**:
```scala
sealed trait ChefState {
def batches: List[Mixing]
}
final case class MixingState(batches: List[Mixing]) extends ChefState
```
- **定义序列化器和事件标签**:
```scala
object ChefModel {
import play.api.libs.json._
implicit val mixingFormat = Json.format[Mixing]
val serializers = List(
JsonSerializer(mixingFormat),
JsonSerializer(Json.format[MixingDone]),
JsonSerializer(Json.format[MixingState])
)
val EventTag: AggregateEventTag[MixingDone] = AggregateEventTag[MixingDone]("MixingDone")
}
```
- **配置 Cassandra 键空间**:
在 `application.conf` 中进行如下配置:
```plaintext
user.cassandra.keyspace = chefprogress
cassandra-journal.keyspace = ${user.cassandra.keyspace}
cassandra-snapshot-store.keyspace = ${user.cassandra.keyspace}
lagom.persistence.read-side.cassandra.keyspace = ${user.cassandra.keyspace}
```
- **定义服务接口**:
```scala
trait ChefService extends Service {
def mix: ServiceCall[Groceries, Done]
def resultsTopic: Topic[Dough]
override def descriptor: Descriptor = {
named("ChefService")
.withCalls(call(mix))
.withTopics(topic(ChefService.ResultsTopic, resultsTopic))
.withAutoAcl(true)
}
}
object ChefService {
val ResultsTopic = "MixedResults"
}
```
- **服务实现**:
```scala
class ChefServiceImpl(persistentEntities: PersistentEntityRegistry, as: ActorSystem) extends ChefService {
private lazy val entity = wire[ChefPersistentEntity]
persistentEntities.register(entity)
override def mix: ServiceC
```
0
0
复制全文
相关推荐










