커스텀 코드에 기반한 REST 서비스를 웹 API로 변환하는 작업에 직면했다. 이 서비스는 상당한 양의 요청을 가지고 있으며 데이터로드에 시간이 걸릴 수 있지만 일단로드되면 캐싱되어 모든 들어오는 요청을 처리하는 데 사용될 수 있습니다. 이전 버전의 서비스에는 데이터를로드하고 캐시로 가져 오는 스레드가 하나있었습니다. IIS가 작업자 스레드를 모두 사용하지 못하도록 클라이언트는 캐시가 준비 될 때까지 "나중에 다시 돌아옵니다"라는 응답을 받게됩니다.웹 API 병행 성 및 확장 성
웹 API에 대한 필자의 이해는 웹 서비스가 비동기 동작을 내장하고있어 결과적으로 요청 수가 홀드되는 실제 스레드의 수와 직접적으로 관련이 없다는 것입니다.
서비스의 새로운 구현에서 캐시가 준비 될 때까지 요청을 대기시킨 다음 유효한 응답을 할 계획입니다. 나는 설명하기 위해 코드의 매우 거친 스케치를 만든 :
public class ContactsController : ApiController
{
private readonly IContactRepository _contactRepository;
public ContactsController(IContactRepository contactRepository)
{
if (contactRepository == null)
throw new ArgumentNullException("contactRepository");
_contactRepository = contactRepository;
}
public IEnumerable<Contact> Get()
{
return _contactRepository.Get();
}
}
public class ContactRepository : IContactRepository
{
private readonly Lazy<IEnumerable<Contact>> _contactsLazy;
public ContactRepository()
{
_contactsLazy = new Lazy<IEnumerable<Contact>>(LoadFromDatabase,
LazyThreadSafetyMode.ExecutionAndPublication);
}
public IEnumerable<Contact> Get()
{
return _contactsLazy.Value;
}
private IEnumerable<Contact> LoadFromDatabase()
{
// This method could be take a long time to execute.
throw new NotImplementedException();
}
}
코드의 디자인에 너무 많은 값을 넣지 마십시오 - 단지 문제를 설명하기 위해 건설하고 우리가 그것을 어떻게하지 않다 실제 해결책. IContactRepository는 IoC 컨테이너에 싱글 톤으로 등록되고 컨트롤러에 주입됩니다. Lazy with LazyThreadSafetyMode.ExecutionAndPublication은 초기화 코드가 실행되는 첫 번째 스레드/요청 만 보장하며 다음 rquests는 초기화가 완료 될 때까지 차단됩니다.
Web API는 초기화가 완료 될 때까지 대기하는 1000 개의 요청을 처리 할 수 있습니까? 그렇지 않으면이 Lazy를 타격하지 않는 다른 요청은 서비스 중이며 IIS에는 작업자 스레드가 부족하지 않습니다.