1. 程式人生 > >大資料下載防止系統崩潰解決方案一:阻塞集中式下載

大資料下載防止系統崩潰解決方案一:阻塞集中式下載

/**

 * 下載控制器

 * 阻塞集中式下載 防止系統崩潰

 * 使用定時過期的快取鎖實現

 * 每10分鐘只能下載一次

 **/

import com.google.common.cache.Cache;

import com.google.common.cache.CacheBuilder;

import java.util.concurrent.TimeUnit;

public class DownloadControl {

    private static final String CACHE_KEY = "DOWNLOAD";

    /**

     * 下載許可權儲存地點

     *

     */

    private static final Cache<String, String> cache = CacheBuilder.newBuilder()

            .initialCapacity(1)

            .concurrencyLevel(1)

            .expireAfterWrite(10, TimeUnit.MINUTES)

            .build();

    /**

     * 嘗試獲取下載許可權 未獲取到許可權

     */

    public

static synchronized boolean notGetPermission() {

        return !tryGetPermission();

    }

    private static synchronized boolean tryGetPermission() {

        String hasLock = cache.getIfPresent(CACHE_KEY);

        if (hasLock == null) {

            cache.put(CACHE_KEY, "1");

            return

true;

        }

        return false;

    }

    /**

     * 重置下載許可權

     */

    public static synchronized void resetPermission() {

        cache.invalidate(CACHE_KEY);

    }

}

在下載方法中使用:

if(DownloadControl.notGetPermission()){

request.setAttribute(ReturnConstant.MEMO, "當前下載佇列滿!請稍後重試。");

return mapping.findForward(ReturnConstant.ERROR);

}

try{

下載程式碼

} catch (Exception e) {

String memo = "下載失敗,請稍後再試 ···";

log.info("異常:{} ", memo, e);

}finally {

    DownloadControl.resetPermission();

}

測試:

public class DownloadControlTest {

    @Test

    public void hasPermission() throws InterruptedException {

        //模擬併發

        ExecutorService executorService = Executors.newCachedThreadPool();

        for (int i = 0; i < 10; i++) {

            Thread.sleep(500);

            final int finalI = i;

            executorService.execute(new Runnable() {

                @Override

                public void run() {

                    try {

                        boolean res = DownloadControl.notGetPermission();

                        System.out.println(finalI + " " + res + "   " + DateUtil.getNow());

                    } catch (Exception e) {

                        e.printStackTrace();

                    }

                }

            });

        }

    }

    @Test

    public void resetPermission() throws InterruptedException {

        //模擬併發

        ExecutorService executorService = Executors.newCachedThreadPool();

        Thread.sleep(1000L);

        executorService.execute(new Runnable() {

            @Override

            public void run() {

                try {

                    boolean res = DownloadControl.notGetPermission();

                    System.out.println(res + "   " + DateUtil.getNow());

                } catch (Exception e) {

                    e.printStackTrace();

                }

                DownloadControl.resetPermission();

            }

        });

        Thread.sleep(1000L);

        executorService.execute(new Runnable() {

            @Override

            public void run() {

                try {

                    boolean res = DownloadControl.notGetPermission();

                    System.out.println(res + "   " + DateUtil.getNow());

                } catch (Exception e) {

                    e.printStackTrace();

                }

            }

        });

        Thread.sleep(1000L);

        executorService.execute(new Runnable() {

            @Override

            public void run() {

                try {

                    boolean res = DownloadControl.notGetPermission();

                    System.out.println(res + "   " + DateUtil.getNow());

                } catch (Exception e) {

                    e.printStackTrace();

                }

            }

        });    }

}