Memcached笔记——(四)应对高并发攻击【转】
http://snowolf.iteye.com/blog/1677495
近半个月过得很痛苦,主要是产品上线后,引来无数机器用户恶意攻击,不停的刷新产品各个服务入口,制造垃圾数据,消耗资源。他们的最好成绩,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
- */
- @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笔记——(四)应对高并发攻击
顶
踩
- 2012-09-13 09:48
- 浏览 10171
- 评论(8)
- 分类:企业架构
- 相关推荐
评论
好眼力
各有利弊,需要根据业务需求权衡。
写得非常好!应对高并发的时候,我们通常的思维是泄洪模式,通过一道又一道的防洪大堤将洪水分流,尤其是在应对数据要求不严厉的SNS这类产品,异步的保存数据值得提倡!
不过,更好的方式是:通过旁路式架构,解决代码层面的大部分压力。现在很多商城的商品展示和搜索都采用NOSQL技术来应对处理,异步增加或更新,并不显得那么重要了,更多的是通过产品和技术架构来调整,比如通过分析用户喜好,事先静态化搜索结果。
赞同,感谢分享! 最核心的优化,还是应当在产品层面多下工夫。找到用户-产品-技术,三方都能满足的平衡点。
各有利弊,需要根据业务需求权衡。
写得非常好!应对高并发的时候,我们通常的思维是泄洪模式,通过一道又一道的防洪大堤将洪水分流,尤其是在应对数据要求不严厉的SNS这类产品,异步的保存数据值得提倡!
不过,更好的方式是:通过旁路式架构,解决代码层面的大部分压力。现在很多商城的商品展示和搜索都采用NOSQL技术来应对处理,异步增加或更新,并不显得那么重要了,更多的是通过产品和技术架构来调整,比如通过分析用户喜好,事先静态化搜索结果。
各有利弊,需要根据业务需求权衡。
转载于:https://www.cnblogs.com/fx2008/p/4114975.html
Memcached笔记——(四)应对高并发攻击【转】相关推荐
- Java高并发秒杀API(四)之高并发优化
Java高并发秒杀API(四)之高并发优化 1. 高并发优化分析 关于并发 并发性上不去是因为当多个线程同时访问一行数据时,产生了事务,因此产生写锁,每当一个获取了事务的线程把锁释放,另一个排队线程才 ...
- 京东云携手达达构建行业首个跨云双活平台 应对高并发需求
达达快送平台的孙壮不经意间刷新了自己配送时效的记录. 2020年6月18日,他只用了十几分钟就将达达集团旗下即时零售平台京东到家的订单送到了用户手中.并且还是在层层山峦,蜿蜒崎岖的山城重庆. 跟孙壮一 ...
- 小米开源监控系统OpenFalcon应对高并发7种手段
2019独角兽企业重金招聘Python工程师标准>>> 小米开源监控系统OpenFalcon应对高并发7种手段 原创 2016-04-01 秦晓辉 高可用架构 编者按:本文是秦晓辉在 ...
- 程序员过关斩将--应对高并发系统有没有通用的解决方案呢?
" 灵魂拷问: 应对高并发系统有没有一些通用的解决方案呢? 这些方案解决了什么问题呢? 这些方案有那些优势和劣势呢? 对性能孜孜不倦的追求是互联网技术不断发展的根本驱动力,从最初的大型机到现 ...
- 应对高并发的几个常见方法
我们在应对高并发大流量时也会采用类似"抵御洪水"的方案,归纳起来共有三种方法. Scale-out(横向扩展):分而治之是一种常见的高并发系统设计方法,采用分布式部署的方式把流量分 ...
- 如何应对高并发问题?
如何应对高并发问题? 我觉着可以从两方面来着手,第一方面是硬件,第二方面是软件.当然硬件方面做的比较少,从软件方面来说做的就比较多了. 硬件方面的话,我们可以购买性能更好的服务器,或者是提升现有服务器 ...
- 视频直播系统开发:如何应对高并发访问?
视频直播开发的挑战 随着移动互联网的快速普及,视频直播已经成为了新的社交媒体形式,也成为了一种新的商业模式.现在,越来越多的人开始使用视频直播来展示自己的生活和工作,同时,越来越多的企业开始将视频直播 ...
- memcached在大负载高并发网站上的应用(一)
大家可能对memcached这种产品早有了解,或者已经应用在自己的网站中了,但是也有一些朋友从来都没有听说过或者使用过. 这都没什么关系,本文旨在从各个角度综合的介绍这种产品,尽量深入浅出,如果能对您 ...
- 深入浅出!阿里运维专家三种方法教你如何应对高并发“海啸”场景
作者:田杰,阿里云数据库高级运维专家 在数据库的日常使用中,来自应用的高并发场景并不罕见,其标志性的表现为 高新连接创建速率(CPS,比如 PHP 短连接).发送大量请求到 DB 数据库层. 如同 海 ...
- java队列实现限流,java中应对高并发的两种策略
目的:提高可用性 通过ExecutorService实现队列泄洪 //含有20个线程的线程池 private ExecutorService executorService = Executors.n ...
最新文章
- R语言临床预测模型的评价指标与验证指标实战:综合判别改善指数IDI(Integrated Discrimination Improvement, IDI)
- linux c 调试 strace 诊断 调试程序 异常退出 崩溃
- silverlight中的socket编程注意事项
- STM32寄存器与输入捕获
- 专题突破一之分块——Untitled Problem II,Balanced Lineup,[ioi2009]Regions
- fir c语言程序,fir.rar fir的c语言程序 - 下载 - 搜珍网
- 360手机浏览器_网信办:UC、QQ、360、搜狗等8款手机浏览器被纳入首批整治范围...
- 对于整数数组类的算法的终极解决方案
- frm ibd文件导入mysql_Mariadb,Mysql如何根据.frm和.ibd文件来恢复数据和表结构
- extracting lines bases a list using awk
- 一个基于对话框的简单MFC程序分析
- 回到顶部功能:uniapp微信小程序回到顶部的几种方法
- PhpSpreadsheet读写Excel文件
- CMCT-FA修饰阿霉素纳米脂质体/ADR-HAS-MS单抗Hab18偶联阿霉素人血清白蛋白微球的制备方法
- Law of continuity
- 一个39岁程序员的应聘被拒 | 文末送书
- java socket通信 客户端_JavaのSocket编程之简单客户端与服务器端通信
- [转]基于mysql数据库binlog的增量订阅消费中间件:Canal
- 国外接活网站介绍:Elance vs GetAFreelancer vs ScriptLance
- wps出现安装installer_wps总出现稿纸加载项安装怎么办 - 卡饭网
热门文章
- android的JNI标准 android的NDK
- 公务员工资分配的一种方法
- 全局程序集缓存工具 (Gacutil.exe)
- antd的Tree控件实现点击展开功能
- CSS——简写属性(在padding和margin这样的简写属性中,值赋值的顺序是top、right、bottom、left)...
- 随着浏览器窗口缩小表格出现横向滚动条
- 使用SQL语句操作数据
- Delphi多媒体设计之TMediaPlayer组件(三)
- Silverlight 2.0 RTW 正式版发布(附下载地址)
- 字符串超长导致emWin卡死