Eu tenho um servidor nginx 1.10.3 rodando no Debian Stretch. Um dos sites que ele atende é um compartilhamento WebDAV lido e gravado por um aplicativo de desktop. O aplicativo executa as seguintes etapas quando um arquivo chamado myfile
é salvo no servidor WebDAV:
-
DELETE /myfile.tmp
-
PUT /myfile.tmp
, body contém novos dados de arquivo
-
DELETE /myfile
-
MOVE /myfile.tmp
, Destination: http://webdav.example.com/myfile
-
GET /myfile
O aplicativo cliente compara a resposta da etapa 5 com os dados enviados na etapa 2 e, se os dados do arquivo não corresponderem, será gerado um erro. Essas etapas acontecem com extrema rapidez em nossa rede particular (o servidor e o cliente estão geograficamente próximos, conectados ao mesmo switch Ethernet) - meu teste com o tcpdump sugere que toda a conversa termine dentro de 45 ms.
O problema é que os dados retornados na etapa 5 não correspondem imediatamente ao que o cliente enviou na etapa 2. Os dados que estão sendo retornados são da versão anterior de myfile
, antes da DELETE
/ MOVE
etapas substituiu-o. Se eu fosse voltar e repetir o passo 5 manualmente um momento depois, os dados do arquivo seriam a nova versão conforme o esperado.
Eu sei que o cliente espera que cada resposta chegue antes de emitir uma solicitação subsequente. Meu melhor palpite é que diferentes solicitações estão atingindo diferentes operadores / threads do nginx, ou talvez haja algum tipo de invalidação de cache ou flush que não esteja acontecendo rápido o suficiente.
Como posso corrigir esse comportamento sem modificar o aplicativo cliente ou desacelerar artificialmente as solicitações?
O nginx.conf completo e a configuração do site são os seguintes:
pid /run/nginx.pid;
user www-data;
worker_processes auto;
worker_rlimit_nofile 20000;
events {
multi_accept on;
use epoll;
worker_connections 4000;
}
http {
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log warn;
sendfile on;
server_tokens off;
tcp_nodelay on;
tcp_nopush on;
keepalive_requests 100000;
keepalive_timeout 65;
client_body_timeout 10;
send_timeout 10;
reset_timedout_connection on;
types_hash_max_size 2048;
open_file_cache max=200000 inactive=20s;
open_file_cache_errors on;
open_file_cache_min_uses 2;
open_file_cache_valid 30s;
include /etc/nginx/mime.types;
default_type application/octet-stream;
gzip on;
gzip_buffers 16 8k;
gzip_comp_level 6;
gzip_disable msie6;
gzip_http_version 1.1;
gzip_min_length 10240;
gzip_proxied any;
gzip_vary on;
gzip_types
application/atom+xml
application/javascript
application/json
application/ld+json
application/manifest+json
application/rss+xml
application/vnd.geo+json
application/vnd.ms-fontobject
application/x-font-ttf
application/x-javascript
application/x-web-app-manifest+json
application/xhtml+xml
application/xml
application/xml+rss
font/opentype
image/bmp
image/svg+xml
image/x-icon
text/cache-manifest
text/css
text/javascript
text/plain
text/vcard
text/vnd.rim.location.xloc
text/vtt
text/x-component
text/x-cross-domain-policy
text/xml;
server {
listen 80;
listen [::]:80;
server_name webdav.example.com;
root /var/www/webdav.example.com;
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
dav_access user:rw group:r all:r;
dav_methods DELETE MOVE PUT;
create_full_put_path on;
}
}
EDIT: Uma observação interessante que descobri. Se eu recarregar o nginx ( sudo service nginx reload
), a primeira tentativa de salvar o arquivo será bem-sucedida. Mas se eu tentar salvá-lo em um momento posterior, o mesmo erro acontecerá.