developer tip

웹 개발에 대한 기본적이지만 중요한 질문이 있습니까?

optionbox 2021. 1. 8. 08:09
반응형

웹 개발에 대한 기본적이지만 중요한 질문이 있습니까?


지금까지 PHP, Python 및 Java를 사용하여 웹 기반 애플리케이션을 개발했습니다. 그러나 근본적이지만 매우 중요한 질문이 여전히 내 지식을 넘어서서 여러분의 도움과 설명을 얻기 위해이 게시물을 작성했습니다.

백엔드 언어 (PHP / Python / .Net / Java 등)로 일부 프로그래밍 언어를 사용하고 웹 서버 (apache / lighttpd / nginx / IIS 등)로 애플리케이션을 배포한다고 가정 해 보겠습니다. T 시점에 내 페이지 중 하나가 서로 다른 사용자로부터 100 개의 동시 요청을 받았다고 가정합니다. 그래서 내 질문은 다음과 같습니다.

  1. 내 웹 서버는 이러한 100 개의 동시 요청을 어떻게 처리합니까? 웹 서버는 각 요청에 대해 하나의 프로세스 / 스레드를 생성합니까? (예인 경우 프로세스 또는 스레드?)
  2. 백엔드 언어의 통역사는 어떻게합니까? 요청을 어떻게 처리하고 적절한 HTML을 생성합니까? 인터프리터는 각 요청에 대해 프로세스 / 스레드를 생성합니까? (예인 경우 프로세스 또는 스레드입니까?)
  3. 인터프리터가 각 요청에 대해 프로세스 / 스레드를 생성한다면 이러한 프로세스 (스레드)는 어떻습니까? 코드 공간을 공유합니까? 서로 의사 소통 할 것인가? 백엔드 코드에서 전역 변수를 처리하는 방법은 무엇입니까? 아니면 독립적 인 프로세스 (스레드)입니까? 프로세스 / 스레드 기간은 얼마나됩니까? 요청이 처리되고 응답이 반환 될 때 폐기됩니까?
  4. 웹 서버가 100 개의 동시 요청 만 지원할 수 있지만 이제는 1000 개의 동시 요청이 있다고 가정합니다. 그러한 상황을 어떻게 처리합니까? 큐처럼 처리하고 서버를 사용할 수있을 때 요청을 처리합니까? 아니면 다른 접근법?
  5. 요즘 Comet에 관한 기사를 읽었습니다. 그리고 긴 연결이 실시간 다중 사용자 사용 사례를 처리하는 좋은 방법 일 수 있음을 발견했습니다. 그렇다면 긴 연결은 어떻습니까? 특정 웹 서버의 기능입니까, 아니면 모든 웹 서버에서 사용할 수 있습니까? 연결 시간이 길면 기존 통역사 프로세스가 필요합니까?

편집 : 최근에 CGI 및 fastcgi에 대한 기사를 읽었습니다. 따라서 fastcgi의 접근 방식이 hanlde 요청에 대한 일반적인 접근 방식이어야한다는 것을 알게되었습니다.

프로토콜은 여러 독립적 인 FastCGI 요청간에 단일 전송 연결을 다중화합니다. 이는 이벤트 기반 또는 다중 스레드 프로그래밍 기술을 사용하여 동시 요청을 처리 할 수있는 애플리케이션을 지원합니다.

여러 요청을 처리 할 수 ​​있고 다중 스레드 기술로 구현할 수있는 연결 을 언급 한 fastcgi spec 에서 인용했습니다 . 연결프로세스처리 될 수 있고 각 요청에 대해 여러 스레드생성 할 수 있는지 궁금합니다 . 이것이 사실이라면 각 스레드에서 공유 리소스를 처리하는 방법에 대해 혼란스러워집니다.

추신 : 게시물을 여러 게시물로 나누는 조언에 대해 Thomas에게 감사하지만 질문은 관련이 있으며 함께 그룹화하는 것이 좋습니다.

훌륭한 답변에 대해 S.Lott에게 감사하지만 각 질문에 대한 일부 답변은 너무 짧거나 전혀 다루지 않습니다.

모든 사람의 답변에 감사드립니다.


2018 년 봄 업데이트 :

저는 2010 년에이 답변을 썼고 그 이후로 웹 백엔드 개발자의 세계에서 많은 것이 바뀌 었습니다. 즉, 원 클릭로드 밸런서 및 자동 확장과 같은 서비스를 상품으로 전환하는 "클라우드"서비스의 출현으로 애플리케이션 확장의 실제 메커니즘을 훨씬 쉽게 시작할 수 있습니다.

즉, 2010 년에 제가이 기사에서 작성한 내용은 오늘날에도 대부분 사실이며 웹 서버와 언어 호스팅 환경이 실제로 작동하는 방식과이를 조정하는 방법을 이해하면 호스팅 비용을 상당히 절감 할 수 있습니다. 이러한 이유로, 스택을 조정하는 데 팔꿈치가 깊어지기 시작하는 모든 사람을 위해 원래 아래에 작성된 기사를 남겼습니다.


1. 웹 서버에 따라 다릅니다 (때로는 구성). 다양한 모델에 대한 설명 :

  • mpm_prefork를 사용하는 Apache (Unix의 기본값) : 요청 당 처리. 시작 시간을 최소화하기 위해 Apache는 크기를 구성하는 새 요청을 처리하기 위해 대기하는 유휴 프로세스 풀을 유지합니다. 새 요청이 들어 오면 마스터 프로세스는이를 사용 가능한 작업자에게 위임하고 그렇지 않으면 새 요청을 생성합니다. 100 개의 요청이 들어온 경우 100 명의 유휴 작업자가없는 경우 부하를 처리하기 위해 일부 분기를 수행해야합니다. 유휴 프로세스 수가 MaxSpare 값을 초과하면 유휴 프로세스가 너무 많을 때까지 요청을 완료 한 후 일부가 수확됩니다.

  • mpm_event, mpm_worker, mpm_winnt가있는 Apache : 요청 당 스레드. 마찬가지로 아파치는 대부분의 상황에서 유휴 스레드 풀을 유지하며 구성 가능합니다. (작은 세부 사항이지만 기능적으로는 동일합니다. mpm_worker는 여러 프로세스를 실행하며 각 프로세스는 다중 스레드입니다).

  • Nginx / Lighttpd : select () / epoll () / poll ()을 사용하여 다중 스레드 또는 프로세스없이 여러 소켓을 다중화하는 경량 이벤트 기반 서버입니다. 매우 세심한 코딩과 비 차단 API 사용을 통해 상용 하드웨어에서 수천 개의 동시 요청으로 확장 할 수 있으며 사용 가능한 대역폭과 올바르게 구성된 파일 설명자 제한이 제공됩니다. 주의 할 점은 기존 임베디드 스크립팅 언어를 서버 컨텍스트 내에서 구현하는 것이 거의 불가능하다는 것입니다. 이것은 대부분의 이점을 무효화합니다. 둘 다 외부 스크립팅 언어에 대해 FastCGI를 지원합니다.

2. 사용하는 배포 모델에 따라 언어 또는 일부 언어에 따라 다릅니다. 일부 서버 구성은 특정 배포 모델 만 허용합니다.

  • Apache mod_php, mod_perl, mod_python : 이러한 모듈은 각 Apache 작업자에 대해 별도의 인터프리터를 실행합니다. 이들 중 대부분은 mpm_worker와 잘 작동하지 않습니다 (클라이언트 코드의 스레드 안전성과 관련된 다양한 문제로 인해). 따라서 대부분 forking 모델로 제한됩니다. 즉, 각 아파치 프로세스에 대해 php / perl / python 인터프리터가 내부에서 실행됩니다. 이것은 메모리 풋 프린트를 심각하게 증가시킵니다. 만약 주어진 아파치 워커가 일반적으로 시스템에서 약 4MB의 메모리를 차지한다면, PHP를 사용하는 것은 15MB를, Python을 사용하는 것은 평균 애플리케이션에 20-40MB를 차지할 수 있습니다. 이 중 일부는 프로세스간에 공유되는 메모리이지만 일반적으로 이러한 모델은 매우 크게 확장하기가 매우 어렵습니다.

  • Apache (지원되는 구성), Lighttpd, CGI : 이것은 대부분 죽어가는 호스팅 방법입니다. CGI의 문제는 요청을 처리하기 위해 새로운 프로세스를 포크 할뿐만 아니라로드를 늘려야 할 때뿐만 아니라 모든 요청에 ​​대해 포크한다는 것입니다. 오늘날의 동적 언어는 시작 시간이 다소 길기 때문에 웹 서버에 많은 작업을 할뿐만 아니라 페이지로드 시간이 크게 늘어납니다. 작은 펄 스크립트는 CGI로 실행하는 것이 좋지만 큰 파이썬, 루비 또는 자바 애플리케이션은 다소 다루기 어렵습니다. Java의 경우 앱 시작을 위해 1 초 이상 대기 할 수 있으며 다음 요청에서 모든 작업을 다시 수행하면됩니다.

  • 모든 웹 서버, FastCGI / SCGI / AJP : 동적 언어를 실행하는 '외부'호스팅 모델입니다. 흥미로운 변형의 전체 목록이 있지만 요점은 응용 프로그램이 일종의 소켓에서 수신 대기하고 웹 서버가 HTTP 요청을 처리 한 다음 다른 프로토콜을 통해 소켓에 전송한다는 것입니다 (정적 페이지는 일반적으로 웹 서버에서 직접 처리).

    This confers many advantages, because you will need less dynamic workers than you need the ability to handle connections. If for every 100 requests, half are for static files such as images, CSS, etc, and furthermore if most dynamic requests are short, you might get by with 20 dynamic workers handling 100 simultaneous clients. That is, since the normal use of a given webserver keep-alive connection is 80% idle, your dynamic interpreters can be handling requests from other clients. This is much better than the mod_php/python/perl approach, where when your user is loading a CSS file or not loading anything at all, your interpreter sits there using memory and not doing any work.

  • Apache mod_wsgi : 이것은 특히 Python 호스팅에 적용되지만 웹 서버 호스팅 앱 (쉬운 구성) 및 외부 호스팅 (프로세스 멀티플렉싱)의 장점 중 일부가 필요합니다. 데몬 모드에서 실행할 때 mod_wsgi는 필요할 때만 데몬 작업자에게 요청을 위임하므로 4 개의 데몬이 100 명의 동시 사용자를 처리 할 수 ​​있습니다 (사이트 및 해당 작업량에 따라 다름).

  • Phusion Passenger : Passenger는 주로 루비 앱을 호스팅하는 아파치 호스팅 시스템이며 mod_wsgi와 마찬가지로 외부 및 웹 서버 관리 호스팅의 이점을 모두 제공합니다.

3. 다시 말하지만, 이것이 적용 가능한 경우 호스팅 모델을 기반으로 질문을 나누겠습니다.

  • mod_php, mod_python, mod_perl : 일반적으로 애플리케이션의 C 라이브러리 만 아파치 워커간에 공유됩니다. 이것은 아파치가 먼저 포크 한 다음 동적 코드를로드하기 때문입니다 (미묘함으로 인해 대부분 공유 페이지를 사용할 수 없습니다). 통역사는이 모델 내에서 서로 통신하지 않습니다. 일반적으로 공유되는 전역 변수는 없습니다. mod_python의 경우 전역이 프로세스 내에서 요청 사이에 머물 수 있지만 프로세스 간에는 머물 수 없습니다. 이로 인해 매우 이상한 동작이 발생할 수 있습니다 (브라우저가 동일한 연결을 영원히 유지하는 경우는 거의 없으며 대부분은 주어진 웹 사이트에 여러 개를 엽니 다). 따라서 전역을 사용하는 방법에 매우주의해야합니다. 공유해야하는 세션 저장소 및 기타 캐시 비트와 같은 항목에는 memcached 또는 데이터베이스 또는 파일과 같은 것을 사용하십시오.

  • FastCGI / SCGI / AJP / Proxied HTTP : 애플리케이션은 본질적으로 서버 자체이므로 서버가 작성된 언어 (일반적으로 코드와 동일한 언어이지만 항상 그런 것은 아님) 및 다양한 요인에 따라 다릅니다. 예를 들어 대부분의 Java 배포는 요청 당 스레드를 사용합니다. Python과 "flup"FastCGI 라이브러리는 프리 포크 또는 스레드 모드에서 실행할 수 있지만 Python과 GIL은 제한적이므로 프리 포크에서 최상의 성능을 얻을 수 있습니다.

  • mod_wsgi / passenger : 서버 모드의 mod_wsgi는 작업을 처리하는 방식을 구성 할 수 있지만 고정 된 수의 프로세스 를 제공하는 것이 좋습니다 . 파이썬 코드를 메모리에 보관하고 가동하고 바로 사용할 수 있기를 원합니다. 지연 시간을 예측 가능하고 낮게 유지하는 가장 좋은 방법입니다.

위에서 언급 한 거의 모든 모델에서 프로세스 / 스레드의 수명은 단일 요청보다 깁니다. 대부분의 설정은 아파치 모델의 몇 가지 변형을 따릅니다. 몇 가지 구성 가능한 제한을 기반으로 예비 작업자를 주변에두고 필요할 때 더 많이 생성하고 너무 많으면 수확합니다. 이러한 설정의 대부분은 요청 후 프로세스를 파괴하지 않지만 일부는 애플리케이션 코드를 지울 수 있습니다 (예 : PHP fastcgi의 경우).

4. "웹 서버는 100 개의 요청 만 처리 할 수 ​​있습니다"라고 말하면 실제 웹 서버 자체를 의미하는지 아니면 웹 서버의 동적 부분을 의미하는지에 따라 다릅니다. 실제 제한과 기능 제한 사이에도 차이가 있습니다.

예를 들어 Apache의 경우 최대 작업자 수 (연결)를 구성합니다. 이 연결 수가 100이고 도달하면 누군가 연결이 끊어 질 때까지 아파치에서 더 이상 연결을 허용하지 않습니다. 연결 유지를 사용하면 이러한 100 개의 연결이 단일 요청보다 훨씬 더 오랫동안 열려있을 수 있으며 요청을 기다리는 다른 900 명의 사용자는 시간이 초과 될 수 있습니다.

제한이 충분히 높으면 해당 사용자를 모두 수락 할 수 있습니다. 그러나 가장 가벼운 아파치를 사용하더라도 작업 자당 비용은 약 2-3MB이므로 아파치 만 사용하면 프로세스 ID, 파일 설명자, 기타 제한적인 OS 리소스는 말할 것도없고 연결을 처리하기 위해 3GB 이상의 메모리를 사용할 수 있습니다. 응용 프로그램 코드를 고려하기 전입니다.

lighttpd / Nginx의 경우 작은 메모리 공간에서 많은 수의 연결 (수천 개)을 처리 할 수 ​​있으며, 종종 1,000 개 연결 당 몇 메그 만 처리 할 수 ​​있습니다 (버퍼 및 비동기 IO API 설정 방법에 따라 다름). 대부분의 연결이 연결 상태가 유지되고 80 % (또는 그 이상) 유휴 상태라고 가정하면 동적 프로세스 시간이나 전체 메모리를 낭비하지 않기 때문에 매우 좋습니다.

외부 호스팅 모델 (mod_wsgi / fastcgi / ajp / proxied http)에서 10 명의 작업자 만 있고 1000 명의 사용자가 요청을한다고 가정하면 웹 서버는 동적 작업자에 대한 요청을 대기열에 추가합니다. 이것이 이상적입니다. 요청이 빠르게 반환되는 경우 더 많은 작업자가 필요없이 훨씬 더 큰 사용자 부하를 계속 처리 할 수 ​​있습니다. 일반적으로 프리미엄은 메모리 또는 DB 연결이며 대기열에 추가하면 일부 사용자를 거부하는 대신 동일한 리소스로 더 많은 사용자에게 서비스를 제공 할 수 있습니다.

주의 : 보고서를 작성하거나 검색을 수행하는 한 페이지가 있고 몇 초가 걸리고 많은 사용자가이 작업으로 작업자를 묶고 있다고 가정합니다. 첫 페이지를로드하려는 사람은 몇 초 동안 대기 할 수 있습니다. 장기 실행 요청이 완료되었습니다. 대안은 별도의 작업자 풀을 사용하여보고 앱 섹션에 대한 URL을 처리하거나 별도로보고 (백그라운드 작업에서와 같이) 한 다음 나중에 완료를 폴링하는 것입니다. 거기에는 많은 옵션이 있지만 응용 프로그램에 약간의 고려가 필요합니다.

5. 메모리 사용량이 많기 때문에 동시 사용자를 많이 처리해야하는 Apache를 사용하는 대부분의 사람들은 연결 유지 기능을 해제합니다. 또는 킵 얼라이브가 켜진 Apache와 짧은 킵 얼라이브 시간 제한 (예 : 10 초) (단일 페이지로드에서 첫 페이지와 이미지 / CSS를 가져올 수 있음). 정말로 1000 개 이상의 연결로 확장해야하고 연결 유지를 원하면 Nginx / lighttpd 및 기타 경량 이벤트 기반 서버를 살펴 보는 것이 좋습니다.

It might be noted that if you do want apache (for configuration ease of use, or need to host certain setups) you can put Nginx in front of apache, using HTTP proxying. This will allow Nginx to handle keep-alive connections (and, preferably, static files) and apache to handle only the grunt work. Nginx also happens to be better than apache at writing logfiles, interestingly. For a production deployment, we have been very happy with nginx in front of apache(with mod_wsgi in this instance). The apache does not do any access logging, nor does it handle static files, allowing us to disable a large number of the modules inside apache to keep it small footprint.

I've mostly answered this already, but no, if you have a long connection it doesn't have to have any bearing on how long the interpreter runs (as long as you are using external hosted application, which by now should be clear is vastly superior). So if you want to use comet, and a long keep-alive (which is usually a good thing, if you can handle it) consider the nginx.

Bonus FastCGI Question You mention that fastcgi can multiplex within a single connection. This is supported by the protocol indeed (I believe the concept is known as "channels"), so that in theory a single socket can handle lots of connections. However, it is not a required feature of fastcgi implementors, and in actuality I do not believe there is a single server which uses this. Most fastcgi responders don't use this feature either, because implementing this is very difficult. Most webservers will make only one request across a given fastcgi socket at a time, then make the next across that socket. So you often just have one fastcgi socket per process/thread.

Whether your fastcgi application uses processing or threading (and whether you implement it via a "master" process accepting connections and delegating or just lots of processes each doing their own thing) is up to you; and varies based on capabilities of your programming language and OS too. In most cases, whatever is the default the library uses should be fine, but be prepared to do some benchmarking and tuning of parameters.

As to shared state, I recommend you pretend that any traditional uses of in-process shared state do not exist: even if they may work now, you may have to split your dynamic workers across multiple machines later. For state like shopping carts, etc; the db may be the best option, session-login info can be kept in securecookies, and for temporary state something akin to memcached is pretty neat. The less you have reliant on features that share data (the "shared-nothing" approach) the bigger you can scale in the future.

Postscript: I have written and deployed a whole lot of dynamic applications in the whole scope of setups above: all of the webservers listed above, and everything in the range of PHP/Python/Ruby/Java. I have extensively tested (using both benchmarking and real-world observation) the methods, and the results are sometimes surprising: less is often more. Once you've moved away from hosting your code in the webserver process, You often can get away with a very small number of FastCGI/Mongrel/mod_wsgi/etc workers. It depends on how much time your application stays in the DB, but it's very often the case that more processes than 2*number of CPU's will not actually gain you anything.


How does my web server handle such 100 simultaneous requests? Does web server generate one process/thread for each request? (if yes, process or thread?)

It varies. Apache has both threads and processes for handling requests. Apache starts several concurrent processes, each one of which can run any number of concurrent threads. You must configure Apache to control how this actually plays out for each request.

How does the interpreter of the backend language do? How will it handle the request and generate the proper html? Will the interpreter generate a process/thread for each request?(if yes, process or thread?)

This varies with your Apache configuration and your language. For Python one typical approach is to have daemon processes running in the background. Each Apache process owns a daemon process. This is done with the mod_wsgi module. It can be configured to work several different ways.

If the interpreter will generate a process/thread for each request, how about these processes(threads)? Will they share some code space? Will they communicate with each other? How to handle the global variables in the backend codes? Or they are independent processes(threads)? How long is the duration of the process/thread? Will they be destroyed when the request is handled and the response is returned?

Threads share the same code. By definition.

Processes will share the same code because that's the way Apache works.

They do not -- intentionally -- communicate with each other. Your code doesn't have a way to easily determine what else is going on. This is by design. You can't tell which process you're running in, and can't tell what other threads are running in this process space.

The processes are long-running. They do not (and should not) be created dynamically. You configure Apache to fork several concurrent copies of itself when it starts to avoid the overhead of process creation.

Thread creation has much less overhead. How Apaches handles threads internally doesn't much matter. You can, however, think of Apache as starting a thread per request.

Suppose the web server can only support 100 simultaneous requests, but now it got 1000 simultaneous requests. How does it handle such situation? Will it handle them like a queue and handle the request when the server is available? Or other approaches?

This is the "scalability" question. In short -- how will performance degrade as the load increases. The general answer is that the server gets slower. For some load level (let's say 100 concurrent requests) there are enough processes available that they all run respectably fast. At some load level (say 101 concurrent requests) it starts to get slower. At some other load level (who knows how many requests) it gets so slow you're unhappy with the speed.

There is an internal queue (as part of the way TCP/IP works, generally) but there's no governor that limits the workload to 100 concurrent requests. If you get more requests, more threads are created (not more processes) and things run more slowly.


To begin with, requiring detailed answers to all your points is a bit much, IMHO.

Anyway, a few short answers about your questions:

#1

It depends on the architecture of the server. Apache is a multi-process, and optionally also, multi-threaded server. There is a master process which listens on the network port, and manages a pool of worker processes (where in the case of the "worker" mpm each worker process has multiple threads). When a request comes in, it is forwarded to one of the idle workers. The master manages the size of the worker pool by launching and terminating workers depending on the load and the configuration settings.

Now, lighthttpd and nginx are different; they are so-called event-based architectures, where multiple network connections are multiplexed onto one or more worker processes/threads by using the OS support for event multiplexing such as the classic select()/poll() in POSIX, or more scalable but unfortunately OS-specific mechanisms such as epoll in Linux. The advantage of this is that each additional network connection needs only maybe a few hundred bytes of memory, allowing these servers to keep open tens of thousands of connections, which would generally be prohibitive for a request-per-process/thread architecture such as apache. However, these event-based servers can still use multiple processes or threads in order to utilize multiple CPU cores, and also in order to execute blocking system calls in parallel such as normal POSIX file I/O.

For more info, see the somewhat dated C10k page by Dan Kegel.

#2

Again, it depends. For classic CGI, a new process is launched for every request. For mod_php or mod_python with apache, the interpreter is embedded into the apache processes, and hence there is no need to launch a new process or thread. However, this also means that each apache process requires quite a lot of memory, and in combination with the issues I explained above for #1, limits scalability.

In order to avoid this, it's possible to have a separate pool of heavyweight processes running the interpreters, and the frontend web servers proxy to the backends when dynamic content needs to be generated. This is essentially the approach taken by FastCGI and mod_wsgi (although they use custom protocols and not HTTP so perhaps technically it's not proxying). This is also typically the approach chosen when using the event-based servers, as the code for generating the dynamic content seldom is re-entrant which it would need to be in order to work properly in an event-based environment. Same goes for multi-threaded approaches as well if the dynamic content code is not thread-safe; one can have, say, frontend apache server with the threaded worker mpm proxying to backend apache servers running PHP code with the single-threaded prefork mpm.

#3

Depending on at which level you're asking, they will share some memory via the OS caching mechanism, yes. But generally, from a programmer perspective, they are independent. Note that this independence is not per se a bad thing, as it enables straightforward horizontal scaling to multiple machines. But alas, some amount of communication is often necessary. One simple approach is to communicate via the database, assuming that one is needed for other reasons, as it usually is. Another approach is to use some dedicated distributed memory caching system such as memcached.

#4

Depends. They might be queued, or the server might reply with some suitable error code, such as HTTP 503, or the server might just refuse the connection in the first place. Typically, all of the above can occur depending on how loaded the server is.

#5

The viability of this approach depends on the server architecture (see my answer to #1). For an event-based server, keeping connections open is no big issue, but for apache it certainly is due to the large amount of memory required for every connection. And yes, this certainly requires a long-running interpreter process, but as described above, except for classic CGI this is pretty much granted.


Web servers are multi-threaded environment ; besides using application scoped variables, a user request doesn't interact with other threads.

So:

  1. 예, 모든 사용자에 대해 새 스레드가 생성됩니다.
  2. 예, 모든 요청에 ​​대해 HTML이 처리됩니다.
  3. 응용 프로그램 범위 변수를 사용해야합니다.
  4. 처리 할 수있는 것보다 더 많은 요청을 받으면 대기열에 추가됩니다. 구성된 시간 초과 기간 이전에 서비스를받은 경우 사용자는 응답을 받거나 오류와 같은 "서버 사용 중"이 표시됩니다.
  5. Comet은 서버 / 언어에 한정되지 않습니다. 다른 불쾌한 스레드 문제를 처리하지 않고 n마다 서버를 쿼리하여 동일한 결과를 얻을 수 있습니다 .

참조 URL : https://stackoverflow.com/questions/1969545/some-fundamental-but-important-questions-about-web-development

반응형