请教 JAVA 服务器现在是怎么处理大量的连接的? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
ncisoft
V2EX    Java

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

  •  
  •   ncisoft 2015-11-17 13:10:58 +08:00 via Android 8594 次点击
    这是一个创建于 3675 天前的主题,其中的信息可能已经有所发展或是发生改变。
    由于线程的缺陷, 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     Solana     5481 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 37ms UTC 03:25 PVG 11:25 LAX 19:25 JFK 22:25
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86