精华内容
下载资源
问答
  • 应对高并发攻击

    2014-05-14 17:43:04
    他们的最好成绩,1秒钟 可以并发6次,赶在Database入库前,Cache进行Missing Loading前,强占这其中十几毫秒的时间,进行恶意攻击。 为了应对上述情况,做了如下调整:   更新数据时,先写Cache,然后写...

    近半个月过得很痛苦,主要是产品上线后,引来无数机器用户恶意攻击,不停的刷新产品各个服务入口,制造垃圾数据,消耗资源。他们的最好成绩,1秒钟 可以并发6次,赶在Database入库前,Cache进行Missing Loading前,强占这其中十几毫秒的时间,进行恶意攻击。


    为了应对上述情况,做了如下调整:

     

    1. 更新数据时,先写Cache,然后写Database(双写),如果可以,写操作交给队列后续完成。
    2. 限制统一帐号,同一动作,同一秒钟并发次数,超过1次不做做动作,返回操作失败。
    3. 限制统一用户,每日动作次数,超限返回操作失败。

    要完成上述操作,同事给我支招。用Memcached的add方法,就可以很快速的解决问题。不需要很繁琐的开发,也不需要依赖数据库记录,完全内存操作。

    以下实现一个判定冲突的方法:

     

    Java代码  收藏代码
    1. /** 
    2.  * 冲突延时 1秒 
    3.  */  
    4. public static final int MUTEX_EXP = 1;  
    5. /** 
    6.  * 冲突键 
    7.  */  
    8. public static final String MUTEX_KEY_PREFIX = "MUTEX_";  
    9.   
    10. /** 
    11.  * 冲突判定 
    12.  *  
    13.  * @param key 
    14.  */  
    15. public boolean isMutex(String key) {  
    16.     return isMutex(key, MUTEX_EXP);  
    17. }  
    18.   
    19. /** 
    20.  * 冲突判定 
    21.  *  
    22.  * @param key 
    23.  * @param exp 
    24.  * @return true 冲突 
    25.  */  
    26. public boolean isMutex(String key, int exp) {  
    27.     boolean status = true;  
    28.     try {  
    29.         if (memcachedClient.add(MUTEX_KEY_PREFIX + key, exp, "true")) {  
    30.             status = false;  
    31.         }  
    32.     } catch (Exception e) {  
    33.         logger.error(e.getMessage(), e);  
    34.     }  
    35.     return status;  
    36. }  

     

    做个说明:

     

    选项 说明
    add 仅当存储空间中不存在键相同的数据时才保存
    replace 仅当存储空间中存在键相同的数据时才保存
    set 与add和replace不同,无论何时都保存

    也就是说,如果add操作返回为true,则认为当前不冲突!

     

    回归场景,恶意用户1秒钟操作6次,遇到上述这个方法,只有乖乖地1秒后再来。别小看这1秒钟,一个数据库操作不过几毫秒。1秒延迟,足以降低系统负载,增加恶意用户成本。

     

    附我用到的基于XMemcached实现:

     

    Java代码  收藏代码
    1. import net.rubyeye.xmemcached.MemcachedClient;  
    2.   
    3. import org.apache.log4j.Logger;  
    4. import org.springframework.beans.factory.annotation.Autowired;  
    5. import org.springframework.stereotype.Component;  
    6.   
    7. /** 
    8.  *  
    9.  * @author Snowolf 
    10.  * @version 1.0 
    11.  * @since 1.0 
    12.  */  
    13. @Component  
    14. public class MemcachedManager {  
    15.   
    16.     /** 
    17.      * 缓存时效 1天 
    18.      */  
    19.     public static final int CACHE_EXP_DAY = 3600 * 24;  
    20.   
    21.     /** 
    22.      * 缓存时效 1周 
    23.      */  
    24.     public static final int CACHE_EXP_WEEK = 3600 * 24 * 7;  
    25.   
    26.     /** 
    27.      * 缓存时效 1月 
    28.      */  
    29.     public static final int CACHE_EXP_MONTH = 3600 * 24 * 30 * 7;  
    30.   
    31.     /** 
    32.      * 缓存时效 永久 
    33.      */  
    34.     public static final int CACHE_EXP_FOREVER = 0;  
    35.   
    36.     /** 
    37.      * 冲突延时 1秒 
    38.      */  
    39.     public static final int MUTEX_EXP = 1;  
    40.     /** 
    41.      * 冲突键 
    42.      */  
    43.     public static final String MUTEX_KEY_PREFIX = "MUTEX_";  
    44.     /** 
    45.      * Logger for this class 
    46.      */  
    47.     private static final Logger logger = Logger  
    48.             .getLogger(MemcachedManager.class);  
    49.   
    50.     /** 
    51.      * Memcached Client 
    52.      */  
    53.     @Autowired  
    54.     private MemcachedClient memcachedClient;  
    55.   
    56.     /** 
    57.      * 缓存 
    58.      *  
    59.      * @param key 
    60.      * @param value 
    61.      * @param exp 
    62.      *            失效时间 
    63.      */  
    64.     public void cacheObject(String key, Object value, int exp) {  
    65.         try {  
    66.             memcachedClient.set(key, exp, value);  
    67.         } catch (Exception e) {  
    68.             logger.error(e.getMessage(), e);  
    69.         }  
    70.         logger.info("Cache Object: [" + key + "]");  
    71.     }  
    72.   
    73.     /** 
    74.      * Shut down the Memcached Cilent. 
    75.      */  
    76.     public void finalize() {  
    77.         if (memcachedClient != null) {  
    78.             try {  
    79.                 if (!memcachedClient.isShutdown()) {  
    80.                     memcachedClient.shutdown();  
    81.                     logger.debug("Shutdown MemcachedManager...");  
    82.                 }  
    83.             } catch (Exception e) {  
    84.                 logger.error(e.getMessage(), e);  
    85.             }  
    86.         }  
    87.     }  
    88.   
    89.     /** 
    90.      * 清理对象 
    91.      *  
    92.      * @param key 
    93.      */  
    94.     public void flushObject(String key) {  
    95.         try {  
    96.             memcachedClient.deleteWithNoReply(key);  
    97.         } catch (Exception e) {  
    98.             logger.error(e.getMessage(), e);  
    99.         }  
    100.         logger.info("Flush Object: [" + key + "]");  
    101.     }  
    102.   
    103.     /** 
    104.      * 冲突判定 
    105.      *  
    106.      * @param key 
    107.      */  
    108.     public boolean isMutex(String key) {  
    109.         return isMutex(key, MUTEX_EXP);  
    110.     }  
    111.   
    112.     /** 
    113.      * 冲突判定 
    114.      *  
    115.      * @param key 
    116.      * @param exp 
    117.      * @return true 冲突 
    118.      */  
    119.     public boolean isMutex(String key, int exp) {  
    120.         boolean status = true;  
    121.         try {  
    122.             if (memcachedClient.add(MUTEX_KEY_PREFIX + key, exp, "true")) {  
    123.                 status = false;  
    124.             }  
    125.         } catch (Exception e) {  
    126.             logger.error(e.getMessage(), e);  
    127.         }  
    128.         return status;  
    129.     }  
    130.   
    131.     /** 
    132.      * 加载缓存对象 
    133.      *  
    134.      * @param key 
    135.      * @return 
    136.      */  
    137.     public <T> T loadObject(String key) {  
    138.         T object = null;  
    139.         try {  
    140.             object = memcachedClient.<T> get(key);  
    141.         } catch (Exception e) {  
    142.             logger.error(e.getMessage(), e);  
    143.         }  
    144.         logger.info("Load Object: [" + key + "]");  
    145.         return object;  
    146.     }  
    147.   

    展开全文
  • 用Memcached的add方法,就可以很快速的解决问题。不需要很繁琐的开发,也不需要依赖数据库记录,完全内存操作,应对高并发下的重复请求

    原文链接:http://snowolf.iteye.com/blog/1677495


    产品上线后,引来无数机器用户恶意攻击,不停的刷新产品各个服务入口,制造垃圾数据,消耗资源。他们的最好成绩,1秒钟可以并发6次,赶在Database入库前,Cache进行Missing Loading前,强占这其中十几毫秒的时间,进行恶意攻击。

     

    为了应对上述情况,做了如下调整:

     

    1. 更新数据时,先写Cache,然后写Database(双写),如果可以,写操作交给队列后续完成。
    2. 限制统一帐号,同一动作,同一秒钟并发次数,超过1次不做做动作,返回操作失败。
    3. 限制统一用户,每日动作次数,超限返回操作失败。

    用Memcached的add方法,就可以很快速的解决问题。不需要很繁琐的开发,也不需要依赖数据库记录,完全内存操作。

    以下实现一个判定冲突的方法:

     

    Java代码  收藏代码
    1. /** 
    2.  * 冲突延时 1秒 
    3.  */  
    4. public static final int MUTEX_EXP = 1;  
    5. /** 
    6.  * 冲突键 
    7.  */  
    8. public static final String MUTEX_KEY_PREFIX = "MUTEX_";  
    9.   
    10. /** 
    11.  * 冲突判定 
    12.  *  
    13.  * @param key 
    14.  */  
    15. public boolean isMutex(String key) {  
    16.     return isMutex(key, MUTEX_EXP);  
    17. }  
    18.   
    19. /** 
    20.  * 冲突判定 
    21.  *  
    22.  * @param key 
    23.  * @param exp 
    24.  * @return true 冲突 
    25.  */  
    26. public boolean isMutex(String key, int exp) {  
    27.     boolean status = true;  
    28.     try {  
    29.         if (memcachedClient.add(MUTEX_KEY_PREFIX + key, exp, "true")) {  
    30.             status = false;  
    31.         }  
    32.     } catch (Exception e) {  
    33.         logger.error(e.getMessage(), e);  
    34.     }  
    35.     return status;  
    36. }  

     

    做个说明:

     

    选项 说明
    add 仅当存储空间中不存在键相同的数据时才保存
    replace 仅当存储空间中存在键相同的数据时才保存
    set 与add和replace不同,无论何时都保存

    也就是说,如果add操作返回为true,则认为当前不冲突!

     

    回归场景,恶意用户1秒钟操作6次,遇到上述这个方法,只有乖乖地1秒后再来。别小看这1秒钟,一个数据库操作不过几毫秒。1秒延迟,足以降低系统负载,增加恶意用户成本。

     

    附我用到的基于XMemcached实现:

     

    Java代码  收藏代码
    1. import net.rubyeye.xmemcached.MemcachedClient;  
    2.   
    3. import org.apache.log4j.Logger;  
    4. import org.springframework.beans.factory.annotation.Autowired;  
    5. import org.springframework.stereotype.Component;  
    6.   
    7. /** 
    8.  *  
    9.  * @author Snowolf 
    10.  * @version 1.0 
    11.  * @since 1.0 
    12.  */  
    13. @Component  
    14. public class MemcachedManager {  
    15.   
    16.     /** 
    17.      * 缓存时效 1天 
    18.      */  
    19.     public static final int CACHE_EXP_DAY = 3600 * 24;  
    20.   
    21.     /** 
    22.      * 缓存时效 1周 
    23.      */  
    24.     public static final int CACHE_EXP_WEEK = 3600 * 24 * 7;  
    25.   
    26.     /** 
    27.      * 缓存时效 1月 
    28.      */  
    29.     public static final int CACHE_EXP_MONTH = 3600 * 24 * 30 * 7;  
    30.   
    31.     /** 
    32.      * 缓存时效 永久 
    33.      */  
    34.     public static final int CACHE_EXP_FOREVER = 0;  
    35.   
    36.     /** 
    37.      * 冲突延时 1秒 
    38.      */  
    39.     public static final int MUTEX_EXP = 1;  
    40.     /** 
    41.      * 冲突键 
    42.      */  
    43.     public static final String MUTEX_KEY_PREFIX = "MUTEX_";  
    44.     /** 
    45.      * Logger for this class 
    46.      */  
    47.     private static final Logger logger = Logger  
    48.             .getLogger(MemcachedManager.class);  
    49.   
    50.     /** 
    51.      * Memcached Client 
    52.      */  
    53.     @Autowired  
    54.     private MemcachedClient memcachedClient;  
    55.   
    56.     /** 
    57.      * 缓存 
    58.      *  
    59.      * @param key 
    60.      * @param value 
    61.      * @param exp 
    62.      *            失效时间 
    63.      */  
    64.     public void cacheObject(String key, Object value, int exp) {  
    65.         try {  
    66.             memcachedClient.set(key, exp, value);  
    67.         } catch (Exception e) {  
    68.             logger.error(e.getMessage(), e);  
    69.         }  
    70.         logger.info("Cache Object: [" + key + "]");  
    71.     }  
    72.   
    73.     /** 
    74.      * Shut down the Memcached Cilent. 
    75.      */  
    76.     public void finalize() {  
    77.         if (memcachedClient != null) {  
    78.             try {  
    79.                 if (!memcachedClient.isShutdown()) {  
    80.                     memcachedClient.shutdown();  
    81.                     logger.debug("Shutdown MemcachedManager...");  
    82.                 }  
    83.             } catch (Exception e) {  
    84.                 logger.error(e.getMessage(), e);  
    85.             }  
    86.         }  
    87.     }  
    88.   
    89.     /** 
    90.      * 清理对象 
    91.      *  
    92.      * @param key 
    93.      */  
    94.     public void flushObject(String key) {  
    95.         try {  
    96.             memcachedClient.deleteWithNoReply(key);  
    97.         } catch (Exception e) {  
    98.             logger.error(e.getMessage(), e);  
    99.         }  
    100.         logger.info("Flush Object: [" + key + "]");  
    101.     }  
    102.   
    103.     /** 
    104.      * 冲突判定 
    105.      *  
    106.      * @param key 
    107.      */  
    108.     public boolean isMutex(String key) {  
    109.         return isMutex(key, MUTEX_EXP);  
    110.     }  
    111.   
    112.     /** 
    113.      * 冲突判定 
    114.      *  
    115.      * @param key 
    116.      * @param exp 
    117.      * @return true 冲突 
    118.      */  
    119.     public boolean isMutex(String key, int exp) {  
    120.         boolean status = true;  
    121.         try {  
    122.             if (memcachedClient.add(MUTEX_KEY_PREFIX + key, exp, "true")) {  
    123.                 status = false;  
    124.             }  
    125.         } catch (Exception e) {  
    126.             logger.error(e.getMessage(), e);  
    127.         }  
    128.         return status;  
    129.     }  
    130.   
    131.     /** 
    132.      * 加载缓存对象 
    133.      *  
    134.      * @param key 
    135.      * @return 
    136.      */  
    137.     public <T> T loadObject(String key) {  
    138.         T object = null;  
    139.         try {  
    140.             object = memcachedClient.<T> get(key);  
    141.         } catch (Exception e) {  
    142.             logger.error(e.getMessage(), e);  
    143.         }  
    144.         logger.info("Load Object: [" + key + "]");  
    145.         return object;  
    146.     }  
    147.   
    148. }  

     

    PS:Redis的SETNX(即SET if Not eXists,类似于memcache的add)


    展开全文
  • 他们的最好成绩,1秒钟可以并发6次,赶在Database入库前,Cache进行Missing Loading前,强占这其中十几毫秒的时间,进行恶意攻击。 为了应对上述情况,做了如下调整:   更新数据时,先写Cache,然后写...

    近半个月过得很痛苦,主要是产品上线后,引来无数机器用户恶意攻击,不停的刷新产品各个服务入口,制造垃圾数据,消耗资源。他们的最好成绩,1秒钟可以并发6次,赶在Database入库前,Cache进行Missing Loading前,强占这其中十几毫秒的时间,进行恶意攻击。

    为了应对上述情况,做了如下调整:

     

    1. 更新数据时,先写Cache,然后写Database,如果可以,写操作交给队列后续完成。
    2. 限制统一帐号,同一动作,同一秒钟并发次数,超过1次不做做动作,返回操作失败。
    3. 限制统一用户,每日动作次数,超限返回操作失败。

    要完成上述操作,同事给我支招。用Memcached的add方法,就可以很快速的解决问题。不需要很繁琐的开发,也不需要依赖数据库记录,完全内存操作。

    以下实现一个判定冲突的方法:

     

    Java代码  收藏代码
    1. /** 
    2.  * 冲突延时 1秒 
    3.  */  
    4. public static final int MUTEX_EXP = 1;  
    5. /** 
    6.  * 冲突键 
    7.  */  
    8. public static final String MUTEX_KEY_PREFIX = "MUTEX_";  
    9.   
    10. /** 
    11.  * 冲突判定 
    12.  *  
    13.  * @param key 
    14.  */  
    15. public boolean isMutex(String key) {  
    16.     return isMutex(key, MUTEX_EXP);  
    17. }  
    18.   
    19. /** 
    20.  * 冲突判定 
    21.  *  
    22.  * @param key 
    23.  * @param exp 
    24.  * @return true 冲突 
    25.  */  
    26. public boolean isMutex(String key, int exp) {  
    27.     boolean status = true;  
    28.     try {  
    29.         if (memcachedClient.add(MUTEX_KEY_PREFIX + key, exp, "true")) {  
    30.             status = false;  
    31.         }  
    32.     } catch (Exception e) {  
    33.         logger.error(e.getMessage(), e);  
    34.     }  
    35.     return status;  
    36. }  

     

    做个说明:

     

    选项 说明
    add 仅当存储空间中不存在键相同的数据时才保存
    replace 仅当存储空间中存在键相同的数据时才保存
    set 与add和replace不同,无论何时都保存

    也就是说,如果add操作返回为true,则认为当前不冲突!

     

    回归场景,恶意用户1秒钟操作6次,遇到上述这个方法,只有乖乖地1秒后再来。别小看这1秒钟,一个数据库操作不过几毫秒。1秒延迟,足以降低系统负载,增加恶意用户成本。

     

    附我用到的基于XMemcached实现:

     

    Java代码  收藏代码
    1. import net.rubyeye.xmemcached.MemcachedClient;  
    2.   
    3. import org.apache.log4j.Logger;  
    4. import org.springframework.beans.factory.annotation.Autowired;  
    5. import org.springframework.stereotype.Component;  
    6.   
    7. /** 
    8.  *  
    9.  * @author Snowolf 
    10.  * @version 1.0 
    11.  * @since 1.0 
    12.  */  
    13. @Component  
    14. public class MemcachedManager {  
    15.   
    16.     /** 
    17.      * 缓存时效 1天 
    18.      */  
    19.     public static final int CACHE_EXP_DAY = 3600 * 24;  
    20.   
    21.     /** 
    22.      * 缓存时效 1周 
    23.      */  
    24.     public static final int CACHE_EXP_WEEK = 3600 * 24 * 7;  
    25.   
    26.     /** 
    27.      * 缓存时效 1月 
    28.      */  
    29.     public static final int CACHE_EXP_MONTH = 3600 * 24 * 30;  
    30.   
    31.     /** 
    32.      * 缓存时效 永久 
    33.      */  
    34.     public static final int CACHE_EXP_FOREVER = 0;  
    35.   
    36.     /** 
    37.      * 冲突延时 1秒 
    38.      */  
    39.     public static final int MUTEX_EXP = 1;  
    40.     /** 
    41.      * 冲突键 
    42.      */  
    43.     public static final String MUTEX_KEY_PREFIX = "MUTEX_";  
    44.     /** 
    45.      * Logger for this class 
    46.      */  
    47.     private static final Logger logger = Logger  
    48.             .getLogger(MemcachedManager.class);  
    49.   
    50.     /** 
    51.      * Memcached Client 
    52.      */  
    53.     @Autowired  
    54.     private MemcachedClient memcachedClient;  
    55.   
    56.     /** 
    57.      * 缓存 
    58.      *  
    59.      * @param key 
    60.      * @param value 
    61.      * @param exp 
    62.      *            失效时间 
    63.      */  
    64.     public void cacheObject(String key, Object value, int exp) {  
    65.         try {  
    66.             memcachedClient.set(key, exp, value);  
    67.         } catch (Exception e) {  
    68.             logger.error(e.getMessage(), e);  
    69.         }  
    70.         logger.info("Cache Object: [" + key + "]");  
    71.     }  
    72.   
    73.     /** 
    74.      * Shut down the Memcached Cilent. 
    75.      */  
    76.     public void finalize() {  
    77.         if (memcachedClient != null) {  
    78.             try {  
    79.                 if (!memcachedClient.isShutdown()) {  
    80.                     memcachedClient.shutdown();  
    81.                     logger.debug("Shutdown MemcachedManager...");  
    82.                 }  
    83.             } catch (Exception e) {  
    84.                 logger.error(e.getMessage(), e);  
    85.             }  
    86.         }  
    87.     }  
    88.   
    89.     /** 
    90.      * 清理对象 
    91.      *  
    92.      * @param key 
    93.      */  
    94.     public void flushObject(String key) {  
    95.         try {  
    96.             memcachedClient.deleteWithNoReply(key);  
    97.         } catch (Exception e) {  
    98.             logger.error(e.getMessage(), e);  
    99.         }  
    100.         logger.info("Flush Object: [" + key + "]");  
    101.     }  
    102.   
    103.     /** 
    104.      * 冲突判定 
    105.      *  
    106.      * @param key 
    107.      */  
    108.     public boolean isMutex(String key) {  
    109.         return isMutex(key, MUTEX_EXP);  
    110.     }  
    111.   
    112.     /** 
    113.      * 冲突判定 
    114.      *  
    115.      * @param key 
    116.      * @param exp 
    117.      * @return true 冲突 
    118.      */  
    119.     public boolean isMutex(String key, int exp) {  
    120.         boolean status = true;  
    121.         try {  
    122.             if (memcachedClient.add(MUTEX_KEY_PREFIX + key, exp, "true")) {  
    123.                 status = false;  
    124.             }  
    125.         } catch (Exception e) {  
    126.             logger.error(e.getMessage(), e);  
    127.         }  
    128.         return status;  
    129.     }  
    130.   
    131.     /** 
    132.      * 加载缓存对象 
    133.      *  
    134.      * @param key 
    135.      * @return 
    136.      */  
    137.     public <T> T loadObject(String key) {  
    138.         T object = null;  
    139.         try {  
    140.             object = memcachedClient.<T> get(key);  
    141.         } catch (Exception e) {  
    142.             logger.error(e.getMessage(), e);  
    143.         }  
    144.         logger.info("Load Object: [" + key + "]");  
    145.         return object;  
    146.     }  
    147.   


    展开全文
  • 近半个月过得很痛苦,主要是产品上线后,引来无数机器用户恶意攻击,...他们的最好成绩,1秒钟可以并发6次,赶在Database入库前,Cache进行Missing Loading前,强占这其中十几毫秒的时间,进行恶意攻击。 相关链...

    近半个月过得很痛苦,主要是产品上线后,引来无数机器用户恶意攻击,不停的刷新产品各个服务入口,制造垃圾数据,消耗资源。他们的最好成绩,1秒钟可以并发6次,赶在Database入库前,Cache进行Missing Loading前,强占这其中十几毫秒的时间,进行恶意攻击。

     

    相关链接: 
    Memcached笔记——(一)安装&常规错误&监控 
    Memcached笔记——(二)XMemcached&Spring集成 
    Memcached笔记——(三)Memcached使用总结 

    Memcached笔记——(四)应对高并发攻击

     

    为了应对上述情况,做了如下调整:

     

    1. 更新数据时,先写Cache,然后写Database(双写),如果可以,写操作交给队列后续完成。
    2. 限制统一帐号,同一动作,同一秒钟并发次数,超过1次不做做动作,返回操作失败。
    3. 限制统一用户,每日动作次数,超限返回操作失败。

    要完成上述操作,同事给我支招。用Memcached的add方法,就可以很快速的解决问题。不需要很繁琐的开发,也不需要依赖数据库记录,完全内存操作。

    以下实现一个判定冲突的方法:

     

    /**
    	 * 冲突延时 1秒
    	 */
    	public static final int MUTEX_EXP = 1;
    	/**
    	 * 冲突键
    	 */
    	public static final String MUTEX_KEY_PREFIX = "MUTEX_";
    
    	/**
    	 * 冲突判定
    	 * 
    	 * @param key
    	 */
    	public boolean isMutex(String key) {
    		return isMutex(key, MUTEX_EXP);
    	}
    
    	/**
    	 * 冲突判定
    	 * 
    	 * @param key
    	 * @param exp
    	 * @return true 冲突
    	 */
    	public boolean isMutex(String key, int exp) {
    		boolean status = true;
    		try {
    			if (memcachedClient.add(MUTEX_KEY_PREFIX + key, exp, "true")) {
    				status = false;
    			}
    		} catch (Exception e) {
    			logger.error(e.getMessage(), e);
    		}
    		return status;
    	}

     

    做个说明:

     

    选项 说明
    add 仅当存储空间中不存在键相同的数据时才保存
    replace 仅当存储空间中存在键相同的数据时才保存
    set 与add和replace不同,无论何时都保存

    也就是说,如果add操作返回为true,则认为当前不冲突!

     

    回归场景,恶意用户1秒钟操作6次,遇到上述这个方法,只有乖乖地1秒后再来。别小看这1秒钟,一个数据库操作不过几毫秒。1秒延迟,足以降低系统负载,增加恶意用户成本。

     

    附我用到的基于XMemcached实现:

     

    import net.rubyeye.xmemcached.MemcachedClient;
    
    import org.apache.log4j.Logger;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    /**
     * 
     * @author Snowolf
     * @version 1.0
     * @since 1.0
     */
    @Component
    public class MemcachedManager {
    
    	/**
    	 * 缓存时效 1天
    	 */
    	public static final int CACHE_EXP_DAY = 3600 * 24;
    
    	/**
    	 * 缓存时效 1周
    	 */
    	public static final int CACHE_EXP_WEEK = 3600 * 24 * 7;
    
    	/**
    	 * 缓存时效 1月
    	 */
    	public static final int CACHE_EXP_MONTH = 3600 * 24 * 30 * 7;
    
    	/**
    	 * 缓存时效 永久
    	 */
    	public static final int CACHE_EXP_FOREVER = 0;
    
    	/**
    	 * 冲突延时 1秒
    	 */
    	public static final int MUTEX_EXP = 1;
    	/**
    	 * 冲突键
    	 */
    	public static final String MUTEX_KEY_PREFIX = "MUTEX_";
    	/**
    	 * Logger for this class
    	 */
    	private static final Logger logger = Logger
    			.getLogger(MemcachedManager.class);
    
    	/**
    	 * Memcached Client
    	 */
    	@Autowired
    	private MemcachedClient memcachedClient;
    
    	/**
    	 * 缓存
    	 * 
    	 * @param key
    	 * @param value
    	 * @param exp
    	 *            失效时间
    	 */
    	public void cacheObject(String key, Object value, int exp) {
    		try {
    			memcachedClient.set(key, exp, value);
    		} catch (Exception e) {
    			logger.error(e.getMessage(), e);
    		}
    		logger.info("Cache Object: [" + key + "]");
    	}
    
    	/**
    	 * Shut down the Memcached Cilent.
    	 */
    	public void finalize() {
    		if (memcachedClient != null) {
    			try {
    				if (!memcachedClient.isShutdown()) {
    					memcachedClient.shutdown();
    					logger.debug("Shutdown MemcachedManager...");
    				}
    			} catch (Exception e) {
    				logger.error(e.getMessage(), e);
    			}
    		}
    	}
    
    	/**
    	 * 清理对象
    	 * 
    	 * @param key
    	 */
    	public void flushObject(String key) {
    		try {
    			memcachedClient.deleteWithNoReply(key);
    		} catch (Exception e) {
    			logger.error(e.getMessage(), e);
    		}
    		logger.info("Flush Object: [" + key + "]");
    	}
    
    	/**
    	 * 冲突判定
    	 * 
    	 * @param key
    	 */
    	public boolean isMutex(String key) {
    		return isMutex(key, MUTEX_EXP);
    	}
    
    	/**
    	 * 冲突判定
    	 * 
    	 * @param key
    	 * @param exp
    	 * @return true 冲突
    	 */
    	public boolean isMutex(String key, int exp) {
    		boolean status = true;
    		try {
    			if (memcachedClient.add(MUTEX_KEY_PREFIX + key, exp, "true")) {
    				status = false;
    			}
    		} catch (Exception e) {
    			logger.error(e.getMessage(), e);
    		}
    		return status;
    	}
    
    	/**
    	 * 加载缓存对象
    	 * 
    	 * @param key
    	 * @return
    	 */
    	public <T> T loadObject(String key) {
    		T object = null;
    		try {
    			object = memcachedClient.<T> get(key);
    		} catch (Exception e) {
    			logger.error(e.getMessage(), e);
    		}
    		logger.info("Load Object: [" + key + "]");
    		return object;
    	}
    
    }

     

    相关链接: 
    Memcached笔记——(一)安装&常规错误&监控 
    Memcached笔记——(二)XMemcached&Spring集成 
    Memcached笔记——(三)Memcached使用总结 

    Memcached笔记——(四)应对高并发攻击

    转载于:https://my.oschina.net/mohaiyong/blog/221254

    展开全文
  • 他们的最好成绩,1秒钟可以并发6次,赶在Database入库前,Cache进行Missing Loading前,强占这其中十几毫秒的时间,进行恶意攻击。   相关链接:  Memcached笔记——(一)安装&常规错误&监控  Memcached...
  • 他们的最好成绩,1秒钟可以并发6次,赶在Database入库前,Cache进行Missing Loading前,强占这其中十几毫秒的时间,进行恶意攻击。 为了应对上述情况,做了如下调整: 更新数据时,先写Cache,然后写Database...
  • 他们的最好成绩,1秒钟可以并发6次,赶在Database入库前,Cache进行Missing Loading前,强占这其中十几毫秒的时间,进行恶意攻击。 相关链接:Memcached笔记——(一)安装&常规错误&监控Memcached笔记...
  • 近半个月过得很痛苦,主要是产品上线后,引来...他们的最好成绩,1秒钟可以并发6次,赶在Database入库前,Cache进行Missing Loading前,强占这其中十几毫秒的时间,进行恶意攻击。 相关链接:Memcached笔记—...
  • 主要介绍了Windows服务器应对高并发和DDOS攻击的配置方法,本文讲解了应对高并发请求、应对DDOS攻击的多种配置方法,需要的朋友可以参考下
  • windows服务器应对高并发和DDOS攻击

    千次阅读 多人点赞 2013-08-02 17:22:09
    windows系统本身就有很多机制可以用来提高性能和安全,其中有不少可以用来应对高并发请求和DDOS攻击的情况。通过修改TCP延迟等待时间、最大用户端口、最大TCP控制块、最大哈希表大小、保持连接时间等可以有效提高...
  • 123
  • 其特点是占有内存少,并发能力强,事实上Nginx的并发能力确实在同类型的网站服务器中表现较好。 1、Nginx的优势及工作原理 #1)优势 轻量级 安装文件小 运行时CPU内存使用率低 性能强 支持多核,处理静态文件效率高,...
  • 如何模拟并发请求

    2019-10-28 17:42:01
    网站出现恶意并发攻击,解决问题第一步,自己先模拟并发,进行测试 注意: session 登录状态,我们需要设置 cookie api 登录状态,我们一般需要设置 Bearer token 1.并发工具: postman - 网上各种说 ...
  • 并发及概述

    2019-05-15 12:34:00
    网站比并发性能不好的话, 遭遇恶意并发攻击, 造成服务器崩溃。 高并发(High Concurrency)是互联网分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计保证系统能够同时并行处理很多请求。 高...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,544
精华内容 617
关键字:

并发攻击