《微服务设计》4、5章笔记

上一篇 《微服务设计》1~3章笔记



第四章 集成

目标:

  1. 保持自治
  2. 独立修改和发布

4.1 寻找理想的集成技术

  • 避免破坏性修改
  • 保证api的技术无关性
  • 使你的服务易于消费者方使用(使用客户端库会有耦合问题)
  • 隐藏内部实现细节(修改服务本身对消费者而言不修改)

4.3 数据库集成

  1. 消费者不修改表结构
  2. 数据库是共享的大API,同时也不稳定。
    更改可能需要做大量的回归测试。
  3. 现在看来似乎关系型数据库有优势。
    或许以后会发现非关系型才是更好选择
  4. 行为(服务怎么共享行为呢?)
    而且很难做到不被破坏。

4.4 同步与异步

  • 同步:似乎很合理,反馈成功与否。
  • 异步:对运行时长较长的,较为有用。(保证网卡)
    技术复杂性。

事件发布协作

对于整个系统都是很聪明的。
业务逻辑并非集中在某个核心大脑,而是平均分布在不同的协作者中。

4.5 编排与协同

编排:驱动整个流程

缺点

  • 中心控制承担太多职责,会导致一些“上帝”服务、贫血服务、基于curd的服务。
  • 不稳定
  • 修改代价大

协同

各个部分清楚自己各自的职责。

  • 优点-->消除耦合。
  • 缺点-->看不到明显的业务流程。
    ==》结合领域模型
    ==》可以和异步结合

4.6 远程过程调用

RPC主要卖点:简单容易使用。

问题:

  1. 技术耦合(比如:java RMI)
  2. 本地调用和远程调用是不同的,
    性能问题在RPC服务,封装+解封
    网络本身是不可靠的
  3. 脆弱性(所有客户端重新生成桩,对象序列化的问题)
  4. RPC很糟糕么?
    protocol buffer 或 Thrift 可以消除部分问题。
    注意:不要对远程调用过度抽象,确保你可以独立升级。

4.7 REST

本质:资源概念

REST和HTTP

  • http缓存代理
  • 负载均衡
  • 对终端用户透明
  • 安全控制
  • 有不少很好的特性与标准

留心过多的约定

  • 不要轻易暴露存储对象
  • 服务是由消费者需求驱动衍生出来的(推迟了数据存储的集成)

缺点

  • 无法帮助你生成桩代码。==》又会走回rpc的服务器与客户端共享库。
  • 性能。(封装性能问题?)
    • webscoket性能更高(更低的延迟)
    • udp或者其他的rpc框架

4.8 实现基于事件的异步协作方式


**技术选择(服务发布事件+消费者接收事件)** - mq(代价:服务器+流程) - atom(使用方便,追踪消息+管理轮询) 还可以自定义

异步架构的复杂性

  • 不仅是发布,而且怎么响应处理呢?
  • 思维上的转变
  • 建立死信对立(存储失效的消息)
  • 建立管理ID

4.11 微服务世界中DRY和代码重用的危险


> Don't Repeat Yourself ! 不要拷贝代码 分布到各个系统中,只会产生各种问题bug.

问题

  • 共享库,对微服务来谁可能是危险的。(耦合)
  • 跨服务调用也很有可能引入耦合!!
  • 作者经验:在跨服务中可以偶尔违反 DRY。
  • 服务之间耦合可能带来更大的问题。

4.12 按引用访问

思考:如何传递领域实体?
微服务应该包含核心领域实体全生命周期的相关操作。

  1. 传递所有用户信息?写入队列,处理时候用户信息被改了怎么办?
    解决-->传入userId(缺点:负载问题-->加缓存)
  2. 有些服务并不需要整个用户信息
    https://martinfowler.com/articles/richardsonMaturityModel.html

4.13 版本管理

  1. 尽可能推迟(不改+避免client与server耦合)
  2. 宽进严出
    对自己发送出去的数据严格,对接收的东西要宽容。
  3. 及早发现破坏性修改
  4. 使用语义化的版本管理
    http://semver.org/lang/zh-CN/

5. 不同的接口共存(保留老接口)

扩展、收缩模式
扩展服务的能力,对老的消费者采用新的方式,收缩API去掉旧的功能
==》多个版本实体(痛苦)
6. 同时使用多个版本的服务
老用户路由到老服务,新用户路由到新服务。(比较难)
怀疑?

第五章 分解单块系统

恐怖而庞大的存在

5. 1 关键是接缝

理清楚代码库,甚至识别出服务边界。

5. 2 分解MusicCorp

给代码找位置,剩下的就是上下文的代码。

5. 3 分解单块系统的原因

增量开凿!!

  1. 改变的速度
  2. 团队结构
  3. 技术

5. 4 杂乱的依赖

识别出哪些接缝会比较难处理。

5. 6 识别出关键性问题

  1. 工具SchemaSpy
  2. 识别出不同上下文的表之间的耦合

5. 7 打破外键关系

  1. 两次服务调用代替外键!(一定程度的慢是可以接受的)
  2. 系统的期望行为是什么,跟着它去做决定。

5. 8 共享静态数据

解决:

  1. 复制表
  2. 共享静态数据到代码,或放到一个枚举。
  3. 放到一个服务去

5. 9 共享数据

可变数据共享,是一个麻烦。

领域概念不是在代码中建模,相反是在数据库中隐式进行建模。
财务服务-->客户服务
仓库服务-->客户服务

5. 10 共享表(分离)

5. 11 重构数据库

实施分离(不影响消费者)

5. 12 事务边界

分离后就被抹掉了。

  • 再试一次-->最终一致性(√)
  • 终止整个操作(重置会最初的状态)
  • 分布式事务(两阶式提交)
  • 应该怎么处理呢?

5. 13 报告(日志监控)

5.15 通过服务调用获取数据

多次调用多次封装,大量数据就不适用了。

报告系统

  • 依赖一些sql接口
  • 遍历所有用户,显得低效。
  • 解决,调用生成存储的cvs,共享位置下载。

5.16 数据导出

导出到单独的数据库(去除耦合)

建议:导出程序和报告系统版本控制。
也可以使用视图(聚合),性能取决于你选的数据库

另一个方向

  • 一系列的json数据导出到AWSS3,数据集市。
  • 数据量很大之后就不适用了。

5.17 事件数据导出

  1. 好处:与源微服务底层数据库耦合消除了。
  2. 关键:设计事件
  3. 缺点:事件广播,数据量大的时候

思考:

数据备份?

5.19 走向实时

所有都要马上输出么?

5.20 修改的代价

  1. 要知道,改变会影响多少东西。
  2. 在白板上写上服务边界,运行用例,然后就会发生什么呢?

类-职责-交互(写卡片,理清楚自身和其他东西的关系)

5.21 理解根本原因

大服务拆分小服务。为什么要这样做呢?

  1. 服务一定会慢慢变大的。
  2. 巨大到不健康之前,发现它。

推荐书籍:《修改代码的艺术》

image

posted on 2017-11-13 21:31  魔术师Carvendy  阅读(172)  评论(0编辑  收藏  举报