百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

大厂技术专家原创亿级流量网站架构核心技术+微服务治理读书笔记

off999 2025-04-06 19:58 38 浏览 0 评论

概述

交易系统的设计原则

高并发原则

高可用原则

业务设计原则

高可用

负载均衡与反向代理

隔离术

线程隔离

进程隔离

集群隔离

机房隔离

读写隔离

动静隔离

爬虫隔离

热点隔离

资源隔离

使用Hystrix实现隔离

基于servlet 3实现请求隔离

限流

限流算法

应用级限流

分布式限流

接入层限流

降级特技

降级预案

自动降级

人工降级

读服务降级

写服务降级

多级降级

配置中心

超时与重传机制

回滚机制

事务回滚

代码库回滚

部署版本回滚

数据版本回滚

静态资源版本回滚

压测与预案

系统压测

线下压测

线上压测

系统优化和容灾

应急预案

高并发

应用级缓存

缓存类型

缓存回收策略

回收算法

缓存使用模式

HTTP缓存

多级缓存

如何缓存数据

分布式缓存与应用负载均衡

热点数据与缓存更新

单机全量缓存加主从

分布式缓存加应用本地热点

更新缓存与原子性

缓存崩溃与快速恢复

连接池线程池

连接池

线程池

异步并发

如何扩容

单体应用垂直扩容

单体应用水平扩容

应用拆分

数据库拆分

数据异构

概述

交易系统的设计原则

高并发原则

高并发原则需要以下几种:

1. 服务是无状态的

ps:单体架构微服务化改造时,经常面临的一种场景是为了编码方便,将数据存储在session中,比如短信验证码,在分布 式场景中,流量分发是随机的,负载均衡算法不能保证两次请求流量分配到到同一台web服务中,这种必须改,用spring 集群session的方案或者将验证码存储到redis中。

2. 服务能拆分就拆

ps:也就是现在当前互联网业界比较流行的微服务治理,微服务治理不仅是拆分,包括公司组织架构变更、研发文化和流 程打造、日志平台、链路跟踪、软件规划、产品规划、软件能力、测试能力、运维能力、持续集成、灰度发布、容器化等

devops一体化能力提升等。

互联网公司微服务化治理进程并不是一蹴而就的,绝大多数公司在创业初期的产品架构是单体架构,随着业务量的扩大, 选择微服务化治理,不同的公司微服务化治理时的面临的业务场景、公司现状差异太大,微服务理论实践和实践也差异太 大,笔者经历过的案例总结如下:

1)大公司生产环境流量大、生产数据量大,同时面临新需求开发、数据库重构、又要保证业务稳定性,如何实施微服 务?一般选择的方案是基础通用业耦合度低的业务或者新开发模块先剥离,例如账号、sso、网关、组织架构、支付等。 所谓基础业务拆分先行,基础架构剥离成功,灰度上线后,后续再考虑进行数据库升级和迁移,数据量大的情况下,生产 数据库得采用在线平滑迁移的方式,数据逐步分离分批迁移(双写+单读+切读的方式),如果业务可接受停机,可以采 用离线迁移的方式。基础业务拆分完成后,后续再进行各个业务模块的逐步分拆剥离,业务剥离稳定后,再升级拆分数据 库。在业务剥离的过程中,有新需求开发怎么办,建议新需求进度放缓,分迭代进行,实在有紧急需求,在老版本中开发 上线,微服务开发落地后,进行代码迁移。

2) 中等体量公司的微服务拆分,业务活跃量和体量没有大公司那么大,可以考虑全新重构一套新的面向未来的微服务业 务系统配套新的数据库设计,产品架构全新设计,从产品层面独立,新的需求完全在新的产品上开发,老产品保持维护状 态,这种方案也面临数据迁移的问题,需要一次性将生产环境的数据迁移到新的系统,老系统逐步下线,考虑到业务稳定 性,可以考虑分批迁移,做迁移开关。

3)微型公司的微服务拆分,创业公司并非一开始就要选择单体架构,给后面公司面向未来发展埋了很多坑,一个好的有 技术规划的公司可以开始做到

多模块拆分,可以不需要微服务治理,不需要容器化、不需要网关、可以做到前后端分离、数据库拆分,在预见公司业务 可能出现爆发的时候提前进行

微服务彻底改造,提升研发平台能力。

3. 微服务治理基础架构的选择:业界比较流行的spring组织开源的spring cloud和spring boot+阿里dubbo集成方案。 springcloud全家桶方案对于中小公司更加方便,spring boot+阿里dubbo只做模块拆分,也是一个不错的选择。业界 也有些公司结合netty+dubbo来做大流量异步网关。最近阿里也出了一个spring cloud ali的方案,整合了阿里开源的各 个微服务组件,相当强大。

4. 消息队列。解耦异构系统:电商秒杀场景中一般会存在这种大流量场景,需要做异构解耦。

5. 数据异构。大流量场景更多的是解决分表分库,在线迁移,异构数据库迁移,对于一般体量的公司,可以选择云数据库, 靠物理机支撑单表一个亿也没有问题,然后用阿里的polardb或者hbase做冷备,所以分表分库也不是完全必须的。不缺 钱的土豪公司直接用polardb来,解决超大数据库的问题。数据异构也会带来很多复杂场景,例如多库多表join查询,分 布式事务等。超大量业务数据的差距,可以用es+业务表来查询,如果是运营数据,日志数据,可以考虑用大数据平台来 承载。

更大的数据量查询,通过大数量平台+hlive查询。

6. 缓存银弹。客户端、网络、本地、分布式缓存等

7. 并发化。就是访问异步化,避免串行

8. 运营管理系统到底要不要微服务模块重构:业务业界资料比较少,欢迎大牛讨论,目前业界讨论更多的是面向toc或者tob 用户端的业务系统重构,我理解运营管理系统可以进行模块化,但是没有必要进行微服务治理。

9. 多IDC: 保证微服务的高可用,需要保证跨IDC高可用,目前只有大互联网公司能做到,常见的方案是基础数据如用户数 据、服务注册数据双向同步。

10. 国际化:不同的国家面临的法治环境不一样,需要独立部署,不仅是语言环境,还包括法律环境、数据隔离等原则,但是 对研发组织来讲,base模块一定是公用的,涉及到研发业务模块架构的划分和代码分支管理,区域组织定期从base拉公共 代码拉代码到分支合并,分支需求回base模块开发,更多的是需求和研发层面管控。

11. 混合云和开放平台:常见于tob互联网公司的业务交付模型中,一般公司是多套系统独立私有化交付,比较领先的公司如 钉钉和saleforce用to c 的统一架构模型来交付tob客户。

本书高并发涉及知识如下所示:

高可用原则

1. 降级。开关控制、分级降级、尽量前置

2. 限流

3. 切换流量。故障时,DNS、LVS、Nginx切换访问目的地

本书高可用涉及知识如下所示:

业务设计原则

1. 防重设计

2. 幂等设计

3. 流程可定义

4. 状态与状态机

5. 后台系统操作可反馈

6. 后台系统审批化

7. 文档和注释

8. 备份

高可用

负载均衡与反向代理

从用户操作开始,首先是访问DNS,所以第一步的DNS就可以做一定的负载均衡,如下图所示:

DNS虽然方便,但是无法感知后端服务器的存活与否

4层以上的负载均衡一般用nginx,nginx同时支持基于TCP和HTTP的心跳检测

隔离术

线程隔离 进程隔离 集群隔离 机房隔离 读写隔离 动静隔离 爬虫隔离 热点隔离

资源隔离

资源包括:

1. 磁盘

2. CPU。将繁忙进程绑定到特定CPU、中断负载均衡、中断绑定到CPU

3. 网络

使用Hystrix实现隔离

基于servlet 3实现请求隔离

限流

限流算法

1. 令牌桶算法

2. 漏桶算法

应用级限流

1. 限制总并发/连接/请求数

2. 限制总资源数,例如线程池、连接池

3. 限制某个接口的总并发/请求数

4. 限制某个接口的时间窗请求数

5. 平滑限流某个接口的请求数

分布式限流

分布式限流可以基于redis和nginx进行,一般用得比较少

接入层限流

接入层限流可以基于nginx实现

降级特技

降级预案

1. 梳理核心业务,确定哪些可以降级,哪些一定不能降级

2. 降级是否自动化

3. 读服务降级、写服务降级

4. 多级降级

5. NA

自动降级

自动降级需要根据一些统计信息来自动判断。例如:

1. 超时

2. 失败次数

3. 依赖服务故障

人工降级

人工降级则是人工干预启动的降级,例如切换机房、屏蔽掉某些功能

读服务降级

页面降级、页面片段降级、页面异步请求降级都是读服务降级,属于丢卒保帅

写服务降级

写服务一般不可用降级,不过可以迂回处理,例如同步转为异步、限制写的量比

多级降级

1. 页面降级

2. 接入层降级

3. 应用层降级

配置中心

降级开关根据依赖服务的复杂性,可以放在本地配置文件,更可以放在配置中心

放在本地文件时,可以用watchService监听配置文件的变更

超时与重传机制

回滚机制

事务回滚

当一个业务涉及的子系统非常多时,完全的回滚是不现实的,此时不必追求分布式事务的强一致性,最终一致性即可。可以考 虑如下手段实现最终一致性:

1. 事务表(事务日志)

2. 消息队列

3. 补偿机制

4. TCC模式

5. Sagas模式

代码库回滚

用git开发方便代码库回溯和回滚

部署版本回滚

部署系统时,要考虑出现错误后的快速恢复,一般采用如下方式:

1. 部署版本化。就是部署发布时是全量发布,不要搞增量发布(只发布修改的部分),这是为了方便版本全量回退

2. 小版本增量发布。修改bug时,只更新一台服务,如果观察OK,再批量更新其他服务

3. 大版本灰度发布。采用新老系统同时在线的方式部署,出了问题能快速回退到老系统。例如URL请求中带版本号,方便快 速切换

4. 架构升级并发发布。例如采用A/B的方式将流量慢慢引入新系统,10%--》20%--》100%

数据版本回滚

静态资源版本回滚

压测与预案

系统压测

压测前需要有压测方案:

1. 压测的接口

2. 并发量

3. 压测策略(突发、逐步加压)

4. 压测指标(机器符合、QPS/TPS、响应时间)

最后是总结压测报告,一般要包括:

1. 压测方案

2. 机器负荷

3. QPS/TPS

4. 响应时间(最大、最小、平均)

5. 成功率

6. 相关参数(JVM参数、压缩参数等) 最后根据压测报告进行系统优化和容灾

线下压测

用jmeter或者ab工具进行压测

线上压测

读/写压测、仿真压测/引流压测、隔离集群压测/线上集群压测、单机压测、离散数据压测

线上压测目前很少公司能做到,需要线上系统进行改造。

系统优化和容灾

应急预案

步骤:

1. 进行系统分级,确认哪些是核心哪些是辅助

2. 对核心服务进行全链路分析,包括网络接入层、应用接入层、web应用层、服务层、数据层

3. 演习

全链路关键路径分析如下所示:

高并发

应用级缓存

缓存类型

应用级缓存由快到慢,也是分级的,如下所示:

具体分为:

1. 堆缓存

2. 堆外缓存

3. 磁盘缓存

4. 分布式缓存

5. 多级缓存

缓存回收策略

缓存都要有回收策略,一般基于以下纬度进行回收:

1. 基于容量

2. 基于空间

3. 基于时间。例如TTL、TTI

4. 基于java对象应用。例如软引用、弱引用

回收算法

回收算法一般如下:

1. FIFO

2. LRU

3. LFU

缓存使用模式

缓存使用模式如下:

1. cache-aside。业务负责对缓存和数据源进行读写

2. cache-as-sor。业务只和缓存读写,由缓存负责和数据源对接

3. copy-pattern。分为:读时拷贝和写时拷贝

cache-aside:

1. 读场景,先读缓存,命中不了则回源读,并且更新到缓存

2. 写场景,先回源写,成功后再写缓存

缺点:可能存在并发更新

cache-as-sor:

1. read-through。通过缓存读数据,如果缓存没有数据,则由缓存和数据源读

2. write-through。通过缓存写数据,由缓存同步到数据源

3. write-behind。通过缓存写数据,缓存可以异步批量写入数据源,可以通过 python脚本定期同步缓存数据源到数据库,注意缓存开启本地文件持久化。

HTTP缓存

httpclient源码包是java中最常用的http包,分析源码了解相关操作

多级缓存

应该一般架构如下所示:

接下来描述各级缓存作用及解决的问题

如何缓存数据

1. 过期与不过期。缓存不要放在DB事务中;存储空间足够可以设置不过期;冷数据设置过期时间或者淘汰机制(例如LRU)

2. 维度化和增量更新。如果某个对象属性特别多,可以根据维度进行拆分缓存,更新时只更新变化部分,不更新所有

3. 大value。尽量避免大value缓存;对大value进行压缩存储;拆分value,由客户端进行聚合

4. 热点数据。增加更多缓存的从节点进行负载均衡;进程内可以缓存一部分

分布式缓存与应用负载均衡

应用负载均衡一般采用轮询或者一致性哈希 轮询优点缺点:

1. 每台应用负荷非常均匀;但缓存命中率低

一致性哈希:

1. 相同请求会转发到同一个节点,缓存命中率高;但遇上热点数据时个别服务器负荷将失衡

两种算法各有优点和缺点,实际最好根据实际情况动态选择哪种算法:

1. 负荷低时,使用一致性哈希

2. 热点请求时将一致性哈希降级为轮询

3. 将热点数据推送到接入层nginx,直接响应给用户

热点数据与缓存更新

单机全量缓存加主从

这种方案如下所示:

缓存更新策略:

1. 懒加载

2. 订阅消息

分布式缓存加应用本地热点

在应用nginx中启用本地缓存,收到请求时优先从本地缓存查数据,如果查不到再向缓存集群请求或者回源系统

本地缓存的热点数据的发现,根据业务实际情况,有些可以提前发现,有些无法预测的,可以建一个热点发现系统(例如 storm集群),将热点数据更新到应用nginx本地缓存,如下所示:

除此之外还可以:

1. 订阅热点数据主题进行更新

2. 周期性更新(允许数据短暂不一致时)

3. 秒杀活动的热点数据可以提前知道,提前推送到nginx

更新缓存与原子性

保证原子性的解决方法:

1. 更新时带时间戳或者版本,只有最新的时间戳或者版本才能更新成功;redis事务单线程,自动满足了串行更新要求

2. 使用代理来更新缓存,例如用canal订阅数据库的binlog,然后更新到缓存。这样可以避免各个应用服务并发更新了

3. 将更新请求放到队列里面,由单线程读取队列进行更新

4. 使用分布式锁

缓存崩溃与快速恢复

备份更多节点、降级

连接池线程池

连接池

连接池包括:

1. 数据库连接池

2. HTTP连接池

线程池

线程池一般有核心线程池和线程池最大大小配置,线程空闲一段时间可能被回收,核心线程不会被回收,如下图所示:

Java提供ExecutorService三种实现:

1. ThreadPoolExecutor

2. ScheduledThreadPoolExecutor

3. ForkJoinPool

异步并发

JAVA中的异步并非真正异步,而是通过线程池来模拟的,实现真正的异步化是很困难滴哦

异步化并不能提升性能,但是可以提升系统吞吐量

异步化手段:

1. 异步Future

2. 异步callback

3. 异步编排CompletableFuture

4. web异步实现:借助servlet3、CompletableFuture实现web服务的异步化

5. 对请求结果进行缓存。可以自定义缓存;也可以使用Hystrix实现请求缓存

6. 请求合并。通过Hystrix可以将多个请求合并为一个批量请求

如何扩容

单体应用垂直扩容

也就是简单的提升硬件配置进行扩容,例如加内存、加CPU、机械硬盘换成SSD等,扩容后依然是单机

单体应用水平扩容

水平扩容就是加机器数量

应用拆分

应用拆分演变过程:

1. 应用拆分为多个,通过RPC进行通信

2. 服务自动注册与发现

3. 功能拆分为前后端,各自发展。前端用上CDN

4. ......

数据库拆分

演变过程:

1. 按照业务纬度进行拆分,例如商品、订单、用户各自独自一个数据库实例(甚至一个物理节点)

2. 读写分离

3. 分表分库

4. 利用缓存

5. 为了数据安全,可以同步双写,但是缺点也很明显

6. 异步双写,也有一定时延,数据不太安全

数据异构

1. 查询维度异构。根据商家或者用户查询维度,将数据组装起来存储到缓存或者ES系统中,以方便查询,减少对DB的访问

2. 聚合数据异构。将一个跨越多表的对象数据聚合在一起,一次就能查询到该对象所有数据

相关推荐

使用 python-fire 快速构建 CLI_如何搭建python项目架构

命令行应用程序是开发人员最好的朋友。想快速完成某事?只需敲击几下键盘,您就已经拥有了想要的东西。Python是许多开发人员在需要快速组合某些东西时选择的第一语言。但是我们拼凑起来的东西在大多数时候并...

Python 闭包:从底层逻辑到实战避坑,附安全防护指南

一、闭包到底是什么?你可以把闭包理解成一个"带记忆的函数"。它诞生时会悄悄记下自己周围的变量,哪怕跑到别的地方执行,这些"记忆"也不会丢失。就像有人出门时总会带上...

使用Python实现九九乘法表的打印_用python打印一个九九乘法表

任务要求九九乘法表的结构如下:1×1=11×2=22×2=41×3=32×3=63×3=9...1×9=92×9=18...9×9=81使用Python编写程序,按照上述格式打印出完整的九...

吊打面试官(四)--Java语法基础运算符一文全掌握

简介本文介绍了Java运算符相关知识,包含运算规则,运算符使用经验,特殊运算符注意事项等,全文5400字。熟悉了这些内容,在运算符这块就可以吊打面试官了。Java运算符的规则与特性1.贪心规则(Ma...

Python三目运算基础与进阶_python三目运算符判断三个变量

#头条创作挑战赛#Python中你学会了三步运算,你将会省去很多无用的代码,我接下来由基础到进阶的方式讲解Python三目运算基础在Python中,三目运算符也称为条件表达式。它可以通过一行代码实现条...

Python 中 必须掌握的 20 个核心函数——set()详解

set()是Python中用于创建集合的核心函数,集合是一种无序、不重复元素的容器,非常适合用于成员检测、去重和数学集合运算。一、set()的基本用法1.1创建空集合#创建空集合empty_se...

15个让Python编码效率翻倍的实用技巧

在软件开发领域,代码质量往往比代码数量更重要。本文整理的15个Python编码技巧,源自开发者在真实项目中验证过的工作方法,能够帮助您用更简洁的代码实现更清晰的逻辑。这些技巧覆盖基础语法优化到高级特性...

《Python从小白到入门》自学课程目录汇总(和猫妹学Python)

小朋友们好,大朋友们好!不知不觉,这套猫妹自学Python基础课程已经结束了,猫妹体会到了水滴石穿的力量。水一直向下滴,时间长了能把石头滴穿。只要坚持不懈,细微之力也能做出很难办的事。就比如咱们的学习...

8÷2(2+2) 等于1还是16?国外网友为这道小学数学题吵疯了……

近日,国外网友因为一道小学数学题在推特上争得热火朝天。事情的起因是一个推特网友@pjmdoll发布了一条推文,让他的关注者解答一道数学题:Viralmathequationshavebeen...

Python学不会来打我(21)python表达式知识点汇总

在Python中,表达式是由变量、运算符、函数调用等组合而成的语句,用于产生值或执行特定操作。以下是对Python中常见表达式的详细讲解:1.1算术表达式涉及数学运算的表达式。例如:a=5b...

Python运算符:数学助手,轻松拿咧

Python中的运算符就像是生活中的数学助手,帮助我们快速准确地完成这些计算。比如购物时计算总价、做家务时分配任务等。这篇文章就来详细聊聊Python中的各种运算符,并通过实际代码示例帮助你更好地理解...

Python学不会来打我(17)逻辑运算符的使用方法与使用场景

在Python编程中,逻辑运算符(LogicalOperators)是用于组合多个条件表达式的关键工具。它们可以将多个布尔表达式连接起来,形成更复杂的判断逻辑,并返回一个布尔值(True或Fa...

Python编程基础:运算符的优先级_python中的运算符优先级问题

多个运算符同时出现在一个表达式中时,先执行哪个,后执行哪个,这就涉及运算符的优先级。如数学表达式,有+、-、×、÷、()等,优先级顺序是()、×、÷、+、-,如5+(5-3)×4÷2,先计算(5-3)...

Python运算符与表达式_python中运算符&的功能

一、运算符分类总览1.Python运算符全景图2.运算符优先级表表1.3.1Python运算符优先级(从高到低)优先级运算符描述结合性1**指数右→左2~+-位非/一元加减右→左3*//...

Python操作Excel:从基础到高级的深度实践

Python凭借其丰富的库生态系统,已成为自动化处理Excel数据的强大工具。本文将深入探讨五个关键领域,通过实际代码示例展示如何利用Python进行高效的Excel操作,涵盖数据处理、格式控制、可视...

取消回复欢迎 发表评论: