Python 版本:2.7
现在需要利用 tornado 实现这个样子的一个功能:
1.利用 tornado 创建多个进程。
2.进程内写有 从数据库读取配置信息 的方法,读取出来的配置信息将会存储在进程中的一个 A 变量中。
3.进程内写有 根据配置信息做出对应的操作 的方法,其中配置信息是从 A 变量中取出的。
4.因为连接数据库比较耗时,所以将配置信息存在变量中,以供下次更快得获取配置信息。数据库中的配置信息会被修改(但频次不确定,有可能半天一次,有可能一天一次,所以不准备用定时任务同步配置信息),当其他服务修改完配置信息后会调用 从数据库读取配置信息 的接口方法。
目前遇到的问题:
假设有 10 个进程在跑,在其他服务修改完配置信息后,其发送的请求只有一次,只会被一个进程竞争到从而调用 从数据库读取配置信息 的方法,但是剩下的 9 个是不会调用该方法的。由于是利用多进程进行处理,所以每个进程的 A 变量是不同的,因此会造成一个进程的 A 变量存放的是半小时前的配置信息,但是另一个进程的 A 变量存放的是刚刚更新的配置信息。 有什么办法可以让每个进程的 A 变量都同步起来呢?
尝试过的解决方案:
1.采用管道( Pipe )通信,在一个进程接收到 从数据库读取配置信息 的调用请求时,通过管道向其他进程发送消息,使他们都调用一次 从数据库读取配置信息 的方法。但是管道通信貌似是阻塞的,而且发出来的一次消息,被消费后就不存在的,也就是说只有一个进程可以收到这条通知。无效~
2.事件方式,灵感来自于 ioloop.add_handler()。但是 google 了一下,貌似只有 ioloop 有这个方法,不知道可不可以对进程添加一个监听事件。
尝试了 2 天,没有好的解决方案,因此来这里求指点~ 谢谢大家啦~~~
1
lzlzlzlz 2018-04-10 16:38:33 +08:00
不知道你是怎么来创建多进程的. 如果是用 multiprocessing 话, 那么里面有 manager 这个模块, 其作用是进程间共享数据.
|
2
zhu327 2018-04-10 18:55:03 +08:00 1
从描述来看,问题点是不是这样的:
1. 需要在 tornado 进程里面更新配置 A, 更新是通过外部调用一个请求过来的 2. 当前只能请求一次,所以只有一个进程的配置被更新了 如果是上面的问题的话,你需要的应该是一种订阅通知的机制,某个事件发生的时候,需要通知到所有的进程 所以建议考虑用 redis 的 PUB/SUB 来实现, etcd 这种专门用来做配置管理的也很合适 另外开发一个进程专门来处理外部调用的请求,收到请求后从数据库读取配置,PUB 配置到 redis,所有 tornado 进程 SUB,收到配置后更新 A |
3
wcsjtu 2018-04-10 23:59:43 +08:00
试试 redis 的发布者 /订阅者模型, 反正同步的 redis 驱动的速度也非常快。。。
|
4
Danic OP @lzlzlzlz 我现在是用 tornado.process.fork_process(4) 这种方式创建进程的,你说的这种方法我今天试试看~
|
7
petelin 2018-04-11 13:02:51 +08:00
我想说要是用 go 的话 这就不是问题了, 有 channel
|
8
petelin 2018-04-11 14:33:18 +08:00
还可以通过 tcp 来通信, 这种方法就是省了 Redis
|
9
sujin190 2018-04-11 20:36:03 +08:00
这个变量 A 在 fork 之前用 multiprocessing 创建成共享内存变量就行了啊,这样 fork 之后任何一个字进程修改了变量的值,其他进程都会同步读取到新的值,只是每次访问共享变量比访问普通变量要慢很多
|
10
bookding0 2018-04-12 16:08:31 +08:00
你说的用 tornado 创建多个进程指的是 fork 出多个 tornado application 的子进程,还是说直接跑多个进程?
|
11
Danic OP @bookding0 我是直接通过 tornado.process.fork_process(4) 这种方式创建多个子进程的。
|
13
Danic OP @petelin 这样会不会导致效率变低呀,网络请求的耗时感觉会长一点,算法那边是要求速度能快一点就好,感觉用一个共享的内存变量应该效率会高一点,但是多进程处理同一个变量会出好多问题。
|
14
Danic OP 开始是考虑了 @zhu327 所述的 redis 中 PUB/SUB 模式,但是我在网上的资料找到是是需要用 redis 环境的,目前服务器不准备配置 redis,所以这个方案先暂时放到后续考虑。
后面我想了一下,与其多个进程维护各自的变量,不如让多个进程去维护一个共享的变量,这样管理也会方便很多,也不会出现多个进程变量不一致的情况。我采用了[https://docs.python.org/2/library/multiprocessing.html#managers]中,第 16.6.1.4. 节的 Sharing state between processes 下的 Server Process 方法,利用 multiprocessing 创建一个服务进程,利用该进程去维护一个变量,然后在其他进程中的操作也会同步到服务进程的变量中。 可是用上述的 Server Process 方法,貌似会遇到锁的问题,我得再研究研究。 先谢过大家了~~~ |