
什么是高并发?
高并发是互联网分布式系统架构的性能指标之一,它通常是指单位时间内系统能够同时处理的请求数, 简单点说,就是 QPS(Queries per second)。 那么我们在谈论高并发的时候,究竟在谈些什么东西呢?
1 opengps 2019-06-01 19:12:44 +08:00 via Android 文末没有广告,文章内容可信 |
2 checgg OP 一位常年潜水的个人开发者,没有任何广告哈~~ 写了一些本人的一点沉淀和思考。 |
3 Pythondr 2019-06-01 22:22:40 +08:00 via Android 写的很好,值得拜读 |
4 best1a 2019-06-01 22:49:53 +08:00 via iPhone current != qps |
5 mcrwayfun 2019-06-01 22:55:43 +08:00 不是添狗,确实写得好 |
6 lhx2008 2019-06-01 22:57:43 +08:00 via Android 好像没有什么干货,东拼西凑的。测试也不能说明什么,阻塞之后 netty 不行,应该是你线程没开够。netty 默认给的线程很少。而且 sleep 机制不同语言实现也不同。直接比较没有什么意义。 |
7 Zzdex 2019-06-01 23:04:20 +08:00 持久层还是 redis,memcached? 写错了吧 |
8 lhx2008 2019-06-01 23:08:20 +08:00 via Android 还有两台机器的最大连接数其实是可以至少有几千万个的,因为服务器可以同时开几千个端口,客户端这边连上去就行了 |
9 zjp 2019-06-01 23:13:53 +08:00 并行:两个事件同一时刻完成 应该是 同一时刻进行 |
10 vone 2019-06-02 00:34:45 +08:00 文中提到: 本地的最大 HTTP 连接数为:65535 * 本地 ip 数 = 65535 个。 远端的最大 HTTP 连接数为:65535 * 远端 ip 数 = 无限制~~ 。 但是 http 协议不应该是 80=>5001,80=>5002 这样吗,服务端始终监听 80 端口,然后客户端自己随机创建端口,那么最大连接数是否不是 tcp 可用端口数量,而应该是系统允许创建最大连接数吗 |
11 hellodudu86 2019-06-02 01:54:13 +08:00 写的挺好,爱了 |
12 ThisDay 2019-06-02 02:14:53 +08:00 via Android 写得好,我选择 Java |
13 Yvette 2019-06-02 02:42:36 +08:00 via iPhone 503 了… |
14 blless 2019-06-02 03:40:01 +08:00 via Android 我觉得写的不行, hello world 测试真的太简单了 想起了之前 python 的 sanic 框架,单 hello world qps 都快赶上 c 语言框架了。实际业务随便接入点啥换成 go 实现都是被秒得渣都不剩 |
15 specita 2019-06-02 04:54:13 +08:00 mark 下,明天看 |
16 iceheart 2019-06-02 05:31:42 +08:00 via Android 感觉是讲的不够彻底,一半就收尾了,只有测试角度,缺少框架设计上的剖析。为啥这样没说清楚。 |
17 kevinlm 2019-06-02 06:08:43 +08:00 via iPhone 当初从 web 开发转安卓,就是因为没有类似的经验,也没有实操机会…好羡慕你们这些 web 大佬 |
18 lhx2008 2019-06-02 07:52:04 +08:00 via Android @vone socket 四个变量,源 IP,源端口,服务器 IP,服务器端口。你提的,源 IP,服务器 IP,服务器端口都不变,就只剩源端口变量,而这种情况下只能开到 65535,这个是最初设计 TCP 的时候就写死了,16 个 bit。 系统限制虽然说也是一方面,不过是可以改到挺大的。 |
20 lhx2008 2019-06-02 13:15:17 +08:00 @vone 如果三台机器都在局域网内部的话,是的。但是我上面也说了,只要服务器开多一个端口,就可以直接翻一番了。 如果是局域网到公网,可能会被 NAT 限制。 |
21 csidez 2019-06-02 13:32:00 +08:00 好厉害!作为一个小白,原谅我只看懂了前面的理论知识,后面的那部分对比和测试我看不懂了.... |
22 wdmx007 2019-06-02 14:06:44 +08:00 笑死我了,在 Netty 的 EventLoop 线程里面 Sleep ,然后还来对比测试结果 |
23 zhuyichen1017 2019-06-02 22:21:57 +08:00 = = Netty 的 Sleep 具体咋写的。如果真的在 EventLoop 线程里确实是使用不对 |
24 a7217107 2019-06-03 09:13:33 +08:00 厉害诶 |
25 Aruforce 2019-06-03 09:45:50 +08:00 代码你倒是贴上啊...在哪里 sleep ? |
26 checgg OP @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);br /> } } 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(); } } ``` |