东风草堂博客

公众号:开发者来风

怎么处理epoll的事件?基于reactor反应堆模型,基于事件进行处理,不要基于fd去做判断,基于事件处理的代码逻辑更加清晰!做到百万并发并没有那么难!

阅读全文 »

/proc/sys/net/ipv4/tcp_mem
确定TCP栈应该如何反映内存使用,每个值的单位都是内存页(通常是4KB)。第一个值是内存使用的下限;第二个值是内存压力模式开始对缓冲区使用应用压力的上限;第三个值是内存使用的上限。在这个层次上可以将报文丢弃,从而减少对内存的使用。对于较大的BDP可以增大这些值(注意,其单位是内存页而不是字节)。

tcp_mem(3个INTEGER变量):low, pressure, high

  • low:当TCP使用了低于该值的内存页面数时,TCP不会考虑释放内存。理想情况下,这个值应与指定给tcp_wmem的第2个值相匹配,这第2个值表明,最大页面大小乘以最大并发请求数除以页大小,如131072*300/4096。
  • pressure:当TCP使用了超过该值的内存页面数量时,TCP试图稳定其内存使用,进入pressure模式,当内存消耗低于low值时则退出pressure状态。理想情况下这个值应该是TCP可以使用的总缓冲区大小的最大值,如204800*300/4096。
  • high:允许所有tcp sockets用于排队缓冲数据报的页面量。如果超过这个值,TCP 连接将被拒绝,这就是为什么不要令其过于保守(512000*300/4096)的原因了。 在这种情况下,提供的价值很大,它能处理很多连接,是所预期的2.5倍;或者使现有连接能够传输2.5倍的数据。 我的网络里为192000 300000 732000
1
2
3
4
5
6
7
8
9
10
11
12
static void tcp_init_mem(void)
{
/* nr_free_buffer_pages()计算ZONE_DMA和ZONE_NORMAL的页数,
* 对于64位系统来说,其实就是所有内存了。
*/
unsigned long limit = nr_free_buffer_pages() / 8;
limit = max(limit, 128UL); /* 不能低于128页 */

sysctl_tcp_mem[0] = limit / 4 * 3; /* 最小值设为3/32的系统内存 */
sysctl_tcp_mem[1] = limit; /* 压力值设为1/8的系统内存 */
sysctl_tcp_mem[2] = sysctl_tcp_mem[0] * 2; /* 最大值设为3/16的系统内存 */
}

sndbuf是根据什么定的?业务
在实际的过程中发送数据和接收数据量比较大,可以设置socket缓冲区,而避免了send()、recv()不断的循环收发。

阅读全文 »

WANIPConnection

参考:http://upnp.org/specs/gw/UPnP-gw-WANIPConnection-v2-Service.pdf

  1. AddPortMapping()

  2. NAT

  3. upnp流程
    最多进行4层映射,第一层路由通过/proc/net/route获取本地网关,也就是route -n的功能,第一层映射成功后,可以根据GetExternalIPAddress获得该层路由出口ip,如果出口ip为内网ip,说明还有多层路由,traceroute可以跟踪路由信息,如traceroute -m 4 -w 1 -q 2 www.baidu.com,设置为各层路由的网关,使用出口ip作为NewInternalClient,发送upnp映射请求给各层路由的网关,尝试多层映射。

1
2
3
4
1. 设备 A 向多播地址发送信息(例如,发送到组播地址 X.X.X.X)。
2. 其他监听同一组播地址的设备 B、C、D 等可能会收到这个信息。
3. 设备 B 在收到信息后,如果需要回复,会使用单播(Unicast)向设备 A 发送回复。
4. 回复消息中的来源 IP 地址是设备 B 的 IP 地址。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#define UPNP_MULTICAST "239.255.255.250"
#define UPNP_MULTICAST_PORT 1900
#define UPNP_SERVICE_WANIP "urn:schemas-upnp-org:service:WANIPConnection:1"
#define UPNP_SERVICE_WANPPP "urn:schemas-upnp-org:service:WANPPPConnection:1"

struct sockaddr_in addr = { 0 };
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(UPNP_MULTICAST);
addr.sin_port = htons(UPNP_MULTICAST_PORT);

//发送组播搜索路由器
char buf[1024] = { 0 };
snprintf(buf, sizeof(buf), "M-SEARCH * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nMAN: \"ssdp:discover\"\r\nMX: 6\r\nST: %s\r\n\r\n", UPNP_SERVICE_WANPPP);
sendto(sock, buf, strlen(buf), 0, (sockaddr*)&addr, sizeof(addr);

memset(buf, 0, 1024);
snprintf(buf, sizeof(buf), "M-SEARCH * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nMAN: \"ssdp:discover\"\r\nMX: 6\r\nST: %s\r\n\r\n", UPNP_SERVICE_WANIP);
sendto(sock, buf, strlen(buf), 0, (sockaddr*)&addr, sizeof(addr))

//还要循环发给各级网关,第二层nat打洞只需要往该层网关发就行
for (auto it = gatewaySet.begin(); it != gatewaySet.end(); ++it) {
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(it->c_str());
addr.sin_port = htons(UPNP_MULTICAST_PORT);

snprintf(buf, sizeof(buf), "M-SEARCH * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nMAN: \"ssdp:discover\"\r\nMX: 6\r\nST: %s\r\n\r\n", UPNP_SERVICE_WANPPP);
sendto(sock, buf, strlen(buf), 0, (sockaddr*)&addr, sizeof(addr));

memset(buf, 0, 1024);
snprintf(buf, sizeof(buf), "M-SEARCH * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nMAN: \"ssdp:discover\"\r\nMX: 6\r\nST: %s\r\n\r\n", UPNP_SERVICE_WANIP);
sendto(sock, buf, strlen(buf), 0, (sockaddr*)&addr, sizeof(addr))
}

//接收路由器的响应
char buf[4096] = { 0 };
socklen_t addrLen = sizeof(sockaddr_in);
recvfrom(sock, buf, sizeof(buf) - 1, 0, (sockaddr*)&addr, &addrLen);
阅读全文 »

http1.x的缺点

安全不足和性能不高。
HTTP/2 借用了哈夫曼编码对于Header进行高效压缩,提高传输效率。
HTTP1.X中最大的问题是队头阻塞,HTTP1.X中浏览器对于同一域名的并发连接访问此时是有限的,所以常常会导致只有个位数的连接可以正常工作,后续的连接都会被阻塞。
HTTP1.1支持请求管道化(pipelining)。基于HTTP1.1的长连接,使得请求管线化成为可能。管线化使得请求能够“并行”传输。
注意:这里的“并行”并不是真正意义上的并行传输,需要注意的是,服务器必须按照客户端请求的先后顺序依次回送相应的结果,以保证客户端能够区分出每次请求的响应内容。
也就是说,HTTP管道化可以让我们把先进先出队列从客户端(请求队列)迁移到服务端(响应队列)。
HTTP/2 解决队头阻塞是以 HTTP1.X 管道化的为基础拓展,它使用了二进制流和帧概念解决应用层队头阻塞。应用层的阻塞被解决便是实现流并发传输。
为了控制资源的资源的获取顺序,HTTP在并发传输的基础上实现请求优先级以及流量控制,流的流量控制是考虑接收方是否具备接收能力。

二进制帧

二进制帧保留Header+Body传输结构,但是打散了内部的传输格式,把内容拆分为二进制帧的格式,HTTP/2把报文的基本传输单位叫做帧,而帧分为两个大类 HEADERS(首部) 和 DATA(消息负载),一个消息划分为两类帧传输同时采用二进制编码。

这种做法类似Chunked化整数据的方式,把Header+body等同的帧数据,同时内部通过类型判断进行标记。

阅读全文 »

费曼学习法有四个关键词:concept「概念」、teach「教授」、review「回顾」、simplify「简化」。如果你不能用简洁的语言把一个概念说明白,说明你没有真正的掌握它。

阅读全文 »

仅仅使用openssl,不依赖其他配置文件,自建CA并签发服务器证书。

CA私钥和自签证书

执行以下命令,回答提示问题,生成CA的证书。

1
2
openssl genrsa -out rootCA.key 4096
openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 7000 -out rootCA.crt

rootCA.key 是CA私钥,要存好了。

阅读全文 »

用户往任务队列里面生产任务,线程池从任务队列里面取任务进行消费,让少数线程的线程池来处理大量任务的任务队列,这就是一个生产者和消费者的模型。

阅读全文 »

nat的四种类型是什么样的?怎么通过stun来探测当前网络处于哪一种nat类型后面?

阅读全文 »

rocksDB是什么?

分布式领域的三架马车:GFS、BigTable、MapReduce。
高效发挥存储硬件性能的嵌入式KV存储引擎,是facebook基于google的leveldb发展而来的。

rocksDB解决了什么问题?

写多读少的场景需求,Mysql的InnoDb的B+树是为了解决读多写少的问题。

RockdsDB是怎么解决的?

阅读全文 »
0%