我的rails应用程序导出大量数据时遇到问题。
我有几种类型的相关数据,并希望将它们一起以zip文件(大型CSV文件,png和其他图像)发送。
我正在创建zip文件,然后将其发送给客户端,直到我们的数据集变大,并且由于数据量而导致服务器过载和超时。
我将代码切换为使用zip_tricks(https://github.com/WeTransfer/zip_tricks)来传输数据。批量处理数据似乎可以解决问题。但是,流媒体在生产中不起作用。
我将AWS Elastic Beanstalk用于生产服务器。
在我的开发服务器上一切正常。该文件在创建时会显示在浏览器中。在生产中,日志中的所有内容看起来都很不错,代码工作正常。只是文件不流。它只是发送一个空的zip文件。
我以为这可能是NGINX的问题,但是我检查了NGINX日志,但那里什么也没有。
以下是发送zip流的控制器代码:
def data_export
...
params stuff
...
zip_tricks_stream do |zip|
#### CSV #########
zip.write_deflated_file('report1.csv') do |sink|
CSV(sink) do |csv|
# csv << Person.column_names
lookup = { taken: "Date of Course", id: "Student ID", workname: 'Student Name', name: 'Employer Name', title: "Course Name", provider: "Course Provider", instructor: "Instructor", expiry: "Expiry Date" }
csv << lookup.values
# CSV::Row.new(lookup.values, true)
@workers.find_each(batch_size: 20) do |work|
# csv << person.attributes.values
...
CSV code
...
csv << lookup.keys.map { |attr| combo["#{attr}"] }
end
end
end
end
if @qrparams
@workers.find_each(batch_size: 20) do |work|
zip.write_deflated_file("#{work.firstname}-#{work.lastname}-#{work.id}-qrcode.png") do |sink|
sink << work.generate_qr.to_s
end
end
end
if params[:certs]
@workers.find_each(batch_size: 20) do |work|
...
PDF CODE
...
pdf.stylesheets << css
# zos.print pdf.to_pdf
sink << pdf.to_pdf.to_s
end ## Sink
end ## Rec Loop
work.certificates.each do |cert|
if cert.image && cert.image.file
ext = cert.image.file.extension.downcase
zip.write_deflated_file("#{work.firstname}-#{work.lastname}-#{cert.paperwork.title}-#{cert.id}.#{ext}") do |sink|
sink << cert.image.file.read
end ## Sink
else
logger.info cert.image
end
end
end ## Work Loop
end
end ## Zip Loop
end
我不知道是什么阻止了zip流传输。有什么想法吗?
我在控制器上设置了一个简化的动作来进行测试。与上面的代码类似,但仅适用于带有查询集的CSV。
在执行测试操作之前,我没有在生产或开发Rails日志中看到任何错误。我现在也看不到任何错误。但是,卷曲测试的结果有所不同。
这是在开发服务器上使用curl的结果:
$ curl -v 127.0.0.1:3000/workers/data_export_test
* Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 3000 (#0)
> GET /workers/data_export_test HTTP/1.1
> Host: 127.0.0.1:3000
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: application/zip
< Cache-Control: no-cache
< X-Request-Id: 4299ee33-45ce-4343-a5fa-8465266aae30
< X-Runtime: 0.228082
< Transfer-Encoding: chunked
<
PK�*��M
report1.csvUT�[d���][s�:r~?���/I���q#�G�����>�]�3=�4,Q��3c������ݜ! �D��Ö��?���~�����"j͡�����ᶨ�ѻ���c�Xį��Tͯ��������������h�w�n��6���_�Ϗ�����%�� 3WIz�������b��z��e�};l��v��
��report1.csvUT�[d��PK���B���
Written using ZipTricks 4.6.0
zip文件按预期出现。
在生产方面,结果有些不同:
$ curl -v http://[my server]/workers/data_export_test
* Trying xxx.xxx.xxx.xxx...
* Connected to [my server]/ (xxx.xxx.xxx.xxx) port 80 (#0)
> GET /workers/data_export_test HTTP/1.1
> Host: [my server]
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Cache-Control: max-age=0, private, must-revalidate
< Content-Type: application/zip
< Date: Fri, 03 Aug 2018 16:38:45 GMT
< ETag: W/"179b594c438a742e70ceda4a7e54455b"
< Server: nginx/1.12.1
< X-Content-Type-Options: nosniff
< X-Frame-Options: SAMEORIGIN
< X-Request-Id: e5ad7f84-34ea-4f90-8089-bde81799ed69
< X-Runtime: 0.112295
< X-XSS-Protection: 1; mode=block
< Content-Length: 50
< Connection: keep-alive
<
* Connection #0 to host [my server] left intact
PK�ք�M
report1.csvUT�[d��
该zip文件的作用与以前相同。 50个字节的损坏文件。
我的任何日志,nginx,puma等都没有看到错误。
答案 0 :(得分:0)
我现在开始工作了。这是由于nginx配置。 我在nginx配置文件中添加了一些更改,现在一切顺利。
我从这里更改了位置部分:
location / {
proxy_pass http://my_app; # match the name of upstream directive which is defined above
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
对此:
location / {
proxy_pass http://my_app; # match the name of upstream directive which is defined above
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Connection '';
proxy_http_version 1.1;
chunked_transfer_encoding off;
proxy_buffering off;
proxy_cache off;
}
它现在按预期工作。