JavaWeb的架构演进

Java编程里有两座高峰:高并发、高可用。Java到最后主要是玩架构。

集群和分布式的区别

演进:单机 -> 集群 -> 分布式
集群:复制模式,每台机器做一样的事情。
分布式:两台机器分工合作,每台机器做的事情不一样。比如有业务流。
集群和分布式往往是混合使用。

架构演进

  1. 静态文件读取
  2. 数据库开发(LAMP)
  3. javaweb的雏形
    tomcat + servlet + jsp + mysql,一个war包打天下。使用 ssh/ssm 三层结构
  4. javaweb的集群
    硬件机器的横向复制,对整个项目结构无影响。数据库主从(读写分离)。使用负载均衡(Nginx)。
  5. javaweb的分布式
    将Service层单独分离出去,成为一个单独的项目jar。单独运行。Web服务器通过rpc框架,对分离出去的service进行调用。
    分布式的拓展方案:把service层吃紧的service独立成单独的服务。如果还扛不住,就集群,复制集群模式。
  6. javaweb的微服务
    从业务角度,细分业务为微服务,每一个微服务是一个完整的服务(从http请求到返回)。在微服务内部,将需要对外提供的接口,包装成rpc接口,对外部开放。把controller、service和dao全拆出,独立为一个服务。商品表也从数据库独立出来,成为一个独立的数据库。微服务里的数据库,是私有库,对外不开放的。微服务与分布式是相辅相成的,相互之间 rpc 调用是无障碍的。

微服务治理的框架:dubbo/springcloud

  1. 跨系统调用 rpc: RMI, webservice, http请求, 通过网络达到服务间访问。
    dubbo:很多协议(RMI, webservice, http),推荐dubbo协议。springcloud:http协议。
  2. 服务集群,有负载路由。需要服务发现(zookeeper)。
  3. 数据积累大。分库分表(对sql语句有影响),分区。
    mysql单表到达 700w 时,性能会急剧下降。
    分库分表:需要修改业务sql语句,有侵入性。用 mycat 中间件。
    分区:队sql语句没有侵入性。对库没有办法减压,可以解决分表的弊端,不能解决分库的弊端。

架构一个系统的依据

  1. 系统目标并发数(tps)多少。
    并发数(tps,transation per seconds):每秒处理的事务数。单个tomcat能承受多少 tps:一般500。架构系统最大要求是稳定,这个500是保守值。
  2. 系统要承受的数据量级。

前后的交互模式的演进

  1. 整页提交
    浏览器请求皆为页面级请求,每次请求都是一次页面跳转/刷新。
  2. 页面+ajax
    浏览器请求主要为页面级请求,有局部刷新使用ajax刷新(返回 json 串),页面体验更好。
  3. 单页应用mvvm模式
    首次请求返回页面html,后续请求皆为restful返回json。前后端分离的模式。
    1. 前端人员开发的程序包放在静态服务器里
    2. 浏览器访问静态服务器,得到前端 html
    3. html 页面发起 ajax 请求到后台服务器,得到业务数据,渲染出页面。

架构改进中常见解决方案

  1. 缓存(list/redis/memached)
    • 缓存静态资源
    • 接口数据缓存
    • 查库时缓存
  2. 横向拓展(集群负载)
  3. 拆分高负载服务,独立为一模块
  4. 大表数据切片( mysql分库分区分表)
  5. 使用搜索中间件: solr/elasticsearch
    全网站搜索:不指定业务表的搜索,任何一个like的匹配。es/solr 搜索中间件。

缓存方案

缓存服务器:redis、memached
一般缓存方案:

  1. 先到缓存中查,有值直接返回
  2. 无值(缓存穿透、击穿)则调用接口或者查库,并将值补入缓存区
  3. 缓存区数据与db中可能不一致,使用过期时间调节
  4. 若缓存区数据集中在某一短时刻失效,将导致大量的缓存击穿(雪崩)

永不过期方案:

  1. 不设置过期时间,数据永久有效,避免雪崩
  2. 需要额外机制来实现数据的同步更新(参照数据同步)

session 跨域共享

  1. 负载使用 hash(ip)
  2. 使用redis共享session

tomcat 自己的插件,实现session共享
spring-session插件,实现session共享

MQ 消息总线

  1. 每个应用启动时,主动注册队列
  2. 后续收/发信息,只管收/发队列中数据
  3. 队列中数据的路由策略,由mq管理者来配置,跟应用程序无关,解耦。

同步转异步

空间换时间。jdk 里有一个 future 模式。

数据切片

Redis/es/fastdfs,将数据按片切分:

  1. 切成6个片,每个片存储总量1/6数据
  2. 则两个库每个库分担三个片
  3. 若三个库,则每个库只需要承担两个片
  4. 路由管理,只记录数据与片柱的关系

此模式实现集群的动态扩容,数据的路由(数据和柱的对应关系)保持不变。扩容时柱的数量不变,容量变大。

posted @ 2021-01-08 09:11  qianbuhan  阅读(218)  评论(0)    收藏  举报