本文介绍架构的复杂度来源之一,高性能。
高性能的复杂度主要体现在两面,一是单机实现高性能带来的复杂度,一是集群实现高性能带来的复杂度。
单机中最复杂的就是操作系统,操作系统中与性能有关的就是进程和线程。
在早期,计算机每执行一个操作前,都需要等待用户输入指令,这显然无比低效。于是,后面有了批处理操作系统,提前将需要执行的指令和数据录入,形成一个指令清单,这就是我们常说的“任务”,再让操作系统运行。
不过,CPU的执行速度是很快的,如果发生IO操作,那么CPU就会空闲。于是,为了提高CPU的利用率,出现了进程的概念,一个任务就是一个进程,进程间互不相关,不能相互访问。并且,操作系统不再将一个进程完全执行完毕,而是给每个进程分配一个执行时间,分时地调度进程来执行,当进程在IO的时候,CPU就可以执行其他进程,从而实现了一个并发的执行。
如果进程间不能通信,就只能等待前一个进程将数据写进存储,另一个进程再从存储中读取,这样无疑也是很低效的。于是,后面有了进程通信方式。
多进程让任务可以并发地处理,但还是存在缺陷。比如,如果想让一个进程可以执行多个子任务,那么当一个子任务执行时间较长,那么其他任务就会阻塞住,体现在用户上就是一部分用户执行其他子任务时卡住。于是,为了解决这个场景,进程下有了线程的概念,线程共享进程资源,线程成为CPU更小的调度单位,在进程中并发调度执行。
单处理机下,多进程只能并发运行,即在一个时间间隔运行。为了实现进程并行执行,后面操作系统有了像对称多处理器结构,实现了多进程真正并行运行。
当单台服务器扩展到多台服务器之后,解决复杂度的方式主要有两种,任务分配和任务拆分。
任务分配
通过任务分配器将用户的请求任务按指定的分配算法分配到相应的服务器,每台服务器有完整的请求处理逻辑。
随着用户量增加,首先需要增加服务器。假设原先一台服务器每秒可以处理5000个请求,增加到两台服务器后,理论上每秒可以处理10000个请求,但实际上效果打八折,只能处理8000个请求。

用户量继续增加,任务分配器的性能到达瓶颈,需要从单机变成集群方式。

当从单机变成集群后,复杂度就上来了,体现在:
1、不同用户的请求需要合理地分配到不同的任务分配器,任务分配器又要合理地将请求分配到业务服务器。
2、业务处理器状态管理和故障管理复杂度都增加。
缺点:
当业务逻辑越来越复杂,单纯的任务分配来扩展性能,得到的收益将越来越低。因为单台服务器的处理性能越来越低。
任务拆分
为了解决任务分配方式下,单台服务器到达性能瓶颈,可以采用任务拆分的方法。举例,将一个完整的业务流程拆分成多个处理逻辑,分到多个业务集群中。

优势在于:
1、单个系统功能简单越容易实现高性能
2、业务功能解耦,可以针对单个模块进行扩展,而不影响其他模块
注意,不是业务拆分的越细越好,业务拆分的太细,可能反而会降低性能,因为太多远程调用需要网络传输,将降低响应速率。并且,任务拆分提升的性能也是有限的,需要架构师把控拆分的粒度,让性能逼近这个极限。
我在加密来self正在使用的第三方供应商的值时遇到问题。他们的指令如下:1)Converttheencryptionpasswordtoabytearray.2)Convertthevaluetobeencryptedtoabytearray.3)Theentirelengthofthearrayisinsertedasthefirstfourbytesontothefrontofthefirstblockoftheresultantbytearraybeforeencryption.4)EncryptthevalueusingAESwith:1.256-bitkeysize,2.25
我正在开发西洋跳棋实现,其中有许多易于测试的方法,但我不确定如何测试我的主要#play_game方法。我的大多数方法都可以很容易地确定输入和输出,因此也很容易测试,但这种方法是多方面的,实际上并没有容易辨别的输出。这是代码:defplay_gameputs@gui.introwhile(game_over?==false)message=nil@gui.render_board(@board)@gui.move_requestplayer_input=getscoordinates=UserInput.translate_move_request_to_coordinates(play
方法应返回-1,0或1分别表示“小于”、“等于”和“大于”。对于某些类型的可排序对象,通常将排序顺序基于多个属性。以下是可行的,但我认为它看起来很笨拙:classLeagueStatsattr_accessor:points,:goal_diffdefinitializepts,gd@points=pts@goal_diff=gdenddefothercompare_pts=pointsother.pointsreturncompare_ptsunlesscompare_pts==0goal_diffother.goal_diffendend尝试一下:[LeagueStats.new(
我正在使用Ruby解决一些ProjectEuler问题,特别是这里我要讨论的问题25(Fibonacci数列中包含1000位数字的第一项的索引是多少?)。起初,我使用的是Ruby2.2.3,我将问题编码为:number=3a=1b=2whileb.to_s.length但后来我发现2.4.2版本有一个名为digits的方法,这正是我需要的。我转换为代码:whileb.digits.length当我比较这两种方法时,digits慢得多。时间./025/problem025.rb0.13s用户0.02s系统80%cpu0.190总计./025/problem025.rb2.19s用户0.0
我正在寻找一个用ruby演示计时器的在线示例,并发现了下面的代码。它按预期工作,但这个简单的程序使用30Mo内存(如Windows任务管理器中所示)和太多CPU有意义吗?非常感谢deftime_blockstart_time=Time.nowThread.new{yield}Time.now-start_timeenddefrepeat_every(seconds)whiletruedotime_spent=time_block{yield}#Tohandle-vesleepinteravalsleep(seconds-time_spent)iftime_spent
如果用户是所有者,我有一个条件来检查说删除和文章。delete_articleifuser.owner?另一种方式是user.owner?&&delete_article选择它有什么好处还是它只是一种写作风格 最佳答案 性能不太可能成为该声明的问题。第一个要好得多-它更容易阅读。您future的自己和其他将开始编写代码的人会为此感谢您。 关于ruby-on-rails-如果条件与&&,是否有任何性能提升,我们在StackOverflow上找到一个类似的问题:
关闭。这个问题需要更多focused.它目前不接受答案。想改进这个问题吗?更新问题,使其只关注一个问题editingthispost.关闭8年前。Improvethisquestion我们有以下(以及更多)系统,我们将数据从一个应用推送/拉取到另一个:托管CRM(InsideSales.com)Asterisk电话系统(内部)横幅广告系统(openx,我们托管)潜在客户生成系统(自行开发)电子商务商店(spree,我们托管)工作板(本土)一些工作网站抓取+入站工作提要电子邮件传送系统(如Mailchimp,自主开发)事件管理系统(如eventbrite,自主开发)仪表板系统(大量图表和
我编写了一个Ruby应用程序,它可以解析来自不同格式html、xml和csv文件的源中的大量数据。我如何找出代码的哪些区域花费的时间最长?有没有关于如何提高Ruby应用程序性能的好资源?或者您是否有任何始终遵循的性能编码标准?例如,你总是用加入你的字符串吗?output=String.newoutput或者你会使用output="#{part_one}#{part_two}\n" 最佳答案 好吧,有一些众所周知的做法,例如字符串连接比“#{value}”慢得多,但是为了找出您的脚本在哪里消耗了大部分时间或比所需时间更多,您需要进行分
LL库和HAL库简介LL:Low-Layer,底层库HAL:HardwareAbstractionLayer,硬件抽象层库LL库和hal库对比,很精简,这实际上是一个精简的库。LL库的配置选择如下:在STM32CUBEMX中,点击菜单的“ProjectManager”–>“AdvancedSettings”,在下面的界面中选择“AdvancedSettings”,然后在每个模块后面选择使用的库总结:1、如果使用的MCU是小容量的,那么STM32CubeLL将是最佳选择;2、如果结合可移植性和优化,使用STM32CubeHAL并使用特定的优化实现替换一些调用,可保持最大的可移植性。另外HAL和L
假设我有一个函数defodd_or_evennifn%2==0return:evenelsereturn:oddendend我有一个简单的可枚举数组simple=[1,2,3,4,5]然后我用我的函数在map中运行它,使用一个do-endblock:simple.mapdo|n|odd_or_even(n)end#=>[:odd,:even,:odd,:even,:odd]如果不首先定义函数,我怎么能做到这一点?例如,#doesnotworksimple.mapdo|n|ifn%2==0return:evenelsereturn:oddendend#Desiredresult:#=>[