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

当我们在谈论高并发的时候究竟在谈什么?

  •  2
     
  •   checgg · 2019-06-01 19:03:16 +08:00 · 5239 次点击
    这是一个创建于 2000 天前的主题,其中的信息可能已经有所发展或是发生改变。

    什么是高并发?

    高并发是互联网分布式系统架构的性能指标之一,它通常是指单位时间内系统能够同时处理的请求数,
    简单点说,就是 QPS(Queries per second)。
    

    那么我们在谈论高并发的时候,究竟在谈些什么东西呢?

    https://segmentfault.com/a/1190000019360335

    26 条回复    2019-06-03 10:26:00 +08:00
    opengps
        1
    opengps  
       2019-06-01 19:12:44 +08:00 via Android   ❤️ 2
    文末没有广告,文章内容可信
    checgg
        2
    checgg  
    OP
       2019-06-01 20:57:04 +08:00
    一位常年潜水的个人开发者,没有任何广告哈~~
    写了一些本人的一点沉淀和思考。
    Pythondr
        3
    Pythondr  
       2019-06-01 22:22:40 +08:00 via Android
    写的很好,值得拜读
    best1a
        4
    best1a  
       2019-06-01 22:49:53 +08:00 via iPhone
    current != qps
    mcrwayfun
        5
    mcrwayfun  
       2019-06-01 22:55:43 +08:00
    不是添狗,确实写得好
    lhx2008
        6
    lhx2008  
       2019-06-01 22:57:43 +08:00 via Android
    好像没有什么干货,东拼西凑的。测试也不能说明什么,阻塞之后 netty 不行,应该是你线程没开够。netty 默认给的线程很少。而且 sleep 机制不同语言实现也不同。直接比较没有什么意义。
    Zzdex
        7
    Zzdex  
       2019-06-01 23:04:20 +08:00
    持久层还是 redis,memcached?
    写错了吧
    lhx2008
        8
    lhx2008  
       2019-06-01 23:08:20 +08:00 via Android
    还有两台机器的最大连接数其实是可以至少有几千万个的,因为服务器可以同时开几千个端口,客户端这边连上去就行了
    zjp
        9
    zjp  
       2019-06-01 23:13:53 +08:00
    并行:两个事件同一时刻完成
    应该是 同一时刻进行
    vone
        10
    vone  
       2019-06-02 00:34:45 +08:00
    文中提到:
    本地的最大 HTTP 连接数为:65535 * 本地 ip 数 = 65535 个。
    远端的最大 HTTP 连接数为:65535 * 远端 ip 数 = 无限制~~ 。

    但是 http 协议不应该是 80=>5001,80=>5002 这样吗,服务端始终监听 80 端口,然后客户端自己随机创建端口,那么最大连接数是否不是 tcp 可用端口数量,而应该是系统允许创建最大连接数吗
    hellodudu86
        11
    hellodudu86  
       2019-06-02 01:54:13 +08:00
    写的挺好,爱了
    leeyuzhe
        12
    leeyuzhe  
       2019-06-02 02:14:53 +08:00 via Android   ❤️ 1
    写得好,我选择 Java
    Yvette
        13
    Yvette  
       2019-06-02 02:42:36 +08:00 via iPhone
    503 了…
    blless
        14
    blless  
       2019-06-02 03:40:01 +08:00 via Android
    我觉得写的不行,
    hello world 测试真的太简单了
    想起了之前 python 的 sanic 框架,单 hello world qps 都快赶上 c 语言框架了。实际业务随便接入点啥换成 go 实现都是被秒得渣都不剩
    specita
        15
    specita  
       2019-06-02 04:54:13 +08:00
    mark 下,明天看
    iceheart
        16
    iceheart  
       2019-06-02 05:31:42 +08:00 via Android
    感觉是讲的不够彻底,一半就收尾了,只有测试角度,缺少框架设计上的剖析。为啥这样没说清楚。
    kevinlm
        17
    kevinlm  
       2019-06-02 06:08:43 +08:00 via iPhone
    当初从 web 开发转安卓,就是因为没有类似的经验,也没有实操机会…好羡慕你们这些 web 大佬
    lhx2008
        18
    lhx2008  
       2019-06-02 07:52:04 +08:00 via Android
    @vone socket 四个变量,源 IP,源端口,服务器 IP,服务器端口。你提的,源 IP,服务器 IP,服务器端口都不变,就只剩源端口变量,而这种情况下只能开到 65535,这个是最初设计 TCP 的时候就写死了,16 个 bit。
    系统限制虽然说也是一方面,不过是可以改到挺大的。
    vone
        19
    vone  
       2019-06-02 13:03:30 +08:00 via Android
    @lhx2008 如果有第二台客户机,可连接数是不是会翻一番
    lhx2008
        20
    lhx2008  
       2019-06-02 13:15:17 +08:00
    @vone 如果三台机器都在局域网内部的话,是的。但是我上面也说了,只要服务器开多一个端口,就可以直接翻一番了。
    如果是局域网到公网,可能会被 NAT 限制。
    csidez
        21
    csidez  
       2019-06-02 13:32:00 +08:00
    好厉害!作为一个小白,原谅我只看懂了前面的理论知识,后面的那部分对比和测试我看不懂了....
    wdmx007
        22
    wdmx007  
       2019-06-02 14:06:44 +08:00   ❤️ 1
    笑死我了,在 Netty 的 EventLoop 线程里面 Sleep ,然后还来对比测试结果
    zhuyichen1017
        23
    zhuyichen1017  
       2019-06-02 22:21:57 +08:00
    = = Netty 的 Sleep 具体咋写的。如果真的在 EventLoop 线程里确实是使用不对
    a7217107
        24
    a7217107  
       2019-06-03 09:13:33 +08:00
    厉害诶
    Aruforce
        25
    Aruforce  
       2019-06-03 09:45:50 +08:00
    代码你倒是贴上啊...在哪里 sleep ?
    checgg
        26
    checgg  
    OP
       2019-06-03 10:26:00 +08:00
    @Aruforce @zhuyichen1017

    https://github.com/netty/netty/tree/4.1/example/src/main/java/io/netty/example/http/helloworld

    65-69 行:

    ```
    /*
    * Copyright 2013 The Netty Project
    *
    * The Netty Project licenses this file to you under the Apache License,
    * version 2.0 (the "License"); you may not use this file except in compliance
    * with the License. You may obtain a copy of the License at:
    *
    * http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing, software
    * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
    * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
    * License for the specific language governing permissions and limitations
    * under the License.
    */
    package io.netty.example.http.helloworld;

    import io.netty.buffer.Unpooled;
    import io.netty.channel.ChannelFuture;
    import io.netty.channel.ChannelFutureListener;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.SimpleChannelInboundHandler;
    import io.netty.handler.codec.http.DefaultFullHttpResponse;
    import io.netty.handler.codec.http.FullHttpResponse;
    import io.netty.handler.codec.http.HttpObject;
    import io.netty.handler.codec.http.HttpRequest;
    import io.netty.handler.codec.http.HttpUtil;

    import static io.netty.handler.codec.http.HttpHeaderNames.CONNECTION;
    import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_LENGTH;
    import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_TYPE;
    import static io.netty.handler.codec.http.HttpHeaderValues.CLOSE;
    import static io.netty.handler.codec.http.HttpHeaderValues.KEEP_ALIVE;
    import static io.netty.handler.codec.http.HttpHeaderValues.TEXT_PLAIN;
    import static io.netty.handler.codec.http.HttpResponseStatus.OK;

    public class HttpHelloWorldServerHandler extends SimpleChannelInboundHandler<HttpObject> {
    private static final byte[] CONTENT = { 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd' };

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
    ctx.flush();
    }

    @Override
    public void channelRead0(ChannelHandlerContext ctx, HttpObject msg) {
    if (msg instanceof HttpRequest) {
    HttpRequest req = (HttpRequest) msg;

    boolean keepAlive = HttpUtil.isKeepAlive(req);
    FullHttpResponse response = new DefaultFullHttpResponse(req.protocolVersion(), OK,
    Unpooled.wrappedBuffer(CONTENT));
    response.headers()
    .set(CONTENT_TYPE, TEXT_PLAIN)
    .setInt(CONTENT_LENGTH, response.content().readableBytes());

    if (keepAlive) {
    if (!req.protocolVersion().isKeepAliveDefault()) {
    response.headers().set(CONNECTION, KEEP_ALIVE);
    }
    } else {
    // Tell the client we're going to close the connection.
    response.headers().set(CONNECTION, CLOSE);
    }
    try {
    Thread.sleep(10);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    ChannelFuture f = ctx.write(response);

    if (!keepAlive) {
    f.addListener(ChannelFutureListener.CLOSE);
    }
    }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
    cause.printStackTrace();
    ctx.close();
    }
    }

    ```
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1912 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 16:19 · PVG 00:19 · LAX 08:19 · JFK 11:19
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.