Java架构师之路
2020-02-11 12:04:01 0 举报
AI智能生成
java架构师学习之路
作者其他创作
大纲/内容
1、基础知识
JVM性能调优
1. Java内存区域
虚拟机的历史
运行时数据区域
深入辨析堆和栈
方法的出入栈
虚拟机中的对象
堆参数设置和内存溢出实战
2. 垃圾回收器和内存非配策略
GC概述
判断对象的存活
辨析强、弱等各种引用
GC算法
分代收集
垃圾回收器
Stop The World现象
GC日志解读
内存分配与回收策略
内存泄露和内存溢出辨析
JDK为我们提供的工具
了解MAT (Memory Analyzer Tool)
3. JVM的执行子系统
Class类文件的本质
Class文件格式
字节码指令
类加载机制
栈帧详解
方法调用详解
基于栈的字节码解析执行引擎
4. 编写高效优雅的Java程序
构造器参数太多怎么办
不需要实例化的类应该构造器私有
不要创建不必要的对象
避免使用终结方法(finalize)
使类和成员的可访问性最小化
使可变性最小化
优先使用复合
接口优于抽象类
可变参数要谨慎使用
返回零长度的数组或集合,不要返回null
优先使用标准的异常
用枚举代替int常量
将局部变量的作用域最小化
精确计算,避免使用float和double
当心字符串连接的性能
5. 深入了解性能优化
常用的性能评价/测试指标
常用的性能优化手段
详细了解应用服务器性能优化
网络编程与高效IO
网络协议
网络模型
TCP
UDP
HTTP
原生JDK网络编程(NIO/BIO)
1. Netty应用
Netty是什么?为什么要用Netty?
第一个Netty程序
Netty组件再了解
解决粘包,半包问题
编解码器框架
序列化问题
单元测试
2. Netty进阶和实战
实现UDP通信
服务器推送技术
WebSocket通信
实现自己的通信框架
3. Netty源码分析
引导过程分析
EventLoop和EventLoopGroup分析
服务端接受连接事件分析OP_ACCEPT
分析读事件OP_READ
分析写数据和处理写数据OP_WRITE
分析客户端连接和连接事件OP_CONNECT
并发编程进阶
1. 线程基础、线程之间的共享和协作
基础概念
启动和终止线程
线程间的共享
线程间的协作
2. 线程的并发工具类
Fork/Join
CountDownLatch作用、应用场景和实战
CyclicBarrier作用、应用场景和实战
Semaphore作、应用场景和实战
Exchange作用、应用场景和实战
Callable、Future和FutureTask
3. 原子操作CAS
CAS的原理
CAS的问题
原子操作类的使用
4. 显式锁和AQS
显式锁
LockSupport工具进阶
AbstractQueuedSynchronizer实现及源码分析
5. 并发容器
ConcurrentHashMap
其他并发容器
阻塞队列
6. 线程池
什么是线程池?为什么要用线程池?
实现一个我们自己的线程池
JDK中的线程池
线程池的工作机制
合理配置线程池
Executor框架
CompletionService
7. 并发安全
类的线程安全
如何做到类的线程安全
线程不安全引发的问题
线程安全的单例模式
8. JMM和底层实现原理
现代计算机物理上的内存模型
Java内存模型 (JMM)
Mysql深度优化
1. Mysql逻辑架构入门介绍
2. 存储引擎
MyISAM
Innodb
Archive
Memory
Federated
3. 业务设计
锁
事务
逻辑设计
物理设计
4. 查询以及索引
慢查询
索引
执行计划
SQL优化
Linux
Linux注意事项
Linux基础之类
Linux Jdk1.8环境安装及操作指令
Linux Tomcat安装与停启
2、高性能架构
分布式架构思维
大型互联网架构演进过程
架构师应具备的分布式知识
主流分布式架构设计详解
分布式架构原理
分布式架构演进过程
如何把应用从单机扩展到分布式
CDN加速静态文件访问
系统监控、容灾、储存动态扩展
结构设计及业务驱动分化
CAP、Base理论及其应用
分布式架构策略
分布式架构网络通信原理剖析
通信协议中的序列化和反序列化
基于框架的RPC技术、WebService、RMI、Hession
深入分析ZooKeeper在disconf应用中心的应用
基于zookeeper实现分布式服务器动态上下线感知
深入分析Zookeeper Zab协议及选举机制源码解读
Dubbo管理中心及监控平台安装部署
基于Dubbo的分布式系统架构实战
Dubbo容错机制及高扩展性分析
分布式协调和分流
Zookeeper分布式环境指挥官
zk的入门
zk开发基础
zookeeper应用实战
协议及算法分析
Nginx高并发分流进阶实战
nginx安装
正反向代理
nginx进程模型
核心配置结构
日志配置及签个
location规则
rewrite的使用
动静分离
跨域配置
缓存配置,Gzip配置
https配置
横向扩展带来的问题
LVS
keepalived
异步与消息中间件
概述
什么是消息中间件? 和RPC有何区别?
消息中间件使用场景介绍
消息中间件(ActiveMQ、RabbitMQ、RocketMQ、Kafka)简介及对比
ActiveMQ消息中间件
JMS规范
ActiveMQ使用
ActiveMQ高级特性和用法
企业级高可用集群部署方案
RabbitMQ消息中间件
AMQP规范和RabbitMQ基本概念
Windows下安装和运行
Linux下安装与配置
原生Java客户端使用
消息发布时的权衡
消息消费时的权衡
消息的拒绝
控制队列
消息的属性
与Spring集成
集群化与镜像队列
RocketMQ消息中间件
RocketMQ简介、环境搭建
RocketMQ HelloWorld示例、 重试策略讲解
RocketMQ 架构设计、双主双从集群环境搭建、顺序消费、事务消费
RocketMQ API使用简介、拉取机制
RocketMQ实战案例讲解
RocketMQ事物讲解
Kafka百万级吞吐实战
Kafka入门
Kafka的安装和配置参数
Kafka的集群
Kafka的生产者和消费者
整合Spring
深入理解Kafka
保证Kafka的可靠数据传递
缓存和NoSQL
Redis高性能缓存数据库
Redis初入门及介绍
Java客户端
Redis常用命令及多项目设计实战
数据一致性
Redis性能优化
Redis主从模式
Redis持久化
哨兵核心机制
高可用集群
MongoDB
MongoDB入门
nosql与sql使用场景分析
基础概念
mongodb进阶
常用命令
快速入门
mongodo客户端驱动
增删改查与聚合
安全控制
mongodb高级知识
存储引擎
索引
高可用
最佳实践与注意事项
缓存解决方案实战
缓存的概念
SpringCache的用法
缓存的一致性策略
缓存雪崩方案
缓存穿透方案
高可用数据储存
MySQL高性能储存实战
Mycat进阶实战
FastDFS分布式文件储存实战
文件储存实战
文件同步实战
文件查询实战
分布式部署实战
分布式常见常见方案实战
事务概念
事务与锁
分布式事务产生背景
X/OpenDTP事务模型
标准分布式事务
分布式事务解决方案
两阶段提交
BASE理论与柔性事务
TCC方案
补偿性方案
异步确保与最大努力型
单店登陆方案
单店登陆的问题背景
页面跨域问题
Session跨域共享方案
Session的扩展
分布式任务调度方案
Quartz调度的用法
Elastic-Job示例
分布式调度的疑难点
Quartz集群定制化分布式调度
常见指标
响应时间(Response Time)
吞吐量(Throughput)
单位时间内处理的请求数量
每秒查询率QPS(Query Per Second)
每秒响应请求数。在互联网领域,这个指标和吞吐量区分的没有这么明显
并发用户数
同时承载正常使用系统功能的用户数量
如何提升并发
垂直扩展,提升单机处理能力
增强单机硬件性能
提升单机架构性能,例如:使用Cache来减少IO次数,使用异步来增加单服务吞吐量,使用无锁数据结构来减少响应时间
水平扩展(Scale Out)
增加服务器数量,就能线性扩充系统性能
反向代理层的水平扩展,是通过“DNS轮询”实现的
站点层的水平扩展,是通过“nginx”实现的
服务层的水平扩展,是通过“服务连接池”实现的(注册中心)
数据库水平拆分方式
按照范围水平拆分
优点
服务层的水平扩展,是通过“服务连接池”实现的
数据均衡性较好
比较容易扩展,可以随时加一个uid[2kw,3kw]的数据服务
缺点
请求的负载不一定均衡,一般来说,新注册的用户会比老用户更活跃,大range的服务请求压力会更大
按照哈希水平拆分
优点
规则简单,service只需对uid进行hash能路由到对应的存储服务
数据均衡性较好
请求均匀性较好
缺点
不容易扩展,扩展一个数据服务,hash方法改变时候,可能需要进行数据迁移
负载均衡
LVS
位于传输层的四层负载
方式
修改IP地址(NAT)
源地址修改 SNAT(请求返回)
目标地址修改 DNAT(请求进入)
修改目标 MAC(DR 模式)
请求由LVS接收,由真实服务器直接返回给用户
LVS转发过程中,只修改mac地址,不修改ip地址
DR 模式具有较好的性能,也是目前大型网站使用最广泛的一种负载均衡手段
优点
抗负载能力强、是工作在传输层上仅作分发之用,没有流量的产生,这个特点也决定了它在负载均衡软件里的性能最强的,对内存和 cpu 资源消耗比较低。
配置性比较低,这是一个缺点也是一个优点,因为没有可太多配置的东西,所以并不需要太多接触,大大减少了人为出错的几率。
工作稳定,因为其本身抗负载能力很强,自身有完整的双机热备方案,如 LVS + Keepalived。
无流量,LVS 只分发请求,而流量并不从它本身出去,这点保证了均衡器 IO 的性能不会受到大流量的影响。
应用范围比较广,因为 LVS 工作在传输层,所以它几乎可以对所有应用做负载均衡,包括 http、数据库、在线聊天室等等。
缺点
软件本身不支持正则表达式处理,不能做动静分离;而现在许多网站在这方面都有较强的需求,这个是 Nginx、HAProxy + Keepalived 的优势所在
如果是网站应用比较庞大的话,LVS/DR + Keepalived 实施起来就比较复杂了,相对而言,Nginx / HAProxy + Keepalived 就简单多了
Nginx
以反向代理的方式进行负载均衡的,通过upstream来实现
方式
轮询(默认):每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器 down 掉,能自动剔除。
weight:指定轮询几率,weight 和访问比率成正比,用于后端服务器性能不均的情况。
ip_hash:每个请求按访问 ip 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决 session 的问题。
fair(第三方):按后端服务器的响应时间来分配请求,响应时间短的优先分配。
url_hash(第三方):按访问 url 的 hash 结果来分配请求,使每个 url 定向到同一个后端服务器,后端服务器为缓存时比较有效。
优点
跨平台:Nginx 可以在大多数 Unix like OS编译运行,而且也有 Windows 的移植版本
配置异常简单:非常容易上手。配置风格跟程序开发一样,神一般的配置
非阻塞、高并发连接:官方测试能够支撑5万并发连接,在实际生产环境中跑到2~3万并发连接数
事件驱动:通信机制采用 epoll 模型,支持更大的并发连接
Master/Worker 结构:一个 master 进程,生成一个或多个 worker 进程
内存消耗小:处理大并发的请求内存消耗非常小。在3万并发连接下,开启的10个 Nginx 进程才消耗150M 内存(15M*10=150M)
内置的健康检查功能:如果 Nginx 代理的后端的某台 Web 服务器宕机了,不会影响前端访问
节省带宽:支持 GZIP 压缩,可以添加浏览器本地缓存的 Header 头
稳定性高:用于反向代理,宕机的概率微乎其微
缺点
Nginx 仅能支 持http、https 和 Email 协议,这样就在适用范围上面小些
对后端服务器的健康检查,只支持通过端口来检测,不支持通过 ur l来检测。不支持 Session 的直接保持,但能通过 ip_hash 来解决
HAProxy
对后端服务器的健康检查,只支持通过端口来检测,不支持通过 ur l来检测。不支持 Session 的直接保持,但能通过 ip_hash 来解决
HAProxy 的优点能够补充 Nginx 的一些缺点,比如支持 Session 的保持,Cookie 的引导;同时支持通过获取指定的 url 来检测后端服务器的状态
HAProxy 跟 LVS 类似,本身就只是一款负载均衡软件;单纯从效率上来讲 HAProxy 会比 Nginx 有更出色的负载均衡速度,在并发处理上也是优于 Nginx 的
HAProxy 支持 TCP 协议的负载均衡转发,可以对 MySQL 读进行负载均衡,对后端的 MySQL 节点进行检测和负载均衡,大家可以用 LVS+Keepalived 对 MySQL 主从做负载均衡
HAProxy 负载均衡策略非常多:Round-robin(轮循)、Weight-round-robin(带权轮循)、source(原地址保持)、RI(请求URL)、rdp-cookie(根据cookie)
流式计算
Storm分布式流式计算简介、环境搭建、集群环境提交Topology、Spout、Bolt、Topology概念
StormWorker、Executor、Task配置详解、分组模式讲解
Storm WorldCount例子、保证机制、Drpc讲解
Trident学习使用、结合Redis使用、Solr
3、高可用
高可用应用
负载均衡进行故障转移
集群的session管理
同IP会话黏滞
session服务器
redis共享session
高可用存储
数据备份
冷备
热备
异步热备
同步热备
主备复制
主从复制
主机负责读写,从机只负责读
主主复制
对数据的设计有严格的要求,一般适合临时、可丢失、可覆盖的数据场景
数据集群
数据集中集群
一主多备
一主多从
数据分散集群
Hadoop的HDFS存储系统
独立的服务器负责数据分区的分配(Namenode)
Elasticsearch
选举一台服务器做数据分区的分配(master node)
分布式事务算法
2PC,强一致性算法
Commit请求阶段
Commit提交阶段
3PC
提交判断阶段
准备提交阶段
提交执行阶段
分布式一致性算法
Paxos
纯理论算法,特别复杂,是其他算法的鼻祖
Raft
为工程实践而设计,Paxos算法的不完整版
ZAB
高可用伸缩和扩展
网站架构伸缩
不同功能物理分离
相同功能集群伸缩
负载均衡器
DNS域名解析负载均衡,缺点是失效转移存在一定的时效性
反向代理(应用层负载均衡)
NGINX,七层负载,5万/每秒
数据链路层负载均衡
LVS,四层负载,80万/每秒
负载均衡算法
轮询
加权轮询
负载最低优先
LVS可以以连接数来判断
Nginx可以以HTTP请求数来判断
性能最优
响应最快,性能最优
原地址散列(哈希)
分布式缓存集群
一致性性Hash算法
数据存储服务器集群
关系型数据库集群
读写分离
分库
不同业务部署在不同的集群
分片
单表拆分,存在多个库中
支持数据分片的中间件:Cobar,缺点是只能在单一数据库实例上处理查询请求,无法执行跨库的Join操作
NoSql
HBase
以HRegion为单位进行管理
HDFS分布式文件系统
高可用服务
分级管理
核心服务优先使用更好的硬件
不同级别的服务需要隔离,避免故障连锁反应
超时设置
超时后,通信框架抛出异常,程序选择继续重试或失效转移
异步调用
消息队列
防止关联的服务互相影响
服务降级
拒绝服务
拒绝低优先级应用的调用,减少服务调用并发数
随机拒绝
关闭功能
关闭部分不重要的服务
关闭服务内部部分不重要的功能
实施方式
基于Java的信号量机制:Semaphore
调用超时次数超过阈值,自动降级,后续来的流量直接拒绝,等超过休眠时间点,再次对服务进行重试
幂等性设计
重复调用和调用一次必须保证结果相同
异地多活机房
保证核心业务异地多活
例:注册、登录、用户信息,只有登录才是核心业务
核心数据最终一致性
尽量减少数据同步,只同步核心业务数据
保证最终一致性,不保证实时一致性
采用多种手段同步数据
消息队列
二次读取
第一次读取本地失败后,根据路由规则去另外一个机房读取
存储系统同步方式
Mysql同步
回源读取
session id不同步,本地机房没有该id的情况下,根据路由去另外一个机房获取
重新生成数据
session id在另外一个机房未获取到,则让用户重新登录
保证大部分用户的异地多活
高可用数据
数据失效转移机制
失效确认
访问转移
数据恢复
CAP
一个提供数据服务的存储系统无法同时满足数据一致性、数据可用性、分区容忍性,通常会牺牲数据一致性
一致性(Consistency)
对指定的某个客户端来说,读操作保证能够返回最新的写操作结果
可用性(Availability)
非故障的节点在合理的时间内返回合理的响应(非错误和超时的响应)
分区容忍性(Partition Tolerance)
当出现网络分区(网络故障)后,系统能够继续“履行职责”
ACID
数据库约束
Atomicity原则性
Consistency一致性
Isolation隔离性
Durability持久性
BASE
Basically Available基本可用
分布式系统在出现故障时,允许损失部分可用性,即保证核心可用
Soft State软状态
Eventual Consistency最终一致性
是CAP理论中AP方案的延伸,即使无法做到强一致性,但应用可以采取适合的方式达到最终一致性
自动化测试
工具:selenium
接口性能工具:Jmeter,loadrunner
监控
数据采集
用户行为
服务器性能
系统load
内存占用
磁盘IO
网络IO
运行数据
缓存命中率
平均响应延迟时间
每分钟发送邮件数目
待处理任务总数
监控管理
系统报警
失效转移
自动优雅降级
Linux命令
日志查看
cat
cat -n access.log 显示行数
more
Enter:下一行,空格:下一页,F:下一屏,B:上一屏
less
sort
对内容进行排序
-n
数字从小到大排列
-r
数字从大到小排列
-k
指定排序的列
-t
指定分隔符
wc
统计指定文件的字符数、字数、行数
-l
统计行数
uniq
查看重复出现的行
sort uniqfile | uniq -c
-c:每一行前面加上该行出现的次数
常用脚本
页面访问量前十的f1列
cat access.log | cut -f1 -d " " | sort |uniq -c | sort -k 1 -n -r |head -10
查看最耗时的页面
cat access.log | sort -k 2 -n -r | head -10
系统监控
uptime
查看系统的load
一般来说,load不大于3,表示负载正常,load大于5,负载压力过高
top | grep Cpu
st
us
表示CPU执行用户进程所占的时间,越高越好
sy
在内核态所花费的时间,越低越好
ni
系统在调整进程优先级花费的时间
id
系统空闲时间
wa
CPU在等待IO操作所花费的时间,越低越好
hi
系统处理硬件中断所占用的时间
si
系统处理软件中断所占用的时间
top -p 进程号
查看指定进程
du-d 1 -h
查看磁盘剩余空间,-d 1表示递归深度
sar -n DEV 1 1
查看系统的网络状况
iostat -d -k
查看系统的IO
free -m
查看内存使用情况
swap过高,表示物理内存不够用
vmstat
查看当前swap的IO情况
4、性能优化
理解性能优化
性能基准
性能优化到底是什么
衡量维度
性能测试工具
ab:ApacheBench
ab [options] [http[s]://]localhost[:port]/path
-n
请求次数
-c
并发数
JMeter
使用JMeter进行压测的时候,可以使用jconsole、VisualVM等工具查看CPU和内存使用情况
LoadRunner
HP
商业未开源
反向代理引流
nginx调整负载权重
upstream
TCPCopy
请求复制工具,将在线请求复制到测试机器,模拟真实环境
TCPCopy Client
运行在线上,用来捕获在线请求数据包
TCPCopy Server
运行在线下测试机,用来截获响应包,并将响应包的头部信息传递给TCPCopy Client,以完成TCP交互
寻找性能瓶颈
YSlow
yahoo的前端分析浏览器插件
firebug
firefox的插件
btrace
动态跟踪工具,能够快速定位和发现耗时方法
GC日志分析
JVM启动增加参数:-verbose:gc -Xloggc:/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps
PrintGCDetails表示输出GC详情
PrintGCDateStamps表示输出GC时间戳
数据库慢查询
show variables like 'log_slow_queries'
查看是否启用慢日志
show variables like 'long_query_time'
查看慢于多少秒的SQL会记录到日志
my.cnf
log_slow_queries = /var/log/mysql/mysql-slow.log
日志地址
long_query_time=1
慢于多少秒记录
WEB前端
浏览器访问优化
浏览器缓存
设置http头中的Cache-Control
设置http头中的Expires
页面压缩
合理布局
CSS放在页面最上面
js放在最下边
减少cookie传输
减少数据量
静态资源独立域名
减少Http请求
合并css
合并js
合并图片
CDN加速
缓存静态资源,如图片、文件等
反向代理
动静分离
js、css等文件独立部署,使用专门的域名
图片服务
用户上传,独立部署
反向代理
提供页面缓存
DNS
DNS负载均衡
代码优化
线程池
Future模式
新建线程异步获取数据,执行完一段逻辑后,使用线程对象的get()方法可获取线程内的执行结果,如未获取到,则线程阻塞
NIO
Selector 非阻塞IO机制
资源复用
单例模式
对象池
减少上下文切换
当可运行的线程大于CPU数量,则正在运行的某个线程可能就会被挂起,增加调度开销
锁竞争激烈也会导致上下文切换频繁
尽可能的缩短锁持有的时间
减少锁的粒度
将使用单独锁保护多个变量变为采用独立的锁分别进行保护
放弃使用独占锁,使用读写锁
ReentrantReadWriteLock
JVM
JVM内存结构
堆heap
存储对象的内存空间,对象的创建和释放、垃圾回收都在这里进行
是Java虚拟机所管理的内存中最大的一块。Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。
分类
年轻代
Eden空间
From Survivor空间
To Survivor空间
默认比例为 8:1:1
老年代
方法区(Method Area)/永久代(PermGen)
与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
程序计数器(Program Counter Register)
是一块较小的内存空间,它的作用可以看做是当前线程所执行的字节码的行号指示器。
栈
JVM栈(JVM Stacks)
存储线程上下文信息,如方法参数、局部变量等
本地方法栈(Native Method Stacks)
与虚拟机栈所发挥的作用是非常相似的,其区别不过是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的Native方法服务。
总结:方法区和堆是所有线程共享的内存区域;而Java栈、本地方法栈和程序计数器是运行是线程私有的内存区域。
对象分配规则
对象优先分配在Eden区,如果Eden区没有足够的空间时,虚拟机执行一次Minor GC。
大对象直接进入老年代(大对象是指需要大量连续内存空间的对象)。这样做的目的是避免在Eden区和两个Survivor区之间发生大量的内存拷贝(新生代采用复制算法收集内存)
长期存活的对象进入老年代。虚拟机为每个对象定义了一个年龄计数器,如果对象经过了1次Minor GC那么对象会进入Survivor区,之后每经过一次Minor GC那么对象的年龄加1,知道达到阀值对象进入老年区。
动态判断对象的年龄。如果Survivor区中相同年龄的所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象可以直接进入老年代
空间分配担保。每次进行Minor GC时,JVM会计算Survivor区移至老年区的对象的平均大小,如果这个值大于老年区的剩余值大小则进行一次Full GC,如果小于检查HandlePromotionFailure设置,如果true则只进行Monitor GC,如果false则进行Full GC。
JVM垃圾回收
新生代
Eden Space
新建对象总是在该区创建,当空间满,触发Young GC,将还未使用的独享复制到From区,Eden区则清空
From
当Eden区再次用完,再触发Young GC,将Eden和From区未使用的对象复制到To区
To
当Eden区再次用完,触发Young GC,将Eden和To区未使用的对象复制到From区,如此反复
老年代
经过多次Young GC,某些对象会在From和To多次复制,如果超过某个阈值对象还未释放,则将该对象复制到老年区。如果老年区空间用完,就会触发Full GC
Serial收集器
串行收集器是最古老,最稳定以及效率高的收集器,可能会产生较长的停顿,只使用一个线程去回收。
-XX:+UseSerialGC 串行收集器
ParNew收集器
ParNew收集器其实就是Serial收集器的多线程版本,新生代并行,老年代串行;新生代复制算法、老年代标记-压缩
-XX:+UseParNewGC ParNew收集器
-XX:ParallelGCThreads 限制线程数量
Parallel收集器
Parallel Scavenge收集器类似ParNew收集器,Parallel收集器更关注系统的吞吐量
-XX:+UseParallelGC 使用Parallel收集器+ 老年代串行(并行收集器)
Parallel Old 收集器
Parallel Old是Parallel Scavenge收集器的老年代版本,使用多线程和“标记-整理”算法
-XX:+UseParallelOldGC 使用Parallel收集器+ 老年代并行(并行老年代收集器)
G1收集器
G1 (Garbage-First)是一款面向服务器的垃圾收集器,主要针对配备多颗处理器及大容量内存的机器. 以极高概率满足GC停顿时间要求的同时,还具备高吞吐量性能特征
特点
空间整合,G1收集器采用标记整理算法,不会产生内存空间碎片。分配大对象时不会因为无法找到连续空间而提前触发下一次GC。
可预测停顿,这是G1的另一大优势,降低停顿时间是G1和CMS的共同关注点,但G1除了追求低停顿外,还能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为N毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒,这几乎已经是实时Java(RTSJ)的垃圾收集器的特征了。
JVM调优
知其然、知其所以然
什么是JVM运行时数据区
什么是JVM内存模型 JMM
各垃圾回收器使用场景(Throughput\CMS)
理解GC日志,从日志看端倪
实战MAT分析DUMP文件
GC优化
堆设置
-Xmn:年轻代大小
整个JVM内存大小=年轻代大小 + 年老代大小 + 持久代大小。持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。
YoungGen
对-XX:newSize、-XX:MaxnewSize两个参数同时进行配置(注意:JDK1.4之后才有该参数)
-XX:NewRatio=n:设置年轻代和年老代的比值。如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4
-XX:SurvivorRatio=n:年轻代中Eden区与两个Survivor区的比值。注意Survivor区有两个。如:3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5
CMS收集器
CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器
优点:并发收集、低停顿
缺点:产生大量空间碎片、并发阶段会降低吞吐量
-XX:+UseConcMarkSweepGC 使用CMS收集器(并发收集器)
-XX:+ UseCMSCompactAtFullCollection Full GC后,进行一次碎片整理;整理过程是独占的,会引起停顿时间变长
-XX:+CMSFullGCsBeforeCompaction 设置进行几次Full GC后,进行一次碎片整理
-XX:ParallelCMSThreads 设定CMS的线程数量(一般情况约等于可用CPU数量)
分支主题
-Xms设置堆的最小空间大小
-Xmx设置堆的最大空间大小
-XX:NewSize设置新生代最小空间大小
-XX:MaxNewSize设置新生代最大空间大小。
-XX:PermSize设置永久代最小空间大小
-XX:MaxPermSize设置永久代最大空间大小。
-Xss设置每个线程的堆栈大小
老年代空间大小=堆空间大小-年轻代大空间大小
垃圾回收统计信息
-XX:+PrintGC
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-Xloggc:filename
Tomcat调优
How it works?探查Tomcat运行机制及框架
分析Tomcat线程模型
Tomcat系统参数认识及调优
基准测试
tomcat线程优化
maxThreads
Tomcat使用线程来处理接收的每个请求。这个值表示Tomcat可创建的最大的线程数。默认值150
acceptCount
指定当所有可以使用的处理请求的线程数都被使用时,可以放到处理队列中的请求数,超过这个数的请求将不予处理。默认值10
minSpareThreads
Tomcat初始化时创建的线程数。默认值25
maxSpareThreads
一旦创建的线程超过这个值,Tomcat就会关闭不再需要的socket线程。默认值75
enableLookups
是否反查域名,默认值为true。为了提高处理能力,应设置为false
connnectionTimeout
网络连接超时,默认值60000,单位:毫秒。设置为0表示永不超时,这样设置有隐患的。通常可设置为30000毫秒
maxKeepAliveRequests
保持请求数量,默认值100。 bufferSize: 输入流缓冲大小,默认值2048 bytes
compression
压缩传输,取值on/off/force,默认值off。 其中和最大连接数相关的参数为maxThreads和acceptCount。如果要加大并发连接数,应同时加大这两个参数
32G 内存配置示例:
分支主题
存储性能优化
RAID
RAID0
将磁盘数量分成N份,数据同时并发写入N块磁盘,速度快,缺点是没有备份
RAID1
一份数据同时写入两块磁盘,有备份
RAID10
RAID0与RAID1的结合,缺点是磁盘利用率低
RAID3
数据分成N-1份,并发写入N-1块磁盘,在第N块磁盘记录校验数据,缺点是第N块磁盘在频繁修改情况下容易损坏,实践中很少使用
RAID5
与RAID3不同的是,将第N块磁盘记录校验的数据写入所有的磁盘,避免同时写坏一个磁盘
RAID6
类似RAID5,但是数据只写入到N-1块磁盘,螺旋式的将校验数据写入在两块磁盘中
存储算法
B+树(传统关系型数据库)
LSM树(NOSQL)
HDFS分布式文件系统
NameNode,只有一个实例,负责数据分区的分配
DataNode,真正存储数据的存储节点
关系型数据库
读写分离
分库
问题
join操作问题
事物问题
成本问题
单台数据库服务器一般来说能支撑10万用户量级的业务
分表
垂直分表
将表中某些不常用且占了大量空间的列拆分出去
水平分表
参考:单表超过五千万条建议分表
路由算法
范围路由
选取有序的数据列作为路由条件,不同分段分散到不同的数据库表中
复杂点在于分段大小的选取上,建议分段大小在100万到2000万之间
优点:可随数据的增加平滑地扩充新的表
缺点:分布不均匀。新扩充的表数据量一开始很少
Hash路由
复杂点在于初始表数量的选取上
优点:表分布比较均匀
缺点:扩充新表很麻烦,数据需要重新分布
配置路由
新建一张单独的表记录路由信息
优点:设计简单,扩充表时只需要迁移指定数据,修改路由表
缺点:必须多查询一次路由表,影响整体性能
问题
join操作
进行多个表的join查询,将结果合并
count()操作
count相加
对每个表进行count,最后结果相加
缺点:性能低
记录数表
新建表,包含table_name,row_count两个字段
每次插入或删除成功后,更新记录数表,缺点是增加性能开销
不要求精确的业务,可通过定时任务更新
order by操作
分别查询每个子表中的数据,然后汇总进行排序
实现方式
程序代码封装
TDDL(淘宝)
ShardingJDBC(当当)
中间件
mycat
mysql router
atlas(奇虎360)
mysql
存储引擎
myisam(B树)
表锁策略
innodb(B+树)
行锁
性能优化
合理使用索引
explain
分析执行语句
条件左侧避免使用表达式
like关键字需要进行全表扫描
“最左前缀”原则,即组合索引,如果前面的索引没有命中,后面的索引即无效
反范式设计
冗余很少变化的关联字段
使用查询缓存
select @@query_cache_type;
使用搜索引擎
针对于分表分库的查询
使用key-value数据库
NoSQL
Redis(K-V存储)
两种持久化方式
RDB
只备份当前内存中的数据集,事物执行完毕并不立即写入磁盘
AOF
先执行命令,成功后立即将命令追加到日志文件,也可能丢失命令数据
MongoDB(文档数据库)
特点:no-schema
优点:
新增字段简单,存储json格式的复杂数据
缺点:
不支持事物
无法实现join
HBase(列式数据库)
优点:
节省IO,因为每次只查一列,数据量小
比行式数据库更高的存储压缩比
缺点:
存储不连续,遇到修改操作性能很差
更新时需要将数据解压后更新,然后再压缩,写入磁盘
场景:
离线的大数据分析和统计
Elasticsearch(全文搜索引擎)
原理:
倒排索引(反向索引),建立单词到文档的索引
Elasticsearch是分布式的文档存储方式,它能够存储和检索复杂的数据结构。
为了让搜索引擎支持关系型数据库的全文搜索,需要将关系型数据转换为文档数据
分布式缓存
场景
结果缓存
需要经过复杂运算得到的数据
读多写少,很少变化
不适合缓存
频繁修改的数据
没有热点的数据
设置失效时间
缓存雪崩
更新锁
分布式环境下,对缓存更新操作进行加锁保护,保证只有一个线程能够进行操作
后台更新
缓存有效期设置为永久,后台定时更新
通过定时读取缓存,判断缓存是否存在
业务线程发现缓存丢失后,通过消息队列通知后台
缓存预热
系统上线时将热点数据加载好
缓存穿透
存储数据不存在:造成数据库压力,应对策略是将不存在的数据缓存起来
数据生成耗费大量时间和资源
缓存热点
很多业务请求都命中同一份缓存
解决方案是复制多份缓存,将请求分散到多台服务器
文件存储
小文件
HBase
Hadoop
Hypertable
FastDFS
未开源:TFS(淘宝)、JFS(京东)、Haystack(Facebook)
大文件
Hadoop
HBase
Storm
Hive
5、系统安全
XSS跨站脚本攻击
防御
消毒:特殊字符进行转译
HttpOnly:对于存放敏感信息的cookie,可通过对该Cookie添加HttpOnly属性
分类
反射型:发布带攻击的链接
持久型:将攻击信息存到服务器数据库中
注入攻击
分类
SQL注入
OS注入
防御
消毒:特殊字符转译
参数绑定:sql预编译和参数绑定
CSRF跨站点请求伪造
核心:利用了浏览器的Cookie或服务器Session策略
防御
表单Token
验证码
Referer check
将cookie设置为HttpOnly
DDoS
SYN Flood
基于TCP的三次握手,攻击者伪造大量IP地址给服务器发送SYN报文,导致服务器接收不到客户端的ACK,服务器需要分配资源来维护本次握手,并不断重试。当等待队列占满后,服务器不再接收新的SYN请求。
DNS Query Flood
向被攻击的服务器发送海量的域名解析请求。
CC
基于HTTP协议发起,通过控制大量肉鸡和互联网上大量的代理,模拟正常用户给网站发起请求,直到网站拒绝服务。
从应用层发起,与网站的业务紧密相连,使防守方进行过滤的时候进行大量的误杀,真正业务无法处理。
其他攻击手段
Error Code
程序内部错误,浏览器打印堆栈信息
防御:配置Web服务器参数,跳转到500的专用错误页面
Html注释
注释显示在客户端,给黑客攻击造成便利
防御:代码Review,删除注释
文件上传
利用文件上传功能上传可执行程序,进而控制服务器
防御:设置上传文件白名单,只允许上传可靠文件类型,判断文件上传类型,使用“魔数”
文件单独存储
路径遍历
在请求的URL中使用相对路径,遍历未开放的目录及文件
防御:静态资源独立部署,其他资源不使用静态URL访问,动态参数不包含文件路径信息
防火墙
ModSecurity,开源
SiteShell
深信服
加解密
单向散列加密(摘要算法)
MD5
SHA-1
对称加密
加密与解密使用同一个密匙,远程通信的密匙交换是难题
DES
56位
3DES
AES
AES-128
AES-192
AES-256
RC
非对称加密
算法RSA
位数越大,加解密速度越慢
信息安全传输:公钥加密,私钥解密
数字签名(不可抵赖):私钥加密,公钥解密
发送发:将内容生成摘要,再用私钥将摘要进行加密生成数字签名,最后将数字签名和原文内容传输给接收方。
接收方:将原文内容采用相同的摘要算法生成摘要,再用公钥将数字签名解密成发送方的摘要,最后将两个摘要对比即可确认真伪。
算法
MD5withRSA
SHA1withRSA
数字证书
证书管理
keytool
Java的数字证书管理工具
OpenSSL
进行证书的签发与证书链的管理
6、微服务架构
RPC原理
RMI的实现
原理
服务注册与发布
动态代理
序列化与反射
微服务架构
SOA架构和微服务架构之间的区别和联系
如何设计微服务及其设计原理
解惑Spring Boot流性因素及能够解决什么问题
什么是Spring Cloud, 为何要选择Spring Cloud
基于全局分析Spring Cloud各个组建所解决的问题
SpringBoot底层探析
SpringBoot快速入门
SpringBoot与微服务之间的关系
环境搭建
继承Springmvc
继承mybatis
整合日志
集成jsp
全集异常捕获
打包部署
热部署
集成Swagger2构建API管理体系
核心组件
starter
actuator
auto-configuration
cli
jta+atomikos的分布式事务
性能优化
jvm参数
扫包优化
undertow容器
@SpringBootApplication源码解读
Spring Cloud
Ereca注册中心
Ribbon集成Rest实现负载均衡
Fegion声明式服务调用
Eystrix服务熔断降级方式
Zuul实现微服务网关
Config分布式统一配置中心
Sleuth调用链路跟踪
BUS消息总线
基于Hystrix实现接口实现降级
集成Spring Cloud实现统一整合方案
SpringCloud高级进阶
Zuul路由网管详解及源码探析
Ribbon客户端负载均衡原理与算法详解,与服务端均衡负载区别
Feign声明式服务调用方法实现
Hystrix服务熔断及服务降级实战
Eureka注册中心分析
Config配置服务中心与svn、git快速集成
BUS消息总线技术
Sleuth调用链路追踪
Stream消息驱动的微服务
Docker虚拟化技术
Docker介绍、安装与使用
Docker组成
镜像
容器
私有仓库
Docker Compose部署脚本
Docker Service 服务编排
Docker Redis分布式集群部署
Docker File构建
通过Maven插件打包Docker镜像
Docker部署及运行应用程序
Kubernetes编配
基于Docker构建Mysql集群实战
高可用SpringCloud微服务与Docker继承实现动态扩展实战
Dubbo应用及源码解读
dubbo简介
分布式中rpc调用的痛点
dubbo主要解决那些rpc问题
dubbo设计的概念
dubbo的部署安装
dubbo的配置使用
xml方式
注解方式
api方式
dubbo中各元素属性学习
dubbo在项目的用法
类与类的依赖关系说明
项目之间的依赖划分
实战拆解分布式
dubbo源码解析与示例
dubbo的模块及层级
dubbo的初始化过程
dubbo的服务暴露
dubbo的服务引用
dubbo的服务拦截
服务的注册与发现
7、开源框架知识点
常用设计模式
Proxy代理模式
Factory工厂模式
Singleton单例模式
Delegate委派模式
Strategy策略模式
Prototype原型模式
Template模板模式
Spring
IOC 容器及源码解读
容器启动及配置类加载流程
组件添加
组件赋值
组件注入
后置处理器
声明式事务源码解读
Spring容器源码解读
AOP使用与源码分析
@EnableAspectJAutoProxy注解
切面注解使用解析
AOP源码解读实战
Spring MVC
Servlet 3.0 的注解实现
ServletContainerInitializer 容器初始化
ServletRegistration注册
FilterRegisteration过滤器
ServletContext
性能实战
基于Servlet3.0异步
Callable异步
DeferredResult异步
Mybatis
概述
为什么要用ORM
为什么使用MyBatis
Mybatis快速入门
进阶
Mybatis的配置
映射器的配置
动态SQL
与Spring的集成
缓存
关联查询
多对多级联
代码生成器
高级
源码分析
插件开发
分页插件使用与源码分析
8、团队协作开发
Git
Git基本工作原理
与SVN对比
基本运作流程
Git常用操作及问题处理
工程初始化及克隆
文件提交
分支与常用标签应用
远程仓库管理
合并与冲突解决
架构师职责: Git Flow必备技能,规范团队Git操作
maven
安装和配置
Windows上安装
Linux上安装
目录分析
使用入门
编写POM
编写主代码
编写测试代码
打包和运行
坐标和依赖
Maven坐标以及详解
依赖的配置
依赖的范围
传递性依赖和依赖调解
聚合与集成
聚合
继承
聚合与继承的关系
约定优于配置
反应堆
生命周期与插件
clean生命周期
default生命周期
site生命周期
命令行与生命周期
插件目标
插件绑定
插件配置
常用插件
仓库
本地仓库
远程仓库
中央仓库
快照版本
远程仓库的配置
快照版本与镜像
版本管理
版本号定义约定
主干、标签与分支
私服-Nexus
安装Nexus
Nexus的仓库与仓库组
Nexus使用、上传、配置
Jenkins
环境搭建
Jenkins安装
Jenkins Tomcat安装
Jenkins Git安装
Jenkins Maven安装
配置管理
Jenkins配置
Jenkins管理
Jenkins配置程序作业
Jenkins配置单元测试
Jenkins配置自动化测试
部署分析
Jenkins配置邮件通知
Jenkins配置报表
Jenkins代码分析
Jenkins分布式构建
Jenkins自动部署
高级进阶
Jenkins指标与趋势
Jenkins服务器维护
Jenkins持续部署
Jenkins插件管理
Jenkins备份
Jenkins远程测试
0 条评论
下一页