V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
Tracy1997
V2EX  ›  Python

Tcp 服务器编写的一些问题, io 多路复用?多线程?数据库?

  •  
  •   Tracy1997 · 2019-08-13 11:48:41 +08:00 · 3313 次点击
    这是一个创建于 1920 天前的主题,其中的信息可能已经有所发展或是发生改变。
    需求:
    会有大概小几千台机器跟服务器 tcp 长链接,大概每台机器每秒发一个数据过来。然后把这个数据处理下保存到数据库中。

    想法:
    1.因为都是长连接一直比较活跃,想着用 io 多路复用的 select 或者 poll,不知道是否可行? 2.或者用多线程的模式,每个请求过来就开个线程(socket 的 accept 和 recv 都是堵塞的)去处理? 3.目前来说不想每次拿到数据就去存一下这样给数据库压力太大,而是大概拿到个一百条再去 commit 到数据库,不知道还有没有更好的方式?

    不知道大家有没有什么其他的方法去实现?如果我的想法很蠢,请务必狠狠的喷我!我太想进步了。

    想法:
    1.因为都是长连接一直比较活跃,想着用 io 多路复用的 select 或者 poll,不知道是否可行? 2.或者用多线程的模式,每个请求过来就开个线程(socket 的 accept 和 recv 都是堵塞的)去处理? 3.目前来说不想每次拿到数据就去存一下这样给数据库压力太大,而是大概拿到个一百条再去 commit 到数据库,不知道还有没有更好的方式?

    不知道大家有没有什么其他的方法去实现?如果我的想法很蠢,请务必狠狠的喷我!我太想进步了。
    16 条回复    2019-08-14 09:14:15 +08:00
    undefinedsymbol
        1
    undefinedsymbol  
       2019-08-13 12:04:28 +08:00
    windows 平台 iocp,linux 平台 epoll,数据可以先做 redis 缓存,然后再落地进 sql
    securityCoding
        2
    securityCoding  
       2019-08-13 12:14:26 +08:00
    io 多路复用肯定是要的. 数据处理可以扔队列异步处理落库
    我理解的是这场景似乎没有什么难点?不知道楼主的困惑在哪里
    opengps
        3
    opengps  
       2019-08-13 12:20:03 +08:00 via Android   ❤️ 1
    想法没啥大问题,注意扩展成分布式的,不要硬用单机单端口承载
    Tracy1997
        4
    Tracy1997  
    OP
       2019-08-13 13:50:23 +08:00
    @securityCoding 谢谢!但是我这种都是连上不会断开且一直发数据的活跃连接似乎用 select 更好一些?
    @undefinedsymbol 谢谢!主要想知道自己这种方式够不够好,有没有更好的。
    @opengps 谢谢,会再去看看。
    AlvaIM
        5
    AlvaIM  
       2019-08-13 14:03:49 +08:00
    小几千台的话机器性能好 select 也能 hold 住, 但是现在 IO 复用的方案很成熟了, 你可以直接上 libevent,libuv ( C, C++)或者 Netty ( Java ) Tornado,Gevent ( Python ),NodeJS,Golang .............

    数据现在本地内存处理, 只需要把处理结果用队列发送给数据库做持久化就行了
    Mirana
        6
    Mirana  
       2019-08-13 14:16:53 +08:00
    裸用 epoll 肯定是可以的 但是为啥不用 libuv libev 这种已经封装好的库呢
    Twain
        7
    Twain  
       2019-08-13 15:21:26 +08:00
    golang 或者 c 语言版本的 state threads
    useben
        8
    useben  
       2019-08-13 16:49:59 +08:00
    这并发不高,随便开个 epoll+异步队列+线程池就 ok 了,或者直接上 go 简单多了
    reus
        9
    reus  
       2019-08-13 16:56:35 +08:00
    几千个而已,一个连接一个线程不成问题,用 go 也可以。
    如果数据库不够快,可以先写入日志文件,顺序写很快的,然后再异步处理入库。
    如果是时序数据,直接找个时序数据库入就行,一般都够快的,不用日志。
    neocanable
        10
    neocanable  
       2019-08-13 17:00:52 +08:00
    几千台的话,select 都能搞定啊,我觉得最简单了,只要 server 端处理的快,应该不成问题,高大上的不如先搞出来,再升级
    lan894734188
        11
    lan894734188  
       2019-08-13 17:04:22 +08:00
    考虑后续扩展性的话就 MQ+中间处理件+redis 缓存+最后数据库
    lan894734188
        12
    lan894734188  
       2019-08-13 17:06:39 +08:00
    1 秒 1 包不是心跳包么… 判断 UpDown 不建议另外程序读写数据库去操作。中间件处理这个性能压力没那么大
    wlgq2
        13
    wlgq2  
       2019-08-13 18:02:40 +08:00
    https://github.com/wlgq2/uv-cpp
    可以满足你的需求
    liuminghao233
        14
    liuminghao233  
       2019-08-13 18:31:33 +08:00 via iPhone
    直接上 go 应该可以粗暴解决问题
    conn4575
        15
    conn4575  
       2019-08-14 08:23:58 +08:00 via Android
    libuv 或者 tornado,考虑后期后期拓展建议前面加 nginx 代理一下 socket,至少部署两台保证高可用,异步队列处理都是锦上添花看你需求
    yinqi025
        16
    yinqi025  
       2019-08-14 09:14:15 +08:00
    为什么不试试做个缓存???
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3561 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 04:41 · PVG 12:41 · LAX 20:41 · JFK 23:41
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.