之后会把nginx使用的简单epoll skeleton 总结一下
// epoll检测到 EPOLLIN 调用之前注册的 ngx_connection_t r结构体指针
1: ngx_epoll_module.c : rev->handler(rev);
//开始处理http请求
2: ngx_http_request.c:
ngx_http_process_request_headers(r)
ngx_http_process_request_line(r)
ngx_http_process_request(r)
//开始真正的http 处理程序
3: ngx_http_core_module.c: ngx_http_handler(r)
4: ngx_http_core_module.c: ngx_http_core_run_phases(r);
//好戏开始了,这里开始打包http头部
5: ngx_http_static_module.c: ngx_http_send_header(r)
//经过一系列的过滤模块
6:
ngx_http_chunked_filter_module.c: ngx_http_next_header_filter(r)
ngx_http_header_filter_module.c: ngx_http_write_filter(r)
//真正的发送
7:ngx_http_write_filter_module.c: chain = c->send_chain(c, r->out, limit);
ngx_linux_sendfile_chain.c: rc = writev(c->fd, header.elts, header.nelts);
相信到这里大家对nginx的http请求相应有了一个粗犷的认识 .. 他没有用EPOLLOUT 去等到缓冲变化 来send
下面是我写的一个基本功能demo epoll 的例子 和网上很多给的应该大不相同 ,因为那些好多都是漏洞百出 一压就死的
static ssize_t epoll_recv(sock_con_s *c)
{
static jj=0;
ssize_t n_b,n_head;
unsigned short len;
struct iovec iov[3];
buf_head_s b_head;
struct epoll_event un_use;
if(c->sock_fd <= 0) return EXC_OK;
int i = 0;
while(1)
{
if(c->recv_bytes == 0 && c->if_head == 0 ){
/*recv buf head!*/
iov[0].iov_base = b_head._head;
iov[0].iov_len = 2;
iov[1].iov_base = &b_head._len;
iov[1].iov_len = sizeof(u_short);
iov[2].iov_base = b_head._context;
iov[2].iov_len = 4;
memset(put_buf, 0x00, sizeof(put_buf));
memset(&b_head,0x00,sizeof(b_head));
n_head = readv(c->sock_fd, iov, 3);
if(n_head < 0){
if (errno == EAGAIN) return 0;
else {goto PEER_OVER;}
}
if((n_head != sizeof(buf_head_s)) ||
(check_protocol(&b_head) != 0))
goto PEER_OVER;
len = ntohs(b_head._len);
c->total_bytes = len;
c->if_head = 1;
for( i = 0 ;i < 8 ;i++)
printf(" %.2x",((char*)(&b_head))[i]);
printf("%d\n",jj++);
}
n_b = recv(c->sock_fd, put_buf + c->recv_bytes,
c->total_bytes - c->recv_bytes, 0);
if(n_b < 0 ){
switch(errno)
{
case EAGAIN:
return c->recv_bytes;
case EINTR:
break;
default:
goto PEER_OVER;
}
}
else if(n_b == 0)
{ goto PEER_OVER;}
else{
c->recv_bytes += n_b;
}
if(c->recv_bytes == c->total_bytes){
c->data = put_buf;
mem_map(c);
c->if_head = 0;
c->recv_bytes = 0;
}
}
#if 0
ev.data.fd = aEv->data.fd;
ev.events = EPOLLIN ;//| EPOLLOUT;
ev.events = EPOLLOUT | EPOLLET;
epoll_ctl(epfd,EPOLL_CTL_MOD, aEv->data.fd ,&ev);
#endif
PEER_OVER:
shutdown(c->sock_fd,SHUT_WR|SHUT_RD);
close(c->sock_fd);
mem_kick(c);
epoll_ctl(ep, EPOLL_CTL_DEL, c->sock_fd, &un_use);
CON_PEER(c,"",-1,NULL,-1);
return EXC_OK;
}
static int sock_init()
{
struct sockaddr_in my_addr;
listener = -1;
if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1)
return EXC_ERROR;
bzero(&my_addr, sizeof(my_addr));
my_addr.sin_family = PF_INET;
my_addr.sin_port = htons(SOCK_PORT);
my_addr.sin_addr.s_addr = INADDR_ANY;
if(sock_set(listener) == EXC_ERROR)
return EXC_ERROR;
if (bind (listener, (struct sockaddr *)&my_addr,
sizeof(struct sockaddr))== -1)
return EXC_ERROR;
if (listen(listener, LISTEN_NUM) == -1)
return EXC_ERROR;
if(mon_nonblocking(listener) ==-1)
return EXC_ERROR;
return listener;
}
static int check_con(const char* sock_addr)
{
int i ;
if(sock_addr == NULL) return EXC_ERROR;
for(i = 1; i < LISTEN_NUM; i++){
if(strcmp(sock_cons[i].sock_addr,sock_addr) == 0){
//close(sock_cons[i].sock_fd);
return -1;
}
if(strlen(sock_cons[i].sock_addr) < 1)
return i;
else continue;
}
return EXC_ERROR;
}
static int sock_epoll_init()
{
struct epoll_event ee;
sock_con_s *con_accpet;
int epoll_lis ;
if((epoll_lis = sock_init()) == EXC_ERROR)
return EXC_ERROR;
memset(sock_cons,0x00,sizeof(sock_cons));
if(mem_init(0) != 0) return EXC_ERROR;
con_accpet = &sock_cons[0];
CON_ACC(con_accpet, epoll_lis, accpet_init);
if((ep = epoll_create(LISTEN_NUM)) == -1)
return EXC_ERROR;
ee.events = EPOLLIN|EPOLLET;
ee.data.ptr = (void *)(uintptr_t)con_accpet;
if (epoll_ctl(ep, EPOLL_CTL_ADD, epoll_lis, &ee) == -1)
return EXC_ERROR;
event_list = mem_alloc(
sizeof(struct epoll_event) * LISTEN_NUM);
if(event_list == NULL)
return EXC_ERROR;
return epoll_lis;
}
static int epoll_process()
{
sock_con_s *con_sock;
uint32_t revents;
int events;
int i,c;
int listen_fd ;
if((listen_fd = sock_epoll_init()) <= 0){
close(ep);
close(listen_fd);
return EXC_ERROR;
}
/*indefinitely*/
while(1){
events = epoll_wait(ep, event_list, LISTEN_NUM, -1);
if(errno == EINTR) continue;
if(events == -1)
break;
/* Time out ?Impossible */
if(events == 0 )
break;
for(i = 0; i < events; i++){
con_sock = event_list[i].data.ptr;
revents = event_list[i].events;
if( con_sock->sock_fd == listen_fd ){
con_sock->sacpt(con_sock);
continue;
}
if ((revents & (EPOLLERR|EPOLLHUP))
&& (revents & (EPOLLIN)) == 0){
revents |= EPOLLIN;
}
if( revents & EPOLLIN ){
if(event_list[i].data.fd < 0)
continue;
con_sock->srecv(con_sock);
}
#if 0
if( revents & EPOLLOUT ){
if(event_list[i].data.fd < 0 )
continue;
}
if (revents & (EPOLLERR|EPOLLHUP))
continue;
#endif
}
}
close(ep);
close(listen_fd);
return EXC_ERROR;
}
static int accpet_init(sock_con_s *c)
{
struct sockaddr_in peer_addr;
socklen_t sock_len;
struct sockaddr rem_addr;
struct epoll_event ee;
int accp_fd;
int i;
sock_con_s *peer_sock;
while(1){
sock_len = sizeof(peer_addr);
bzero(&peer_addr, sock_len);
accp_fd = accept(listener,(struct sockaddr *)&peer_addr,
&sock_len);
if (accp_fd < 0)
{
switch(errno){
//case EINTR:
case ECONNABORTED:
continue;
case EAGAIN:
return EXC_OK;
default:
return EXC_ERROR;
}
}
if(mon_nonblocking(accp_fd) == -1){
close(accp_fd);
continue;
}
i = check_con(inet_ntoa(peer_addr.sin_addr));
if(i < 0) {
shutdown(accp_fd,SHUT_WR|SHUT_RD);
close(accp_fd);
continue;
}
else{
ee.events = EPOLLIN|EPOLLET;
ee.data.ptr =(void *)(uintptr_t)(&sock_cons[i]);
if (epoll_ctl(ep, EPOLL_CTL_ADD, accp_fd, &ee) < 0) {
shutdown(accp_fd,SHUT_WR|SHUT_RD);
close(accp_fd);
continue;
}
else{
peer_sock = (sock_con_s*)&sock_cons[i];
CON_PEER(peer_sock, inet_ntoa(peer_addr.sin_addr),
accp_fd, epoll_recv, i);
continue;
}
continue;
}
}
}
分享到:
相关推荐
<stopexecutable>D:\work\nginx_13_Violet\nginx.exe</stopexecutable> <stoparguments>-p D:\work\nginx_13_Violet -s stop</stoparguments> </service> ``` **nginx-service.exe.config** ```xml ...
### Nginx优化详细知识点 #### 一、Nginx 运行工作进程个数的优化 - **重要性**:Nginx 的工作进程数直接影响到其处理并发请求的能力和资源利用效率。 - **配置建议**:推荐将 `worker_processes` 设置为 CPU 核心...
- 解压并进入目录:`tar zxf nginx-<version>.tar.gz && cd nginx-<version>` - 配置编译选项:`./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module` - 编译及安装:...
- 在每个Tomcat实例的`conf/server.xml`中启用`<Manager>`元素的`sessionBackup`属性,配置为`true`,并设置相同的`sessionIDManager`。 - 使用`<Cluster>`元素定义集群,包括`node`和`sessionIDGenerator`等属性...
<Engine name="Catalina" defaultHost="localhost" jvmRoute=" tomcatX"> tomcatX 在这里表示不同的tomcat,我的两个 tomcat 分别使用 tomcat1和tomcat2;来区分。 这个设置是主要用以tomcat的集群。 如果看不懂可以...
Nginx是一个高性能的HTTP和反向代理服务器,...在Linux操作系统下,nginx使用epoll事件模型,得益于此,nginx在Linux操作系统下效率相当高。同时Nginx在OpenBSD或FreeBSD操作系统上采用类似于Epoll的高效事件模型kqueue.
Nginx 的事件处理机制是基于 epoll 机制的,例如,`use epoll;` 指定 Nginx 使用 epoll 机制来处理事件。这个设置对 Nginx 的性能和稳定性有很大的影响。 HTTP 服务器配置 Nginx 的 HTTP 服务器配置是指 Nginx 的 ...
Nginx 1.22.0 Linux 版本,解压安装。 Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理...能够支持高达 50,000 个并发连接数的响应,感谢Nginx为我们选择了 epoll and kqueue作为开发模型。
Nginx 1.22.0 Windows版本,解压安装。 Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)...能够支持高达 50,000 个并发连接数的响应,感谢Nginx为我们选择了 epoll and kqueue作为开发模型。
其中,`<regex>` 是正则表达式,`<replacement>` 是替换后的 URL,`[flag]` 可选标志,如 `last`(停止当前规则集的匹配)、`break`(跳出当前规则)、`redirect`(返回重定向)等。 3. **示例** 例如,将所有以 ...
8. kqueue、epoll、rt signals、/dev/poll 和 select 支持:Nginx 支持多种事件机制,包括 kqueue、epoll、rt signals、/dev/poll 和 select,可以根据需要选择合适的事件机制。 9. sendfile 支持:Nginx 支持 send...
事件处理模型是 Nginx 服务器处理客户端请求的重要组件,我们可以通过 `use` 指令来设置事件处理模型,例如 `use epoll;`,这将设置事件处理模型为 epoll。 客户端请求头部缓冲区大小 客户端请求头部缓冲区大小是 ...
2. **事件驱动模型**:Nginx使用Epoll(Linux)或KQueue(FreeBSD)等高效I/O复用技术,实现非阻塞I/O,使得在处理大量并发连接时性能优秀。 3. **反向代理**:Nginx可以作为反向代理服务器,将客户端请求转发到...
`显示帮助,`./nginx`启动服务器,`./nginx -c /path/to/nginx.conf`指定配置文件启动,`nginx -s reload`或`kill -HUP <nginx进程PID>`用于平滑重载配置。 在配置实践中,Nginx的灵活性体现在其模块化设计。它可以...
#epoll是多路复用IO(I/O Multiplexing)中的一种方式,但是仅用于linux2.6以上内核,可以大大提高nginx的性能 worker_connections 1024;#单个后台worker process进程的最大并发链接数 # multi_accept on; } ……...
patch -p0 < ../nginx_upstream_check_module-master/check_1.9.2+.patch ./configure --prefix=/usr/local/nginx \ --with-http_ssl_module --with-http_stub_status_module --with-pcre \ --with-...
6. **高性能并发**:Nginx采用epoll事件模型,可以处理成千上万的并发连接,尤其适合高流量的网站。 7. **错误页面定制**:Nginx允许自定义404、500等错误页面,提升用户体验。 在实际部署中,Nginx通常与动态语言...
- `events`块用于配置Nginx如何处理连接事件,如`events { use epoll; worker_connections 1024; }`,其中`use`指定事件模型(如epoll),`worker_connections`指每个工作进程的最大连接数。 3. **http块** - `...
能够支持高达 50,000 个并发连接数的响应,感谢 Nginx 为我们选择了 epoll and kqueue 作为开发模型. 作为负载均衡服务器:Nginx 既可以在内部直接支持 Rails 和 PHP,也可以支持作为 HTTP代理服务器 对外进行服务。...
其基于epoll(Linux)或kqueue(FreeBSD)等高效I/O复用机制,优化了处理速度。 2. **反向代理和负载均衡**:Nginx 可以作为反向代理服务器,将来自客户端的请求转发到后端服务器集群,同时支持基于多种策略(如...