`

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

阅读更多

近半个月过得很痛苦,主要是产品上线后,引来无数机器用户恶意攻击,不停的刷新产品各个服务入口,制造垃圾数据,消耗资源。他们的最好成绩,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;
	}

}

 

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

 

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

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

6
2
分享到:
评论
10 楼 diyutaizi3721 2015-11-04  
不知道 大神  有没有 高并发下get数据时 遇到过net.spy.memcached.OperationTimeoutException: Timeout waiting for value
Caused by: net.spy.memcached.internal.CheckedOperationTimeoutException: Timed out waiting for operation - failing node: /192.168.0.54:11211
9 楼 diyutaizi3721 2015-11-04  
不知道 大神  有没有 高并发下get数据时 遇到过
8 楼 风吟想飞 2014-04-16  
[size=medium]您好,我初次使用XMemcached ,现在有个项目的业务和您在“Memcached笔记——(四)应对高并发攻击”中的业务描述一样,我看了您的文章,但是因为基础薄落,没有很好的明白怎么进行冲突判定。想麻烦您讲解一下。谢谢。[/size]
7 楼 di1984HIT 2014-04-14  
说的非常好啊
6 楼 snowolf 2014-02-26  
richardor 写道
那个超时一个月的常量,少乘7了

好眼力
5 楼 richardor 2014-02-25  
那个超时一个月的常量,少乘7了
4 楼 snowolf 2012-12-11  
zym820910 写道
snowolf 写道
CurrentJ 写道
先写Cache,然后写Database,断电或者故障会导致用户数据丢失。

各有利弊,需要根据业务需求权衡。


写得非常好!应对高并发的时候,我们通常的思维是泄洪模式,通过一道又一道的防洪大堤将洪水分流,尤其是在应对数据要求不严厉的SNS这类产品,异步的保存数据值得提倡!

不过,更好的方式是:通过旁路式架构,解决代码层面的大部分压力。现在很多商城的商品展示和搜索都采用NOSQL技术来应对处理,异步增加或更新,并不显得那么重要了,更多的是通过产品和技术架构来调整,比如通过分析用户喜好,事先静态化搜索结果。

赞同,感谢分享! 最核心的优化,还是应当在产品层面多下工夫。找到用户-产品-技术,三方都能满足的平衡点。
3 楼 zym820910 2012-12-11  
snowolf 写道
CurrentJ 写道
先写Cache,然后写Database,断电或者故障会导致用户数据丢失。

各有利弊,需要根据业务需求权衡。


写得非常好!应对高并发的时候,我们通常的思维是泄洪模式,通过一道又一道的防洪大堤将洪水分流,尤其是在应对数据要求不严厉的SNS这类产品,异步的保存数据值得提倡!

不过,更好的方式是:通过旁路式架构,解决代码层面的大部分压力。现在很多商城的商品展示和搜索都采用NOSQL技术来应对处理,异步增加或更新,并不显得那么重要了,更多的是通过产品和技术架构来调整,比如通过分析用户喜好,事先静态化搜索结果。
2 楼 snowolf 2012-11-07  
CurrentJ 写道
先写Cache,然后写Database,断电或者故障会导致用户数据丢失。

各有利弊,需要根据业务需求权衡。
1 楼 CurrentJ 2012-11-07  
先写Cache,然后写Database,断电或者故障会导致用户数据丢失。

相关推荐

    SSM实战项目——Java高并发秒杀API,详细流程+学习笔记

    SSM实战项目——Java高并发秒杀API是一个深入学习Java后端开发的重要实践,它涵盖了Spring、SpringMVC和MyBatis三大框架的整合应用,以及如何处理高并发下的秒杀场景。在这个项目中,我们将深入理解如何设计并实现一...

    memcached-笔记资料

    【标题】"memcached-笔记资料"涉及到的核心知识点是分布式内存缓存系统——Memcached,它是一个高性能、轻量级的缓存解决方案,主要用于减轻数据库的负载,提高Web应用的性能。 【描述】"memcached-笔记资料"暗示了...

    高并发Web架构实现思路——java版

    ### 高并发Web架构实现思路——Java版 #### 一、引言 随着互联网的快速发展,Web应用系统面临着巨大的挑战,尤其是如何处理高并发、海量数据的情况。传统的Web架构已经无法满足当前的需求,这就需要我们探索新的...

    Memcached学习笔记 — 第四部分:Memcached Java 客户端-gwhalin(1)-介绍及使用

    Memcached是一种广泛使用的分布式内存缓存系统,它能够...通过这篇学习笔记,你应该对gwhalin Memcached Java客户端有了初步了解,接下来可以结合实际项目,深入学习和实践,充分发挥Memcached在高并发场景下的优势。

    资料_高并发_数据库高并发集群笔记_

    在IT行业中,数据库高并发集群是应对大规模用户访问和数据处理的关键技术。尚硅谷的百战程序员提供的这份“数据库高并发集群笔记”涵盖了这一领域的核心概念、设计原则以及实践策略。下面将对这些知识点进行详细阐述...

    memcached笔记资料

    memcached笔记资料,配套视频:https://www.bilibili.com/list/474327672?sid=4486766&spm_id_from=333.999.0.0&desc=1

    高并发web架构完整1

    《高并发Web架构完整1》是一份关于优化和构建高性能Web站点的综合资源,共分为五个部分。在当今互联网行业中,随着用户数量的急剧增长...对于希望提升Web应用性能、应对高并发挑战的开发者来说,这是一个宝贵的资源库。

    韩顺平 PHP Memcached缓存技术资料源码笔记图解PPT_Ady

    3. 并发处理:Memcached不支持事务,对于并发操作,需要在代码层面进行控制。 六、Memcached与Redis对比 虽然两者都是缓存解决方案,但Memcached更适合简单的键值对存储,而Redis提供了更丰富的数据结构(如列表、...

    memcached笔记

    **Memcached笔记** Memcached是一种高性能的分布式内存对象缓存系统,它被广泛应用于Web应用中,用于减轻数据库的负载,提高数据访问速度。本文将深入探讨Memcached的基础知识、工作原理、安装与配置,以及如何在...

    Memcached 学习资料(memcached Memcached使用手册 Memcached源码剖析笔记)

    Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提供动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的...

    《亿级流量网站架构核心技术——跟开涛学搭建高可用高并发系统》

    《亿级流量网站架构核心技术——跟开涛学搭建高可用高并发系统》这本书深入探讨了在互联网行业中如何设计和构建能够处理亿级用户流量的高可用、高并发系统。作者开涛,作为业界资深专家,以其丰富的实战经验,为我们...

    Memcached 源码剖析笔记

    memcached 源码剖析笔记和源码。 Memcached 是一个自由、源码开放、高性能、分布式内存对象缓存系统,目的在于过减轻数据库负载来使动态 Web 应用程序提速。

    Memcached源码剖析笔记

    **Memcached**是一个高性能的分布式内存对象缓存系统,其主要目标是通过缓存数据和对象到内存中,从而减少对后端数据库的访问频率,进而提升动态Web应用程序的速度。这种缓存策略有效地减轻了数据库的负载,特别是在...

    21丨分布式架构:如何应对高并发的用户请求.pdf

    "21丨分布式架构:如何应对高并发的用户请求"这个主题探讨了如何通过分布式架构来解决这一问题。分布式架构是一种通过在多台服务器之间分散负载,增加系统处理能力和可扩展性的技术策略。 首先,文章提到了两种应对...

    基于Nginx和Memcached的高并发WEB服务器设计_戴华

    10. 关键词:并发服务器、高并发WEB服务器设计、Nginx、Memcached、分布式缓存、一致性哈希算法、云计算。 整体而言,文章所探讨的技术内容和知识点涉及了现代高性能WEB服务器设计的关键技术和策略,以及它们在实际...

    Memcached源码剖析笔记.docx

    Memcached 是一个自由、开源、高性能、分布式内存对象缓存系统,旨在通过减轻数据库负载来使动态 Web 应用程序提速。下面是 Memcached 源码剖析笔记的知识点总结: 1. 背景 Memcached 的出现是为了解决动态 Web ...

Global site tag (gtag.js) - Google Analytics