写点什么

第十周作业总结

用户头像
jizhi7
关注
发布于: 2021 年 02 月 07 日

一、背景:

1、单体应用的问题:

1. 形成巨无霸应用,编译打包困难,打包出来的包有四五个 G。

2. 代码分支管理困难。

3. 单体应用部署大规模集群,导致数据库连接不够用。

4. 新增业务困难。

2、解决方案:

1. 拆分,将模块独立出来开发部署,降低系统的耦合性。

1) 纵向拆分,将一个大应用拆分为多个小应用,如果新增业务比较独立,那么直接将其设计部署为一个独立的应用。

2) 横向拆分,将复用的业务拆分出来,独立部署为微服务,新增业务只需要调用这些微服务。

3、难点:

微服务的业务和服务的划分,以及服务的开发和维护上。所以拆分之前要对业务系统很了解,堆拆分的每一个微服务定义好职责边界。

二、Web Service 与企业级分布式服务

1、缺点:

1. 臃肿的注册与发现机制

2. 低效的 XML 序列化手段

3. 开销较高的 HTTP 通信

4. 复杂的部署与维护

三、微服务框架

1、基本需求:

1. 负载均衡

2. 失效转移(Fail Over):

调用的服务是不可用的,要及时转移,切换到其他服务上。

3. 高效的远程通信:

在微服务中,服务之间的调用是很频繁的,核心服务每天的调用次数回达到数以亿计,如果没有高效的通信手段。服务调用可能会成为系统性能的瓶颈。(应使用基于长连接的通信,序列化的应简单,减少数据传输)

4. 对应用最少侵入:

是否使用微服务需要根据业务的发展规划,微服务也需要循序渐进式的演化,甚至会出现使用了微服务后,退回到集中式部署。

5. 版本管理:

为了响应快速变化的需求,服务升级不可避免。如果访问的接口发生了变化,就需要服务请求者和服务提供者同时升级,而同时升级会导致网站服务不可用。因此要服务提供者先升级接口,同时提供旧接口的调用,当请求者访问接口升级了之后才能关闭旧接口。

四、微服务架构落地

1、业务先行,先理顺业务边界和依赖,技术是手段而不是目的。

2、先有独立的模块,后有分布式的服务。

3、业务耦合严重,逻辑复杂多变的系统进行微服务重构要谨慎。

4、要搞清除微服务的目的是什么,业务复用?开发边界清晰?分布式集群提升性能?

5、最佳实践:

1. 命令与查询职责隔离:

1) 含义:在服务接口层面,将查询(读操作)与命令(写操作)隔离,实现服务层的读写分离。

2) 优点:能针对读写分别优化,查询服务不会修改数据,更好的保护数据。

3) 实现:设计一个专门的读微服务和写微服务,都访问不同的数据库。独立部署。网关别分调用。读微服务可以更多的使用缓存提升读性能,写微服务可以通过消息队列,异步提升写性能。

2. 事件溯源:

1) 含义:将用户请求处理过程中的每次状态变化都记录到事件日志中,并按照时间序列经行持久化存储。

2) 优点:可以复现用户任何状态,进行复核审计。可以有效地监控用户状态变化,并在此基础上实现分布式事务。

3) 实现:

3. 断路器:

1) 含义:当某个服务出现故障,响应延迟或者失败率增加,继续调用这个服务会导致调用者请求阻塞,资源耗尽,进而出现服务级联失效。断路器三种状态:关闭、打开、半开。

4. 服务重试及调用超时:

上游调用者超时时间要大于下游调用者超时时间之和。

5. 最重要的是需求。

五、微服务网关的技术架构

1、背景:

对于微服务的调用,不再是通过对一些复杂的 WEB 应用的直接调用,而是通过一个网关调用。

APP,WEB 等调用,会先调用网关,然后网关调用不同的微服务。

2、网关作用:

1. 统一接入:高性能、高并发、高可靠、负载均衡

2. 安全防护:防刷控制、黑白名单

3. 流量管控与容错:限流、降级、熔断

4. 协议适配:HTPP、Dubbo、JSF(不同的微服务协议,一个网关适配多个微服务协议)

3、网管管道技术:

网关本身没有什么业务,主要职责是做各种校验与拦截,这些职责可以通过管道技术连接起来。

--request-->参数校验--->限流控制--->接口调用--request-->

4、异步网关与异步微服务框架

利用 Servlet3 实现异步网关。req.startAsync()返回一个 AsyncContext 就可以结束当前线程了,request 对象和 response 对象都在 context 里面,整个 socket 都还在保持着。要返回 response 结果的时候,从 AsyncContext 里面获得一个 response 输出。

传统的同步 WEB 编程,如果线程释放了,socket 连接也就会释放了。Servlet3 的异步网络编程,可以释放掉当前线程,但是不会释放掉 socket 连接,可以通过 AysncContext 获得之前的连接。

5、开放平台网关:

1. 开放平台网关暴露一些 API 给第三方合作者使用。要支持:协议转换、安全、审计、路由、流程。

2. 开放授权协议 OAuth2.0:

步骤:

1) 第三方应用向资源所有者(用户)请求授权

2) 资源所有者(用户),同意授权

3) 第三方应用向授权服务器申请令牌

4) 授权服务器发放令牌

5) 第三方应用使用令牌向资源服务器访问资源

6) 资源服务器确认令牌,发放资源。

六、领域驱动设计 DDD

1、背景:

1.事务脚本(贫血模型):

Controller -> Service -> Dao,导致重 Service,Service 会越来越臃肿。

2.领域模型(充血模型):

根据对象,每个对象承担自己的业务职责和业务逻辑。通过对象的组合方式完成业务功能。(把复杂的业务逻辑拆分成不同的对象去完成)

3. 贫血模型:

Service、Dao 这些对象只有方法,没有数值成员变量,而方法调用时传递的数值对象,因此事务脚本又被称作贫血模型。

4. 充血模型:

领域模型是合并了行为和数据的领域的对象模型。

通过领域模型对象的交互完成业务逻辑的实现,也就是说,设计好了领域模型对象,也就设计好了业务逻辑实现。和事务脚本被称作贫血模型相对应的,领域模型也被称为充血模型。

2、DDD 设计:

1. 战略设计:

高层的,业务架构层面。

2. 战术设计:

底层的,编程编码方面的实现。

3、战略设计:

(1) 领域:

1. 领域是一个组织所做的事情以及其包含的一切,通俗地说,就是组织的业务范围和做事方式,也是软件开发的目标范围。

2. 领域驱动设计就是从业务领域出发,分析领域内模型及其关系,进而设计软件系统的方法。

3. 将大领域拆分成子领域。

(2) 限界上下文:

1. 在一个子域中,会创建一个概念上的领域边界,在这个边界中,任何领域对象都只表示特定于该边界内部的确切含义。这样边界便称为限界上下文。限界上下文和子域具有一对一的关系,用来控制子域的边界,保证子域内的概念统一性。

2. 通常限界上下文对应一个组件或者一个模块,或者一个微服务,一个子系统。

(3) 上下文映射图:

不同的限界上下文,也就是不同的子系统或者模块之间会有各种的交互合作。DDD 使用上下文映射图来设计这种关联和交互。

4、战术设计:

(1) 实体:

领域模型对象也被称为实体,每个实体都是唯一的,具有一个唯一标识。

实体设计是 DDD 的核心所在,首先通过业务分析,识别出实体对象,然后通过相关的业务逻辑设计实体的属性和方法。

(2) 值对象:

并不是领域内的对象都应该被设计为实体,DDD 推荐尽可能将对象设计为值对象。

比如像住址这样的对象就是典型的值对象,也许建在住址上的房子可以被当做一个实体,但是住址仅仅是对房子的一个描述,像这样仅仅用来做度量或描述的对象应该被设计为值对象。

值对象的一个特点是不变性,一个值对象创建以后就不能再改变了。

(3) 聚合:

聚合是一个关联对象的集合,我们将其作为一个单元来处理数据更改。每个集合都有一个根和一个边界。边界定义了聚合内部的内容。根是聚合中包含的单个特定实体。

聚合根:将多个实体和值对象聚合在一起的实体。

5、DDD 分层架构:

(1) 用户接口层:

和贫血模型的 Controller 层一样。

(2) 应用层:

参数处理,事务控制,组合调用领域层。

(3) 领域层:

具体的业务操作。

6、DDD 六边形架构:

领域模型通过应用程序封装成一个相对比较独立的模块,而不同的外部系统则通过不同的适配器和领域模型交互,比如可以通过 HTTP 接口访问领域模型,也可以通过 Web Service 或者消息队列访问领域模型,只需要为这些不同的访问接口提供不同的适配器就可以了。

七、软件组件设计原则:

1、组件内聚原则:

1. 复用发布等同原则:

1) 软件复用的最小粒度应该等同于其发布的最小粒度。也就是说,如果你希望别人以怎样的粒度复用你的软件,你就应该以怎样的粒度发布你的软件。

2) 版本号约定建议:

a. 版本号格式:主版本号.次版本号.修订号。比如 1.3.12,在这个版本号中,主版本号是 1,次版本号是 3,修订号是 12。

b. 主版本号升级,表示组件发生了不向前兼容的重大修订;

c. 次版本号升级,表示组件进行了重要的功能修订或者 bug 修复,但是组件是向前兼容的;

d. 修订号升级,表示组件进行了不重要的功能修订或者 bug 修复。

2. 共同封闭原则:

我们应该将那些会同时修改,并且为了相同目的而修改的类放到同一个组件中。而将不会同时修改,并且不会为了相同目的而修改的类放到不同的组件中。

3. 共同复用原则:

共同复用原则是说,不要强迫一个组件的用户依赖他们不需要的东西。

2、组件耦合原则:

1. 无循环依赖原则:

无循环依赖原则说,组件依赖关系中不应该出现环。如果组件 A 依赖组件 B,组件 B 依赖组件 C,组件 C 又依赖组件 A,就形成了循环依赖。

2. 稳定依赖原则:

稳定依赖原则说,组件依赖关系必须指向更稳定的方向。较少变更的组件是稳定的,也就是说,经常变更的组件是不稳定的。根据稳定依赖原则,不稳定的组件应该依赖稳定的组件,而不是反过来。

稳定依赖原则通俗地说就是,组件不应该依赖一个比自己还不稳定的组件。

3. 稳定抽象原则:

稳定抽象原则说,一个组件的抽象化程度应该与其稳定性程度一致。也就是说,一个稳定的组件应该是抽象的,而不稳定的组件应该是具体的。


用户头像

jizhi7

关注

还未添加个人签名 2018.09.08 加入

还未添加个人简介

评论

发布
暂无评论
第十周作业总结