老板:把系统从单体架构升级到集群架构!

单体架构到SOA演化的实战路径与避坑指南 单体架构(All in One)与面向服务架构(SOA)并非过时概念,而是应对业务规模、团队扩张与交付压力失衡的技术响应机制。其核心原理在于通过服务拆分缓解模块耦合导致的修改扩散与发布风险,技术价值体现在提升系统可维护性、团队并行效率与故障隔离能力;典型应用场景包括SaaS系统快速迭代、政务平台合规演进及智能仓储等高耦合业务系统的渐进式解耦。本文基于真实生产环境中的压测基线采集、绞杀者模式迁移、本地消息表实现最终一致性等关键实践,深入解析从单体走向SOA过程中必须直面的数据自治、契约治理与组织适配问题。 阅读详情

如题,本文针对工作中实际经验,整理了把一个单体架构的系统升级成集群架构需要做的准备工作,以及为集群架构的升级做指导方针。

本文首先分析了单体架构存在的问题,然后介绍了集群架构(好处、注意的问题、架构图),接着分析了目前系统的主要功能以及集群后需要做哪些调整,然后对集群架构涉及的技术做横向对比,最后确定技术选型。从这几个方面介绍了从单体架构到集群架构的改造过程,希望对你有帮助。

背景

单机存在单点故障的隐患

Jvm内存频繁在某时段报警

单体架构存在的问题

项目目前的架构是单体垂直架构,只有一个服务节点,存在一些问题,以下是对存在问题的分析:

1、服务可用性差

单机部署只有一个节点提供服务,如果服务进程挂掉或服务器宕机导致服务不可用,将会影响用户的正常使用,如果服务重新上线的时间很长,将会严重公司业务开展,对于下单等常规业务带来的损失无法估量。这个问题就是我们常说的单点故障。

2、服务性能存在瓶颈

单机所能承载的读写压力、请求数都是有限的,当系统业务增长到一定程度的时候,单机的硬件资源将无法满足你的业务需求,增加服务器配置所带来的的性能提升与昂贵的成本不成正比,性价比不高。

3、不可伸缩性

单体架构的弊端之一就是伸缩性不强。随着需求和负荷的增长,单体架构的性能满足不了现有需求时,增加服务器资源的手段收效甚微,服务的性能可扩展性低是单体架构的致命缺点。

4、代码量庞大,系统臃肿,牵一发动全身

随着业务功能增加,系统代码量不断增加,系统变得庞大而臃肿,开发人员修改一处代码往往担心会牵涉到其他功能。

据统计,项目后端代码行数高达12万行(Java),前端代码行数高达34万行(html+css+js),日常维护、版本迭代、发版上线的成本也相应增加。每次项目上线前都要对系统进行回归测试,上线时要把项目进行全量打包发布,上线后监测系统日志是否正常,担心会不会影响其他功能模块。

可规划系统拆分。

集群架构

3.1 为什么要集群部署?

1、单点故障
单机部署很容易出现服务挂了之后,没有备用节点,从而影响用户使用。单机对外提供服务,风险很大,服务器任何故障都可能引起整个服务的不可用。

2、性能瓶颈
单机遇到资源瓶颈时,要想支持更大的用户量,性能有较大的提升,一般是优化业务和增加服务器配置。然而这么做只能是杯水车薪,成本巨大并且效果非常有限。而集群部署通过部署多个服务节点水平扩展服务的性能,成倍的增加服务器性能,而且支持动态扩展。

3.2 集群的好处

1、高可用性。提高服务的可用性,只要有一个服务可用就能对外提供服务。高可用性是指,在不需要操作者干预的情况下,防止系统发生故障或从故障中自动恢复的能力。通过把故障服务器上的应用程序转移到备份服务器上运行,集群系统能够把正常运行时间提高到大于99.9%,大大减少服务器和应用程序的停机时间。

2、吞吐量。增加吞吐量,并发量,支持更大的用户量。

3、易扩展。也叫可伸缩性,可伸缩性体现在节点数量的调整,在预知流量增大的情况下,可以提前增加节点。

3.3 集群部署需要注意的问题

1、负载均衡问题。

请求应该由哪个节点处理?–应用集群需要有一个组件来管理请求的分发。–常见的如Nginx

2、session失效问题。

登录请求被节点1处理后session存储在节点1,后续的请求分发到节点2则需要重新登录。

–集群环境下session需要同步。方案:Tomcat自带的session复制、spring session+redis实现分布式session

3、定时任务执行问题。

定时任务分配给哪台机器执行?

确保不会重复执行,最简单的办法就是定时任务拆分出来,只部署一个节点。方案:分布式job框架、分布式锁实现job的分配。

4、缓存一致性问题。

原来缓存在本地的数据,需要保证数据的一致性,实现共享,只保存一份。(比如两个节点各缓存了一份不同版本的数据,就会出现同一个页面刷新,交替展示不一样的数据直到缓存失效)。–Redis

3.4 集群架构

站点部署多个节点,集群前面架设Nginx做负载均衡,Tomcat之间通过Redis实现session共享。

前后端分离

系统功能点及集群部署后需作何调整

4.1 功能点

主要分为这几个大类:用户登录登出、权限控制、业务功能、定时任务。

4.2 用户登录登出的处理

登录涉及到用户信息的存储,目前单机部署,session交给web容器Tomcat管理,存储在内存中。集群环境多个Tomcat,当同一个用户的多次请求被分发到不同的服务器上,假设第一次请求访问的A服务器,创建了一个session,但是第二次请求访问到了B服务器,这时就会出现取不到session的情况,认为用户没有登录,跳到登录页再次让用户登录,如此反复。于是,集群环境中,session共享就成了一个必须要解决的问题。

解决方案:

1.不要有session:大家可能觉得我说了句废话,但是确实在某些场景下,是可以没有session的,在很多接口类系统当中,都提倡【API无状态服务】;也就是每一次的接口访问,都不依赖于session、不依赖于前一次的接口访问;

2.存入cookie中:将session存储到cookie中,但是缺点也很明显,例如:每次请求都得带着session;session数据存储在客户端本地,是有风险的;

3.session同步:多个服务器之间同步session,这样可以保证每个服务器上都有全部的session信息。不过当服务器数量比较多的时候,同步是会有延迟甚至同步失败;

4.粘滞会话:使用Nginx(或其他负载均衡软硬件)中的ip绑定策略,同一个ip只能在指定的同一个机器访问,但是这样做风险也比较大,而且也失去了负载均衡的意义;

5.session分布式存储:把session放到Redis中存储,虽然架构上变得复杂,并且需要多访问一次Redis,但是这种方案带来的好处也是很大的:实现session共享,可以水平扩展(增加Redis服务器);服务器重启session不丢失(不过也要注意session在Redis中的刷新/失效机制);不仅可以跨服务器session共享,甚至可以跨平台(例如网页端和APP端)。

4.3 权限控制的处理

系统中权限控制基于数据库权限表实现,无需调整。

4.4 业务功能的处理

梳理出哪些业务功能会受到影响?影响包括变量的使用。

通过梳理系统中代码,发现目前系统中对数据的缓存其实是缓存在本地jvm内存中的,自己实现了一套缓存过期机制,但是这种方式并未对缓存占据内存大小进行控制,这样缓存使用的内存有无限增长的可能,甚至导致内存泄漏。

这些变量用做本地缓存,存在jvm中,若集群部署,则在各自的jvm进程中都会存一份,不能共享,可能存在如下问题:第一次请求,由服务器A处理,其查询后存了一份数据V1,第二次请求由服务器B处理,刚好数据发生变化,查询后存了一份数据V2,后续请求如果均匀的分发到AB服务器,那么用户看到的数据将一会儿是V1一会儿是V2(在缓存未过期时),这样就造成了数据不一致。

4.5 定时任务的处理

集群部署的初衷是解决JVM内存频繁告警,内存告警的原因可能是定时任务比较耗内存,本次讨论不展开jvm内存频繁告警的问题。另外,系统一旦做集群部署就需要考虑集群环境下的定时任务不能重复执行。

1. 代码拆分

JOB任务耗时耗内存占用服务器资源,对用户操作有一定的影响,将定时任务从项目中拆分出来,单独做个站点跑定时任务,采用单机/集群部署。

拆分的好处:由定时任务耗时耗内存引起的内存告警,可能会影响正常业务进行,拆分的好处之一就是业务隔离。若不拆分,集群部署只能将同一时间的定时任务分散到不同节点执行,分摊内存压力。但若要彻底解决定时任务引起的内存报警,光靠集群部署是不能彻底解决的,因为有可能某一时刻的定时任务都由同一个节点执行,这样又回到单机的状态,还是会发生内存告警问题。若要彻底解决,首先是拆分定时任务独立运行,观察内存情况后再做后续优化。

2. 任务防重复执行

如果将定时任务代码拆分且集群部署或不拆分(原系统集群部署),那么定时执行的任务,需要控制同一个任务触发时只有一个节点执行,可用分布式锁实现、或quartz框架自身支持。

分布式锁方式:执行前先尝试获取锁,获取到则执行,否则不执行。缺点:需引入分布式锁,修改现有业务代码。

quartz自带集群功能的支持:需修改配置文件,同时数据库导入quartz官方的11张表。优点:自带功能,对外透明,不需要改代码,对现有业务影响较小。

集群部署涉及的技术方案对比

5.1 负载均衡方案

在服务器集群中,需要有一台服务器充当调度者的角色,用户的所有请求都会首先由它接收,调度者再根据每台服务器的负载情况将请求分配给某一台后端服务器去处理。

那么在这个过程中,调度者如何合理分配任务,保证所有后端服务器都将性能充分发挥,从而保持服务器集群的整体性能最优,这就是负载均衡问题。

负载均衡种类:DNS、硬件、软件

参考:

负载均衡种类及优缺点

高并发解决方案之一 ——负载均衡

5.2 session共享

Tomcat集群session复制
简介:将一台机器上的Session数据广播复制到集群中其余机器上
使用场景:机器较少,网络流量较小
优点:实现简单、配置较少、当网络中有机器Down掉时不影响用户访问
缺点:广播式复制到其余机器有一定延时,带来一定网络开销

多个服务器之间同步session,这样可以保证每个服务器上都有全部的session信息,不过当服务器数量比较多的时候,同步是会有延迟甚至同步失败;

实现方式参考:Tomcat集群和Session复制说明

spring session+redis实现分布式session

简介:将Session存入分布式缓存集群中的某台机器上,当用户访问不同节点时先从缓存中拿Session信息
使用场景:集群中机器数多、网络环境复杂
优点:可靠性好
缺点:实现复杂、稳定性依赖于缓存的稳定性、Session信息放入缓存时要有合理的策略写入

把session放到Redis中存储,虽然架构上变得复杂,并且需要多访问一次Redis,但是这种方案带来的好处也是很大的:实现session共享,可以水平扩展(增加Redis服务器),应用服务器重启session不丢失(不过也要注意session在Redis中的刷新/失效机制),不仅可以跨服务器session共享,甚至可以跨平台(例如网页端和APP端)。

5.3 定时任务防重复执行

指定某一个节点执行
通过特定IP限制,在定时任务的代码上加一段逻辑:仅某个ip的服务器能运行该定时任务。

优点:解决方法容易理解,部署简单,不需要多套代码。

缺点:

需要修改现有代码;

存在单点问题,只能规定一台服务器运行,发生故障时需要人工介入。

通过锁控制
锁的性质需满足悲观、独占、非自旋、分布式。

在定时任务业务逻辑执行前先尝试获取锁,谁获取到谁执行,拿不到锁就直接放弃,或者进行其他的处理逻辑。

优点:解决单点问题

缺点:无法故障转移

利用quartz集群分布式(并发)部署解决方案

quartz自身提供了集群分布式(并发)部署的一套解决方案,主要解决思路是通过数据库锁的方式实现。

实现原理 和 解决方案 和 Quartz-cluster最佳实践
特性:

1.持久化任务:当应用程序停止运行时,所有调度信息不被丢失,当你重新启动时,调度信息还存在,这就是持久化任务(保存到数据库表中)。

2.集群和分布式处理:当在集群环境下,当有配置Quartz的多个客户端时(节点),采用Quartz的集群和分布式处理时,我们要了解几点好处

  1. 一个节点无法完成的任务,会被集群中拥有相同的任务的节点取代执行。

2) Quartz调度是通过触发器的类别来识别不同的任务,在不同的节点定义相同的触发器的类别,这样在集群下能稳定的运行,一个节点无法完成的任务,会被集群中拥有相同的任务的节点取代执行。

3)分布式体现在当相同的任务定时在一个时间点,在那个时间点,不会被两个节点同时执行。

有两点需要注意:

1)集群配置文件quartz.properties部署的时候必须要一致

2)集群建立起来之后,如果运行过程中需要修改quartz调度器的策略,例如:原来每5天执行一次任务,现在要改成每半个月执行一次,这个时候要修改所有的配置文件,并且要重新执行数据库脚本,或者手动修改数据库中存的corn表达式(容易改错),或找到那条记录删除(多表主外键关联)。

实现步骤:

1)修改quartz.properties配置文件

配置文件详解 和 quartz配置详解

org.quartz.jobStore.misfireThreshold = 120000
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass =org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.dataSource = myDS
org.quartz.jobStore.isClustered = true
org.quartz.jobStore.acquireTriggersWithinLock=true
org.quartz.jobStore.clusterCheckinInterval = 15000
org.quartz.jobStore.maxMisfiresToHandleAtATime = 1

2)导入表结构,

quartz-2.3.0.jar!\org\quartz\impl\jdbcjobstore\tablesmysqlinnodb.sql

DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
DROP TABLE IF EXISTS QRTZ_LOCKS;
DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
DROP TABLE IF EXISTS QRTZ_CALENDARS;
......

图片

优点:

1)框架自带功能,实现方式对外透明

2)不需要改代码,对现有业务影响较小。

缺点:

1)后期如果修改定时任务的执行时间,数据库不会刷新,需手动改库。

2)后期想停掉定时任务需要从数据库中删除或修改下次执行时间为无穷大(只在代码中注掉定时任务的注册不起作用)

5.4 缓存(可选)

第4.4章节中,使用jvm内存缓存了一些基础数据,当集群部署后,这些数据会在每个jvm都缓存一份,无法做到数据唯一性。

Redis
Redis 是完全开源的,遵守 BSD 协议,是一个高性能的 key-value 数据库。

Redis 与其他 key - value 缓存产品有以下三个特点:

•Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。

•Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。

•Redis支持数据的备份,即master-slave模式的数据备份。

Redis 优势

•性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。

•丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。

•原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。

•丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。

Redis与其他key-value存储有什么不同?

•Redis有着更为复杂的数据结构并且提供对他们的原子性操作,这是一个不同于其他数据库的进化路径。Redis的数据类型都是基于基本数据结构的同时对程序员透明,无需进行额外的抽象。

•Redis运行在内存中但是可以持久化到磁盘,所以在对不同数据集进行高速读写时需要权衡内存,因为数据量不能大于硬件内存。在内存数据库方面的另一个优点是,相比在磁盘上相同的复杂的数据结构,在内存中操作起来非常简单,这样Redis可以做很多内部复杂性很强的事情。同时,在磁盘格式方面他们是紧凑的以追加的方式产生的,因为他们并不需要进行随机访问。

Memcache
Memcache特点
Memcache是一套开放源代码的分布式高速缓存系统。Memcache通过在内存里维护一个统一的巨大的hash表,它能够用来存储各种格式的数据,包括图像、视频、文件以及数据库检索的结果等。简单的说就是将数据调用到内存中,然后从内存中读取,从而大大提高读取速度。
1、协议简单:Memcached的服务器客户端通信使用简单的基于文本的协议。
2、基于libevent的事件处理:libevent是个程序库,他将Linux 的epoll、BSD类操作系统的kqueue等时间处理功能封装成统一的接口,能在Linux、BSD、Solaris等操作系统上发挥其高性能。
3、内置内存存储方式:Memcached的数据都存储在内置的内存存储空间中,因此重启Memcached,重启操作系统会导致全部数据消失。另外,内容容量达到指定的值之后Memcached会自动删除不适用的缓存。
4、两阶段哈希结构:Memcached就像一个巨大的、存储了很多对的哈希表,客户端可以把数据存储在多台memcached上。查询数据时,客户端首先计算出阶段一哈希,选中一个节点;客户端将请求发送给选中的节点,然后memcached节点通过计算出阶段二哈希,查找真正的数据(item)并返回给客户端。从实现的角度看,Memcached是一个非阻塞的、基于事件的服务器程序。
5、不互通信的分布式:服务器端并没有分布式功能,不会互相通信以共享信息。分布式是通过客户端实现。

Redis和Memcache区别,优缺点对比
图片

1、 Redis和Memcache都是将数据存放在内存中,都是内存数据库。不过memcache还可用于缓存其他东西,例如图片、视频等等。
2、Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,hash等数据结构的存储。
3、分布式–设定memcache集群,利用magent做一主多从;redis可以做一主多从。都可以一主一从
4、存储数据安全–memcache挂掉后,数据没了;redis可以定期保存到磁盘(持久化)
5、灾难恢复–memcache挂掉后,数据不可恢复; redis数据丢失后可以通过aof恢复
6、Redis支持数据的备份,即master-slave模式的数据备份。

redis和memecache的不同在于:
1、存储方式:
memecache 把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小
redis有部份存在硬盘上,这样能保证数据的持久性,支持数据的持久化(有快照和AOF日志两种持久化方式,在实际应用的时候,要特别注意配置文件快照参数,要不就很有可能服务器频繁满载做dump)。
2、数据支持类型:
redis在数据支持上要比memecache多的多。
3、使用底层模型不同:
新版本的redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。
4、运行环境不同:
redis目前官方只支持LINUX 上运行,从而省去了对于其它系统的支持,这样的话可以更好的把精力用于本系统环境上的优化,虽然后来微软有一个小组为其写了补丁,但是没有放到主干上。

总结一下,有持久化需求或者对数据结构和处理有高级要求的应用,选择redis,其他简单的key/value存储,选择memcache。

5.5 分布式锁(可选)

用于控制定时任务由哪个节点执行,若4.5节中采用quartz自带功能解决,则不需引入分布式锁。

分布式锁三种实现方式:

1、基于数据库实现分布式锁;

2、基于缓存(Redis等)实现分布式锁;

3、基于Zookeeper实现分布式锁。

数据库实现分布式锁
基于数据库实现的分布式锁,是最容易理解的。但是,因为数据库需要落到硬盘上,频繁读取数据库会导致 IO 开销大,因此这种分布式锁适用于并发量低,对性能要求低的场景。

基于数据库实现分布式锁比较简单,绝招在于创建一张锁表,为申请者在锁表里建立一条记录,记录建立成功则获得锁,消除记录则释放锁。

该方法依赖于数据库,优点就是容易理解,实现简单,但缺点也很明显:

1)单点故障问题。一旦数据库不可用,会导致整个系统崩溃。

2)死锁问题。数据库锁没有失效时间,未获得锁的进程只能一直等待已获得锁的进程主动释放锁。倘若已获得共享资源访问权限的进程突然挂掉、或者解锁操作失败,使得锁记录一直存在数据库中,无法被删除,而其他进程也无法获得锁,从而产生死锁现象。

Redis(缓存)实现分布式锁
基于缓存实现分布式锁的方式,也就是说把数据存放在计算机内存中,不需要写入磁盘,减少了 IO 读写。

使用Redis实现分布式锁,通常可以使用 setnx(key, value) 函数来实现分布式锁, 当进程通过 setnx 函数返回 1 时,表示已经获得锁。排在后面的进程只能等待前面的进程主动释放锁,或者等到时间超时才能获得锁。

相对于基于数据库实现分布式锁的方案来说,基于缓存实现的分布式锁的优势表现在以下几个方面:

1)性能更好。数据被存放在内存,而不是磁盘,避免了频繁的 IO 操作。

2)很多缓存可以跨集群部署,避免了单点故障问题。

3)使用方便。很多缓存服务都提供了可以用来实现分布式锁的方法,比如 Redis 的 setnx 和 delete 方法等。

4)可以直接设置超时时间(例如 expire key timeout)来控制锁的释放,因为这些缓存服务一般支持自动删除过期数据。

缺点:

1)锁删除失败、过期时间不好控制

ZK分布式锁实现
ZooKeeper 基于树形数据存储结构实现分布式锁,来解决多个进程同时访问同一临界资源时,数据的一致性问题。ZooKeeper 基于临时顺序节点实现了分布锁 。

临时节点(EPHEMERAL):当客户端与 Zookeeper 连接时临时创建的节点。与持久节点不同,当客户端与 ZooKeeper 断开连接后,该进程创建的临时节点就会被删除。

临时顺序节点(EPHEMERAL_SEQUENTIAL):就是按时间顺序编号的临时节点。

可以解决前两种方法提到的各种问题,比如单点故障、不可重入、死锁等问题。但该方法实现较复杂,且需要频繁地添加和删除节点,所以性能不如基于缓存实现的分布式锁。

缺点:性能不如Redis分布式锁实现。

图片

这里的实现复杂性,是针对同样的分布式锁的实现复杂性,与之前提到的基于数据库的实现非常简易不一样。

基于数据库实现的分布式锁存在单点故障和死锁问题,仅仅利用数据库技术去解决单点故障和死锁问题,是非常复杂的。而 ZooKeeper 已定义相关的功能组件,因此可以很轻易地解决设计分布式锁时遇到的各种问题。所以说,要实现一个完整的、无任何缺陷的分布式锁,ZooKeeper 是一个最简单的选择。

总结来说,ZooKeeper 分布式锁的可靠性最高,有封装好的框架,很容易实现分布式锁的功能,并且几乎解决了数据库锁和缓存式锁的不足,因此是实现分布式锁的首选方法。

总结

技术选择

负载均衡:使用哪种负载均衡策略不需要我们关心,由运维支持,告知需负载均衡即可。(若公司需自己搞,推荐Nginx)

session共享:spring session+redis

定时任务防重复执行:quartz-cluster

缓存:Redis(公司大面积使用)

分布式锁:Redis(公司提供了Redis分布式锁实现)

说的再好,不如行动。不怕慢,就怕站。

Plone单体架构云原生迁移实战:ZODB上云七步法 Plone作为基于ZODB对象数据库的Python内容管理系统,其单体架构与云原生范式存在深层冲突——ZODB的强状态性、blob文件路径硬编码、ZEO的CP一致性约束,均使其无法简单‘搬站’上云。本文从云原生核心原理出发,解析如何通过RelStorage解耦元数据与大文件、EFS实现跨实例blob共享、CloudFront重构缓存语义、ALB+Auto Scaling应对动态负载,将Plone从物理服务器的确定性黑盒,转变为具备弹性伸缩、多AZ容灾、分钟级恢复能力的云原生系统。适用于运行Plone 4/5 阅读详情

相关推荐

深入浅出 -- 系统架构之单体到分布式架构的演变

同时,就算部署业务程序的机器损坏,也不会丢失系统数据,在一定程度上也提升了系统的抗风险性。显然,这种方式虽然成本低,数据交换快,但并不能支撑太大的访问量,当流量增大时,系统很可能因为CPU、内存、带宽、磁盘等各因素出现性能问题,而一旦遇到瓶颈,为了保证系统正常运行,集“前端、后端、运维、测试、售后……以数据库为例,数据库由于并发影响,读取数据越来越慢,所以阻塞在后端服务中等待数据返回的请求越来越多,入站流量远大于出站流量,长此以往,后端服务线程数超负荷,系统再次出现响应缓慢、无返回等严重事故。

xiaoli8748的专栏 1968

Java架构师:单体部署 ->Nginx 集群 -> + Keepalived“高可用”组件 -> + LVS负载均衡

Java架构师:单体部署 ----> 高可用集群

u013250861的博客 2356

Python 静态导入与动态导入

python中模块的静态导入 与 动态导入(运行时指定模块),以及具体对应示例。

慢也好,步子小也好,往前走就好~ 717

02单体应用真的是地狱吗

单体应用(Monolithic Application)是指将整个应用程序作为一个单一的代码库和部署单元的软件架构模式。在单体应用中,所有的功能模块、组件和服务都集中在一个应用中,它们共享同一个数据库和资源。

rainyonelove的专栏 931

ORB-SLAM3复现的详细过程——配置安装及ROS和脚本运行---Ubuntu20.04

所提供的图像具有高动态范围,事先进行了光度标定,用20Hz的帧率采集,分辨率为1024像素*1024像素;需要下载数据集dataset-room1_512_16和rgbd_dataset_freiburg1_desk。在一键安装ROS后,只需要再安装Pangolin即可,其他所有的需要都已经存在。用微型飞行器采集的视觉惯性数据集,包含双目相机和IMU同步测量数据及位姿的真值。第二条命令中的${ROS_PACKAGE_PATH}是自己文件的路径。其采用的相机和IMU传感器,在硬件上进行了时间同步。

琉璃轻纱的博客 1万+

深入了解 CPU 的型号、代际架构与微架构!

深入了解 CPU 的型号、代际架构与微架构!

欢迎朋友,我是一名十多年开发经验的新手,希望多多指教。 3196

java技术--单体架构的集群

1.正对单体架构的不足,演化出了集群 2. 集群就是单体架构的多实例 (1)多个服务器上部署多个服务,每个服务就是一个节点 (2)每个节点就是一个单体架构的服务 (3)部署N个节点,处理业务的能力就提升 N倍(大约) (4)这些节点的集合就叫做集群 3.单体架构使用服务器集群 (1)随着业务的发展,大多数公司会将单体应用进行集群部署,井增加负载均衡服务器(例如Nginx 等〉 (2)...

qq591009234的博客 1472

MPU6050的四元数解算姿态方法

使用MPU6050硬件DMP解算姿态是非常简单的,下面介绍由三轴陀螺仪和加速度计的值来使用四元数软件解算姿态的方法。 我们先来看看如何用欧拉角描述一次平面旋转(坐标变换): MPU6050的四元数解算姿态方法 设坐标系绕旋转α角后得到坐标系,在空间中有一个矢量在坐标系中的投影为,在内的投影为由于旋转绕进行,所以Z坐标未变,即有。 转换成矩阵形式表示为: 即 所以从旋转到可以写成上面仅仅是绕一根轴的旋转,如果三维空间中的欧拉角旋转要转三次: MPU6050的四元数解算姿态方法 上面得到了一个表示旋转的方

qq_41938005的博客 8392

【架构】单体应用->集群->分布式->微服务->ServiceMesh

1. 单体架构 1.1 单体应用 相对的,要理解什么是微服务,那么可以先理解什么是单体应用,在没有提出微服务的概念的“远古”年代,一个软件应用,往往会将应用所有功能都开发和打包在一起。 1.2 集群架构 随着用户规模和业务量的不断上涨,单个应用服务器将出现性能瓶颈,对于PB级的数据和高并发用户大流量访问,单一或者主备的数据库、文件系统都已经不能满足需求,需要集群化来分担负载。当数据规模达到一定规模,传统关系型数据库性能下滑非常严重,通过分库分表也难以应对,为了支撑海量数据和流量,出现了NoSql数据库,

红尘道,红尘练心 976

从0到1:OpenClaw 助力单元测试代码自动化与覆盖率飞升

OpenClaw 的横空出世,宛如一道曙光,照亮了这片黑暗的领域。它作为一款强大的本地 AI 助手,拥有着令人惊叹的能力。OpenClaw 能够深入理解代码的逻辑结构,自动分析代码中的各种功能和潜在的风险点,从而精准地生成高质量的单元测试代码。它就像是一位不知疲倦的测试专家,能够快速、准确地完成那些繁琐的测试编写工作,将开发者从重复劳动中解放出来,让他们能够将更多的精力投入到更具创造性和价值的工作中。

远程部署调试 运行安装 项目调试 二次开发 项目技术新 持续迭代 部分源码免费分享 477

帆软报表导出各种格式之后台导出

我们前面介绍了帆软报表在界面上的导出是通过类似的URL:http://localhost:8075/webroot/decision/view/report?op=export&sessionID=10653244-3e46-408c-bc54-f89a214a9bc7&format=image&extype=PNG 来完成的,就是带OP=export以及format参数来完成的。如果不从界面传参数,比如我们自己实现了一个HTTP接口,也可以通过传参数format来完成各种格式的导

帆软爱好者的专栏 4270

Java集群实战:单体架构升级到集群架构(一)使用NGINX建立集群

对于大厂的IT技术人员来说,微服务架构是天天都在使用,滚瓜烂熟了。而对小厂的菜鸟程序员来说,我们天天做的都是CRUD,对我们来说集群、分布式、微服务也只是头脑中一个模糊的概念。我们写的大多是单体架构的系统,运行在一台服务器上,如果用户量增加了,服务器撑不住了,我们就加配置吧,反正阿里云腾讯云现在加配置也很容易。但是如果有一天(希望所有菜鸟都有这么一天),我们的用户数增加太快太多,使用最高配置的服务器还是撑不住,对我们来说这算不算是幸福的烦恼?――幸福的是老板,烦恼的却是我们。

dengxiaodai的专栏 2627

Smart PLC高速脉冲输入计米轮模块(编码器测速/计米详细讲解)

线缆行业单绞机PLC控制算法详细解读可以参看下面的文章链接:线缆行业单绞机控制算法(详细图解+代码)_RXXW_Dor的博客-优快云博客在了解单绞机之前需要大家对收放卷以及排线控制有一定的了解,不清楚的可以参看下面几篇博客,这里不再赘述,受水平和能力所限,文中难免出现错误和不足之处,诚恳的欢迎大家批评和指正。PLC张力控制(开环闭环算法分析)_RXXW_Dor的博客-优快云博客_plc闭环控制实例。SMART PLC时间间隔定时器应用(高速脉冲测频/测速)_RXXW_Dor的博客-优快云博客。

RXXW_Dor的博客 2819

老板下了死命令,要上微服务!

你知道的越多,不知道的就越多,业余的像一棵小草!你来,我们一起精进!你不来,我和你的竞争对手一起精进!编辑:业余草cnblogs.com/PatrickLiu推荐:https://www....

xmt1139057136的专栏 637

openlayers:实现在连续更改时间维度时如何平滑地重新加载层 (附完整源码)

openlayers:实现在连续更改时间维度时如何平滑地重新加载层 (附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 348

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

第30周Java分布式入门 分布式基础

*一致性(Consistency)**🌟所有节点同时看到相同数据。如:节点1写入X=100后,节点2读取必须也是100。**可用性(Availability)**🌟每次请求都能获得有效响应。如:购物网站必须即时显示商品库存(即使数据可能不是最新)。**分区容错性(Partition Tolerance)**🌟网络故障时系统仍可运行。如:跨国服务器集群能容忍中美海底光缆中断。维度集群分布式部署内容同一项目的多个副本不同项目/模块部署核心目的分散压力、负载均衡多节点协同工作协作方式无需业务协作。

Sweeping_Robot的博客 1035

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

架构演变 之 超市进化

使用Serverless→ 通常不分层,一个函数干一件事。-微服务架构下的每个服务,可以是单体,也可以是分层架构。

zzginfo的专栏 1054

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Kubernetes 企业级指南第三版(七)

在本章中,我们学习了单体应用和微服务在 Istio 中的运行方式。我们探讨了何时以及为何使用这两种方法。我们部署了一个单体应用,并确保单体应用的会话管理正常工作。然后我们开始部署微服务,进行请求身份验证、授权请求,最后讨论了服务如何安全地进行通信。最后,我们讨论了在使用 Istio 时,API 网关是否仍然必要。Istio 可能比较复杂,但如果使用得当,它可以提供相当强大的功能。本章未涉及的是如何构建容器并管理服务的部署。我们将在下一章,第十八章提供多租户平台中讨论这个问题。

龙哥盟 891

《大型网站技术架构》-大型网站技术架构背后的系统性思维(精华解读)

分布式架构的核心不是“拆分”,而是“解耦”——让每个模块聚焦自己的核心职责,通过标准化的接口通信,既提升了开发效率,又能通过横向增加服务器节点,应对业务规模的扩张。要灵活性,就要接受一定的复杂性。以淘宝的双11架构为例:双11的峰值流量是平时的几十倍,既要应对亿级用户的并发访问,又要保障订单、支付的准确性,这对架构是巨大的考验。当我们下次在亿级流量的网站上流畅操作时,不妨想一想背后那套“生长”出来的技术骨架——它没有多么玄妙,却在一次次迭代中,用最务实的方式,支撑着业务的增长,守护着用户的体验。

uzong 726

从单体到分布式:大数据架构的演进之路

本文旨在用“从小到大”的视角,解释大数据架构为何从简单的单体模式演变为复杂的分布式系统。内容覆盖架构演进的关键阶段(单体→垂直扩展→分布式)、核心技术(分片、副本、一致性算法),以及实际应用场景(如电商大促、日志分析)。本文从“奶茶店的烦恼”故事引入,逐步拆解单体架构的瓶颈;通过“开分店”类比分布式架构的核心设计;结合代码示例和数学模型(如CAP定理)讲解技术细节;最后以实战案例(Hadoop集群搭建)和未来趋势收尾。单体架构:简单但“扛不住”,适合小业务(如日均1万订单)。分布式架构。

AI云原生与云计算技术学院 650

程序人家:你的老板逼你上微服务了吗??

可均可可读完需要10分钟速读仅需 3分钟这些年软件的设计规模越来越庞大,业务需求也越来越复杂,针对系统的性能、高吞吐率、高稳定性、高扩展等特性提出了更高的要求。可以说业务需求是软件架构...

中生代技术 398

分布式基础知识点

水一期

weixin_50216991的博客 344

系统架构设计实战:从零构建可演进的业务系统

系统架构是将业务需求转化为稳定、可扩展技术系统的顶层设计方法。其核心在于理解数据一致性、服务通信、计算边界与部署形态四大支柱的协同原理,通过最小可行架构(MVA)降低试错成本,并以契约驱动、分层建模和可观测性保障工程落地质量。在微服务普及与云原生深化的背景下,架构决策直接影响高并发响应、多端接入弹性及长期技术债水平。本文聚焦连锁零售、社区服务等典型中型业务场景,结合MySQL事务模型、OpenAPI契约、Docker轻量编排与幂等性设计等关键技术实践,提供一套可验证、可度量、可演进的架构构建路径。

weixin_30667649的博客 485
上一篇: 从一道面试题开始学习JVM:Java最大栈深度有多大?
下一篇: 阿里P8整理的《百亿级并发系统设计》实战教程,实在是太香了
Java技术那些事儿
博客等级 码龄5年 2306粉丝 2584原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值