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

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

off999 2025-04-06 19:58 32 浏览 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. 聚合数据异构。将一个跨越多表的对象数据聚合在一起,一次就能查询到该对象所有数据

相关推荐

编写更多 pythonic 代码(十三)——Python类型检查

一、概述在本文中,您将了解Python类型检查。传统上,类型由Python解释器以灵活但隐式的方式处理。最新版本的Python允许您指定显式类型提示,这些提示可由不同的工具使用,以帮助您更...

[827]ScalersTalk成长会Python小组第11周学习笔记

Scalers点评:在2015年,ScalersTalk成长会完成Python小组完成了《Python核心编程》第1轮的学习。到2016年,我们开始第二轮的学习,并且将重点放在章节的习题上。Pytho...

用 Python 画一颗会跳动的爱心:代码里的浪漫仪式感

在编程的世界里,代码不仅是逻辑的组合,也能成为表达情感的载体。今天我们就来聊聊如何用Python绘制一颗「会跳动的爱心」,让技术宅也能用代码传递浪漫。无论是写给爱人、朋友,还是单纯记录编程乐趣,这...

Python面向对象编程(OOP)实践教程

一、OOP理论基础1.面向对象编程概述面向对象编程(Object-OrientedProgramming,OOP)是一种编程范式,它使用"对象"来设计应用程序和软件。OOP的核心...

如何在 Python 中制作 GIF(python做gif)

在数据分析中使用GIF并发现其严肃的一面照片由GregRakozy在Unsplash上拍摄感谢社交媒体,您可能已经对GIF非常熟悉。在短短的几帧中,他们传达了非常具体的反应,只有图片才能传达...

Python用内置模块来构建REST服务、RPC服务

1写在前面和小伙伴们分享一些Python网络编程的一些笔记,博文为《PythonCookbook》读书后笔记整理博文涉及内容包括:TCP/UDP服务构建不使用框架创建一个REST风格的HTTP...

第七章:Python面向对象编程(python面向对象六大原则)

7.1类与对象基础7.1.1理论知识面向对象编程(OOP)是一种编程范式,它将数据(属性)和操作数据的函数(方法)封装在一起,形成一个称为类(Class)的结构。类是对象(Object)的蓝图,对...

30天学会Python编程:8. Python面向对象编程

8.1OOP基础概念8.1.1面向对象三大特性8.1.2类与对象关系核心概念:类(Class):对象的蓝图/模板对象(Object):类的具体实例属性(Attribute):对象的状态/数据方法...

RPython GC 对象分配速度大揭秘(废土种田,分配的对象超给力)

最近,对RPythonGC的对象分配速度产生了浓厚的兴趣。于是编写了一个小型的RPython基准测试程序,试图探究它对象分配的大致速度。初步测试与问题发现最初的设想是通过一个紧密循环来分配实...

30天学会Python编程:2. Python基础语法结构

2.1代码结构与缩进规则定义与原理Python使用缩进作为代码块的分界符,这是Python最显著的特征之一。不同于其他语言使用大括号{},Python强制使用缩进来表示代码层次结构。特性与规范缩进量...

Python 类和方法(python类的方法与普通的方法)

Python类和方法Python类创建、属性和方法具体是如何体现的,代码中如何设计,请继续看下去。蟒蛇类解释在Python中使用OOP?什么是Python类?Python类创建Pyt...

动态类型是如何一步步拖慢你的python程序的

杂谈人人都知道python慢,这都变成了人尽皆知的事情了,但你知道具体是什么拖慢了python的运行吗?动态类型肯定要算一个!动态类型,能够提高开发效率,能够让我们更加专注逻辑开发,使得编程更加灵活。...

用Python让图表动起来,居然这么简单

我好像看到这个emoji:动起来了!编译:佑铭参考:https://towardsdatascience.com/how-to-create-animated-graphs-in-python-bb6...

Python类型提示工程实践:提升代码质量的静态验证方案

根据GitHub年度开发者调查报告,采用类型提示的Python项目维护成本降低42%,代码审查效率提升35%。本文通过9个生产案例,解析类型系统在工程实践中的应用,覆盖API设计、数据校验、IDE辅助...

Python:深度剖析实例方法、类方法和静态方法的区别

在Python中,类方法(classmethod)、实例方法(instancemethod)和静态方法(staticmethod)是三种不同类型的函数,它们在使用方式和功能上有一些重要的区别。理...

取消回复欢迎 发表评论: