Web进阶 | 构建高可靠、高性能的Web应用

功能 -> 性能✔ -> 智能

可靠性:可扩展性、服务降级、负载均衡、灰度
性能:缓存、并发、池化、异步

一、可靠性

1、应用扩展
  • 垂直扩展(scala up)
    方式:提升机器硬件
    缺点:成本昂贵,扩展能力有限
垂直扩展:增加一台机器硬件数量(并不一定是单机的)
  • 水平扩展(scala out)
    方式:增加节点(增加机器数量)
    优点:升级过程平滑透明,硬件成本低,理论上可无限扩展
    缺点:会增加系统的复杂度,维护成本高,服务须无状态(比如多台机器无法使用Session),可分布式的
水平扩展:增加多台机器
2、数据库扩展
  • 垂直拆分
    原先:一个库数据量太大,将业务紧密,表间关联密切的表划分在一起
    分库:将数据表拆分,可以提高性能、隔离故障
  • 水平拆分
    一个表的数据量太大,一表拆多表,根据查询使用情况确定拆分规则;
    MySQL单表最大记录数不要超过5000W;
    带来的问题
    (1)如何从多张表中定位到数据所在的表?
    自定义映射规则
    为某个字段计算hash从而对应到相应的表中

    例子:
    用户聊天信息表拆分为message_00,message_01,message_02..........message_98,message_99,
    然后根据用户的ID来判断这个用户的聊天信息放到哪张表里面,可以用hash的方式来获得,
    可以用求余的方式来获得,方法很多
    

(2)如何使代码优雅(代码层不牵扯数据库分表)
Spring动态数据源 -->> 连接不同的库
分表组件:如TSharding,是一个简易 sharding 组件,也是一个 Mybatis 分库分表组件。

Mybatis 分库分表组件 TSharding-Client

  • 数据库扩展考虑点
  • 数据量:现有/未来数据量会有多大?
  • 增长速度:增长速度影响数据量,提前考虑分表(如何评估?周期不要超过半年,不可靠)
  • QPS:每秒查询量
  • 切分规则:根据具体业务、表内容、需求等进行合理分片
3、负载均衡
  • 方案

  • Nginx反向代理服务器(推荐): 用户请求到达Nginx服务器,按照一定策略http转发到具体的机器

  • HTTP重定向: 302

  • DNS轮询解析

  • LVS: 网络4层,内核协议栈

  • HAProxy: 4/7层

  • 分发策略

  • Random:随机分发(请求次数公平)

  • RoundRobin:RR,轮询分发(请求次数公平)

  • LeastActive:最少活跃,根据服务器当前处理请求的能力(处理能力公平)

  • Hash:如根据ip做hash、根据内容(请求内容)做hash

  • 健康检查
    将空的健康检查文件HealthyCheck.html放在各个服务器上,以供Nginx等服务器检查应用服务器的运行状态。

4、服务降级
  • 服务分级
    对提供的服务进行分级,核心服务具有更高的优先级,频率低、不重要的服务级别低
  • 功能开关
  • 全流程开关
  • config

二、性能

1、并发
Servlet非线程安全
每个Servlet线程都有自己的存储区域,计算完毕后再将数据写回寄存器,线程不安全

多线程环境下,需要使用线程安全的集合、共享资源加锁等。

并发锁
  • synchronized/ReentrantLock

  • 可重入锁:

  • 互斥:同一时刻只能有一个线程持有(相对的是共享锁)

  • 读写锁

  • ReadWriterLock:有timeout机制,超时不等待

  • 读锁:是共享锁

  • 写锁:是排它锁,互斥

  • 锁不能升级(读锁->写锁),只能降级(写锁->读锁);
    写锁要等待所有的读锁释放

  • 乐观锁

  • 乐观锁( Optimistic Locking ) 相对悲观锁而言,乐观锁假设认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让返回用户错误的信息,让用户决定如何去做。

  • 悲观锁

  • 正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系 统不会修改数据)。

2、缓存
缓存:将请求频繁的数据从DB / 磁盘加载到内存
  • 本地缓存
  • HashMap

  • ConcurrentHashMap(并发环境)

  • Guava Cache

  • memcached
  • Key-Value
    username_zhangsan -> {"username":zhangsan,"nickname":"张全蛋"}

  • LRU
    Least Recently Used近期最少使用

  • 分布式
    一致性Hash
    client实现

  • Client
    xmemcached
    spymemcached


    [memcached](https://www.baidu.com/link?url=h3veG-DxMyBf86uSyo-ASq3Yg81BQXgBZ7q4cXQS4omKnRCBpEwaTXQYW-gNQsEsQuDKk7PpNkF4OkNmZL1Dc0d2Bp61s4eGZUMipAYrSpq&wd=&eqid=891a485f0000a2be0000000358d4d91e) 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的[hashmap](http://baike.baidu.com/item/hashmap)。其[守护进程](http://baike.baidu.com/item/%E5%AE%88%E6%8A%A4%E8%BF%9B%E7%A8%8B)(daemon )是用[C](http://baike.baidu.com/item/C/7252092)写的,但是客户端可以用任何语言来编写,并通过memcached协议与守护进程通信。
  • redis
  • 数据结构丰富
    Hash
    List
    Set
    ...

  • 操作丰富

  • 可持久化:定期将内存数据保存到磁盘,关机后可load到内存

  • 单线程、多实例

redis提供了丰富的数据结构
3、序列化
概念

将对象的状态信息转换为可以存储或传输形式的过程

方式
  • Json:将对象信息转换为json数据
  • Java serialization

java序列化一定应该注意**的6个事项
1、如果子类实现Serializable接口而父类未实现时,父类不会被序列化,但此时父类必须有个无参构造方法,否则会抛InvalidClassException异常。
2、静态变量不会被序列化,那是类的“菜”,不是对象的。
3、transient关键字修饰变量可以限制序列化。
4、虚拟机是否允许反序列化,不仅取决于类路径和功能代码是否一致,一个非常重要的一点是两个类的序列化ID是否一致,就是 private static final long serialVersionUID = 1L。
5、Java 序列化机制为了节省磁盘空间,具有特定的存储规则,当写入文件的为同一对象时,并不会再将对象的内容进行存储,而只是再次存储一份引用。反序列化时,恢复引用关系。
6、序列化到同一个文件时,如第二次修改了相同对象属性值再次保存时候,虚拟机根据引用关系知道已经有一个相同对象已经写入文件,因此只保存第二次写的引用,所以读取时,都是第一次保存的对象。读者在使用一个文件多次 writeObject 需要特别注意这个问题(基于第5点)。

  • Hessian
  • Protobuf
  • Kryo
4、池化技术
场景
  • 可复用资源
  • 创建代价大
类型
  • 线程池
  • Executor
  • 连接池
  • tomcat-jdbc
  • dbpc
  • c3p0
  • 对象池
  • Spring Bean 管理
5、异步
前端轮询、后端异步
  • Futrue/CountDownLatch
消息队列
  • QMQ/Kafka/AMQ/rabbitmq
HTTP
  • async-http-client
  • Apache HttpComponents
Dubbo
  • 异步调用、参数回调
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,335评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,895评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,766评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,918评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,042评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,169评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,219评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,976评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,393评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,711评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,876评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,562评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,193评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,903评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,142评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,699评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,764评论 2 351

推荐阅读更多精彩内容