V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
ncisoft
V2EX  ›  Java

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

  •  
  •   ncisoft · 2015-11-17 13:10:58 +08:00 via Android · 7920 次点击
    这是一个创建于 3279 天前的主题,其中的信息可能已经有所发展或是发生改变。
    由于线程的缺陷, JAVA 在处理大量连接方面存在诸多限制,然后各种反人类的技术,如 Erlang node.js scala 开始大行其道,还有 golang 也出来了。有段时间没跟踪技术了,请教现在是什么情况,是否有新技术出现解决这个问题了?
    50 条回复    2016-09-27 11:04:59 +08:00
    aisk
        1
    aisk  
       2015-11-17 13:22:37 +08:00
    有线程池的情况下多线程也不是什么大问题。
    garfeildma
        2
    garfeildma  
       2015-11-17 13:25:22 +08:00
    netty 不是很好么
    raysonx
        3
    raysonx  
       2015-11-17 13:28:11 +08:00   ❤️ 2
    不谈语言下的实现,现在比较高效地处理大量连接一般都是用 Linux 下的 epoll 系统调用。让系统内核管理连接,当某个连接发来数据时,回调你的程序处理,这样既可以避免为每个用户单独创建线程加大开销,也不用去浪费 CPU 时间去轮询每一个套接字。
    akira
        4
    akira  
       2015-11-17 13:31:56 +08:00
    不要指望一个语言打天下呀
    helloworldwt
        5
    helloworldwt  
       2015-11-17 13:38:03 +08:00
    java 线程池+nio 技术可以应对一些情况
    canesten
        6
    canesten  
       2015-11-17 13:43:56 +08:00
    tedeyang
        7
    tedeyang  
       2015-11-17 13:48:21 +08:00
    楼主好好研究 Java7 的 AIO 吧。也可以用 Netty
    HunterPan
        8
    HunterPan  
       2015-11-17 13:49:49 +08:00
    复用复用复用
    feilaoda
        9
    feilaoda  
       2015-11-17 14:32:02 +08:00
    > 由于线程的缺陷, JAVA 在处理大量连接方面存在诸多限制

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

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

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

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

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