什么是高并发?
高并发是互联网分布式系统架构的性能指标之一,它通常是指单位时间内系统能够同时处理的请求数,
简单点说,就是 QPS(Queries per second)。
那么我们在谈论高并发的时候,究竟在谈些什么东西呢?
1
opengps 2019-06-01 19:12:44 +08:00 via Android 2
文末没有广告,文章内容可信
|
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
leeyuzhe 2019-06-02 02:14:53 +08:00 via Android 1
写得好,我选择 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 1
笑死我了,在 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); } } 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(); } } ``` |