linux 高性能 服务器,linux高性能服务器编程--读书笔记

2014年7月1日

1、tcp报头格式 6个标志位syn ack psh rst fin urg

2、半连接下read读到的字节数为0

3、Tcp头部报文最长为60字节,20字节的固定头部,选项信息最多40字节。选项信息可以包含窗口扩大因子的设置,最大报文段的限制,sack的设置,时间戳的设置等8项。

4、Tcp头部中的窗口大小用于流量控制

5、netstat查看当前tcp的状态

6、Tcp状态转移图

终止tcp连接,而不是引用计数减1,用shutdown(int sockfd,int howto)

Tcp数据读写:recv(int sockfd,void *buff,size_t len,int flag)

send(int sockfd,void *buff,size_t len,int flag)

Udp数据读写:recvfrom(int sockfd,void *buff,size_t len,int flag,struct sockaddr*src_addr,socklen_t *addrlen);

sendto(int sockfd,void *buff,size_t len,int flag,struct sockaddr*src_addr,socklen_t *addrlen);

通用数据读写:recvmsg(int sockfd,struct msghdr*msg,int flags);

sendmsg(int sockfd,struct msghdr*msg,int flags);

blog_9c371e6d0102uz4k.html

7、

blog_9c371e6d0102uz4k.html

8、设置tcp发送缓冲区setsockopt(int sock,SO_SOCKET,SO_RCVBUF,int *num,int len);

Getsockopt(int sock,SO_SOCKET,SO_RCVBUF,int *num,socklen_t *len);

设置tcp接收缓冲区setsockopt(int sock,SO_SOCK,SO_SENBUF,int *num,int len);

Getsockopt(int sock,SO_SOCK,SO_SENBUF, int *num,socklen_t *len);

9、查看服务的端口号/etc/services

10、查看协议的编号 /etc/protocols

2014年7月11日

11、http请求报头请求方法:GET、PUT、HEAD、POST、DELETE、TRACE、OPTIONS、CONNECT、PATCH

12、http响应码:1**:信息、继续发生数据2**:成功3**:重定向4**:客户端问题5**:服务器问题

2014年7月12日

13、服务器模型:B/S C/S P2P

14、服务器两种高效事件处理模式

blog_9c371e6d0102uz4k.html

Reactor主线程只负责监听文件描述符,所以描述符上的操作包括连接、读写事件都交由工作线程处理。主线程监听监听套接口和连接套接口。这是一种同步I/O模型。

blog_9c371e6d0102uz4k.html

Proactor模式主线程只监听监听套接口,连接套接口读写事件交由工作线程处理。这是一种异步I/O模型。

blog_9c371e6d0102uz4k.html

服务器两种高效的并发模式

半同步/半异步模式

blog_9c371e6d0102uz4k.html

缺点:

只有主线程一个异步线程,主线程和工作线程同时操作请求队列,执行加锁,耗费cpu时间

工作线程只处理一个客户请求,多开线程时造成线程切换,耗费cpu时间

blog_9c371e6d0102uz4k.html

领导者/追随者模型

blog_9c371e6d0102uz4k.html

Nginx模型

blog_9c371e6d0102uz4k.html

http有限状态机:

从缓存中每次读入一行,并记录读到的位置。

提高服务器性能的方法:池、数据复制(ftp sendfile零拷贝)、避免上下文切换(进程线程的切换)、尽量少使用锁或减小锁的粒度比如读写锁(锁不执行代码操作但是要切换到内核态)

2014年7月20日

15、Libevent

创建 struct event_base *base = event_intit()/ event_base_new()

注册事件 struct event * io_ev=event_new()//evsignal_new//evtimer_new

Event_add(io_ev);

Event_base_dispatch(base);

Event_base_loopexit()

没有需要监听的事件(两种退出的条件)

2014年7月21日

16、Linux架构

blog_9c371e6d0102uz4k.html

blog_9c371e6d0102uz4k.html

blog_9c371e6d0102uz4k.html

blog_9c371e6d0102uz4k.html

Linux数据存储的基本单位是字节

blog_9c371e6d0102uz4k.html

Linux的文件类型,-普通文件,目录文件,设备文件、链接文件、管道文件

17、Tcp滑动窗口会造成网络资源利用率低下,比如接收端读数据缓慢,通告窗口的值很小,但是tcp依然发送数据。因为tcp只限制了最大发送窗口,却没有限制最小发送窗口

解决:限制窗口的通告时机。

发送端持续发送少量数据,导致窗口闲置

解决:Nagle算法

确认号本身不含数据,占用宽带资源

解决:ACK延时,只发最后一个数据段的确认号

2014年7月22日

1、信号处理函数必须是可重入函数,为了避免竞态条件的产生,里面严禁调用不可重入函数,比如标准库函数;

2、信号处理函数在执行期间,信号是被屏蔽的,所以信号不会再次被触发。常用的解决方案是用管道将信号传递给主循环;(统一事件源的信号的实现)

3、主机字节序为小端,整数高位在内存的高位地址。网络字节序为大端。Java虚拟机采用大端字节

测试大小端

Union

Short value;

Char byte[sizeof(short)];

Test.Value = 0x0102;

If(test.byte[0] == 1 && test.byte[1] == 2)big endian

4、Htonl(unisigned long int hostlong) 主机字节序转网络字节序

5、Char *Inet_ntoa()网络字节序整数ip转换为字符串,内部是一个静态变量,不可重入

6、Accept只从监听队列中取出连接,而不在乎连接处于何种状态,ESTABLISHED和CLOSE_WAIT

7、Close()只对引用计数减1,shutdown可以由howto参数立即终止读端、写端或者读写端

8、Sockatmark()判断是否设置了带外数据

9、Getsockname()

getpeername()

10.Getsockopt()

setsockopt()

服务器端对socket设置的选项在accept调用后自动继承,客户端则在connect之前设置,connect后三次握手已经完成

10、tcp接受缓冲区最小值是256字节,发送缓冲区最小值为2048字节(一般)。默认情况

11、默认情况下tcp发送缓冲区和接收缓冲区低水位标记都为1字节

12、mmap()申请一段内存空间。Munmap()释放创建的这段内存空间

13、pipe中的零拷贝函数,其中至少有一端为管道。在epoll中可用。Tee函数用于在两个管道中的零拷贝。Fcntl改变文件描述符属性

2014年7月25日

18、零拷贝函数:splice(输入描述符,偏移位置,输出描述符,便宜位置,长度,标志位);

Sendfile(输入描述符,输出描述符,偏移位置,长度);

Tee(输入描述符,输出描述符,长度,标志);

Splice必须有一个为管道,tee两个必须都为管道。

19、存储器的层次结构

blog_9c371e6d0102uz4k.html

20、Select(int nfds,fd_set* readfds, fd_set* writefds, fd_set*excptfds,struct teimeval*timeout);

FD_ZERO(int fd, fd_set *fdset); FD_SET(int fd, fd_set *fdset);

FD_CLR(int fd, fd_set *fdset);

FD_ISSET(int fd, fd_set *fdset);

blog_9c371e6d0102uz4k.html

每次调用select前都要重新设置fd属性,FD_ISSET用来判断是哪种事件

21、Int poll(struct pollfd *fds, nfds_t nfds, int timeout);

22、EPOLLONESHOT:当一个连接套接口上有数据时交给线程处理,设置该参数,当再次有数据到达时不会触发epoll事件,防止多个线程处理同一个套接口

Epoll_wait(int epfd, struct epoll_event* events, int maxevent, int timeout);

23、Select和poll时间复杂度为n,每次遍历整个结构,epoll时间复杂度为1,底层在有事件触发时调用回调函数放在就绪队列里,最后一起拷贝到用户空间。

blog_9c371e6d0102uz4k.html

Select支持描述符个数cat /proc/sys/fs/file-max查看190984个

Linux 5中I/O模型

阻塞I/O、非阻塞I/O、I/O复用、信号驱动I/O、异步I/O

2014年7月26日

24、lsof -i :port命令来查询对应端口号所属程序

25、Killall + name 杀死指定名字的进程

26、多进程的调试

A、通过加一些代码,ps获取进程号,attach+进程号进入调试

B、set detach-on-fork on(调试时进入另一个进程,该进程继续运行)/off(调试时进入另一个进程,该进程挂起)

Set follow-fork-mode child/parent 调试父/子进程

Info inferiors 查看当前调试的进程*为当前调试的进程

Inferior + 1/2 切换调试的进程

2014年8月6日

27、线程同步机制posix信号量、互斥量和条件变量。pthread_join可以看做简单的线程同步方案

pthread_kill(pthread_t thread,int sig);

sig为0时,不发送信号,但会错误检查,可以检测线程是否存在。

2014年8月8日

28、任何一种语言都不能通过变量模拟二元信号量,因为高级语言不存在原子的判断变量为真或假再将其真假状态改变。

Linux 维持两套信号量。systemV和posix信号量。线程同步使用posix信号量。

处理僵尸进程:waitpid((-1,NULL, WNOHANG))>0);

T45页,163页

2014年8月18日

29、poll系统调用的原理:先注册回调函数__poll_wait,再初始化table变量(类型为struct poll_wqueues),接着拷贝用户传入的struct pollfd(其实主要是fd),然后轮流调用所有fd对应的poll(把current挂到各个fd对应的设备等待队列上)。在设备收到一条消息(网络设备)或填写完文件数据(磁盘设备)后,会唤醒设备等待队列上的进程,这时current便被唤醒了。current醒来后离开sys_poll的操作相对简单,这里就不逐行分析了

Poll底层每次在poll_wait时要将所有的文件描述符往内核空间拷贝一次,比如当描述符为1000时,拷贝不止一次,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值