首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python 学习手册
Python Cookbook
Python 基础教程
Python Sites
PyPI - Python Package Index
http://www.simple-is-better.com/
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 · 165 天前 · 1840 次点击
    这是一个创建于 165 天前的主题,其中的信息可能已经有所发展或是发生改变。
    需求:
    会有大概小几千台机器跟服务器 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   165 天前
    windows 平台 iocp,linux 平台 epoll,数据可以先做 redis 缓存,然后再落地进 sql
    securityCoding
        2
    securityCoding   165 天前
    io 多路复用肯定是要的. 数据处理可以扔队列异步处理落库
    我理解的是这场景似乎没有什么难点?不知道楼主的困惑在哪里
    opengps
        3
    opengps   165 天前 via Android   ♥ 1
    想法没啥大问题,注意扩展成分布式的,不要硬用单机单端口承载
    Tracy1997
        4
    Tracy1997   165 天前
    @securityCoding 谢谢!但是我这种都是连上不会断开且一直发数据的活跃连接似乎用 select 更好一些?
    @undefinedsymbol 谢谢!主要想知道自己这种方式够不够好,有没有更好的。
    @opengps 谢谢,会再去看看。
    AlvaIM
        5
    AlvaIM   165 天前
    小几千台的话机器性能好 select 也能 hold 住, 但是现在 IO 复用的方案很成熟了, 你可以直接上 libevent,libuv ( C, C++)或者 Netty ( Java ) Tornado,Gevent ( Python ),NodeJS,Golang .............

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