网络面经总结-仅供参考

网络面经总结-仅供参考

1 服务器如何判断客户端连接不上了

1.1 recv

recv()返回值小于等于0,如果errno == EINTR 则说明recv函数是由于程序接收到信号后返回的,socket连接还是正常的,不应close掉socket连接。

1.2 服务器一段时间内没接收到客户端心跳包反馈
1.3 struct tcp_info info

struct tcp_info info;
int len=sizeof(info);
getsockopt(sock, IPPROTO_TCP, TCP_INFO, &info, (socklen_t *)&len);
if((info.tcpi_state==TCP_ESTABLISHED)) 则说明未断开 else 断开

1.4保活参数

int keepAlive = 1; // 开启keepalive属性
int keepIdle = 60; // 如该连接在60秒内没有任何数据往来,则进行探测
int keepInterval = 5; // 探测时发包的时间间隔为5 秒
int keepCount = 3; // 探测尝试的次数.如果第1次探测包就收到响应了,则后2次的不再发.

setsockopt(rs, SOL_SOCKET, SO_KEEPALIVE, (void )&keepAlive, sizeof(keepAlive));
setsockopt(rs, SOL_TCP, TCP_KEEPIDLE, (void
)&keepIdle, sizeof(keepIdle));
setsockopt(rs, SOL_TCP, TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval));
setsockopt(rs, SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount));

设置后,若断开,则在使用该socket读写时立即失败,并返回ETIMEDOUT错误

Linux中默认的Keepalive的选项如下:
$sudo sysctl -a | grep keepalive
net.ipv4.tcp_keepalive_time = 7200
net.ipv4.tcp_keepalive_probes = 9
net.ipv4.tcp_keepalive_intvl = 75
tcp_keepalive_time/tcp_keepalive_probes/tcp_keepalive_intvl,分别表示连接闲置多久开始发keepalive的ack包、发几个ack包不回复才当对方死了、两个ack包之间间隔多长,

1.5 TCP Keepalive HTTP Keep-Alive 的关系

HTTP协议的Keep-Alive意图在于TCP连接复用,同一个连接上串行方式传递请求-响应数据;TCP的Keepalive机制意图在于探测连接的对端是否存活。

2 心跳包多长时间发一次,如何判断客户端下线了

–(局域网内)3秒发一次,服务器10秒没收到客户端心跳包认为下线

3 四次挥手 通过什么接口来判断?????

– struct tcp_info info;
int len=sizeof(info);
getsockopt(sock, IPPROTO_TCP, TCP_INFO, &info, (socklen_t *)&len);
if((info.tcpi_state==TCP_ESTABLISHED)) 则说明未断开 else 断开

4 epoll只能练500-1000个连接,有没有判断是什么原因引起的

1)linux系统会限制文件打开个数(ulimit -a查看),
–临时修改
ulimit -HSn 2048
–永久修改
vi /etc/security/limits.conf
2)服务器硬件限制

5 noSQL-redis

6 消息队列-应用场景

作用:异步处理,应用解耦,流量削锋和消息通讯

7 微服务容器

它不仅打包了本地应用程序,而且还将本地环境(操作系统的一部分)也打包了,组成一个叫做「 Docker镜像 」的文件包。所以这个「 Docker镜像 」就包含了应用运行所需的全部依赖,我们可以直接基于这个「 Docker镜像 」在本地进行开发与测试,完成之后,再直接将这个「 Docker镜像 」一键上传到云端运行即可。
Docker容器里虽然带有一部分操作系统(文件系统相关),但它并没有内核,因此多个容器之间是共用宿主机的操作系统内核的。
Namespace 技术 只能改变一下进程组的视觉范围
Cgroup技术提供的功能就是实现对内存、磁盘等这些资源进行限制

7.1微服务容器操作
容器基本操作

1 查看docker信息 sudo docker info
2 运行容器 sudo docker run -i -t ubuntu /bin/bash
3 在容器中可以安装软件和我们外面的linux机器一样,只是不一样的ubuntu和centos命令不一样
4 列出容器 sudo docker ps -a (-a 包括没有运行的)
5 启动容器的时候可以给容器命名 sudo docker run --name firstContainername -i -t ubuntu /bin/bash
6 停止容器 sudo docker stop firstContainername (restart)
7 附着进入容器 sudo docker attach firstContainername
8 后台运行容器 sudo docker run -d -i -t ubuntu /bin/bash
9 获取容器日志 sudo docker logs firstContainername
10 持续跟踪容器日志 sudo docker logs -f firstContainername
11 持续跟踪容器日志,并打印时间 sudo docker logs -ft firstContainername
12 可以将日志重定向到宿主机,也有一些日期驱动 sudo docker run --logs-driver="syslog" --name firstContainername -d 使用syslog的日志驱动,关于日志驱动百度
13 查看容器内的进程 sudo docker to firstContainername
14 统计容器的内存,网络,cpu,io等的指标 sudo docker stats firstContainername
15 在后台运行的容器内执行命令 sudo docker exec -d firstContainername touch /etc/new_config_file
16 进入容器 sudo docker exec -it firstContainername /bin/bash
17 停止容器 sudo docker stop firstContainername
18 自动重启 sudo docker run --restart=always --name firstContainername -d ubuntu /bin/sh --restart=always 无论什么情况停止都会重启,还可以加参数 --restart=on-failure:5 退出代码为非0时重启5次
19 获取容器信息 sudo docker inspect firstContainername
20 删除容器 sudo docker rm firstContainername
21 删除所有容器 sudo docker rm ‘sudo docker ps -a -q’ -a返回所有容器 -q只返回容器的id
22 备份容器 docker commit -p 30b8f18f20b4 container-backup
1)->登录 docker login
->打包:docker tag a25ddfec4d2a arunpyasi/container-backup:test
->上传到注册中心:docker push arunpyasi/container-backup
->恢复容器:docker pull arunpyasi/container-backup:test
2)->备份在本地:docker save -o ~/container-backup.tar container-backup
->恢复容器: docker load -i ~/container-backup.tar
3)->加载的镜像去运行Docker容器:docker run -d -p 80:80 container-backup
docker pull: 从仓库中拖镜像

docker run:创建容器

docker stop:停止容器运行

docker start:开始容器运行

docker commit:提交容器到镜像

docker images: 查看当前有的镜像

docker ps:查看当前启动的容器 docker ps -a 列出当前系统所有的容器

镜像

1 列出所有镜像 sudo docker images
2 拉取镜像 sudo docker pull ubuntu 可以指定版本号,不指定为默认最新的镜像
3 查找镜像 sudo docker search ubuntu
4 注册docker账号后就可以使用 docker login命令进行登录
5 可以拉取一个centos镜像 sudo docker pull centos 然后运行 sudo docker run -it --name centosContener centos /bin/bash 进入容器安装vim yum -y install vim 退出容器 exit 提交容器 sudo docker commit -m"信息" -a “作者” centosContener 镜像用户名/仓库名:标签
6 查看镜像的信息 sudo docker inspect 镜像用户名/仓库名:标签
7 Dockerfile
FROM centos
RUN yum -y install nginx
EXPOSE 80
sudo docker build -t=“镜像用户名/仓库名:标签”
8 构建镜像时禁用缓存 sudo docker build --no-cache -t=“镜像用户名/仓库名:标签”
9 查看docker镜像的构建历史 sudo docker history centos 实例 sudo docker history zhaoqinrong/centos:test
10 查看容器端口的映射情况 sudo docker port centosContener 80 会返回映射到宿主机上的端口
11 端口绑定 sudo docker run --name firstContainername -p 80 -d zhaoqinrong/centos
sudo docker run --name firstContainername -p 8080:80 -d zhaoqinrong/centos
sudo docker run --name firstContainername -p 127.0.0.1:8080:80 -d zhaoqinrong/centos
sudo docker run --name firstContainername -p 映射ip:映射到宿主机的端口:容器端口 -d zhaoqinrong/centos
sudo docker run --name firstContainername -p -d zhaoqinrong/centos 将构建镜像中的dockerfile文件中的EXPOSE的所有端口公开,并随机绑定到宿主机的端口上
12 Dockerfile 中的CMD命令,RUN命令是在构建中,docker容器未启动时作用,而CMD是在启动后执行的命令
CMD["/bin/bash","-l"]

8 虚函数析构函数和普通虚函数区别,及原因,析构顺序

析构函数不一定必须是虚函数,是否为虚函数取决于该类的使用,一般该类为基类产生继承和多态时,才会是虚函数,单独使用可以不是虚函数。之所以在继承和多态时设计为虚函数是因为当new派生类并且用基类指针指向这个派生类,在销毁基类指针时只会调用基类的析构函数,不会调用派生类的析构函数,因为基类无法操作派生类中非继承的成员,这样就造成派生类只new无法delete造成内存泄露。 2.默认不是虚析构函数是因为如果析构函数为虚函数就需要编译器在类中增加虚函数表来实现虚函数机制,这样所需内存空间就更大了,因此没有必要默认为虚析构函数。

class B
{
}
class C : public B
{
}
class D : public B
{
}
D* pD = new D();//pD的静态类型是它声明的类型D*,动态类型也是D*
B* pB = pD;//pB的静态类型是它声明的类型B*,动态类型是pB所指向的对象pD的类型D*
C* pC = new C();
pB = pC;//pB的动态类型是可以更改的,现在它的动态类型是C*

构造:先基类,后派生类
析构:先派生类,后基类

class B
  {
   virtual void vfun(int i = 10)
   {
       cout << "B:vfun, i = " << i;
       cout << endl;
   };
      public:
   void modfuc()
   {
       vfun();
   }
   virtual~B()
   {
       cout << "B:~vfun" << endl;
   }
  };
  
  class D : public B
  {
   virtual void vfun(int i = 20)
   {
       cout << "D:vfun, i = " << i;
       cout << endl;
   };
  
   void modfuc()
   {
       vfun();
   }
      public:
   ~D()
   {
       cout << "D:~vfun" << endl;
   }
  };
  
  int main()
  {
      D* pD = new D();
      B* pB = pD;
  
      pB->modfuc();//调用子类vfunc,但是入参是默认参数,静态绑定的所以输出为10,调用基类的i=10
      delete pD;
  }

在这里插入图片描述
9 边沿触发和水平触发区别,边沿触发会引发什么问题
Level Triggered (LT) 水平触发
.socket接收缓冲区不为空 有数据可读 读事件一直触发
.socket发送缓冲区不满 可以继续写入数据 写事件一直触发
符合思维习惯,epoll_wait返回的事件就是socket的状态

Edge Triggered (ET) 边沿触发
.socket的接收缓冲区状态变化时触发读事件,即空的接收缓冲区刚接收到数据时触发读事件
.socket的发送缓冲区状态变化时触发写事件,即满的缓冲区刚空出空间时触发读事件
仅在状态变化时触发事件
LT的编程与poll/select接近,符合一直以来的习惯,不易出错
ET的编程可以做到更加简洁,某些场景下更加高效,但另一方面容易遗漏事件(只提醒一次,需循环接收accept()),容易产生bug

10 Redis为什么是单线程的

原因一:redis本身就是基于内存操作的,所以每个操作执行速度都很快。

如果使用多线程,就需要解决多线程同步的问题,就会涉及到线程的频繁切换而消耗CPU。单线程的使用避免了不必要的上下文切换和竞争条件,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗。

原因二:redis中的数据结构比较简单,对数据的操作也就比较快。

原因三:使用多路复用IO,即非阻塞IO。这样提高了redis的吞吐量。多路是指可以处理多个网络连接产生的流,复用是指一个线程可以服务多条IO流
缺点就是在多处理器情况下,不能充分利用其他CPU。可以的解决方法是开启多个redis服务实例,通过复制和修改配置文件,可以在多个端口上开启多个redis服务实例,这样就可以利用其他CPU来处理连接流。

11 不同机器进程间如何通信:

socket

12 服务器如何转发消息的

ret = recv(*(int *)arg, &RecvBuf, sizeof(RecvBuf), 0);
ret = send(RecvBuf.ToFd, &RecvBuf, sizeof(RecvBuf), 0);
接收客户端A的消息包,从包中取出A需要发送到B的地址,然后服务器把A的消息转发给B
服务器如何转发离线消息(消息队列)

14 西安发消息到上海,接收方消息延迟了,原因

网络原因+客户端内存

15客户端发了很多消息,服务器怎么及时处理?

(多线程+消息队列/缓冲区)
亿万级客户端:搭建服务器集群按业务划分去处理,各个业务服务器之前可以加负载均衡,使用户均匀的分布在各个服务器上。
优点:当某一个服务器故障,不会影响所有用户,只会影响到连接到这个服务器的用户。

16客户端收到大量数据会导致客户端卡顿,怎么优化?

(多线程+缓冲区)
1 延迟加载是指用到的时候,再去进行实际的构建。
2 缓存(页面缓存+数据缓存)
3 异步
4 归并处理(刷新线程->判断当前界面是否存在->定时刷新数据)
5 视觉欺骗 (给出提示信息或者进度条)
客户端数据可以分页显示处理,比如一共有1000页数据,客户端一页可以显示10条,那就按照每次10条显示在客户端,当用户想查询下一页时再拉取下一页的数据显示,直到数据末尾。

17. 十几个日志文件,用什么shell命令可以筛选出自己想要的日志内容

grep -r key 路径

18. 客户端连接不上服务器的问题一般怎么定位?(未解决)

ping、检查IP/PORT、netstat xxx查询连接状态

19. 多进程文件怎么共享,为什么要用mmap。

常规文件操作需要从磁盘到页缓存再到用户主存的两次数据拷贝。而mmap操控文件,只需要从磁盘到用户主存的一次数据拷贝过程。说白了,mmap的关键点是实现了用户空间和内核空间的数据直接交互而省去了空间不同数据不通的繁琐过程。因此mmap效率更高。

mmap优点总结
由上文讨论可知,mmap优点共有一下几点:

1、对文件的读取操作跨过了页缓存,减少了数据的拷贝次数,用内存读写取代I/O读写,提高了文件读取效率。

2、实现了用户空间和内核空间的高效交互方式。两空间的各自修改操作可以直接反映在映射的区域内,从而被对方空间及时捕捉。

3、提供进程间共享内存及相互通信的方式。不管是父子进程还是无亲缘关系的进程,都可以将自身用户空间映射到同一个文件或匿名映射到同一片区域。从而通过各自对映射区域的改动,达到进程间通信和进程间共享的目的。

20. vi打开文件后,怎么替换无数个想要替换的内容

:%s/vivian/sky/g(等同于 :g/vivian/s//sky/g) 替换每一行中所有 vivian 为 sky

21. 10W个用户怎么连接服务器

–每个连接一个fd,linux加大文件打开数限制,加心跳包
–单服务器只有多线程配合强大硬件。最好用多服务器,使用队列协同。
–服务器ip、服务器端口、客户端ip、客户端端口4个因素形成一条唯一连接。记得服务器的ip和端口总是不变的,就是监听的那个。所以不存在端口不够用的问题
–负载均衡和服务器的集群

NIO模型:
在这里插入图片描述
来源连接

分离:登录服务器、通讯服务器、消息服务器 和 数据库服务器;
◎登录服务器(有状态):除给Client提供登录和分配通讯服务器外,重点功能是提供关于用户目前连接在哪台服务器上的查询,所以所有查询基本基于缓存完成;考虑到单点故障问题,登录服务器应双机冗余,但不能太多,否则双机之间的缓存同步代价太高;缓存可使用开源组件。
◎通讯服务器(有状态):负责维护消息长连接,以及消息的收发;通讯服务器缓存自身的所有用户连接信息,和部分(这个要时情况动态调整)非自身的热点用户连接信息(即该用户连在哪台通讯服务器上);消息到达时,将消息转发给消息服务器进行落地;然后根据目标最终用户先查询本地表,查不到就去查询登录服务器;然后直接寻找目标通讯服务器,发送消息到达的通知;通讯服务器的问题是没有Failover,但是也不重要,客户端连接不上就由登录服务器重新分配新的通讯服务器来提供服务即可。
◎ 消息服务器(无状态):负责接收通讯服务器所发来的消息,批量写入数据库中,以及供其它消息服务器存取;另外也提供历史消息查询这类辅助性功能;因为是无状态,所以集群较为简单,略。
◎ 数据库服务器:略。

22. select可以连接2000个客户端吗?

select上限1024个

23. libevent怎么用的?

24. 链表顺序不变,如何排序

数组存指针有序的指向链表节点,输出

25. 硬盘大小不变,服务器只能连接1000个,要连10万个怎么办?

linux加大文件打开数限制
负载均衡和服务器的集群

26 tcp客户端能连接的最大长连接,与几个因素有关,可以超越65536

(1) 进程能打开的最大描述符
(2) IP_TABLE的限制
(3) 临时端口范围
(4) 内存大小

二、调整能打开的最大文件描述符

$ echo “655350” > /proc/sys/fs/file-max
$ vi /etc/security/limits.conf

* soft nofile 655350  
* hard nofile 655350

三、调整临时端口范围与IP_TABLE限制(centos7)
$ vim /etc/sysctl.conf

#临时端口范围
net.ipv4.ip_local_port_range = 10000 65535

#Linux网络内核的IP_TABLE防火墙对最大跟踪的TCP连接数有限制
net.netfilter.nf_conntrack_max = 655350
net.nf_conntrack_max = 655350

27 ping一个域名的过程

28 客户端架构设计

四层架构
在三层架构的基础上多了业务规则层,通常的三层是把业务逻辑和业务规则合并为一个层,统称为业务层.业务规则层的提出,既可以及时处理用户输入的不合法信息, 又可以及时处理数据库错误, 增大了业务逻辑层的结构清晰度, 让业务逻辑人员专心致志做逻辑。

从上至下为:
l 表示层
l 业务规则层
l 业务逻辑层或称为领域层
l 数据访问层

29 TCP和UDP的区别和优缺点

1)、TCP与UDP区别总结:
1、TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接
2、TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付
Tcp通过校验和,重传控制,序号标识,滑动窗口、确认应答实现可靠传输。如丢包时的重发控制,还可以对次序乱掉的分包进行顺序控制。
那么,TCP具体是通过怎样的方式来保证数据的顺序化传输呢?

  1. 主机每次发送数据时,TCP就给每个数据包分配一个序列号并且在一个特定的时间内等待接收主机对分配的这个序列号进行确认,

  2. 如果发送主机在一个特定时间内没有收到接收主机的确认,则发送主机会重传此数据包。

  3. 接收主机利用序列号对接收的数据进行确认,以便检测对方发送的数据是否有丢失或者乱序等,

  4. 接收主机一旦收到已经顺序化的数据,它就将这些数据按正确的顺序重组成数据流并传递到高层进行处理。

3、UDP具有较好的实时性,工作效率比TCP高,适用于对高速传输和实时性有较高的通信或广播通信。
4.每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
5、TCP对系统资源要求较多,UDP对系统资源要求较少。
6、UDP丢包(服务端增加缓冲区),乱序( 发送端给数据设置序号,接收端对数据包根据序号做排序处理)
7、TCP有流量控制和拥塞控制
流量控制:对发送方发送速率的控制
拥塞控制:TCP引入 慢启动 机制, 先发少量的数据, 探探路, 摸清当前的网络拥堵状态, 再决定按照多大的速度传输
在这里插入图片描述
2)、为什么UDP有时比TCP更有优势?
UDP以其简单、传输快的优势,在越来越多场景下取代了TCP,如实时游戏
(1)网速的提升给UDP的稳定性提供可靠网络保障,丢包率很低,如果使用应用层重传,能够确保传输的可靠性。
(2)TCP为了实现网络通信的可靠性,使用了复杂的拥塞控制算法,建立了繁琐的握手过程,由于TCP内置的系统协议栈中,极难对其进行改进。
采用TCP,一旦发生丢包,TCP会将后续的包缓存起来,等前面的包重传并接收到后再继续发送,延时会越来越大,基于UDP对实时性要求较为严格的情况下,采用自定义重传机制,能够把丢包产生的延迟降到最低,尽量减少网络问题对游戏性造成影响。
在这里插入图片描述

30 一个 SQL 执行的很慢的原因

1、大多数情况下很正常,偶尔很慢,则有如下原因
(1)、数据库在刷新脏页,例如 redo log 写满了需要同步到磁盘。
(2)、执行的时候,遇到锁,如表锁、行锁。

2、这条 SQL 语句一直执行的很慢,则有如下原因。
(1)、没有用上索引:例如该字段没有索引;由于对字段进行运算、函数操作导致无法用索引。
(2)、数据库选错了索引。

31 如何查看SQL语句的执行状态,知道这条命令吗

show processlist

32 什么是进程,进程包括哪些数据?进程切换的过程是怎么样的

1、系统进行资源分配和调度的基本单位
2、代码段, 数据段, 堆, 栈
3、切换页目录以使用新的地址空间->切换内核栈和硬件上下文

33 网络建立连接之后是怎么关闭的(四次挥手)。

在这里插入图片描述

34服务器出现大量time_wait 状态的连接原因?(长链接四次挥手出现了丢包、超时等),假如不会出现丢包、超时等,网络非常流畅呢?(短连接导致的)那怎么解决?

原因:(长链接:丢包,超时;或短连接导致)
进入TIME_WAIT状态等待2MSL主要有两个目的:一方面是主动关闭连接的一方在对方没有收到最后一个ACK包时(这时对方还会重发FIN,收到两个FIN的时间间隔一定小于2MSL)有时间可以重发ACK包,另一方面处于TIME_WAIT的连接(IP和端口组合)不能重用,这样可以保证被重新分配的socket不会受到之前残留的延迟重发报文影响。

1) 由于主动关闭TCP连接的一方才会进入TIME_WAIT状态,一般情况服务器端不会出现TIME_WAIT状态,因为大多数情况都是客户端主动发起连接并主动关闭连接。但是某些服务如pop/smtp、ftp却是服务端收到客户端的QUIT命令后主动关闭连接,这就造成这类服务器上容易出现大量的TIME_WAIT状态的连接,而且并发量越大处于此种状态的连接越多。另外,对于被动关闭连接的服务在主动关闭客户端非法请求或清理长时间不活动的连接时(这种情况很可能是客户端程序忘记关闭连接)也会出现TIME_WAIT的状态。
2) 从根本上去优化我们的系统架构设计,减少不必要的短连接请求

解决办法:
1、 看一下现在time_wait的数量
netstat -an | grep TIME_WAIT | wc -l
2、发现系统存在大量TIME_WAIT状态的连接,通过调整内核参数解决,在 /etc/sysctl.conf中加入
net.ipv4.tcp_tw_recycle = 1 (表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭)
net.ipv4.tcp_fin_timeout=30 (修改系統默认的 TIMEOUT 时间
然后执行 /sbin/sysctl -p 让参数生效。
3、看看系统的tcp参数情况
sysctl -a|grep tcp

35 负载均衡

七层负载均衡基本都是基于http协议的,适用于web服务器的负载均衡。(nginx)

  • 四层负载均衡主要是基于tcp协议报文,可以做任何基于tcp/ip协议的软件的负载均衡。(haproxy、LVS)
  • 两者主要区别在于利用的报文所在的层面是不同的,各有各的好处。
  • 七层应用负载的好处,是使得整个网络更”智能化“。例如访问一个网站的用户流量,可以通过七层的方式,将对图片类的请求转发到特定的图片服务器并可以使用缓存技术;将对文字类的请求可以转发到特定的文字服务器并可以使用压缩技术。当然这只是七层应用的一个小案例,从技术原理上,这种方式可以对客户端的请求和服务器的响应进行任意意义上的修改,极大的提升了应用系统在网络层的灵活性。很多在后台,例如Nginx或者Apache上部署的功能可以前移到负载均衡设备上,例如客户请求中的Header重写,服务器响应中的关键字过滤或者内容插入等功能。
  • 四层负载均衡主要是较为灵活,可以作为多种软件的负载均衡器。
  • 在这里插入图片描述
    七层应用负载优点:
    1)是使得整个网络更"智能化"。例如访问一个网站的用户流量,可以通过七层的方式,将对图片类的请求转发到特定的图片服务器并可以使用缓存技术;将对文字类的请求可以转发到特定的文字服务器并可以使用压缩技术。当然这只是七层应用的一个小案例,从技术原理上,这种方式可以对客户端的请求和服务器的响应进行任意意义上的修改,极大的提升了应用系统在网络层的灵活性。很多在后台,例如Nginx或者Apache上部署的功能可以前移到负载均衡设备上,例如客户请求中的Header重写,服务器响应中的关键字过滤或者内容插入等功能。

2)另外一个常常被提到功能就是安全性。网络中最常见的SYN Flood攻击,即黑客控制众多源客户端,使用虚假IP地址对同一目标发送SYN攻击,通常这种攻击会大量发送SYN报文,耗尽服务器上的相关资源,以达到Denial of Service(DoS)的目的。从技术原理上也可以看出,四层模式下这些SYN攻击都会被转发到后端的服务器上;而七层模式下这些SYN攻击自然在负载均衡设备上就截止,不会影响后台服务器的正常运营。另外负载均衡设备可以在七层层面设定多种策略,过滤特定报文,例如SQL Injection等应用层面的特定攻击手段,从应用层面进一步提高系统整体安全。

七层负载均衡缺点表现在如下几个方面:
1)七层负载均衡受到其所支持的协议限制(一般只有HTTP),这样就限制了它应用的广泛性。
2)七层负载均衡检查HTTP报头会占用大量的系统资源,势必会影响到系统的性能,在大量连接请求的情况下,负载均衡设备自身容易成为网络整体性能的瓶颈。
4 总体对比
4.1) 智能性
七层负载均衡由于具备OIS七层的所有功能,所以在处理用户需求上能更加灵活,从理论上讲,七层模型能对用户的所有跟服务端的请求进行修改。例如对文件header添加信息,根据不同的文件类型进行分类转发。四层模型仅支持基于网络层的需求转发,不能修改用户请求的内容。

4.2) 安全性
七层负载均衡由于具有OSI模型的全部功能,能更容易抵御来自网络的攻击;四层模型从原理上讲,会直接将用户的请求转发给后端节点,无法直接抵御网络攻击。

4.3) 复杂度
四层模型一般比较简单的架构,容易管理,容易定位问题;七层模型架构比较复杂,通常也需要考虑结合四层模型的混用情况,出现问题定位比较复杂。

4.4) 效率比
四层模型基于更底层的设置,通常效率更高,但应用范围有限;七层模型需要更多的资源损耗,在理论上讲比四层模型有更强的功能,现在的实现更多是基于http应用。

软件负载均衡与硬件负载均衡的对比
软件负载均衡的优点是需求环境明确,配置简单,操作灵活,成本低廉,效率不高,能满足普通的企业需求;缺点是依赖于系统,增加资源开销;软件的优劣决定环境的性能;系统的安全,软件的稳定性均会影响到整个环境的安全。
硬件负载均衡优点是独立于系统,整体性能大量提升,在功能、性能上优于软件方式;智能的流量管理,多种策略可选,能达到最佳的负载均衡效果;缺点是价格昂贵。

五、负载均衡策略
负载均衡策略的优劣及其实现的难易程度有两个关键因素:负载均衡算法;对网络系统状况的检测方式和能力。
负载均衡算法
1)轮循均衡(Round Robin):每一次来自网络的请求轮流分配给内部中的服务器,从1至N然后重新开始。此种均衡算法适合于服务器组中的所有服务器都有相同的软硬件配置并且平均服务请求相对均衡的情况。
2)权重轮循均衡(Weighted Round Robin):根据服务器的不同处理能力,给每个服务器分配不同的权值,使其能够接受相应权值数的服务请求。例如:服务器A的权值被设计成1,B的权值是 3,C的权值是6,则服务器A、B、C将分别接受到10%、30%、60%的服务请求。此种均衡算法能确保高性能的服务器得到更多的使用率,避免低性能的服务器负载过重。
3)随机均衡(Random):把来自网络的请求随机分配给内部中的多个服务器。
4)权重随机均衡(Weighted Random):此种均衡算法类似于权重轮循算法,不过在处理请求分担时是个随机选择的过程。
5)响应速度均衡(Response Time):负载均衡设备对内部各服务器发出一个探测请求(例如Ping),然后根据内部中各服务器对探测请求的最快响应时间来决定哪一台服务器来响应客户端的服务请求。此种均衡算法能较好的反映服务器的当前运行状态,但这最快响应时间仅仅指的是负载均衡设备与服务器间的最快响应时间,而不是客户端与服务器间的最快响应时间。
6)最少连接数均衡(Least Connection):客户端的每一次请求服务在服务器停留的时间可能会有较大的差异,随着工作时间加长,如果采用简单的轮循或随机均衡算法,每一台服务器上的连接进程可能会产生极大的不同,并没有达到真正的负载均衡。最少连接数均衡算法对内部中需负载的每一台服务器都有一个数据记录,记录当前该服务器正在处理的连接数量,当有新的服务连接请求时,将把当前请求分配给连接数最少的服务器,使均衡更加符合实际情况,负载更加均衡。此种均衡算法适合长时处理的请求服务,如FTP。
7)处理能力均衡:此种均衡算法将把服务请求分配给内部中处理负荷(根据服务器CPU型号、CPU数量、内存大小及当前连接数等换算而成)最轻的服务器,由于考虑到了内部服务器的处理能力及当前网络运行状况,所以此种均衡算法相对来说更加精确,尤其适合运用到第七层(应用层)负载均衡的情况下。
8)DNS响应均衡(Flash DNS):在Internet上,无论是HTTP、FTP或是其它的服务请求,客户端一般都是通过域名解析来找到服务器确切的IP地址的。在此均衡算法下,分处在不同地理位置的负载均衡设备收到同一个客户端的域名解析请求,并在同一时间内把此域名解析成各自相对应服务器的IP地址(即与此负载均衡设备在同一位地理位置的服务器的IP地址)并返回给客户端,则客户端将以最先收到的域名解析IP地址来继续请求服务,而忽略其它的IP地址响应。在种均衡策略适合应用在全局负载均衡的情况下,对本地负载均衡是没有意义的。

36 端口号范围

端口的取值范围是:0-65535。

在这个取值范围中1023以下的端口已经分配给了常用的一些应用程序,这个数字以后的端口部分被使用,所以网络编程可用的端口一般在1024之后选取
系统端口(Well known port)
系统端口范围:0~1023
系统端口由IANA负责分配。需要走申请流程,申请手续最为严格。
用户端口(Registered port)
用户端口范围:1024~49151
用户端口由IANA负责分配。需要走申请流程,申请手续相对系统端口来说不那么严格。
动态端口(Private port)
动态端口范围:49152~65535
动态端口不在IANA的分配范围,应用程序可以在不用申请这些端口的情况下使用这些端口,但是,有个问题,因为这些端口可能会被其他应用程序或者操作系统使用,所以,我们不能假定这些端口在任意时间都可用,因此,不能将这些端口用于标示一个服务。

37 IO瓶颈

37.1 什么样的服务容易出现IO瓶颈

1.IO密集型服务(例如数据库,文件存储服务dfs等)
2.含有大量读写的服务(服务日志写入庞大,文件读取频繁)
3.含有持久化功能的服务(Redis、MQ等)

37.2 具体排查方法

???定位IO瓶颈的方法,iowait低,IO就没有到瓶颈?
通过分析mpstat的iowait和iostat的util%,判断IO瓶颈
IO瓶颈往往是我们可能会忽略的地方(我们常会看top、free、netstat等等,但经常会忽略IO的负载情况),今天给大家详细分享一下如何确认一台服务器的IO负载是否到达了瓶颈,以及可能优化、定位的点。

1.top 看负载,负载高。

2.iostat -x 3 看IO情况 await 列IO响应时间,svctm 没次IO操作服务时间,不应高于5ms-10ms,理想值是await 与svctm接近表示磁盘IO性能很好,如果await 大于svctm表示有IO队列等待,IO读写可能存在瓶颈,util列表示统计时间内IO操作耗时百分比,值越高,IO越繁忙(要结合前两项指标,单纯的高不能断定为IO瓶颈)。

3.iotop查看IO高的进程,strace -p PID 或 lsof -p PID 查看具体进程操作。

补充说明
IO密集型在产生IO瓶颈的时候,负载会高,但CPU百分比未必一定会高,所以要通过iostat、iotop等工具去确认是否是IO瓶颈。

38

close-on-exec
fork底层实现
epoll底层实现即结构
第三方工具查看CPU占用情况
:top,vmstat,dstat
什么是B+树

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值