写点什么

「架构师训练营第 1 期」命题作业

用户头像
Ray
关注
发布于: 2020 年 09 月 19 日

第一周命题作业

作业一 食堂就餐卡系统设计


  • 系统中每个消费者都有一张卡,在管理中心注册缴费,卡内记着消费者的身份、余额。

  • 使用时将卡插入收款机则显示卡上金额,服务员按收款机上数字键,收款机自动计算并显示消费额及余额。

  • 管理中心的管理员监视每一笔消费,可打印出消费情况的相关统计数据。


请设计系统用例图,组件图,组件时序图,部署图。


用例图

组件图


组件时序

一、注册缴费时序图


二、收款时序图


三、监视打印时序图


部署图


作业二 学习总结


第一周。

从 JD 开始,架构师这个名词一下子变得具体。

架构师不光是一个 title,而是由一系列责任和事务组成的。

架构师需要的能力,需要做哪些工作,怎样才能做好,需要补足自己的哪些短板,需要从哪些方面去锻炼,有了一个比较真实的全景图。


复习了 UML 的各种知识点。

UML 是理解疑难,帮助沟通,记录的工具。

不同的图有不同的目标读者。

不在于其“形”,而在于所需要沟通的目标对象。

架构文档原来这么重要,可以说是架构师立身之本。


做技术也许需要务虚才能走得更好。

但务需先务实。


第二周命题作业

作业一


1. 请描述什么是依赖倒置原则,为什么有时候依赖倒置原则又被称为好莱坞原则?


依赖倒置 Dependency Inversion:高层模块不应该依赖低层模块。两者之间应该通过抽象来互相依赖。抽象不因该依赖实现细节。实现细节应该依赖抽象。

例如,Tomcat 服务器和部署在 Tomcat 服务器中的应用程序没有直接的依赖关系,两者通过一个具体的抽象(Java Servlet 规范)来相互依赖。Servlet 规范不依赖服务器和应用的实现细节,Tomcat 服务器和应用程序依赖 Servlet 规范。


好莱坞原则 Don't call me; I'll call you.

软件开发中常把控制反转 IOC(Inversion of Control)称作好莱坞原则。IOC 也是框架概念的精髓。其中,“控制”是指对整个程序执行流程的控制,“反转”指使用框架之后,整个程序的流程不再由程序自己来控制,而是交由框架负责。流程的“控制”权从开发应用的程序员“反转”到了框架。


两者概念有相通之处,但强调的重点似乎又略有差异:依赖倒置强调的是通过“约定”来解耦模块之间的强依赖,使得不同层次的开发可以分别进行,而这个约定可以大到规范,也可以小到接口定义;控制反转更偏向实现的细节,如框架实现中常见的模板模式,Junit 中的 setup 扩展点,Java list 中的 add 重载等。


2. 请用接口隔离原则优化 Cache 类的设计,画出优化后的类图。


优化后:


  • 将客户端相关的操作抽象出接口 CacheAccessable,暴露给应用程序

  • 将系统管理相关的操作抽象出接口 CacheConfigurable,暴露给系统远程调用

  • Cache 服务实现 CacheAccessable 和 CacheConfigurable

  • 应用程序只能通过 CacheAccessable 进行 Cache 进行存取

  • 系统远程调用可以通过 CacheConfigurable 对 Cache 进行 rebuild

作业二:学习总结


第二周框架设计。


从程序开发的历史开始,推导出编程的实质,即:将现实中的领域问题进行分析和抽象,得到对应的模型,再通过编程语言将模型实现成为软件。从抽象程度的演进给 OOP 夯实了地基。

面向对象编程是利用多态性进行编程。

面向对象分析将领域问题进行对象分析。

面向对象设计目的在于高内聚、低耦合,从而演化出了各种设计原则、设计模式、框架以及工具来负载达到这个目的。


面向对象设计的基本原则:SOLID

  • SRP 单一职责原则:

  • 一个类只负责完成一个职责或者功能。不要设计大而全的类,要设计粒度小、功能单一的类。单一职责原则是为了实现代码高内聚、低耦合,提高代码的复用性、可读性、可维护性。

  • OCP 开闭原则:

  • 软件体应该是对于扩展开放,对修改封闭。

  • 添加一个新的功能应该是在已有代码基础上扩展代码(新增模块、类、方法等),而非修改已有代码(修改模块、类、方法等)。

  • L 里氏替换原则:认为“程序中的对象应该是可以在不改变程序正确性的前提下被它的子类所替换的”的概念。

  • I 接口隔离原则:认为“多个特定客户端接口要好于一个宽泛用途的接口”的概念。

  • DIP 依赖倒置原则:认为一个方法应该遵从“依赖于抽象而不是一个实例”的概念。


Flower 框架

分布式异步框架具有巨大的价值,但其上手门槛较高。Flower 框架提供了一个很好的简化开发的切入点。


第三周命题作业

作业一 使用组合设计模式编写程序,打印输出窗口


代码:

package main
import ( "log")
type element interface { print()}
type attributes struct { elementType string name string}
func (a attributes) print() { log.Println("print " + a.elementType + "(" + a.name + ")")}
type button struct { attributes}
type picture struct { attributes}
type Label struct { attributes}
type textBox struct { attributes}
type passwordBox struct { attributes}
type frame struct { attributes subElements}
func (f *frame) print() { f.attributes.print() f.subElements.print()}
func (f *frame) add(e element) { f.elements = append(f.elements, e)}
type window struct { attributes subElements}
type subElements struct { elements []element}
func (s *subElements) add(e element) { s.elements = append(s.elements, e)}
func (s subElements) print() { for _, e := range s.elements { e.print() }}
func (w *window) print() { w.attributes.print() w.subElements.print()}
func newWinForm() *window { instance := &window{ attributes{ "WinFrom", "WINDOW窗口", }, subElements{}, }
instance.subElements.add(picture{attributes{"Picture", "LOGO图片"}}) instance.subElements.add(button{attributes{"Button", "登录"}}) instance.subElements.add(button{attributes{"Button", "注册"}})
f := &frame{attributes{"FRAME", "FRAME1"}, subElements{}} f.subElements.add(Label{attributes{"Lable", "用户名"}}) f.subElements.add(textBox{attributes{"TextBox", "文本框"}}) f.subElements.add(Label{attributes{"Lable", "密码"}}) f.subElements.add(passwordBox{attributes{"PasswordBox", "密码框"}})
instance.add(f) return instance}
func main() { log.SetFlags(0) winForm := newWinForm() winForm.print()}
复制代码


输出:

print WinFrom(WINDOW窗口)print Picture(LOGO图片)print Button(登录)print Button(注册)print FRAME(FRAME1)print Lable(用户名)print TextBox(文本框)print Lable(密码)print PasswordBox(密码框)
复制代码


作业二 学习总结


第三周,常见设计模式以及代码重构。

本周课程中涉及到一些比较常见的设计模式,意识到之间学习设计模式过程中的一些遗漏点:设计模式的待解问题的总结整理。

Panthera 项目的重构案例:非常生动地展示了在项目中灵活使用设计模式、以及应用面向对象原则,能够带来的、对于功能开发、代码维护的巨大价值。


课程中涉及的内容:

工厂模式:

  • 简单工厂

  • 对简单工厂改进:

  • 根据类名反射构造(client 不符合开闭原则、编译安全丢失、只能默认构造函数构建)

  • 配置文件读取实现类名反射构造(编译安全丢失、只能默认构造函数构建


单例模式:

  • 饿汉式

  • 懒汉式(注意多线程使用)


配饰器模式:

  • 将不兼容的接口转换为可兼容的接口


Junit 中:

模板模式:

  • 模板方法模式在一个方法中定义一个算法骨架,并将某些步骤推迟到子类中实现。模板方法模式可以让子类在不改变算法整体结构的情况下,重新定义算法中的某些步骤。


策略模式:

  • 定义一族算法类,将每个算法分别封装起来,让它们可以互相替换。通过“组合”实现扩展。可以用策略工厂“”查表“”来移除 if-else 分支。


组合模式:

  • 将一组对象组织(Compose)成树形结构,以表示一种“部分 - 整体”的层次结构。


装饰器模式:

  • 被装饰类与装饰类实现同样的接口,实现嵌套和增强。不改变对客户端的接口。


Spring 中:

  • 依赖注入 DI

  • 控制反转 IoC

  • MVC 模式


Panthera 重构过程中使用装饰器和模板模式将面条代码转换成职责单一、易扩展的代码架构:

  • 装饰器模式实现语法点转换器的拆分和分离

  • 模板模式在父类实现定义了 log 等包装

  • 模板模式在生成器父类实现了前序、节点、后序生成器流程的定义


第四周命题作业

作业一 一个典型的大型互联网应用系统使用了哪些技术方案和手段,主要解决什么问题?请列举描述。

从分层模型分析大型互联网应用主要技术方案

根据以往的一些学习和经历,结合老师提到的分层模型,整理现代大型互联网应用可能使用的技术手段以及解决方案。

前端/用户层架构

* App 架构

* Native App

* iOS 原生

* Android 原生

* 跨平台 App

* Reactive Native

* Flutter

* Hyprid App 架构

* 组件化、 容器化:将超级 App 拆分成众多组件,各个组件根据规范独立开发、上线。

* 组件化:静态发布,随 App 统一上线

* 容器化:动态发布,容器加载更新发布的组件

* 适合具有相当复杂度的应用,如手机淘宝、微信

* Web 浏览器端开发架构

* HTML5/CSS3 /ES/WebSocket

* Vue.js/AngularJS/React/ 等 Web 框架

* 小程序架构

* 微信小程序

* H5 等

* CDN

* 内容分发、内容路由、内容交换、性能管理

* 静态资源缓存 通过 CDN + 小文件存储服务 实现文件服务、图片服务

* 跨域

* Nginx 代理跨域

* WebSocket 跨域

* 消息推送:iOS 和 Android 阵营相应的消息推送服务

* DNS 域名解析

* 客户端服务发现

* DNS 预解析

网络层、应用层架构

* 网关架构

* 用户管理

* SSO、授权登录

* KeyClock

* 负载均衡

* DNS 地理级别负载均衡

* F5、LVS、Nginx:百万级、十万级、5 万级负载均衡

* 使用云厂商提供的负载均衡:

* 阿里云 SLB

* UCloud ULB

* AWS Elastic Load Balancing

* 业务层架构

* 子系统拆分

* 业务域:通过网关统一对外服务

* 服务网关

服务层、开发层架构

* 开发框架

* Java SSH/Spring MVC

* Ruby on Rails

* Python Django

* PHP ThinkPHP

* Web 服务器

* Java Tomcat, JBoss

* PHP/Python Nginx

* 微服务框架、RPC 接口框架

* Dubbo 分布式服务框架

* Spring Cloud

* gRPC (跨语言 IDL)

* Thrift (跨语言 IDL)

* Quarkus

* Micronaut

* 应用容器化

* Docker

* 容器调度 Kubernetes

* 容器化服务治理 Istio

* 配置中心:集中管理各系统的配置

* etcd (无管理界面)

* Apache Zookeeper

* spring-cloud-config

* 蚂蚁金服 disconf

* 携程 Apollo

* Alibaba Nacos

* 服务中心

* 服务 Naming Service:服务注册、发现、路由

* Netflix Eureka

* etcd

* HashiCorp Consul

* Apache Zookeeper

* Alibaba Nacos

* 服务 Bus System:服务总线系统、负责服务之间的请求调用与交互

* 消息队列

* RocketMQ

* Kafka

* ActiveMQ

* 分布式缓存

* memcache

* Redis

* 分布式数据一致性

* 分布式锁

* Zookeeper、Apache Curator

* Redis RedLock

* 数据库实现分布式锁

* 分布式事务

* 分布式一致性协议

* 2PC、3PC、TCC、Paxos、Raft、ZAB

* 阿里 Seata (TCC、SAGA、XA)

* TiDB

* 流量控制:流量控制、流量整形、熔断降级、系统自适应保护、热点防护

* Sentinel

* Spring Cloud Gateway

* Zuul

* Netflix Hystrix

存储层架构

* 分布式关系数据库

* MySQL Router

* 百度的 DBProxy

* 淘宝 TDDL

* 360 Atlas

* 淘宝 UMP

* TiDB

* CockroachDB

* 分布式 NoSQL

* Memcache

* Redis

* MongoDB

* Apache Cassandra

* 分布式大文件存储

* 淘宝 云梯

* 腾讯 TDW

* 小文件存储

* HBase

* Hadoop

* Hypertable

* FastDFS

* 淘宝 TFS

* 京东 JFS

* Facebook Haystack

* MinIO

后台架构

* 大数据平台

* Hadoop 集群:HDFS、Hive、Spark、HBase

* 流式计算:Storm、Flink、Spark Streaming

* 批计算:MapReduce、Spark

* 资源管理:Yarn

* 搜索引擎

* Lucene

* ElasticSearch

* 推荐引擎

* 数据仓库

* Hive

* Spark SQL

* 运维平台、监控平台

* 配置

* 机器管理

* IP 地址管理

* 虚拟机管理

* 自动化部署 (可以考虑与所采用微服务框架、容器化相关的解决方案)

* 包管理、版本管理

* 灰度发布管理

* 回滚支持

* 日志、监控 (可以考虑与所采用微服务框架、容器化相关的解决方案)

* 线上数据收集、监控

* ELK、Prometheus、Zabbix、Open Falcon、Grafana

* CAT、Zipkin、Jaeger、SkyWalking、Pinpoint

* 应急处理

* 停止应用

* 下线故障机器

* 切换 IP

* 测试平台

* 用例管理

* 资源管理

* 任务管理

* 测试数据管理

* 管理平台(权限管理)

* 身份认证

* 权限控制

数据中心机房架构

*往往需要互联网企业根据自己的需求和实际情况进行设置和自研*

* 多机房

* 同城多机房:应对断电等区域灾难事件

* 跨城多机房

* 应对洪水、地震、大规模断电等极端灾难事件

* 强一致性要求的数据如支付宝余额等,无法做到跨城异地

* 跨国多机房

* 可以服务不同地区的用户

* 可以实现只读业务的多活

* 多中心:多中心同时对外提供服务;业务自动切换

安全架构

* 功能安全:预防常见的安全漏洞和风险(常见的 XSS 攻击、CSRF 攻击、SQL 注入等)

* 防火墙隔离网络、区域访问控制策略

* 运营商流量清洗

作业二 学习总结


本周的学习从互联网系统面对的问题;随着用户规模的增长,互联网架构的演化;常见架构模式;技术框架等几个方面切入了系统架构的主题。几个案例,特别是老师自己的案例非常生动,有现实感。


本周讨论的内容可能是大多数一线架构师最直接面对的工作:为解决业务需求,选择最合适的系统的架构方案。但同时,市面上日新月异的技术和选择项太多,也对架构师不断了解新技术、新方案、新趋势提出了很大的挑战,需要架构师不断地投入时间来学习和积累,才能在需要的时候,更快地找到正确的方向。


第五周命题作业

作业一

  1. 用你熟悉的编程语言实现一致性 hash 算法。

  2. 编写测试用例测试这个算法,测试 100 万 KV 数据,10 个服务器节点的情况下,计算这些 KV 数据在服务器上分布数量的标准差,以评估算法的存储负载不均衡性。

作业:

https://github.com/rayzer/go-playground/tree/master/alg/consistentHash

作业二 学习总结

本周覆盖的系统架构内容:

  1. 缓存

  • 缓存在高性能架构的重要性是无与伦比的

  • 这个主题中总结的很好的是影响命中率的指标的部分:

  • 缓存键集合大小

  • 缓存可使用内存空间

  • 缓存对象生命时间

  • 不适合使用缓存的情况:

  • 频繁修改的数据

  • 没有访问热点

  • 数据不一致与脏读

  • 以及,在系统中设计缓存架构的几个设计需要注意的方面:

  • 缓存穿透:对缓存中不存在数据的处理;对耗费大量计算资源的缓存的处理

  • 缓存雪崩:更新锁保证只有一个线程更新缓存;后台系统更新缓存

  • 缓存热点:多份副本分散热点导致单个缓存服务器的压力


  1. 消息队列

  • 消息队列是构建异步调用架构的关键

  • 通过消息队列可以达到这些好处:

  • 实现异步处理,提升处理性能

  • 更好地伸缩性

  • 削峰填谷

  • 失败隔离和自我修复

  • 解耦

  • 另外:将网状结构变为结构更清晰的线性结构

  • 常见的消息队列产品有 RabbitMQ、ActiveMQ、RocketMQ、Kafka

  • 如果业务对消息的可靠性、时序、事务性要求较高时,需要深入研究这些方案。


  1. 负载均衡架构

  • 定义

  • 种类:

  • HTTP 重定向负载均衡

  • DNS 负载均衡

  • 反向代理负载均衡 Nginx

  • IP 负载均衡 F5、LVS

  • 数据链路层负载均衡 (硬件、LVS)

  • 响应内容不经过负载均衡服务器(三角模式),降低负载均衡服务器的带宽和计算压力

  • 算法

  • 负载均衡集群环境中如何处理服务状态问题


这周内容的知识点很多,也很重要。如果讲解的过程或者 ppt 中理出一个大致的课程框架,说明课程会从哪些方面剖析这个问题,也许就更好了。


第六周命题作业

作业一

  1. 请简述 CAP 原理。

C: 一致性(Consistency)。对某个指定的客户端来说,读操作保证能够返回最新的写操作结果。

A:可用性(Availability)。非故障的节点在合理的时间内返回合理的响应(不是错误和超时的响应)。

P:分区容忍性(Partition Tolerance)。当出现网络分区后,系统能够继续履行职责。


在分布式系统中,"一致性、可用性、分区容错性" 最多满足其二。必选满足 P 的前提下,A 和 C 必须二选一,即只能选择 AP 或者 CP。


CAP 的落地:

  • CAP 是忽略网络延迟的。

  • 正常运行情况下(没有出现分区),不存在 CP 和 AP 的选择,可以同时满足 CA。

  • 放弃 A 或者 C 不是说什么都不做,而是要为分区恢复之后做准备,如记录日志等。


  1. 针对 Doris 案例,请用 UML 时序图描述 Doris 临时失效的处理过程(包括判断系统进入临时失效状态,临时失效中的读写过程,失效恢复过程)。


Doris 临时失效处理过程:


作业二 学习总结

本周学习内容:

  1. 分布式关系数据库

  2. MySQL 传统主备、主主方案

  3. 数据分片

  4. 分布式数据库中间件

  5. Amoeba

  6. Cobar

  7. 集群伸缩

  8. CAP 原理

  9. NoSQL

  10. Cassandra

  11. HBase

  12. 搜索引擎

  13. 搜索引擎整体架构

  14. 爬虫系统架构

  15. 文档矩阵与倒排索引

  16. Lucene 架构

  17. ElasticSearch 架构、集群扩容

  18. Doris KV Engine

  19. 产品需求、目标、技术指标

  20. 逻辑架构

  21. 关键技术点

  22. 产品规划


体会:脚踏实地、以小见大。


第七周命题作业


作业一

性能压测的时候,随着并发压力的增加,系统响应时间和吞吐量如何变化,为什么?


随着并发压力的增加,系统表现可以分为三个阶段:

  1. 性能测试阶段:随着并发数据量增加,吞吐量不断上升;系统响应时间较短,在系统设计的范围内,随着系统压力的增大,逐渐缓慢上升。

  2. 负载测试阶段:系统仍处于系统设计的可承受范围内,吞吐量上升至最高点;响应时间逐渐上升。系统中的某种或多种资源占用已呈饱和状态。

  3. 压力测试阶段:在负载的最高点继续增加压力,超过系统设计容量,系统的处理能力逐渐下降,体现为响应时间极速增加,吞吐量下降,直至系统呈现崩溃失去响应能力。


作业二 学习总结

本周对我比较帮助的内容:锁的比较整理、阿里全链路压测、性能优化分层模型。

  1. 性能测试

  • 指标:

  • 响应时间

  • 并发数:系统能够同时处理请求的数目。

  • 吞吐量:指单位时间内系统处理的请求的数量。TPS,QPS

  • 性能计数器:System Load,线程数,进程数,CPU、内存、磁盘、网络使用率

  • 测试方法:

  • 三个阶段:

  • 性能测试

  • 负载测试

  • 压力测试

  • 稳定性测试

  1. 全链路压测

  • 数据构造

  • 数据隔离

  • 流量构造

  • 全链路压测平台化


  1. 性能优化

  • 不能优化一个没有测试的软件

  • 不能优化一个你不了解的软件

  • 一般方法:

  • 性能测试,获得性能指标

  • 指标分析,发现性能与资源瓶颈点

  • 架构与代码分析,寻找性能与资源瓶颈关键所在

  • 架构与代码优化,优化关键技术点,平衡资源利用

  • 性能测试,进入性能优化闭环

  • 优化的分层思想:

  • 机房与骨干网络性能优化

  • 服务器与硬件性能优化

  • 操作系统性能优化

  • 虚拟机性能优化

  • 基础组件性能优化

  • 阿里巴巴用 Jetty7.1.5 替代 JBOSS4.0.5GA

  • 软件架构性能优化

  • 三板斧:缓存、异步、集群

  • 软件代码性能优化

  • 并发编程,多线程与锁

  • 资源复用,线程池与对象池

  • 异步编程,生产者消费者

  • 数据结构,数组、链表、hash 表、树


  1. 操作系统

  • 临界区:多个线程访问共享资源的这段代码被称为临界区,解决线程安全问题的主要方法是使用 锁,将临界区的代码加锁,只有获得锁的线程才能执行临界区代码。

  • 避免阻塞引起的崩溃

  • 限流:控制进入计算机的请求数,进而减少创建的线程数。

  • 降级:关闭部分功能程序的执行,尽早释放线程。

  • 反应式:异步;无临界区(Actor 模型)


  • CAS

  • 锁状态

  • 偏向锁

  • 轻量级锁

  • 重量级锁

  • 多 CPU 下的锁

  • 总线锁

  • 缓存锁

  • 公平锁、非公平锁

  • 可重入锁:某个线程已经获得某个锁,可以再次获取锁而不会出现死锁

  • 独享锁/互斥锁

  • 共享锁:可以被多个线程所持有;共享数目

  • 读写锁

  • 乐观锁、悲观锁

  • 分段锁

  • 自旋锁


第八周命题作业


作业一

有两个单向链表(链表长度分别为 m,n),这两个单向链表有可能在某个元素合并,也可能不合并,如下图所示的这样。现在给定两个链表的头指针,在不修改链表的情况下,如何快速地判断这两个链表是否合并?如果合并,找到合并的元素,也就是图中的 x 元素。

请用代码(或伪代码)描述算法,并给出时间复杂度。


  • 方法一 Brute Force,时间复杂度 O(m*n)

func getIntersectionNode(headA, headB *ListNode) *ListNode {	if headA == nil || headB == nil {		return nil	}	a := headA	b := headB	for a != nil {		for b != nil {			if a == b {				return a			}			b = b.Next		}		a = a.Next		b = headB	}	return nil}
复制代码


  • 方法二 HashMap,时间复杂度 O(m+n)

func getIntersectionNodeViaMap(headA, headB *ListNode) *ListNode {	if headA == nil || headB == nil {		return nil	}	visited := make(map[*ListNode]bool)	for a := headA; a != nil; a = a.Next {		visited[a] = true	}	for b := headB; b != nil; b = b.Next {		if _, ok := visited[b]; ok {			return b		}	}	return nil}
复制代码


  • 方法三 2 Pointers,时间复杂度 O(m+n)

func getIntersectionNodeViaTwoPointers(headA, headB *ListNode) *ListNode {	if headA == nil || headB == nil {		return nil	}	a, b := headA, headB	for a != b {		if a != nil {			a = a.Next		} else {			a = headB		}
if b != nil { b = b.Next } else { b = headA } } return a}
复制代码


作业二 学习总结


这周学习比较偏重基础,主要帮助我复习了:

  • 文件和硬盘 IO

  • 常见的数据结构

  • 经典算法

  • 网络通信

  • NIO



第九周命题作业


作业一


  • 设计一个秒杀系统,主要的挑战和问题有哪些?核心的架构方案或者思路有哪些?


挑战:

  • 瞬间高并发导致 带宽耗尽

  • 瞬间高并发导致 服务器崩溃

  • 瞬间高并发导致 数据库瘫痪


思路:

1. 明确架构目标

  • 需要支持的并发数

  • 是否使用原系统,提高原有系统承载能力

  • 是否使用单独系统

2. 设计架构方案

  • 静态化减轻后端服务器压力

  • 采用 JS 自动更新技术将动态页面转化为静态页面

  • 通过控制商品列表,判断秒杀开始与否,防止提前秒杀

  • 并发控制、防秒杀器减轻无效服务器压力

  • 设置阀门,只放最前面的一部分人进入秒杀系统(三道阀门)

  • 只允许部分用户(如 1000)进入秒杀页面

  • 只允许部分用户(如 100)进入下单页面

  • 只允许部分用户(如 50)进入支付系统

  • 秒杀页面 URL 随机,在秒杀前放出,1000 次访问上限

  • 下单页面只能通过秒杀页面进入,100 次访问上限

  • 简化流程:

  • 砍掉不重要的分支流程,如下单页面的所有数据库查询

  • 以下单成功作为秒杀成功标志。支付流程只要在 1 天内完成即可。

3. 技术优化:

  • 后端优化:

  • 操作系统调优

  • Web Server 调优

  • 系统优化:

  • 减少数据库操作

  • 减少流程

  • 内存缓存

  • JVM 优化等

  • 前端优化:根据 YSLOW 原则提升页面响应速度

  • 图片合并

  • 内容压缩

  • CSS 精简

  • 避免发送 Cookie

4. 设计应急预案

1. 域名分离、独立域名

2. 备用服务器

3. 失效情况下保关键业务

4. 出错页面

5. 根据方案、准备资源、部署系统

1. 准备服务器资源

2. 准备带宽

1. 资源出口带宽(图片服务器集群处理能力)

2. CDN

6. 根据秒杀系统运行情况总结优化方案

作业二:学习总结

本周主要研究了三个部分:

  • JVM

  • Java 代码优化

  • 如何设计秒杀系统




第十周命题作业

作业一

关于微服务架构(中台架构、领域驱动设计、组件设计原则),你有什么样的思考和认识?


首先,不同的项目会适合不同的开发模式:

  • 业务比较简单的系统,适合贫血模式的传统开发模式。

  • 业务复杂的系统开发,适合基于充血模型的 DDD 开发模式。


CURD 的开发模式,一开始显得清晰明了,易于理解。但随着系统的生命周期,逐渐变得复杂,代码也越来越混乱。我司大型系统的一些业务模块就有这样的问题。

DDD 的开发模式,需要更多的前期调研,理清楚所有的业务,定义领域模型所包含的属性和方法。领域模型相当于可复用的业务中间层。


其次,前期基于 CURD 模式开发的业务模块,在后期维护开发的过程中,特别是在加入一些特别重要的功能,或者在进行比较大的改动时,其实可以估算一些 effort,按照 DDD 的概念对业务领域进行一些梳理,在架构、项目周期允许的情况下,进行一些合理的重构。比如,将一些业务逻辑抽离到领域对象中。即使没有整个项目按 DDD 模式来组织,这种小步的改进依然会对系统的维护性带来帮助。


课程中提到的组件设计原则,回想起来应该是在《Clean Code》中第一次看到清晰的整理,都是一些非常实用好用的经验之谈。内聚原则 REP、CCP、CRP,耦合原则无依赖循环、依赖稳定、稳定抽象,在设计大型的、多模块的系统时值得多加考虑,有助于减少后续开发和维护成本。我司有一个被广泛依赖的核心模块,如果在设计之初能够采用稳定抽象原则剥离接口,也许可以减少不少后期由于安全升级所导致的、需要所有依赖模块进行升级的开销。


中台架构在于能力共享, 为业务服务,是需要根据业务演进逐渐积累、抽离而成的。我司是产品型公司,因此,对中台的应用在现实中不是很多;但中台架构在互联网、运营类企业中开展得如火如荼,其存在不可谓没有道理。也有不同的着重方向和演化:如业务中台、数据中台,还发展出了技术中台、研发中台、移动中台、AI 中台、算法中台、组织中台等等。


而微服务架构是中台架构的重要支持技术,中台是微服务的升级。这种场景下,联系 DDD 模式也许能在系统架构设计,模块划分,后期业务能力重用发挥更大的作用。

作业二:学习总结

本周围绕微服务架构探讨了:

  • 常见微服务框架

  • 微服务架构实践

  • 组件设计原则

  • DDD

组件设计原则、DDD 案例启发很大。


第十一周命题作业

作业一

导致系统不可用的原因有哪些?保障系统稳定高可用的方案有哪些?


导致系统不可用的原因有:

  • 硬件故障:磁盘坏道等

  • 软件 bug

  • 系统发布:发布错误的版本

  • 并发压力:超出系统能够支持的压力

  • 网络攻击:DDoS

  • 外部灾害:水灾、地震、大范围停电


保障系统稳定高可用的方案有:

  • 通过架构手段解耦:

  • 高内聚、低耦合

  • 隔离

  • 业务与子系统隔离

  • 微服务与中台架构

  • 生产者消费者隔离

  • 虚拟机与容器隔离

  • 备份

  • 计算高可用:通过增加更多服务器来达到计算高可用

  • 主备

  • 主从

  • 集群

  • 存储高可用:将数据复制到多个存储设备,通过数据冗余的方式来实现高可用

  • 主备复制

  • 主从复制:双机切换

  • 主主复制

  • 支持失效转移 failover

  • 数据库、负载均衡

  • 异步、无状态的服务,对接口级故障进行:

  • 降级:将某些业务或者接口的功能降低,可以是只提供部分功能,也可以是完全停掉所有功能。

  • 熔断:应对依赖的外部系统故障,不再请求故障服务

  • 限流:只允许系统能够承受的访问量进来,其余拒绝

  • 排队:不拒绝用户,用户需要等待,使用 Kafka 等消息队列来缓存用户请求

  • 幂等:保证服务重复调用和调用一次产生的结果相同

  • 重试:允许重试调用

  • 事务补偿:事务管理,通过执行业务逻辑逆操作,使事务回滚到事务前状态

  • 异地多活架构:

  • 同城异区

  • 跨城异地

  • 跨国异地

  • 通过运维手段

  • 持续发布:自动化测试、自动化部署

  • 持续部署

  • 持续集成

  • 持续交付

  • 持续部署

  • 预发布验证:在预发布服务器上进行功能验证

  • 代码版本控制

  • 自动化发布

  • 灰度发布

  • 运营监控

  • 监控数据采集

  • 用户行为日志收集

  • 服务器性能监控

  • 业务运营数据报告

  • 监控管理

  • 报警

  • 自动处理故障

  • 自动失效转移

  • 自动扩容

  • 自动限流

  • 通过安全架构:

  • 在实现中进行防御,如加密技术等

  • 使用应用防火墙

  • 定期进行安全漏洞扫描

  • 网络安全配置

作业二:学习总结


本周学习主要围绕安全架构和高可用架构进行梳理。故障案例分析非常经典。




第十二周命题作业

作业一

分析如下 HiveQL,生成的 MapReduce 执行程序,map 函数输入是什么?输出是什么,reduce 函数输入是什么?输出是什么?

INSERT OVERWRITE TABLE pv_users SELECT pv.pageid, u.ageFROM page_view pvJOIN user uON (pv.userid = u.userid);
复制代码
  • map 函数输入:表 page_view、表 user 的内容

page_view


user


  • map 函数输出:以 userid 为 key 的键值对



  • reduce 函数输入:map 函数输出经过 Shuffle 后,相同 key 集中在一起的结果


  • reduce 函数输出:pageid 对应 age


作业二:学习总结


本周主要学习了:

  • 大数据应用

  • HDFS 存储

  • MapReduce 分布式计算架构

  • Yarn 资源调度框架

  • Hive SQL 转换成 MapReduce 计算


第十三周命题作业

作业一

Google 搜索引擎是如何对搜索结果进行排序的?


PageRank 利用网页之间的关联关系(超链接)来确定网页的影响力权重。如果一个页面被各种其它页面引用,特别是被“重要”的网站和页面引用,这就说明这个页面的权重更高。

  • 如果 A 页面包含 B 页面的链接,则认为 A 页面给 B 页面投了一票。

  • 假设 ABCD 四个页面,PR(A) = PR(B)/B 页面外链数 + PR(C)/C 页面外链数 + PR(D)/D 页面外链数

  • 随机跳出率 1-a=0.15

  • N 个网页的 某一页面的 PageRank 计算公式

  • 对全世界网页排名,一开始将所有页面的 PageRank 值设为 1,带入上面公式计算,每个页面都得到一个新的 PageRank 值。再把这些新的 PageRank 值带入上面的公式,继续得到更新的 PageRank 值,如此迭代计算,直到所有页面的 PageRank 值几乎不再有大的变化。

  • 根据 PageRank 排序显示结果。

作业二:学习总结

本周主要学习了

  • Spark

  • 流式计算

  • HiBench

  • 大数据引擎、互联网常用指标、数据可视化图表

  • 机器学习常见算法


大作业

作业一










作业二

注:内容太多折叠了部分内容。


用户头像

Ray

关注

还未添加个人签名 2007.07.05 加入

还未添加个人简介

评论

发布
暂无评论
「架构师训练营第 1 期」命题作业