架构师技术栈—知识(精编版)
2022-08-05 15:17:21 3 举报
AI智能生成
架构师学习技术栈理论知识精编版
作者其他创作
大纲/内容
实现了Collection接口
List接口特性:是有序的,元素是可重复的
允许元素为rull
List集合基础
底层结构为数组,初始容量为0,每次增长2倍
它是线程同步的,已被ArrayList替代
Vector
底层结构是双向链接
实现了Deque接口,因此可以像操作栈和队列一样操作即可
线程非同步
LinkedList
底层结构是数据,初始容量为0,每次增长1.5倍
ArrayList
常用的子类
List
set接口特性:无序的,元素不可重复
底层大多数是Map结构的实现
常用的三个子类都是非同步的
set集合基础
底层数据结构是哈希表(一个元素为链表的数组)+红黑shu
实际是封装了HashMAP
元素无序,可以为null
HashSet
底层数据结构由哈希表(一个元素为链表的数组)和双向链表组成
父类是HashMAP
实际为LinkedHashMAP
元素可以为null
LinkedHashSet
底层实际上是一个TreeMap实例(红黑树)
可以实现排序的功能
元素不能为null
TreeSet
常用子类
set
Collection
存储的结构是Key-value键值对,不像Collection是单列集合
阅读Map前最好知道什么是散列表和红黑树
基础知识
底层是散列表+红黑树,初始容量为16,装载因子为0.75,每次扩容2倍
非同步
散列表容量大约64且链表大于8时,转成红黑树
Key的哈希值会与该值的高16位做异或操作,进一步增加随机性
当散列表的元素大于容量装载因子时,会再散列,每次扩容2倍
如果hashCode相同,key不同则替换元素,否则就是散列冲突
HashMAP
底层逻辑列表+红黑树+双向链表,父类是HashMAP
提供插入顺序和访问顺序两种,访问瞬息是符合LRU算法的,一般用于扩展(默认是插入顺序)
迭代与初始容量无关(迭代的是维护的双向链表)
大多使用HashMAP的API,只不过在内部重写了某些方法,维护了双向链表
LinkedHashMAP
底层是红黑树,保证了时间复杂度为log(n)
可以对其进行排序,使用Comparator或者Comparable
只要compare或者CompareTo认定该元素相等,那就相等
自然排序(动手排序),元素不能为null
TreeMap
底层是散列表+红黑树,支持高并发操作
key和Value都不能为null
线程是安全的,利用CAS算法和部分操作上锁实现
get方法是非阻塞,无锁的,重写Node类,通过volatile修饰next来实现每次获取都是最新设置的值
在高并发环境下,统计数据(计算size.....等等)是无意义的,下一时间size值就会变化
ConcurrentHashMap
子类
Map
集合
加载
验证
准备
解析
链接
初始化
过程
创建实例
静态方法
静态字段
反射
初始化子类
main方法
类加载条件
先找父类
父类无,继续向下查找
ClassNotFoundException
双亲委派
给定一个类名,加载一个雷,返回代表这个类的Class实例,如果找不到,则返回异常
loadClass
如果给定的字节码流b定义一个类,off表示位置,len表示长度,该方法只有子类可以使用
defineClass
查找一个累,也是只能子类试用,这是重载classLoader时,最重要的系统扩展点
findClass
同样,这个方案也只有子类能够只用,他会去寻找已经加载的类,这个方法是final方法,无法被修改
findLoadedClass
ClassLoader主要方法
Bootstrap
sun.misc.Launcher$ExtClassLoader
sun.misc.LauncherSAPPClassLoader
自定义加载器用于加载一些特殊途径的类,一断也是用户程序类
自定义加载类
哪些类加载器
SPI
上下文类加载器
重写类加载器逻辑
类加载器的缺陷和补充
jstack看不到死锁信息
光加载死锁
类加载
堆
虚拟机栈
本地方法栈
方法区(永久代)
常量池
程序技术器
直接内存
内存布局
标记清除法
复制算法
标记整理算法
分代收集算法
算法
引用计数
可达性分析
哪些内存需回收
finalize方法
什么时间回收
如何回收问题
GC任务
Serial串行收集器
ParNew并行收集器
Parallel Scavenge
CMS收集器
垃圾处理器
只收集eden的GC
YGC
等同于Full GC
old GC
Full GC
Mixed GC
GC种类
GC
jvm
充分利用多核CPU的运算能力
方便业务拆分
优点
频繁的上下文切换
线程安全(常见的避免死锁的方式)
缺点
同步VS异步
并发VS并行
阻塞VS非阻塞
临界区VS临界资源
易混淆的概念
并发编程的优缺点
集成Thread类
实现Runnable接口
实现Callable或Runnable接口,FutureTask
如何新建线程
NEW
RUNNABLE
WAITING
TIMED-WAITNG
TERMINATED
BLOCKED
线程状态的转换
interrupt
sleep
join
yield
线程的基本操作
守护线程Daemon
线程的状态和基本操作
并发基础
JMM内存模型
重排序
happens-before
内存语义
内存语义的实现
并发理论
synchronized
volatile
final
三大性质
并发关键字
Lock与synchronized
设计意图
如何使用AQS实现自定义同步组件
可重写的方法
AQS提供的模板方法
AQS
同步队列的数据结构
独占式锁
共享式锁
AQS源码解析
ReentrantLock
ReentrantReadWriteLock
Condition机制
LockSupport
Lock体系
并发容器
线程池
原子操作类
JUC工具
并发
JAVA基础
非数值型程序设计中数据的组织方式及其处理的算法
线性结构
层次结构
网状结构
4种基本逻辑结构
顺序存储
链式存储
索引存储
散列存储
4种基本存储结构
类型相同的数据
通过下标访问,顺序存储
内存连续性
大小固定
写入需要移动元素,效率慢
数组
单链表
双向链表
循环链表
链表
跳跃表的每一层都是一条有序的链表
跳跃表的查找次数近似于层数,时间复杂度为0,插入删除也为0
最底层的链表包含所有元素
跳跃表是一种随机化的数据结构
跳跃表的空间复杂度为0
特性
由于元素是有序的,可以通过增加一些路径来加快查找速度
查找
插入
删除
跳表
无序树:树中任意节点的子结点之间没有顺序关系
有序树:树种任意节点的子结点之间有顺序关系,这种树成为二叉树;
二叉树:每个节点最多含有两个子树的树成为二叉树
满二叉树:叶节点除外的所有节点均含有两个子树
完全二叉树:除最后一层外,所有层都是满节点,且最后一层缺右边连续节点的二叉树
哈夫曼树:带权路径最短的二叉树
树
先进后出
栈
先进先出
队列
通常是一个可以被看做一棵树的数组对象。堆的决堤实现一般不通过指针域,而是通过构建一个一维数组与二叉树的父子结点进行对应,因此对总是一颗完整的二叉树
hash散列表
图
含义
数据结构
六大原则
创造型
结构型
行为型
J2EE模式
设计模式
数据设计模式
直接setnx
setnx设置一个过期时间
set nx ex
set nx ex增加一个事务id
set nx +事务id+lua
redlock
redis分布式锁
临时顺序节点
zk分布式锁
分布式锁
ACID(更多指数据库事务层面)
数据库事务
CAP理论
BASE理论
分布式理论
两阶段提交(2PC)
三阶段提交(3PC)
补偿事务(TCC)
本地消息表
可靠事件模式(消息队列)
Sagas事务模型(最终一致性)
最大努力通知方案
解决方案
分布式事务
分布式应用
一般用来实现部署在不同机器上的系统之间的方法调用,使得程序能够像访问本地系统资源一样,通过网络传输去访问远端系统资源
定义
Client Code
Serialization/Deserialization
Stub Proxy
Transport
Server Code
组成部分
RPC
是将对象的状态信息转换成为可存储或传输的形势过程
序列化
是序列化的逆过程,将字节数组反序列化为对象,把字节序列恢复为对象的过程
反序列化
序列化实现
服务注册中心
Zookeeper
注册中心
阻塞
非阻塞
同步
异步
I/O模型
Streams字节流
Writer/Reader字符流
字节流/字符流对比
java I/O
缓冲区(Buffer)
通道(Channel)
Selector选择器
NIO
Netty
应用
底层通信
将请求按照某种策略分布到多台机器上,使得系统能够实现横向扩展,是应用实现可伸缩性的关键技术
目的
分布式服务架构中实现负载均衡是通过软件算法来实现的,有别于基于硬件设备实现负载均衡
分布式服务框架中,负载均衡是在服务消费端实现的
原理
软负载的实现原理
获取服务列表大小范围内的随机数,将该随机数作为列表索引,从服务提供列表中获取服务提供者
随机
在随机算法的基础上针对权重做了处理。首先根据加权数放大服务提供者列表,比如服务提供者A加权数为3,放大之后变为A,A,A,存放在新的服务提供者列表,然后对新的服务提供者列表应用随机算法
加权随机
将服务调用请求按顺序轮流分配到服务提供者后端服务器上,均衡对待每一台服务提供者机器
依次按顺序获取服务提供者列表中的数据,并使用计数器记录使用过得数据索引,若数据索引到最后一个数据,则计数器归零,重新开始新的循环
轮询
首先根据加权数放大服务提供者列表,再在放大后的服务提供者基础上使用轮询算法获取服务提供者
加权轮询
利用请求来源的IP的hashcode对服务提供者列表大小取模,得到服务提供者列表索引,从而获取服务提供者
使用调用方ip地址的hash值,将服务列表大小取模后的值作为服务列表索引,根据该索引取值
源地址hash
负载均衡算法
负载实现
服务注册与发现
软负载
服务质量监控与服务指标数据采集
服务分组路由
服务依赖关系分析
服务降级
服务权重调整
服务调用链路跟踪
记录负责人
服务治理内容
服务分组路由实现原理
简单服务依赖关系分析实现
服务调用链路跟踪实现原理
实现
服务治理
基础
分布式架构
两个相同的repo:repo1和repo2,有修改合并
git diff 的使用方法:创建:git diff 【commit sha1 id】 【commit sha1 id】 > 【diff文件名】打入:git apply 【diff文件名】
一是用git diff生成的UNIX标准补丁.diff文件
创建:git format-patch HEAD^ // 最后一次提交补丁git format-patch HEAD^^ // 最后两次提交补丁git format-patch -1 // 最后一次提交补丁git format-patch -2 // 最后两次提交补丁 打入:git am 【diff文件名】
二是git format-patch生成的Git专用.patch 文件。
GIT打补丁
git
maven
idea
jekins
sonarQube
Nginx是一个 轻量级/高性能的反向代理Web服务器,他实现非常高效的反向代理、负载平衡,他可以处理2-3万并发连接数,官方监测能支持5万并发,现在中国使用nginx网站用户有很多,例如:新浪、网易、 腾讯等。
异步非阻塞事件处理机制:运用了epoll模型,提供了一个队列,排队解决
Nginx性能这么高?
http服务器。Nginx是一个http服务可以独立提供http服务。可以做网页静态服务器。
虚拟主机。可以实现在一台服务器虚拟出多个网站,例如个人网站使用的虚拟机。
反向代理,负载均衡。当网站的访问量达到一定程度后,单台服务器不能满足用户的请求时,需要用多台服务器集群可以使用nginx做反向代理。并且多台服务器可以平均分担负载,不会应为某台服务器负载高宕机而某台服务器闲置的情况。
Nginx应用场景?
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端某个服务器宕机,能自动剔除故障系统。upstream backserver { server 192.168.0.12; server 192.168.0.13; }
1 轮询(默认)
weight的值越大分配到的访问概率越高,主要用于后端每台服务器性能不均衡的情况下。其次是为在主从的情况下设置不同的权值,达到合理有效的地利用主机资源。upstream backserver { server 192.168.0.12 weight=2; server 192.168.0.13 weight=8; }
2 权重 weight
每个请求按访问IP的哈希结果分配,使来自同一个IP的访客固定访问一台后端服务器,并且可以有效解决动态网页存在的session共享问题upstream backserver { ip_hash; server 192.168.0.12:88; server 192.168.0.13:80; }
3 ip_hash( IP绑定)
必须安装upstream_fair模块。对比 weight、ip_hash更加智能的负载均衡算法,fair算法可以根据页面大小和加载时间长短智能地进行负载均衡,响应时间短的优先分配。upstream backserver { server server1; server server2; fair; }
4 fair(第三方插件)
必须安装Nginx的hash软件包按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,可以进一步提高后端缓存服务器的效率。upstream backserver { server squid1:3128; server squid2:3128; hash $request_uri; hash_method crc32; }
5、url_hash(第三方插件)
Nginx负载均衡的算法怎么实现的?策略有哪些?
Nginx
互联网工程
yahoo的前端分析浏览器插件
YSlow
firefox的插件
firebug
动态跟踪工具,能够快速定位和发现耗时方法
btrace
JVM启动增加参数:-verbose:gc -Xloggc:/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps
GC日志分析
查看是否启用慢日志
show variables like 'log_slow_queries'
查看慢于多少秒的SQL会记录到日志
show variables like 'long_query_time'
日志地址
log_slow_queries = /var/log/mysql/mysql-slow.log
慢于多少秒记录
long_query_time=1
my.cnf
数据库慢查询
寻找性能瓶颈
请求次数
-n
并发数
-c
ab [options] [http[s]://]localhost[:port]/path
ab:ApacheBench
使用JMeter进行压测的时候,可以使用jconsole、VisualVM等工具查看CPU和内存使用情况
JMeter
HP
商业未开源
LoadRunner
upstream
nginx调整负载权重
反向代理引流
请求复制工具,将在线请求复制到测试机器,模拟真实环境
运行在线上,用来捕获在线请求数据包
TCPCopy Client
运行在线下测试机,用来截获响应包,并将响应包的头部信息传递给TCPCopy Client,以完成TCP交互
TCPCopy Server
TCPCopy
性能测试工具
设置http头中的Cache-Control
设置http头中的Expires
浏览器缓存
页面压缩
CSS放在页面最上面
js放在最下边
合理布局
减少数据量
静态资源独立域名
减少cookie传输
合并css
合并js
合并图片
减少Http请求
浏览器访问优化
缓存静态资源,如图片、文件等
CDN加速
反向代理
js、css等文件独立部署,使用专门的域名
动静分离
用户上传,独立部署
图片服务
提供页面缓存
DNS负载均衡
DNS
WEB前端
削峰
加快响应速度
异步操作
使用集群
新建线程异步获取数据,执行完一段逻辑后,使用线程对象的get()方法可获取线程内的执行结果,如未获取到,则线程阻塞
Future模式
Selector 非阻塞IO机制
单例模式
对象池
资源复用
当可运行的线程大于CPU数量,则正在运行的某个线程可能就会被挂起,增加调度开销
尽可能的缩短锁持有的时间
将使用单独锁保护多个变量变为采用独立的锁分别进行保护
减少锁的粒度
放弃使用独占锁,使用读写锁
锁竞争激烈也会导致上下文切换频繁
减少上下文切换
代码优化
堆heap
与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
方法区(Method Area)/永久代(PermGen)
是一块较小的内存空间,它的作用可以看做是当前线程所执行的字节码的行号指示器。
程序计数器(Program Counter Register)
存储线程上下文信息,如方法参数、局部变量等
与程序计数器一样,Java虚拟机栈(Java Virtual Machine Stacks)也是线程私有的,它的生命周期与线程相同。虚拟机栈描述的是Java方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧(Stack Frame)用于存储局部变量表、操作栈、动态链接、方法出口等信息。每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
JVM栈(JVM Stacks)
与虚拟机栈所发挥的作用是非常相似的,其区别不过是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的Native方法服务。
本地方法栈(Native Method Stacks)
总结:方法区和堆是所有线程共享的内存区域;而Java栈、本地方法栈和程序计数器是运行是线程私有的内存区域。
JVM内存结构
对象优先分配在Eden区,如果Eden区没有足够的空间时,虚拟机执行一次Minor GC。
大对象直接进入老年代(大对象是指需要大量连续内存空间的对象)。这样做的目的是避免在Eden区和两个Survivor区之间发生大量的内存拷贝(新生代采用复制算法收集内存)
长期存活的对象进入老年代。虚拟机为每个对象定义了一个年龄计数器,如果对象经过了1次Minor GC那么对象会进入Survivor区,之后每经过一次Minor GC那么对象的年龄加1,知道达到阀值对象进入老年区。
动态判断对象的年龄。如果Survivor区中相同年龄的所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象可以直接进入老年代
对象分配规则
新建对象总是在该区创建,当空间满,触发Young GC,将还未使用的独享复制到From区,Eden区则清空
Eden Space
当Eden区再次用完,再触发Young GC,将Eden和From区未使用的对象复制到To区
From
当Eden区再次用完,触发Young GC,将Eden和To区未使用的对象复制到From区,如此反复
To
新生代
经过多次Young GC,某些对象会在From和To多次复制,如果超过某个阈值对象还未释放,则将该对象复制到老年区。如果老年区空间用完,就会触发Full GC
老年代
JVM垃圾回收
串行收集器是最古老,最稳定以及效率高的收集器,可能会产生较长的停顿,只使用一个线程去回收。
-XX:+UseSerialGC 串行收集器
Serial收集器
ParNew收集器其实就是Serial收集器的多线程版本,新生代并行,老年代串行;新生代复制算法、老年代标记-压缩
-XX:+UseParNewGC ParNew收集器
-XX:ParallelGCThreads 限制线程数量
ParNew收集器
Parallel Scavenge收集器类似ParNew收集器,Parallel收集器更关注系统的吞吐量
-XX:+UseParallelGC 使用Parallel收集器+ 老年代串行(并行收集器)
Parallel收集器
Parallel Old是Parallel Scavenge收集器的老年代版本,使用多线程和“标记-整理”算法
-XX:+UseParallelOldGC 使用Parallel收集器+ 老年代并行(并行老年代收集器)
Parallel Old 收集器
CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器
-XX:+UseConcMarkSweepGC 使用CMS收集器(并发收集器)
-XX:+ UseCMSCompactAtFullCollection Full GC后,进行一次碎片整理;整理过程是独占的,会引起停顿时间变长
-XX:+CMSFullGCsBeforeCompaction 设置进行几次Full GC后,进行一次碎片整理
-XX:ParallelCMSThreads 设定CMS的线程数量(一般情况约等于可用CPU数量)
空间整合,G1收集器采用标记整理算法,不会产生内存空间碎片。分配大对象时不会因为无法找到连续空间而提前触发下一次GC。
可预测停顿,这是G1的另一大优势,降低停顿时间是G1和CMS的共同关注点,但G1除了追求低停顿外,还能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为N毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒,这几乎已经是实时Java(RTSJ)的垃圾收集器的特征了。
特点
G1收集器
垃圾回收器
-Xmn:年轻代大小
-XX:NewRatio=n:设置年轻代和年老代的比值。如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4
-XX:SurvivorRatio=n:年轻代中Eden区与两个Survivor区的比值。注意Survivor区有两个。如:3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5
堆设置
-XX:+PrintGC
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-Xloggc:filename
垃圾回收统计信息
GC优化
JVM
Tomcat使用线程来处理接收的每个请求。这个值表示Tomcat可创建的最大的线程数。默认值150
maxThreads
指定当所有可以使用的处理请求的线程数都被使用时,可以放到处理队列中的请求数,超过这个数的请求将不予处理。默认值10
acceptCount
Tomcat初始化时创建的线程数。默认值25
minSpareThreads
一旦创建的线程超过这个值,Tomcat就会关闭不再需要的socket线程。默认值75
maxSpareThreads
是否反查域名,默认值为true。为了提高处理能力,应设置为false
enableLookups
网络连接超时,默认值60000,单位:毫秒。设置为0表示永不超时,这样设置有隐患的。通常可设置为30000毫秒
connnectionTimeout
保持请求数量,默认值100。 bufferSize: 输入流缓冲大小,默认值2048 bytes
maxKeepAliveRequests
压缩传输,取值on/off/force,默认值off。 其中和最大连接数相关的参数为maxThreads和acceptCount。如果要加大并发连接数,应同时加大这两个参数
compression
div class=\"mind-clipboard\" style=\
32G 内存配置示例:
tomcat线程优化
应用服务器
RAID
存储算法
HDFS分布式文件系统
关系型数据库
NoSQL
分布式缓存
文件存储
存储性能优化
高性能
消毒:特殊字符进行转译
HttpOnly:对于存放敏感信息的cookie,可通过对该Cookie添加HttpOnly属性
防御
反射型:发布带攻击的链接
持久型:将攻击信息存到服务器数据库中
分类
XSS跨站脚本攻击
SQL注入
OS注入
消毒:特殊字符转译
参数绑定:sql预编译和参数绑定
注入攻击
核心:利用了浏览器的Cookie或服务器Session策略
表单Token
验证码
Referer check
将cookie设置为HttpOnly
CSRF跨站点请求伪造
基于TCP的三次握手,攻击者伪造大量IP地址给服务器发送SYN报文,导致服务器接收不到客户端的ACK,服务器需要分配资源来维护本次握手,并不断重试。当等待队列占满后,服务器不再接收新的SYN请求。
SYN Flood
向被攻击的服务器发送海量的域名解析请求
DNS Query Flood
基于HTTP协议发起,通过控制大量肉鸡和互联网上大量的代理,模拟正常用户给网站发起请求,直到网站拒绝服务。
从应用层发起,与网站的业务紧密相连,使防守方进行过滤的时候进行大量的误杀,真正业务无法处理。
CC
DDoS
程序内部错误,浏览器打印堆栈信息
Error Code
注释显示在客户端,给黑客攻击造成便利
Html注释
利用文件上传功能上传可执行程序,进而控制服务器
文件上传
在请求的URL中使用相对路径,遍历未开放的目录及文件
路径遍历
其他攻击手段
ModSecurity,开源
SiteShell
深信服
防火墙
MD5
SHA-1
单向散列加密(摘要算法)
加密与解密使用同一个密匙,远程通信的密匙交换是难题
56位
DES
3DES
AES-128
AES-192
AES-256
AES
RC
对称加密
位数越大,加解密速度越慢
算法RSA
信息安全传输:公钥加密,私钥解密
发送发:将内容生成摘要,再用私钥将摘要进行加密生成数字签名,最后将数字签名和原文内容传输给接收方。
接收方:将原文内容采用相同的摘要算法生成摘要,再用公钥将数字签名解密成发送方的摘要,最后将两个摘要对比即可确认真伪。
MD5withRSA
SHA1withRSA
数字签名(不可抵赖):私钥加密,公钥解密
Java的数字证书管理工具
keytool
进行证书的签发与证书链的管理
OpenSSL
证书管理
数字证书
非对称加密
加解密
安全性
负载均衡进行故障转移
同IP会话黏滞
session服务器
redis共享session
集群的session管理
高可用应用
核心服务优先使用更好的硬件
不同级别的服务需要隔离,避免故障连锁反应
分级管理
超时后,通信框架抛出异常,程序选择继续重试或失效转移
超时设置
消息队列
防止关联的服务互相影响
异步调用
拒绝低优先级应用的调用,减少服务调用并发数
随机拒绝
拒绝服务
关闭部分不重要的服务
关闭服务内部部分不重要的功能
关闭功能
基于Java的信号量机制:Semaphore
调用超时次数超过阈值,自动降级,后续来的流量直接拒绝,等超过休眠时间点,再次对服务进行重试
实施方式
重复调用和调用一次必须保证结果相同
幂等性设计
保证核心业务异地多活
核心数据最终一致性
采用多种手段同步数据
保证大部分用户的异地多活
异地多活机房
高可用服务
数据失效转移机制
CAP
ACID
BASE
高可用数据
数据备份
主备复制
主从复制
主主复制
数据集群
分布式事务算法
高可用存储
工具:selenium
接口性能工具:Jmeter,loadrunner
自动化测试
数据采集
监控管理
Linux命令
监控
高可用
降低模块间的耦合性提高模块的复用性分层和分割,以消息传递和依赖调用聚合成完整系统
核心思想:模块化
分布式队列
分布式服务
扩展性
不同功能物理分离
相同功能集群伸缩
网站架构伸缩
DNS域名解析负载均衡,缺点是失效转移存在一定的时效性
NGINX,七层负载,5万/每秒
反向代理(应用层负载均衡)
LVS,四层负载,80万/每秒
数据链路层负载均衡
LVS可以以连接数来判断
Nginx可以以HTTP请求数来判断
负载最低优先
响应最快,性能最优
性能最优
原地址散列(哈希)
负载均衡器
一致性性Hash算法
分布式缓存集群
读写分离
不同业务部署在不同的集群
分库
单表拆分,存在多个库中
支持数据分片的中间件:Cobar,缺点是只能在单一数据库实例上处理查询请求,无法执行跨库的Join操作
分片
关系型数据库集群
以HRegion为单位进行管理
HBase
NoSql
数据存储服务器集群
伸缩性
响应时间(Response Time)
单位时间内处理的请求数量
吞吐量(Throughput)
每秒响应请求数。在互联网领域,这个指标和吞吐量区分的没有这么明显
每秒查询率QPS(Query Per Second)
同时承载正常使用系统功能的用户数量
并发用户数
常见指标
增强单机硬件性能
提升单机架构性能,例如:使用Cache来减少IO次数,使用异步来增加单服务吞吐量,使用无锁数据结构来减少响应时间
垂直扩展,提升单机处理能力
增加服务器数量,就能线性扩充系统性能
反向代理层的水平扩展,是通过“DNS轮询”实现的
站点层的水平扩展,是通过“nginx”实现的
服务层的水平扩展,是通过“服务连接池”实现的(注册中心)
数据库水平拆分方式
LVS
HAProxy
负载均衡
水平扩展(Scale Out)
如何提升并发
高并发
性能分析
inotify机制
日志收集
ActiveMQ-CPP
异步传输
实时分布式流处理系统
Storm
实时处理
MySql
高可用,高性能,可伸缩的列存储系统,支持数据表自动分区
Hbase
Memcahe
MapReduce
Hive SQL
无需提供实时访问,通过如下工具进行分析与挖掘
HDFS
存储
A方案
节点上采集原始数据,发送给Collector
Agent
Collector
数据解析与归档
ETL
数据分析
PigLatin,MapReduce(任务)
页面展示
HICC
Chukwa
B方案
输出JVM虚拟机进程的一些信息,可以列出虚拟机当前执行的进程,并显示其主类和进程的ID
jps
对虚拟机各种运行状态进行监控的工具,可以查看虚拟机的类加载和卸载情况,管理内存的使用和垃圾收集等信息
jstat
查看应用程序的配置参数,以及打印运行JVM时所指定的JVM参数
jinfo
生成虚拟机当前快照信息,线程快照是当前虚拟机每一个线程正在执行的方法堆栈的集合
jstack
用来查看等待回收对象的队列,查看堆的概要信息,包括采用的哪种GC收集器,堆空间的使用情况,以及通过JVM参数指定的各个内存空间的大小。
可以dump当前堆快照,并使用Memory Analyzer分析
jmap
命令
开源的Java程序动态跟踪工具,动态查看程序运行的细节,方便对程序进行调试
BTrace
JDK内置的图形化性能分析工具,对运行的java程序的性能及资源消耗情况进行分析和监控,提供可视化的图表对相关数据进行展现
JConsole
堆分析工具,能够快速找到占用堆内存空间最大的对象
Eclipse插件,亦可独立客户端运行
Memory Analyzer(MAT)
功能十分强大,通过插件组装,可完成:内存监控、GC监控、应用程序分析、线程分析、堆dump分析、CPU,以及内存抽样、BTrace跟踪等。
vi catalina.sh找到如下内容“#—–Execute The Requested Command”,在其上添加以下配置,后重启tomcat```CATALINA_OPTS=\"$CATALINA_OPTS-Dcom.sun.management.jmxremote-Djava.rmi.server.hostname=192.168.23.1-Dcom.sun.management.jmxremote.port=9999-Dcom.sun.management.jmxremote.ssl=false-Dcom.sun.management.jmxremote.authenticate=false```
远程配置方式
重点推荐使用
VisualVM
故障排查
不做宅男
成为自由职业者
假装自己能成功;
打造自身品牌:坚持写博客;
有效管理时间以提升效率;
学会理财:要善于炒股炒房(炒股在中国可能不算理财算赌博);
不要刷爆信用卡(这个问题可能美国人比较严重);
少看电视多运动,争取练成肌肉男。
如何和产品/测试互怼
软技能
什么是重构
程序员对代码所做的为了满足短期利益代码改动,或再没有完全清楚整个架构下的改动,都很容易是代码失去它的清晰结构,偏离需求或设计。而这些改动的积累很容易使代码偏离它原先设计的初衷而变得不可理解和无法维护。
Refactoring则帮助重新组织代码,重新清晰的体现结构和进一步改进设计。
改进软件的设计
容易理解的代码可以很容易的维护和做进一步的开发。即使对写这些代码的程序员本身,容易理解代码也可以帮助容易地做修改。程序代码也是文档。而代码首先是写给人看的,然后才是给计算机看的。
提高代码质量,更易被理解
Refactoring是一个code review和反馈的过程。在另一个时段重新审视自己或别人代码,可以更容易的发现问题和加深对代码的理解。
Refactoring是一个良好的软件开发习惯。
Refactoring帮助尽早的发现错(Bugs)
Refactoring对设计和代码的改进,都可以有效的提高开发速度。好的设计和代码质量是提高开发速度的关键。在一个有缺陷的设计和混乱代码基础上的开发,即使表面上进度较快,但本质是延后了对设计缺陷的发现和对错误的修改,也就是延后了开发风险,最终要在开发的后期付出更多的时间和代价。
项目的维护成本远高于开发成本。
Refactoring可以提高开发速度
为什么重构
代码太混乱,设计完全错误。与其Refactor,不如重写。
永远不要做Last-Minute-Change。推迟Refactoring,但不可以忽略,即使已经正式发布的代码都正确的运行。
明天是DeadLine
Refactoring的工作量显著的影响最后期限
何时不该重构?
重构可以从很大程度上去辅助设计,通常情况下我们的设计不是能贯穿我们软件开发的全过程的,在这个过程中,我们的需求变更的可能性非常大,当需求变了,设计也得变,但是我们已有的实现怎么办?全部废除?显然不能!这时候就要依靠重构来解决这种设计的矛盾
重构与设计
关于重构,有一个常被提出的问题:它对程序的性能将造成怎样的影响?为了让软件易于理解,你常会作出一些使程序运行变慢的修改。这是个重要的问题。我并不赞成为了提高设计的纯洁性或把希望寄托于更快的硬件身上,而忽略了程序性能。已经有很多软件因为速度太慢而被用户拒绝,日益提高的机器速度亦只不过略微放宽了速度方面的限制而已。但是,换个角度说,虽然重构必然会使软件运行更慢,但它也使软件的性能优化更易进行。关键在于自己的理解,当你拥有了重构的经验,你也就有能力在重构的基础上来改进程序的性能。
重构与性能
那么真正要实现重构时,我们有哪些具体的方法呢?可以这样说,重构的准则由很多条,见《重构》这本书。但它不是最终的标准,因为你要是完全按照它的标准来执行,那你也就等于不会重构,重构是一本武功秘籍,而真正的武林高手是不用武功秘籍的,一般是“无招胜有招”。只有根据实际的需要,凭借一定的思想,才能实现符合实际的重构,我们不能被一些固定的模式套牢了,这样你的程序会很僵化。究竟如何把握这个度,需要大家去总结。
重构与模式
要想实现一个好的重构,不是重构本身,而是我们在写代码的时候,思想当中时刻有它的位置存在!非常重要!如果你本身就没想着要去重构,那么就是有再好的模式供你调用又怎么样?就是有了好的模式,你不能根据实际的需要去融会贯通,那你做出来的重构有意义么?
重构与思想
读懂代码(包括测试例子代码)
Refactoring
运行所有的Unit Tests
流程1
读懂代码
应用重构工具进行重构(如Eclipse)
流程2
Refactoring的流程
重新组织你的函数
在对象之间搬移特性
重新组织数据
简化条件表达式
简化函数调用
重构技巧
重构流程
代码重构
架构师技术栈—知识(精编版)
0 条评论
回复 删除
下一页