Memcached笔记——(四)应对高并发攻击
来源:互联网 发布:程序员在家工作 编辑:程序博客网 时间:2024/06/05 16:13
近半个月过得很痛苦,主要是产品上线后,引来无数机器用户恶意攻击,不停的刷新产品各个服务入口,制造垃圾数据,消耗资源。他们的最好成绩,1秒钟可以并发6次,赶在Database入库前,Cache进行Missing Loading前,强占这其中十几毫秒的时间,进行恶意攻击。
相关链接:
Memcached笔记——(一)安装&常规错误&监控
Memcached笔记——(二)XMemcached&Spring集成
Memcached笔记——(三)Memcached使用总结
Memcached笔记——(四)应对高并发攻击
为了应对上述情况,做了如下调整:
- 更新数据时,先写Cache,然后写Database,如果可以,写操作交给队列后续完成。
- 限制统一帐号,同一动作,同一秒钟并发次数,超过1次不做做动作,返回操作失败。
- 限制统一用户,每日动作次数,超限返回操作失败。
要完成上述操作,同事给我支招。用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 */@Componentpublic 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;/** * 缓存时效 永久 */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 */@Autowiredprivate 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笔记——(四)应对高并发攻击
- Memcached笔记——(四)应对高并发攻击
- Memcached笔记——(四)应对高并发攻击
- Memcached笔记——(二)应对高并发攻击
- Memcached-学习(四)应对高并发攻击
- Memcached 应对高并发攻击
- Memcached应对高并发攻击
- 应对高并发笔记
- 应对高并发笔记
- 四 memcache应对高并发
- windows服务器应对高并发和DDOS攻击
- windows服务器应对高并发和DDOS攻击
- Memcached学习笔记(四)——repcached高可用方案
- 如何应对高并发 —— 动态网站静态化
- 如何应对高并发 —— 动态网站静态化
- 如何应对高并发?
- nginx高并发优化——轻松应对1万并发
- java.lang.UnsatisfiedLinkError: D:\Tomcat\apache-tomcat-7.0.37\bin\tcnative-1.dll: Can't load AMD 64
- 面试海量数据存储
- CF 183(div2)
- 使用JDBC时Class.forName()的作用 (本来是想找.forName的作用的,看到觉得不懂就转载来记录下了)
- mysql 日期和时间格式转换实现语句
- Memcached笔记——(四)应对高并发攻击
- 如何调查问题
- CIRCOS教程翻译 5.3——Formatting
- Libgdx SuperJumper
- WIN7 财经日历Gadget
- MySQL的安装
- CityEngine 中的 Annotation
- Memcached笔记——(一)安装&常规错误&监控
- UML类图几种关系的总结(泛化 、继承、实现、依赖、关联、聚合、组合)