多进程+进程锁,还是一个进程?

2014-08-10 18:08:10 +08:00
 georgetso
我过去参与的一个项目的服务端为了处理高并发设计如下:
1个linux系统 with 4 cores
1个nginx with 4 worker_processes
1个mysql 实例
4个业务进程

nginx将接受到的请求随机分配给4个业务进程,每个业务进程如果有mysql写入操作,则在 /tmp 产生 project.sock 文件,内容是进程号,待操作完成后,该业务进程负责销毁文件。

我是移动端开发人员,对 iOS_GCD 熟悉,然后也看过 golang_goroutine,所以想如果用 golang 写服务端的话,这个问题怎么解决? 还是多进程+进程锁?

------------------------------------------------------------------

附加问题:
1. nginx 有4个 worker_processes 意思是不是有4个消息队列,虽然能接受每秒十万次请求,但是同时最多只有4个消息被处理?
2. 整个处理流程是不是,一个http请求到达nginx,被nginx通过fcgi转发到业务进程(阻塞nginx的一个worker_process),业务进程接受该请求并进行处理,然后将处理结果返回给nginx,nginx再返回给客户端?如果是这样,那实际上这种架构最多只能同时处理4个请求?再考虑到数据库写操作的锁,那业务效率不是很低么?
4670 次点击
所在节点    问与答
16 条回复
clino
2014-08-10 19:44:54 +08:00
怎么可能才4个,nginx worker接受到一个请求转发给应用以后在返回前就可以去处理其他请求了,并发数可以很高的
georgetso
2014-08-10 20:01:10 +08:00
@clino 哦,原来是这样啊。那是否有可能出现这种情况:
worker1 接收到请求,转发给业务进程,然后 worker1 就玩儿蛋去了
业务进程处理好这个请求后,将结果返回给nginx, 但是却是 worker2 这个接盘侠接收,并将结果返回给客户端?
georgetso
2014-08-10 20:03:11 +08:00
如果 nginx 能用各种方式实现真正的超高并发,但是业务进程怎么做到这点呢?
假如服务器每秒收到1万个请求,难道要创建1万个业务进程去处理请求?
jasontse
2014-08-10 20:06:25 +08:00
nginx 使用 epoll 它是非阻塞的
georgetso
2014-08-10 20:09:34 +08:00
@jasontse 感觉回复。但是我2/3楼提到的问题呢?golang哪怕有协程这种并发机制,但是业务进程始终只能一次处理一个请求吧?这个如何做到高并发呢?
以及,哪怕做到了业务进程高并发,但是数据库写操作锁又怎么解决呢
clino
2014-08-10 21:14:18 +08:00
@georgetso 我的理解是高并发要在每个环节都要能高并发,nginx能高并发只是说在你的应用环境下它不会成为瓶颈而已,其他环节还要你一一考虑解决
georgetso
2014-08-10 22:17:04 +08:00
@clino 是的,我在3楼和5楼也说到了这个。

那么,业务进程怎样做到并发呢?不管是golang的goroutine,还是ios的gcd,都是在一个进程内的并发方案。那么,对于这种成千上万的web请求,有没有办法在1个或少量进程的情况下实现并发处理多个请求呢?
clino
2014-08-10 22:34:18 +08:00
@georgetso 当然可以了,event类的没问题,协程类的在一个进程里开几万个协程就好了
defia
2014-08-11 02:56:11 +08:00
1。利用channel通讯 少用锁
2。设置GOMAXPROC,这个你可以理解为最大线程数,就可以把goroutine分布到不同的核心上去了。

还有为毛要用fastcgi。直接把特定url丢给golang处理就行了。
defia
2014-08-11 02:58:11 +08:00
还有就是一个进程当然是可以同时照顾nnn个请求的,照顾一个那是apache或者php这种阻塞模型。。
sqbing
2014-08-11 10:15:19 +08:00
分析你的业务流程,分解,使用消息队列分发业务请求
为了让nginx最大程度的发挥高并发特性,最好将业务进程中的IO处理也做成异步
georgetso
2014-08-12 15:18:01 +08:00
@defia @clino 好,我现在知道 golang 的非阻塞了。但是,数据库锁怎么解决呢?
要么建立一个线程专门做数据库操作,所有协程最终都以 FIFO 方式排队?这样会不会太慢?
可是如果多个写操作同时操作数据库,那交给数据库自行解决?还是业务负责锁机制?
defia
2014-08-12 17:46:08 +08:00
@georgetso 数据库这个就跟语言无关了啊..取决于你的具体业务,具体哪些地方需要锁需要事务咯,说全这个可以拿出来单独写一章了..

golang是以同步的形式写异步程序,逻辑上是同步阻塞的,但是底层实际是异步的.
clino
2014-08-12 17:50:19 +08:00
这部分我只是了解皮毛,没实践经验,只能抛下砖,一般来说写才会锁数据库,读不会,所以读的并发会比较高,要再高可以用cache/主从数据库 等,要不就用非关系型数据库
clino
2014-08-12 17:57:53 +08:00
当然像前面写的,要提高并发,最好将所有环节都用异步的方式实现,包括数据库的访问
clino
2014-08-12 18:09:13 +08:00
上面写错了,是非阻塞不是异步

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/127078

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX