不管是 web 服还是应用服务器,一个用户的请求来了,要获取这个请求的用户数据,如果没有在内存中就可能从数据库(比如说 mongodb)读取,同步获取数据比较直接,异步获取会有回调;但同步担心有累计延迟,大家在实际项目中都是如何设计的呢?
1
lhbc 2016-11-24 20:09:10 +08:00 via iPhone
不谈量谈这些都没有意义啊。
|
2
boyhailong OP @lhbc 啊,对,比如并发在 5k 左右呢
|
3
shiny 2016-11-24 20:14:23 +08:00
1 楼 +1 ,怎么设计一个系统是看需求的。用户量小的情况下,尽量直接简单,开发效率优先,同步是个不错的选择;用户量大而且资金紧张,硬件资源有限的时候需要用最少的硬件达到最高的吞吐量,异步是个很好的选择。
同时还要关注业务系统的瓶颈,有时候瓶颈不在 io ,异步并不能带来多少吞吐量的提升。 |
4
boyhailong OP @shiny 但如何评价两种做法对业务带来的影响呢? 做测试的话,两种都要实现,时间紧的话也是不现实啊
|
5
shiny 2016-11-24 21:03:58 +08:00
@boyhailong 这就需要架构者的经验了。从需求到系统设计,然后大致就能想到哪几个开销比较大的场景,压力来自哪里。
比如密集 update ,往往 I/O 是瓶颈。 如果能把多次 update 放到内存里,合并成单次写入, I/O 压力就会下降,内存开销增大,处理数据时候 CPU 占用上升; I/O 能优化到极致的时候, CPU 可能会成为下一个瓶颈,异步就无法带来显著的性能改善。 |
6
shiny 2016-11-24 21:09:00 +08:00
@boyhailong 再比如,如果读取数据库为主,而且有热点内容,缓存命中率高,这个时候磁盘 I/O 可能不会是瓶颈,可以不上异步;如果读取的数据分布均匀,缓存命中率太低,而且读的数据量比较大,那么就需要用异步方案了,必要时候还要做 sharding 。
|
7
bdbai 2016-11-24 22:10:53 +08:00 via Android
能异步就异步,毕竟 CPU 密集任务没那么多。同步的话 CPU 和 IO 资源都有浪费。
回调只是语言层面的事情。比如 Nodejs ,用上 async/await 的话完全不用操心流程控制和 callback hell 。 |
8
ryd994 2016-11-25 00:11:36 +08:00
其实很多数据库驱动本身就是异步的
|
9
enenaaa 2016-11-25 09:18:16 +08:00
异步, 同步后期你还是要重构。
|
10
tftk 2016-11-25 09:44:33 +08:00
从客户端的角度来看,不管同步还是异步,返回的时间都是那么长,而且异步了你让客户端怎么办?等着?回调?
|
11
waterinet 2016-11-25 09:49:46 +08:00
同步代码简单易维护,异步编码较难性能高。能用同步解决的场景就不要用异步了。
|
12
boyhailong OP @shiny 这个就需要对业务的整个业务流程和运营需求都很清楚,但小公司貌似很随意,没有架构师那种,怎么破
|
13
boyhailong OP @bdbai 异步会增加业务复杂度,可能一个业务被分拆成多个了。
|
14
shiny 2016-11-25 17:29:43 +08:00
@boyhailong 小公司的话,建议团队最熟什么就用什么。随便举个例子,比如团队都熟悉 PHP ,那首选 PHP 同步来写了。比如都能 hold 住 Node.js ,对 es6/es2015 都了解,有异步编程的经验,知道如何用 Async/Await 、 Promise 来解决 callback hell 问题,那用 Node.js 写异步也没有什么问题。
很多时候,找一个人人夸奖的方案其实是自己对驾驭项目不够自信。 几年前,我在仓促之下想找个银弹,就选了据说很牛逼的 MongoDB + 异步的 Python 框架: Tornado (就是 V2EX 用的框架),因为自己不熟,掉进了一个又一个坑。回过头来才发现,解决方案其实是用好你熟悉的语言和数据库,做好 profiling ,找到最关键的点去改善,胜过你仓促之下的技术选型。 技术选型,很多时候考虑的不是技术因素。对于大公司,人才多,资源多,能够去选技术上最理想的方案;小公司更应该考虑现实问题。 |
15
bdbai 2016-11-25 21:09:08 +08:00 via Android
|
16
boyhailong OP @shiny 其实是在一个公司,上一个项目选择 C++,所有都是同步操作,但带来的麻烦也就是异步操作写起来真是很分裂;换了个项目用 java ,就是同步操作;作为吃瓜群众习惯了上一个项目的思维,而且上线并没有遇到大问题觉得还行,可能是惯性思维觉得突然换成同步有点不习惯,说是担心性能,其实没经过测试,谈性能也是空谈。
技术选型这种事情,我参与的比较少,只是觉得能从这个框架的设计思想和实际运用中学到些东西,话说上个月还被公司评级问到适合架构还是写逻辑,思考了几秒,说:写逻辑。。。。。 @bdbai C++我是觉得逻辑上写的很爽的并不多; java 的暂时也不怎么了解; js 和 python 等倒是有些很舒服的封装。楼上说的客户端我也没听懂在说啥。。。。 |
17
bdbai 2016-11-25 22:51:17 +08:00
@boyhailong 要说性能,肯定选异步。
像 C#、 Nodejs 和 Python 这种语言,针对异步操作都有很多优化。就拿 js 来说,也许你以为异步是这样的: ```js function processUserAsync(id, callback) { ..Model.User.getAsync(id, function(err, user) { ....// 一些操作 ....user.saveAsync(function(err, result) { ......callback(err, result); ....}); ..} } ``` 其实可以这样: ```js async function processUserAsync(id) { ..const user = await Model.User.getAsync(id); ..// 一些操作 ..return await user.saveAsync(); } ``` 当然以上纯属虚构,希望你能打消对异步的恐惧 :P |
18
boyhailong OP @bdbai 不是恐惧吧。。。。
|
19
bdbai 2016-11-26 13:41:28 +08:00 via Android
@boyhailong 那就放手异步一把
|