V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
ncisoft
V2EX  ›  Java

请教 JAVA 服务器现在是怎么处理大量的连接的?

  •  
  •   ncisoft · Nov 17, 2015 via Android · 8885 views
    This topic created in 3815 days ago, the information mentioned may be changed or developed.
    由于线程的缺陷, JAVA 在处理大量连接方面存在诸多限制,然后各种反人类的技术,如 Erlang node.js scala 开始大行其道,还有 golang 也出来了。有段时间没跟踪技术了,请教现在是什么情况,是否有新技术出现解决这个问题了?
    50 replies    2016-09-27 11:04:59 +08:00
    aisk
        1
    aisk  
       Nov 17, 2015
    有线程池的情况下多线程也不是什么大问题。
    garfeildma
        2
    garfeildma  
       Nov 17, 2015
    netty 不是很好么
    raysonx
        3
    raysonx  
       Nov 17, 2015   ❤️ 2
    不谈语言下的实现,现在比较高效地处理大量连接一般都是用 Linux 下的 epoll 系统调用。让系统内核管理连接,当某个连接发来数据时,回调你的程序处理,这样既可以避免为每个用户单独创建线程加大开销,也不用去浪费 CPU 时间去轮询每一个套接字。
    akira
        4
    akira  
       Nov 17, 2015
    不要指望一个语言打天下呀
    helloworldwt
        5
    helloworldwt  
       Nov 17, 2015
    java 线程池+nio 技术可以应对一些情况
    tedeyang
        7
    tedeyang  
       Nov 17, 2015
    楼主好好研究 Java7 的 AIO 吧。也可以用 Netty
    HunterPan
        8
    HunterPan  
       Nov 17, 2015
    复用复用复用
    feilaoda
        9
    feilaoda  
       Nov 17, 2015
    > 由于线程的缺陷, JAVA 在处理大量连接方面存在诸多限制

    如果仅是大量链接,不需要新技术也没什么问题。
    要并发,有一堆可以参考, netty , AIO ,还有 scala 的 akka
    ncisoft
        10
    ncisoft  
    OP
       Nov 17, 2015
    谢谢各位的回复, java 技术进步得还是不够呀
    ncisoft
        11
    ncisoft  
    OP
       Nov 17, 2015
    @feilaoda 如果仅仅是处理静态资源,要 java 干什么, nginx 就够用了。现在要解决的是大量连接和后台大量 java servlet 线程之间的矛盾
    ryd994
        12
    ryd994  
       Nov 17, 2015 via Android   ❤️ 1
    @ncisoft 如果资源够的话就多服务器, Nginx 做负载均衡
    资源不够的话就 Nginx 控制并发,其余的等待。

    另外,如果大量连接是由于客户端上传下载慢的话,可以增加 Nginx 的 buffer ,由 Nginx 负责收发,等数据齐了以后一次性发到后端,返回给客户端的时候也是同理。

    当然,你有时间有精力维护异步代码的话,异步自然是更好。
    youxiachai
        13
    youxiachai  
       Nov 17, 2015
    其实..大部分人...都用不上处理大量链接吧....
    ncisoft
        14
    ncisoft  
    OP
       Nov 17, 2015 via Android
    @youxiachai 对,我只是作为一个技术问题探讨
    hantsy
        15
    hantsy  
       Nov 17, 2015
    看看 Netflix 的技术架构和开源项目( Spring Cloud 现在全部集成了 NetFlix 开源项目)就明白了,,,处理那种高并发复杂场景怎么可能一两种技术就可以解决的。
    martifact
        16
    martifact  
       Nov 17, 2015   ❤️ 1
    现在面向线程的模型都不怎么用了吧, 都是基于事件的,把事件和处理调度到线程池。 Erlang 和 Scala 的 Actor 模型,通过消除数据竞争提高并发, Go 自己实现调度。
    canesten
        17
    canesten  
       Nov 17, 2015   ❤️ 1
    @ncisoft
    仅仅是 servlet 么?可以试试基于 netty 的 undertow
    ncisoft
        18
    ncisoft  
    OP
       Nov 17, 2015
    @canesten undertow 有点意思,谢谢
    odirus
        20
    odirus  
       Nov 17, 2015
    Netty+1 ,话说我现在正在写 Netty 为基础的项目,挺好用的,而且实际通过工具分析来看,内存消耗、 CPU 消耗都非常满意。

    更优秀的地方就是 Netty 实现了大部分通信协议,从 TCP 到 HTTP ,以及中间的很多协议。
    Cloudee
        21
    Cloudee  
       Nov 17, 2015
    Servlet 从 3.0 开始支持异步了, SpringMVC 也有对应的支持,好好写的话可以释放掉 Servlet 占用的大量线程。但是目前我遇到的问题在于 JDBC 本身是同步的,因此各种 DAO 框架也是同步的,会有大量线程卡在数据库那边
    ncisoft
        22
    ncisoft  
    OP
       Nov 17, 2015 via Android
    @Cloudee 这是 JAVA 要处理的关键架构问题
    ncisoft
        23
    ncisoft  
    OP
       Nov 17, 2015 via Android
    各位,谢谢你们的回复,让我对当前的技术有了一定的了解。但是, netty nio 解决不了 service 层大量的线程问题,你们遇到过几百个 java 线程耗尽 CPU 资源,耗尽 db 资源的情况么。 nio 绝对不是银弹, coroutine 写起来太麻烦了,同步线程方式才是写代码的王道
    ncisoft
        24
    ncisoft  
    OP
       Nov 17, 2015 via Android
    单纯线程池也不是解决问题的正确道路
    cloudzhou
        25
    cloudzhou  
       Nov 17, 2015
    @ncisoft 如果你单单指的是性能的话, netty 绝不逊于其他各种语言的实现方式。对于 Linux 机器,说到底都是 Epoll 模型。 Netty 基于函数回调,并不是需要依赖于大量的线程。
    HunterPan
        26
    HunterPan  
       Nov 17, 2015
    @ncisoft 几百个线程耗尽 cpu ,你用来处理 CPU 密集型的业务固然耗费 CPU ,如果 DB 资源耗尽,一般不就是请求 db 太多,或者没有缓存么
    ncisoft
        27
    ncisoft  
    OP
       Nov 17, 2015
    @cloudzhou 你还是没有明白我的意思, netty 只是解决了网络层的连接问题,可是后面的 service db layer 你跑不掉吧,这个不用线程怎么处理?
    ncisoft
        28
    ncisoft  
    OP
       Nov 17, 2015
    @HunterPan 缓存是不能包打天下的,你当都是微博、论坛、商城么,有的是不能依赖于缓存的业务系统。如果不是 cpu 密集,难道 service 层只做简单处理?
    SparkMan
        29
    SparkMan  
       Nov 17, 2015
    Netty 不就跟 Node.js 一样嘛。都是异步的,又不是每个连接就创建一个线程
    china521
        30
    china521  
       Nov 17, 2015
    @ncisoft 所以才有了 golang, 我生产环境跑两年了,高并发,内存 CPU 一点压力都没
    SparkMan
        31
    SparkMan  
       Nov 17, 2015
    你说的“后面的 service db layer ”,不光 Netty ,别的语言也要处理这个问题,所以现在都 做分布式
    paw
        32
    paw  
       Nov 17, 2015
    前端负载均衡到后端 N 台机器。。。
    martifact
        33
    martifact  
       Nov 17, 2015
    如果有 db 处理的话,就用 async-jdbc, jdbc 做连接池管理和负载均衡, 非阻塞返回 Future 对象添加回调。不过都没有比较正式的库,有一个用 netty 实现的 https://github.com/mauricio/postgresql-async
    ncisoft
        34
    ncisoft  
    OP
       Nov 17, 2015
    @china521 这要看应用特征的吧,可能你的应用就适合 golang 。 ps 并发连接峰值能有多少?
    ncisoft
        35
    ncisoft  
    OP
       Nov 17, 2015
    @martifact 你的方案是把 db 给累死吗?
    martifact
        36
    martifact  
       Nov 17, 2015
    @ncisoft 只不过把同步处理改异步,同样有连接数上限,哪来的累死
    ncisoft
        37
    ncisoft  
    OP
       Nov 17, 2015
    @paw 前端负载均衡到后端 N 台机器。。。这不是 java 方案吧
    china521
        38
    china521  
       Nov 17, 2015
    @ncisoft golang 本身就是处理大并发这种业务的, 好比把业务做成 lua 脚本放到 redis 里跑一样高效.. Java 不太好评论,可能是历史原因..
    ncisoft
        39
    ncisoft  
    OP
       Nov 17, 2015 via Android
    @china521 不讨论 golang ,不挑起语言争论,
    cloudzhou
        40
    cloudzhou  
       Nov 17, 2015
    @ncisoft 后面的 service db layer 这一块,在各种语言都是类似的,由类似“协程”的概念执行。
    也就是说,并没有完全的异步,比如 orm 这一块。
    现在多并发的解决方案,都是监听 M 个链接,如果有读写操作,就激发对应的行为,有使用回调也有不用的,不用的你可以理解为语言级别帮你做了。
    在 Java 里面,也不是一个链接起一个线程,而是把这个链接的 Context 关联起来,当激发回调方法之后接着进行处理,和线程关系是 M : N 的模型, M 是链接数, N 是线程,其中 M 远远大于 N 。

    类似 Golang ,是一种比较激进的做法, Goroutine 是一种非抢占式的运行,直到因为 IO 事件进行切换,所以对线程数需求非常的少。
    motorme
        41
    motorme  
       Nov 17, 2015
    老大,云风的 https://github.com/cloudwu/skynet 会不会对你的口味, c + lua ,通过 lua coroutine 来模拟 erlang 的 actor 模式
    --lgq
    ncisoft
        42
    ncisoft  
    OP
       Nov 17, 2015 via Android
    @motorme QQ 上跟你讨论
    datou552211
        43
    datou552211  
       Nov 17, 2015 via iPhone
    @raysonx io 密集的这种方式比较高效
    a610569731
        44
    a610569731  
       Nov 17, 2015 via iPhone
    围观大神
    tonyVex
        45
    tonyVex  
       Nov 18, 2015
    围观大神,到了一定的连接数, IO 会不会成为瓶颈
    windyboy
        46
    windyboy  
       Nov 18, 2015
    准确来说处理阻塞问题,使用费阻塞模型
    补充一点 关于 linux 的 epoll 机制,我上次看一个有关 unix 的话题的时候有人说道有根本上的设计缺陷
    呵呵
    RisingV
        47
    RisingV  
       Nov 18, 2015
    vert.x akka 不错。但终究, java 作为一门编程语言,可以发挥的余地,解决 c10k 问题绝对是够了。你功力够深,就算只基于 j2se 提供的东西也能解决问题。只是明白这个过程的人,知道怎么选取哪些更加现成的东西。所谓技术进步,不是说这样一些问题是技术进步了才解决了,其实是商业模式的变迁,导致有些问题变得普遍了,就会有更加现成的方案去降低门槛和成本。计算机真正能谈得上的“进步”其实是很缓慢的。我等不过还是在工程界拼拼凑凑。
    cYcoco
        48
    cYcoco  
       Nov 18, 2015
    nodejs 本身就是一个和 netty 差不多的东西吧
    macemers
        49
    macemers  
       Feb 16, 2016
    @raysonx 可以再详细谈谈 epoll 调用实现并发的机制或者使用场景么?或者能给出点参考资料么?
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   3309 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 83ms · UTC 13:09 · PVG 21:09 · LAX 06:09 · JFK 09:09
    ♥ Do have faith in what you're doing.