Как повысить производительность загрузки тяжелых изображений на сервер - PullRequest
0 голосов
/ 02 октября 2019

Я отправляю несколько изображений на сервер, используя мобильное приложение для Android.

Наши бизнес-требования - иметь изображения наилучшего качества и иметь их как можно большего размера, что создает довольно большой беспорядок.

Одно изображение занимает от 3-5 МБ. Я должен сделать 4-5 запросов (отправить 4-5 изображений).

Когда я начинаю делать запросы API, обычно он ничего не делает в течение 15-30 секунд.

enter image description here

Это похоже на тайм-аут ... и затем, после этих 15-30 секунд, изображения на самом деле отправляются довольно быстро (если мы не считаем тайм-аут):

enter image description here

Я вызываю запросы следующим образом:

private fun sendImagesToServer() {
    viewModelScope.launch {
        withContext(dispatcherProvider.background) {

            Images.forEach { img ->
                val sessionImageFile = File(img.FilePath)

                ApiClient.getInstance().sendImage(
                    sessionImageFile
                ) { response ->
                    if (response.isSuccessful) {
                        ...
                    } else {
                        Timber.i("Image WAS NOT sent successfully: ")
                    }
                }
            }
        }
    }

и фактическая реализация запроса выглядит следующим образом:

 public void sendImage(
    File imageFile,
    ServiceCallback<ServiceResponse<Void>> callback
) {
    /* Preparing header data */
    HashMap<String, String> headerMap = new HashMap<>();
    headerMap.put("X-IMS-xxx", ..);
    headerMap.put("X-IMS-aaa", ..);
    headerMap.put("X-IMS-ccc", ..);
    headerMap.put("X-IMS-bb", "...");

    /* Parsing image */
    MultipartBody.Part filePart = MultipartBody.Part.createFormData(
        "file",
        imageFile.getName(),
        RequestBody.create(MediaType.parse("image/*"),
        imageFile)
    );

    ClientCore.sendPicture(
        filePart,
        headerMap,
        callback
    );
}

@Multipart
@Headers("..: true")
@POST("...")
Call<Session> sendPicture(
    @Part MultipartBody.Part filePart,
    @HeaderMap Map<String, String> headers
);

Я попытался загрузить все изображения с помощью веб-приложения, и это заняло 16 секунд для всех изображений - это нормально. Мобильное приложение также загружает изображения примерно в одно и то же время, но проблема заключается в тайм-ауте до того, как оно действительно начнет загружаться. Что является причиной этого и как этого избежать?

Я тестировал эту же реализацию со сжатыми изображениями размером 200-300 КБ, она работала довольно быстро, но я пытаюсь найти решение, которому нужно следоватьбизнес-требования здесь.

Это нормальное поведение? Как повысить производительность этой задачи?

ОБНОВЛЕНИЕ:

2019-10-02 10:34:07.493 21705-21732/? E/rs$DefaultThreadFactory: ===== Detect pool-thread leak =====
2019-10-02 10:34:07.494 21705-21732/? E/rs$DefaultThreadFactory: dalvik.system.VMStack.getThreadStackTrace(Native Method)
2019-10-02 10:34:07.494 21705-21732/? E/rs$DefaultThreadFactory: java.lang.Thread.getStackTrace(Thread.java:1538)
2019-10-02 10:34:07.494 21705-21732/? E/rs$DefaultThreadFactory: java.util.concurrent.Executors$DefaultThreadFactory.newThread(Executors.java:569)
2019-10-02 10:34:07.494 21705-21732/? E/rs$DefaultThreadFactory: sxq.newThread(Unknown Source:9)
2019-10-02 10:34:07.494 21705-21732/? E/rs$DefaultThreadFactory: java.util.concurrent.ThreadPoolExecutor$Worker.<init>(ThreadPoolExecutor.java:636)
2019-10-02 10:34:07.494 21705-21732/? E/rs$DefaultThreadFactory: java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:950)
2019-10-02 10:34:07.494 21705-21732/? E/rs$DefaultThreadFactory: java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1393)
2019-10-02 10:34:07.494 21705-21732/? E/rs$DefaultThreadFactory: sru.a(:com.google.android.gms@19419039@19.4.19 (100408-269184076):14)
2019-10-02 10:34:07.494 21705-21732/? E/rs$DefaultThreadFactory: sru.execute(:com.google.android.gms@19419039@19.4.19 (100408-269184076):2)
2019-10-02 10:34:07.494 21705-21732/? E/rs$DefaultThreadFactory: sfs.a(:com.google.android.gms@19419039@19.4.19 (100408-269184076):2)
2019-10-02 10:34:07.494 21705-21732/? E/rs$DefaultThreadFactory: scg.a(:com.google.android.gms@19419039@19.4.19 (100408-269184076):28)
2019-10-02 10:34:07.494 21705-21732/? E/rs$DefaultThreadFactory: sez.onTransact(:com.google.android.gms@19419039@19.4.19 (100408-269184076):36)
2019-10-02 10:34:07.494 21705-21732/? E/rs$DefaultThreadFactory: android.os.Binder.transact(Binder.java:675)
2019-10-02 10:34:07.494 21705-21732/? E/rs$DefaultThreadFactory: aaht.onTransact(:com.google.android.gms@19419039@19.4.19 (100408-269184076):18)
2019-10-02 10:34:07.494 21705-21732/? E/rs$DefaultThreadFactory: android.os.Binder.transact(Binder.java:675)
2019-10-02 10:34:07.494 21705-21732/? E/rs$DefaultThreadFactory: dxz.onTransact(:com.google.android.gms@19419039@19.4.19 (100408-269184076):3)
2019-10-02 10:34:07.494 21705-21732/? E/rs$DefaultThreadFactory: android.os.Binder.execTransact(Binder.java:739)
...