• 注意箭头函数 this 作用域

  • 刚从 node 那边回来 at 2021年09月19日

    小项目,怎样都无所谓。项目大了才能体会前后分离的优势,无论是一个人撸还是多人一起撸

  • vim +1,用啥自行车

  • 不记得在哪看到一句话:判断一个社会处于什么阶段不要看生产的东西是什么,而是要看组织生产的方式。比如一个奴隶制社会即使使用的是核聚变能源,生产的是反物质武器,它仍然是奴隶制社会。

    这同样也适用于软件开发。关键是组织代码和管理代码的方式

  • 谈一点 Event Sourcing 和 CQRS at 2021年06月17日

    是读写异构所表达的思想,不过 CQRS 更侧重于解决分布式系统中的一些问题,在单一数据源/库场景里反而没什么发挥的空间

    没必要纠结是不是 CQRS,只要理解了读写异构的本质和它提供的解决问题的思路就好了。关于这个有空我再补充下原回答

  • 谈一点 Event Sourcing 和 CQRS at 2021年06月16日

    CQRS 最重要的思想是读写异构,即数据的写入模型和读取模型是不同构的。

    这一点是相对于传统架构来说的。

    举个例子,我们有一个用户表,包含三个字段 id, name, gender。在传统架构里,我们会在 RDS 里定义这么一个数据表,当有新用户时我们插入包含 id, name, gender 的用户数据到这张表;当有查询请求时我们又从同一张数据表里将 id, name, gender 取出来返回给调用方。这种模型我们称为读写同构。

    那么读写异构到底是什么。

    比如说,接着上面的例子。我们还是有一个 RDS 用户表包含 id, name, gender。当有新用户注册时我们插入包含 id, name, gender 的用户数据到这张 RDS 用户表里;当有查询请求时,我们不从这张表直接读取数据了,而是从另一个数据存储器里读取数据(例如 redis,mongo, es 等)- 暂时叫它 “只读数据库”。

    这有什么不同呢?

    不同之处在于,只读数据库可以有多个(以满足多样化的查询需求),且只读数据库中的数据模型跟 RDS 用户表的模型(即 id, name, gender)可以不一样。例如其中一个只读数据库是用于统计所有 gender=男(或女)的用户数;另一个只读数据库是用于统计姓 “李” 的用户的数量,等等。应该可以想象这两个只读数据库模型跟 RDS 用户表的不同。这就是读写异构。

    为什么要读写异构?

    还是以刚才的例子。想象一下在传统方案里,要实现统计所有姓 “李” 的用户数量这个查询,我们需要做什么?性能又如何?跟直接从第二个只读数据库中查询相比复杂程度如何?这仅仅只是其中一种查询需求,在现实需求中有更多且更复杂的查询需求,数据同构方案如何保持数据模型的可维护性和高效性?(方案肯定是有的,但必然陷入成本、复杂性、高效性三角形取舍中)

    说了好处,再说说它为了解决问题而引入的新问题:多个数据库之间如何同步?

    还是接着刚才的例子。现在需要把 RDS 用户表的数据同步到其他数据库,一般会有几种情况:目标数据库跟源库是同族;目标数据库跟源库不同族,但有官方或可靠的插件可实现实时同步;目标数据库跟源库差别较大。第一、二种情况比较简单,可以简单用 binlog 或者插件实现同步;一般复杂度在于第三种情况,比如源库是 mysql/posgres,目标库是 es、mongo、redis 等。ETL 是其中一种方案,这里就不展开了。

    为什么 CQRS 通常会跟 event sourcing 一起被提起?

    event sourcing(即事件溯源)是一个独立概念,实现技术和方案有很多(可以搜到,不一一列举了)。event sourcing 是解决多数据库之间同步问题的一个比较好的方案。特别是在高可扩展性系统里,不仅解决了同步问题,还实现了系统的高可扩展性。比如全新的业务模块需要同步已有模块中的某维度的数据。有了事件溯源,只需要从头把事件轴在新模块里重放一遍,数据就同步到新模块的数据库中了。这个过程对原业务完全透明,也不会因同步对源库造成额外压力。这种方式保证了现有业务的稳定性,也满足了系统的良好扩展性。由此可见,event sourcing 在 CQRS 中的作用。

    码一下,迟点再补充。可能会扩展以下话题

    • CQRS 一定要搭配 event sourcing 吗?
    • golang 在基础架构和中间件的崛起及对 CQRS 的影响
    • serverless 和事件驱动的分布式架构
    • 想到再补充
  • 在 context function 里做 authorization 不难吧

  • 逛了下几大热门 web 语言社区,真的感觉 ruby-china 是氛围最好的,无论是内容质量还是活跃度。同好奇为啥

  • 我觉得 graphql 和 rest 没必要对立起来,graphql 是对 rest 的适当补充,特别是对于复杂查询场景。

    graphql 感觉还适合做 API 聚合器。例如有对外的公共接口,那么用 graphql 将内部一些 rest 接口包装一下,汇总成一个统一的公共接口入口还是蛮适用的。如果内部 rest 接口包含些敏感信息不宜暴露给外部的,还可以在 graphql 这层做过滤,完全不影响内部接口

    无论 rest 也好,graph 也好,rpc 也好,都是接口风格。软件工程里没有银弹,好的架构需要具有一定程度的包容性,利于针对特定场景选择最适合的技术方案

  • 嗯哈,楼主可以调研下是否适合公司的业务场景。这个方案的好处是可以渐进式的重构,原有 rest 还可以继续跑。先重构一些典型复杂查询接口,成功的话再进行更深程度的重构。代价无非是多了个 es 集群和数据同步管道。

    关于权限管理,感觉可以抽出来做一个独立的服务。graphql 里加一个 middleware 调权限管理服务再走正常业务逻辑,权限过不了就直接返回了。(其实一开始也可以先不独立服务,指回现有的权限模块就好,将来真的有必要了再抽出来作为独立的权限管理服务)

    重构这种东西不宜步子迈得太大,容易整段垮掉。渐进式的重构方案可进可退,前期调研和试验后发现不合适放弃也不会造成太大损失,敏捷开发嘛

  • 个人感觉 graphql 更适合做查询,不太适合做修改类的接口。那么如果是复杂项目,架构可以用 CQRS 实现读写异构,即写接口用传统的 rest,读接口可以用 graphql 暴露,而 graphql 可以用 elastic search 作为只读数据源。elastic search 跟 RDS 做一个数据管道实时同步。这样查询的时候就不会出现复杂 query 导致数据库性能问题了,而且在数据同步的时候可以提前做数据合并,很适合 graphql 这种前端想查询什么就给什么的用例。(yy 一下 NoSQL 一张表打天下的情景)

    这样是否一定程度上扬长避短了呢?

    以上纯粹交流哈,感兴趣的可以一起探讨。 当然上面的方案有点跑题了,楼主勿怪~