流量控制闸门——LimitLatch套接字连接数限制器

Tomcat作为web服务器,对于每个客户端的请求将给予处理响应,但对于一台机器而言,访问请求的总流量有高峰期且服务器有物理极限,为了保证web服务器不被冲垮我们需要采取一些措施进行保护预防,需要稍微说明的此处的流量更多的是指套接字的连接数,通过控制套接字连接个数来控制流量。其中一种有效的方法就是采取流量控制,它就像在流量的入口增加了一道闸门,闸门的大小决定了流量的大小,一旦达到最大流量将关闭闸门停止接收直到有空闲通道。

创建一个流量控制器没思路?还是考虑下并发框架AQS吧,通过控制同步器的状态即可实现,如果忘了AQS框架相关知识请移步到前面多线程章节,具体思路是先初始化状态值,然后每到来一个socket就将状态加1,每关闭一个socket将状态减1,如此一来一旦状态值小于0则由AQS机制将停止对socket的接收,直到某个socket处理完释放。我们把思路拆成两部分,一是创建一个支持计数的控制器,另一个是将此控制器嵌入处理流程中。

① 控制器,整个过程是根据AQS推荐的自定义同步器的做法进行,但并没有使用AQS自带的状态变量,而是另外引入一个AtomicLong类型的count变量用于计数,其本质是一样的,不必过于纠结。控制器主要通过countUpOrAwait和countDown两个方法实现控制效果。

public class LimitLatch {

private class Sync extends AbstractQueuedSynchronizer {

public Sync() {}

@Override

protected int tryAcquireShared(int ignored) {

long newCount = count.incrementAndGet();

if (newCount > limit) {

count.decrementAndGet();

return -1;

} else {

return 1;

}

}

@Override

protected boolean tryReleaseShared(int arg) {

count.decrementAndGet();

return true;

}

}

private final Sync sync;

private final AtomicLong count;

private volatile long limit;

public LimitLatch(long limit) {

this.limit = limit;

this.count = new AtomicLong(0);

this.sync = new Sync();

}

public void countUpOrAwait() throws InterruptedException {

sync.acquireSharedInterruptibly(1);

}

public long countDown() {

sync.releaseShared(0);

long result = getCount();

return result;

}

}

② 流程嵌入控制器,伪代码如下,在接收socket前累加计数器,对socket的数据处理则交由另外的线程,它处理需要一段时间,假如这段时间又有1000个请求socket,则第1000个请求会导致停止程序阻塞,而唤醒的条件是线程池中的工作线程处理完其中一个socket并执行countDown操作。tomcat默认的大小为1000。

LimitLatch limitLatch = new LimitLatch(1000);

创建ServerSocket;

limitLatch.countUpOrAwait();//这里可能阻塞

Socket socket = ServerSocket.accept();

从线程池中获取一个空闲工作线程处理socket,处理完关闭socket并执行limitLatch.countDown();

时间: 2024-08-03 22:07:50

流量控制闸门——LimitLatch套接字连接数限制器的相关文章

LINUX TCP套接字详细配置

提高服务器的负载能力,是一个永恒的话题.在一台服务器CPU和内存资源额定有限的情况下,最大的压榨服务器的性能,是最终的目的.要提高 Linux系统下的负载能力,可以先启用Apache的Worker模式,来提高单位时间内的并发量.但是即使这么做了,当网站发展起来之后,连接数过多 的问题就会日益明显.在节省成本的情况下,可以考虑修改Linux的内核TCP/IP参数,来最大的压榨服务器的性能.当然,如果通过修改内核参数也无法 解决的负载问题,也只能考虑升级服务器了,这是硬件所限,没有办法的事. Lin

python使用原始套接字 解析原始ip头数据

使用底层套接字解码底层流量,是这次做的重点工作. 首先来捕获第一个包 # coding:utf-8import socket # 监听的主机IP host = "192.168.1.100" socket_protocol = socket.IPPROTO_ICMP sniffer = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket_protocol) sniffer.bind((host, 0)) sniffer.setso

sockt套接字编程

一.Socket简介 Socket是进程通讯的一种方式,即调用这个网络库的一些API函数实现分布在不同主机的相关进程之间的数据交换. 几个定义: (1)IP地址:即依照TCP/IP协议分配给本地主机的网络地址,两个进程要通讯,任一进程首先要知道通讯对方的位置,即对方的IP. (2)端口号:用来辨别本地通讯进程,一个本地的进程在通讯时均会占用一个端口号,不同的进程端口号不同,因此在通讯前必须要分配一个没有被访问的端口号. (3)连接:指两个进程间的通讯链路. (4)半相关:网络中用一个三元组可以在

sockets: 套接字的IO函数

########################################################### 套接字的IO函數 IO函数都涉及到阻塞问题,所以要考虑超时问题. 推荐使用sendmsg和recvmsg函数. 对socket的操作: #include<sys/types.h> #include <sys/socket.h> ssize_t recv(int sockfd, void*buff, size_t len, int flags); ssize_t s

网络编程--Socket(套接字)

网络编程 网络编程的目的就是指直接或间接地通过网络协议与其他计算机进行通讯.网络编程中 有两个主要的问题,一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后 如何可靠高效的进行数据传输.在TCP/IP协议中IP层主要负责网络主机的定位,数据传输的 路由,由IP地址可以唯一地确定Internet上的一台主机.而TCP层则提供面向应用的可靠的 或非可靠的数据传输机制,这是网络编程的主要对象,一般不需要关心IP层是如何处理数据 的. 目前较为流行的网络编程模型是客户机/服务器(C/S)结构

套接字描述符就绪条件

网络编程中,我们经常讨论等待某个描述符准备好I/O(读/写)或者等待其上发生一个待处理的异常条件.尽管可读性和可写性对于普通文件这样的描述符显而易见,然而对于引起诸如select返回套接字“就绪”的条件我们必须讨论的更明确些. 套接字准备好读的条件 a)该套接字接受缓冲区中的数据字节数大于等于套接字接受缓冲区低水位标记的当前大小.对这样的套接字执行读操作不会阻塞并将返回一个大于0的值(也 就是返回准备好读入的数据).我们可以使用SO_RCVLOWAT套接字选项设置该套接字的低水位标记.对于tcp

套接字I/O模型-WSAEventSelect(转载)

和WSAAsyncSelect类似,它也允许应用程序在一个或多个套接字上,接收以事件为基础的网络事件通知. 该模型最主要的区别是在于网络事件是由对象句柄完成的,而不是通过窗口例程完成. 事件通知 事件通知模型要求应用程序针对打算使用的每一个套接字,首先创建一个事件对象.创建方法是调用WSACreateEvent函数: WSAEVENT WSACreateEvent(void); WSACreateEvent的返回值很简单,就是一个人工重设的事件对象句柄,一旦得到了事件对象句柄之后,必须将它与某个

Linux 套接字编程中的 5 个隐患

在异构环境中开发可靠的网络应用程序 M. Tim Jones ([email protected]), 资深软件工程师, Emulex 简介: Socket API 是网络应用程序开发中实际应用的标准 API.尽管该 API 简单,但是开发新手可能会经历一些常见的问题.本文识别一些最常见的隐患并向您显示如何避免它们. 发布日期: 2005 年 10 月 08 日 级别: 中级 访问情况 : 13059 次浏览 评论: 0 (查看 | 添加评论 - 登录)  平均分 (34个评分)为本文评分 在

【UNIX网络编程(四)】TCP套接字编程详细分析

引言: 套接字编程其实跟进程间通信有一定的相似性,可能也正因为此,stevens这位大神才会将套接字编程与进程间的通信都归为"网络编程",并分别写成了两本书<UNP1><UNP2>.TCP套接字编程是套接字编程中非常重要的一种,仔细分析,其实它的原理并不复杂.现在就以一个例子来详细分析TCP套接字编程. 一.示例要求: 本节中试着编写一个完成的TCP客户/服务器程序示例,并对它进行深入的探讨.该示例会用到绝大多数的基本函数,未用到但比较重要的函数会在后面的补充上