높 은 병발 서비스 구조

2680 단어 높 은 병발
Nginx 와 몇 개의 서버 엔 드 소프트웨어 를 개발 한 후에 높 은 병행 을 지원 하 는 C 프로그램 구 조 를 정리 했다.일반적으로 다 중 프로 세 스 나 다 중 스 레 드 입 니 다.다 중 스 레 드 에 대해 서 는 하나의 process space 이기 때문에 스 레 드 간 공유 메모리 가 좋 고 통신 방식 이 상대 적 으로 풍부 하 며 나 쁜 점 은 하나의 스 레 드 에 문제 가 생기 면 전체 프로 세 스 가 영향 을 받 을 수 있다 는 것 이다.개인 이 비교적 많은 프로 세 스 의 구 조 를 가지 고 있 습 니 다. 여기 서 주요 한 구조 디자인 을 정리 하면 높 은 병행 이 필요 한 모든 서비스 에 사용 할 수 있 습 니 다.
 
주 프로 세 스:
 
int main()
{
	//initializations
	//...

	//init socket
	listenfd = socket(...);
	bind(listenfd, ...);
	listen(listenfd, ...);

	//fork worker processes
	for(...)
	{
		pid_t pid = fork();
		//child
		if(pid == 0)
		{
			//worker main cycle
			work_process_cycle();
		}
		//parent
		else
		{
			//...
		}
	}
	
	//...
}

 하위 프로 세 스 (worker)
void work_process_cycle()
{
	//init epoll
	int epfd = epoll_create(...);

	//...
	
	//add listenfd to epoll
	struct epoll_event ep_ev;
	ep_ev.data.fd = listenfd;
	ep_ev.events = EPOLLIN | EPOLLET;
	epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &ep_ev);
	
	while(1)
	{
		//epoll events
		struct epoll_event events[EPOLL_MAX_EVENTS];
		int nfds = epoll_wait(epfd, events, EPOLL_MAX_EVENTS, EPOLL_TIMEOUT);
		
		for(i = 0; i < nfds; i++) 
		{
			//accept connection
			if(events[i].data.fd == listenfd)
			{
				int connfd = accept(listenfd, ...);
				//add read event
				struct epoll_event ep_ev;
				ep_ev.data.fd = connfd;
				ep_ev.events = EPOLLIN | EPOLLET;
				epoll_ctl(epfd, EPOLL_CTL_ADD, connfd, &ep_ev);
			}
			else if(events[i].events & EPOLLIN)
			{
				//deal with read events
				//recv, read, ...
			}
			else if(events[i].events & EPOLLOUT)
			{
				//deal with write events
				//send, write, ...
			}
		}
		
		//other events
		//process events, timed events, etc.
	}
}
 
 
epoll 의 IO 트리거 메커니즘 을 사 용 했 고 libevent 와 같은 라 이브 러 리 로 IO 이벤트 감청 을 할 수 있 습 니 다.높 은 병행 서비스 라면 하나의 프로 세 스 가 N 개의 서로 다른 연결 을 동시에 처리 해 야 합 니 다. 그러면 프로 세 스 안의 사건 체제 에 비교적 좋 은 디자인 이 필요 합 니 다.예 를 들 어 서비스 중의 특정한 기능 에 대해 일련의 반전 함수 (callback) 와 하나의 구조 체 를 설계 하여 구체 적 인 문맥 정 보 를 저장 할 수 있다.기능 에 있 는 리 셋 함수 가 완 료 될 때마다 이벤트 의 다음 리 셋 함 수 를 업데이트 하고 이벤트 대기 열 (event quue) 에 넣 은 다음 iteration 에서 FIFO 이벤트 처 리 를 하고 리 셋 함 수 를 호출 합 니 다.이렇게 하면 모든 프로 세 스 의 시간 을 나 누 면 비교적 공평 할 수 있다.사실 Nginx 는 바로 상술 한 구조의 좋 은 예 이다.

좋은 웹페이지 즐겨찾기