这里是一些简单的笔记,主要是为了构建知识体系以及方便查找,以后会分点详细撰文。
前端
- HTML/CSS/JavaScript
- 框架:Vue、Backbone、jQuery、LESS
- 构建工具:Webpack、Gulp、Grunt
- 其他:NodeJS
数据交互
HTTP
- HTTP 1.0/1.1
- 建立在 TCP 协议之上,处于计算机网络中的应用层
- 瓶颈及其优化技巧都是基于 TCP 协议本身的特性
- 区别在于长连接支持、多路复用、带宽节约与数据压缩等
- 连接无法复用、队头阻塞、协议开销大和安全因素等多个缺陷
- HTTP/2
- 将请求和响应数据分割为更小的帧,并且它们采用二进制编码。
- 通过多路复用、二进制流、Header 压缩与 Server Push 等技术,极大地提高了性能
- 使用多路复用,一般来说同一域名下只需要使用一个 TCP 连接。在出现丢包的情况下,整个 TCP 都要开始等待重传,也就导致了后面的所有数据都被阻塞了。但是对于 HTTP/1.1 来说,可以开启多个 TCP 连接,出现这种情况反到只会影响其中一个连接,剩余的 TCP 连接还可以正常传输数据。
- HTTP/3
- Google 就自己架起炉灶搞了一个基于 UDP 协议的 QUIC 协议,并且使用在了 HTTP/3 上,HTTP/3 之前名为 HTTP-over-QUIC
数据格式
- protobuf123:smaller,faster,simpler
- Apache Thrift、Apache Avro
- json:{}
- xml:<tag><\tag>
接口规范:
- 响应报文:code、msg、data
- 请求数据:参数
- 参数校验:正则表达式
api:RESTful风格
- GET获取一个资源;POST添加一个资源;PUT修改一个资源;DELETE删除一个资源
- HTTP状态码:200 OK;400 Bad Request;500 Internal Server Error
服务发现
- erueka
- 在一个微服务应用中,一组运行的服务实例是动态变化的,实例有动态分配的网络地址,因此,为了使得客户端能够向服务发起请求,必须要要有服务发现机制。
- 客户端发现:客户端直接 查询服务注册表;服务端发现:客户端通过路由发起请求
- zookeper
RPC
rpc轮子
同步异步阻塞
- 概念:
- 同步:A调用B,此时只有等B有结果了才返回。
- 异步: A调用B,B立即返回,无须等待。当B处理完之后会通过通知或者回调函数的方式来告诉A结果。
- 阻塞:A调用B,A会被被挂起,一直在等待B的结果,什么事都不能干。
- 非阻塞:A调用B,自己用被挂起等待B的结果,可以去干其他的事情。
- java
Java中的IO模型有三种,分别是BIO(同步阻塞IO),NIO(同步非阻塞IO),AIO(异步非阻塞IO)
后端
框架
- JAVA:Spring/SpringMVC/SpringBoot/SpringCloud
- C++:性能最佳
- GO:iris、Revel、beego、buffalo、echo、gin
- https://blog.csdn.net/dev_csdn/article/details/78740990
- PHP:Laravel、Yii、Symfony、ThinkPHP、Codeigniter
- python:Django、Flask、Tornado、Aiohttp
- Tomcat:java服务器;apache:html服务器;Nginx:替代apache
数据库
- mysql、mariadb
- ORM:MyBatis封装jdbc,用xml执行语句,解除sql语句与代码的耦合;hibernate
- Redis:key-value数据库,数据库缓存,二级缓存改善用户体验
- 散列分库
- 读写分离:主数据库提供写操作,从数据库提供读操作,写操作后再同步两个数据库
- 关系型数据库满足ACID
- 纵向扩展横向扩展,关系型横向扩展:主从复制(读写分离)、集群(多个实例)、分片(分表分库)
- 分布式系统满足CAP定理
- key-value是nosql的一种,Memcached使用内存,Redis对数据进行了持久化,pika基于rocksdb上面兼容了redis的协议,解决的是用户使用 Redis 的内存大小超过 50G、80G 等等这样的情况
演进
- 单体数据库
- 读压力变大后:读写分离,主从同步;主库写从库读,读可水平扩展
- 写压力变大后:垂直分库;按照业务拆分,避免或减少跨库访问
- 水平分库(sharding):数据量越来越大
消息队列
- 耦合两个系统,提高系统吞吐率
- 可以根据一定的规则订阅读取请求
- kafka解决大量日志的传输问题
- 点对点通讯
- 异步处理
搜索
雪崩,熔断,降级
- 一个服务失败,导致整条链路的服务都失败的情形,我们称之为服务雪崩
- 服务熔断和服务降级就可以视为解决服务雪崩的手段之一
- 服务熔断:当下游的服务因为某种原因突然变得不可用或响应过慢,上游服务为了保证自己整体服务的可用性,不再继续调用目标服务,直接返回,快速释放资源。如果目标服务情况好转则恢复调用。
- 一般使用断路器模式
- 当下游的服务因为某种原因不可用,上游主动调用本地的一些降级逻辑,避免卡顿,迅速返回给用户!
- 开关降级、限流降级、熔断降级
构建与环境
构建工具:
- make:makefile,linux原始
- ant:xml,思路类似make, init/compile/build/test;没办法管理依赖
- maven:xml,给每个包都标上坐标,这样,便于在仓库里进行查找
- gradle:groovy,构建任务添加log
开发环境:
- pro环境:生产环境,面向外部用户的环境,连接上互联网即可访问的正式环境。
- pre环境:灰度环境,外部用户可以访问,但是服务器配置相对低,其它和生产一样。
- test环境:测试环境,外部用户无法访问,专门给测试人员使用的,版本相对稳定。
- dev环境:开发环境,外部用户无法访问,开发人员使用,版本变动很大。
基础架构
指标
- RPS(Requests Per Second):系统在单位时间内(每秒)处理请求的数量。
- QPS(Query Per Second):是指在一定并发度下,服务器每秒可以处理的最大请求数。
- 服务器平均请求处理时间 = 1/QPS(秒)
- 平均等待时间 = 1/(QPS/并发度) = 并发度/QPS(秒)。
对策
- 百RPS——升级机器配置
- 千RPS——各组件拆分并优化
- 万RPS——水平扩展
- 十万、百万、千万RPS——终极拆分及扩展
大型系统设计
- 描述使用场景、约束和假设、
- 创造一个高层级的设计
- 设计核心组件
- 度量设计
优秀架构师应该具备
- 格局
这个系统的定位是什么?它能创造什么核心价值?
这个系统的背景是什么?-- 为什么以前不做,现在要上?是因为业务发展到了一定规模?还是开发资源现在有多余,没事可干?
这个系统在整个组织架构中,处于什么位置?跟这个系统关联的其它系统目前什么状况?
产品经理如何看待这个系统?技术老大如何看?
这个系统的需求,是处于比较确定、比较清晰状态?还是有很大灰度空间?很多核心点,大家还没想清楚?
这个系统所用的技术体系,是比较老?还是最新的?
业界类似的系统,人家是如何做的? - 历史观-技术血脉
任何一种技术,都不是谁吃饱了没事干凭空想象出来的,它一定是要解决某个特定问题。而这个特定问题,一定有它的历史背景:是因为之前的技术,在解决这个特定问题上,解决的不够好、或者有其它副作用,所以才发明了这个新技术。
- 抽象能力
每个需求的合理性?
这个系统的领域模型是什么样的?
这个系统是应该在旧的上面改造?还是应该另起炉灶?
这个系统可以分成几期,分期实施?
这个系统要拆分成几个子系统?
每个子系统又拆分出多少个模块?
系统的表设计?api接口设计?job的设计?系统之间的消息传输? - 深入思考的能力、技术的深度
- 业务架构 vs. 技术架构 vs. 基础架构
基础架构:这个很容易理解,IDC、云平台、网络、分布式存储、数据库、消息中间件、SOA中间件、缓存、监控系统、大数据计算平台
技术架构:为了支撑某类业务,强调系统的“高性能“,“高并发“,“高可靠”、强一致性等。
业务架构:同样是为了支撑某类业务,但和技术架构的侧重点不同。业务架构强调的是对“领域”的深刻理解,这通常和“领域专家“密切相关,这里可能会强调系统的“可扩展性”,“可复用性”,对需求的弹性应对。
自底往上,基础架构、技术架构、业务架构并不是相互独立的,一般都是“业务驱动技术”,2者在互相促进中,同时往深度、广度上发展。 - 组织架构与领导力
合理的团队,组织架构应该是根据业务的架构来拆分的,业务一直在发展,业务的架构也会一直迭代,组织架构也跟着迭代;
架构集成能力
- 任何一个项目初期,尽可能选定较高的技术层级,仅在底层系统不满足某些关键技术指标时,才考虑向下替换;
- 应避免系统提供的能力涉及多个层次,即使需要如此,也应尽量分成多个解耦的子系统。
高并发处理
高并发问题原因是因为系统中有单点瓶颈,扩容无法继续满足,到最底层实际主要是数据库的问题,因为数据库能承载的并发是有限的。
可以有以下几种方案:
- 系统拆分,不同业务的库分开
- 增加缓存,降低访问数据库的比例
- 消息队列,削峰填谷
- 分库、分表、读写分离,降低单库访问量
服务框架的演进趋势
- 服务框架正在演变成新的“操作系统”
- 学习曲线:Exponential Rise(渐进式) → Sigmoid(阶跃式)
- 风格:配置 → 约定 → DSL → 容器器化
- 业务代码与框架代码的关系:Is-a → Has-a → Duck-typing
- 工具链:IDE → 代码⽣生成器 → 编译器
其他
- 热闹驱动开发(Hype Driven Development,HDD)
- gossip as a service
- docker、kubernetes
- 技术选型
- 微服务架构
- 网页浏览的步骤
- DNS解析
- 浏览器缓存
- hosts
- 域名解析服务器
- 根域服务器
- 1-4某步骤得到ip后就返回浏览器
- 对获得的ip发起TCP请求,从本机的1024<随机端口<65535到服务器的80端口
- 负载均衡:将用户分摊到两个或多个服务器上的方法叫负载均衡,balancer and worker
- web服务器
- 浏览器渲染
- DNS解析
- SOA是Service Oriented Architecture的缩写,面向服务架构
如何快速熟悉一个新项目
- 源码位置、部署环境:所谓项目,其实就是一堆代码放在了一堆机器上而已
- 从页面到数据库
- 了解项目间的关系
- 整理数据库表,整理Controller层的所有接口
- 深入代码层
- 通过交互对自身数据库进行增删改查操作
- 通过定时任务或服务器脚本对自身数据库进行增删改查操作
- 调用或通知其他服务做一些事情
从零开始搭建创业公司后台技术栈
从零开始搭建创业公司后台技术栈
系统设计入门
系统设计入门
性能之殇:从冯·诺依曼瓶颈谈起
性能之殇:从冯·诺依曼瓶颈谈起
- 乐观给了我们很多的好处,总结起来就是一句话:以微小的性能损失换来大幅的性能提升
- 分布式计算来源于人们日益增长的性能需求与落后的 x86 基础架构之间的矛盾。恰似设计模式是面向对象对现实问题的一种妥协
- 信息传递的瓶颈最表层是人类的硬件制造水平决定的,再往底层去是冯·诺依曼架构决定的,再往底层去是图灵机的逻辑模型决定的
高并发的哲学原理
高并发的哲学原理
- 运维的核心价值不在于资源的扩充,而在于资源的隔离。
- 高并发系统通用设计准则
- 负载均衡
- 缓存技术
- 异步处理
- 消息队列
- 数据库优化
- 水平扩展
- 服务隔离
- 软件也重新定义了运维,k8s成为新的标准运营环境
- 在架构上,微服务系统的需求是不会变的,所以 Spring Cloud 和 Kubernetes 有着几乎一一对应的解决方案
- Go 语言在设计上有如下几个优势:
- 并发模型:基于 CSP(Communicating Sequential Processes)理论,使用 goroutines 和 channels 达成了高并发任务的高效率调度和处理。
- 垃圾回收:并发垃圾回收机制,提高垃圾回收效率,使用写屏障技术减少锁使用,提高程序性能。
- 编译优化:编译器在编译阶段进行多种优化操作,减少资源消耗,提高运行速度。
- 内存管理:自动内存管理,减轻程序员负担,减少内存泄漏等问题。
- 标准库:丰富的标准库提供高度优化的函数和类型,提高开发效率,保证程序性能。
- Goroutine 拥有如下这些专门的设计来达成超高性能:
- 并发执行:Goroutine 可以在多个 CPU 核心上并发执行,充分利用多核处理器的性能。通过在操作系统层面进行调度,Goroutine 可以在不同的核上运行,从而实现真正的并行计算。
- 栈空间:Goroutine 的栈空间非常小,通常只有 2KB 左右。这使得大量的 Goroutine 可以在内存中同时存在,而不会因为栈空间的分配和回收导致性能下降。
- 上下文切换开销小:Goroutine 的上下文切换开销非常小,因为它们在同一个操作系统线程中运行。当一个 Goroutine 阻塞时,其他 Goroutine 可以继续执行,而不需要等待阻塞的 Goroutine 完成。这避免了传统线程模型中的忙等待问题,提高了程序的执行效率。
- 简单易用:Goroutine 的使用非常简单,只需要在函数调用前加上关键字 go 即可创建一个 Goroutine。这使得开发者可以轻松地编写高并发的代码,而不需要关心复杂的线程同步和互斥问题。
- 内置调度器:Go 语言内置了一个调度器(scheduler),负责对 Goroutine 进行调度和管理。调度器使用了一种称为 M:N 调度的技术,将多个 Goroutine 分配到多个操作系统线程上执行。这种调度策略可以在保证程序执行顺序的同时,最大限度地利用多核 CPU 的全部计算资源。
- 缓存和队列的架构意义
- 缓存的本质是用一致性换取读取性能
- 队列的本质将关键操作从同步改为异步
- 消息订阅-架构解耦对高并发系统架构的决定性影响
- Kafka 分布式消息订阅系统
其它
《架构整洁之道》书中提到:一个软件系统存在的意义,是系统用来赚钱或省钱的那部分代码,那才是整个系统的皇冠明珠。所以,当拿到一个需求的时候,首先考虑的是要解决什么问题,它的问题域是什么,而不是先考虑用哪种技术去实现或解决这个问题,这是本末倒置的处理方法。
在一个应用研发过程中,很多时候设计只有一次,就像电影导演说电影是遗憾的艺术,因为没有办法在去修改,有了问题也只能看着,因为电影已经发行。
spring boot 建表 jpa mybatis
反应式编程https://juejin.im/post/5b3a22a16fb9a024db5ff13e
zookeep + dubbo
@Primary @Component @Service
@Autowire @Resource
@Async
各语言内存模型
spring网络请求工具
lambda in java8
websocket统计同时在线人数
异步请求的切面:动态代理的切面不能被正确地加载在异步请求中
避免使用sublist:https://www.cnblogs.com/whatarewords/p/8086844.html
guava cache; caffine : https://www.cnblogs.com/mawang/p/6756192.html
java 完全教程
wrk安装
redis 是怎么存储查找的:效率,底层数据结构
java类库怎么设计
https://www.cnblogs.com/liqiu/p/3302607.html
java中的ArrayList 、List、LinkedList、Collection关系详解
java教程
https://www.mkyong.com/tutorials/spring-boot-tutorials/
https://inneka.com/programming/java/why-does-jackson-2-not-recognize-the-first-capital-letter-if-the-leading-camel-case-word-is-only-a-single-letter-long/
不能只有一个小写字母开头,序列化的时候会出现问题
解决问题的能力 + 学习能力
https://mp.weixin.qq.com/s/o5kX0rfpWmDardxcfwo4wA
软件技术人员能力模型
https://gist.github.com/mcfog/70411189992cee788f15c21f68bba1ae