【发布时间】:2019-01-04 00:34:34
【问题描述】:
我的 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 流。有什么想法吗?
8 月 3 日编辑
我在我的控制器上设置了一个简化的操作来测试它。与上面的代码类似,但仅适用于带有集合查询的 CSV。
在测试操作之前,我没有在生产或开发 Rails 日志中看到任何错误。我现在也没有看到任何错误。但是 curl 测试的结果有所不同。
这是在我的开发服务器上使用 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 等中都没有看到错误。
【问题讨论】:
标签: ruby-on-rails amazon-web-services zip amazon-elastic-beanstalk download