-
2019-05-08 17:04:17
- 确认服务器硬件是否足够支持当前的流量
普通的P4服务器一般最多能支持每天10万独立IP,如果访问量比这个还要大, 那么必须首先配置一台更高性能的专用服务器才能解决问题 ,否则怎么优化都不可能彻底解决性能问题。 - 优化数据库访问
前台实现完全的静态化当然最好,可以完全不用访问数据库,不过对于频繁更新的网站, 静态化往往不能满足某些功能。缓存技术就是另一个解决方案,就是将动态数据存储到缓存文件中,动态网页直接调用 这些文件,而不必再访问数据库,WordPress和Z-Blog都大量使用这种缓存技术 如果确实无法避免对数据库的访问,那么可以尝试优化数据库的查询SQL.避免使用 Select * from这样的语句,每次查询只返回自己需要的结果,避免短时间内的大,尽量做到"所查即所得" ,遵循以小表为主,附表为辅,查询条件先索引,先小后大的原则,提高查询效率.量SQL查询。 - 禁止外部的盗链
外部网站的图片或者文件盗链往往会带来大量的负载压力,因此应该严格限制外部对于自身的图片或者文件盗链,好在目前可以简单地通过refer来控制盗链,Apache自 己就可以通过配置来禁止盗链,IIS也有一些第三方的ISAPI可以实现同样的功能。当然,伪造refer也可以通过代码来实现盗链,不过目前蓄意伪造refer盗链的还不多, 可以先不去考虑,或者使用非技术手段来解决,比如在图片上增加水印。 - 控制大文件的下载
大文件的下载会占用很大的流量,并且对于非SCSI硬盘来说,大量文件下载会消耗 CPU,使得网站响应能力下降。因此,尽量不要提供超过2M的大文件下载,如果需要提供,建议将大文件放在另外一台服务器上。 - 使用不同主机分流主要流量
将文件放在不同的主机上,提供不同的镜像供用户下载。比如如果觉得RSS文件占用流量大,那么使用FeedBurner或者FeedSky等服务将RSS输出放在其他主机上,这样别人访问的流量压力就大多集中在FeedBurner的主机上,RSS就不占用太多资源了。 - 使用流量分析统计软件
在网站上安装一个流量分析统计软件,可以即时知道哪些地方耗费了大量流量,哪些页面需要再进行优化,因此,解决流量问题还需要进行精确的统计分析才可以。我推荐使用的流量分析统计软件是Google Analytics(Google分析)。若还有其他的流量分析软件,欢迎共享交流.
更多相关内容 - 确认服务器硬件是否足够支持当前的流量
-
php使用lua+redis实现限流,计数器模式,令牌桶模式
2020-10-17 05:19:13主要介绍了php使用lua+redis实现限流,计数器模式,令牌桶模式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 -
Sentinel限流规则使用总结
2022-04-01 15:46:00目前Sentinel支持以下三种限流/熔断规则:基于资源限流(Flow Rule)、系统自适应限流(SystemRule)、系统熔断降级(DegradeRule),sentinel还支持基于授权的限流(AuthorityRule),其父类为AbstractRule。...一、Sentinel限流/熔断规则
目前Sentinel支持以下五种限流/熔断规则:基于资源限流(FlowRule)、系统自适应限流(SystemRule)、系统熔断降级(DegradeRule)、热点参数限流(ParamFlowRule),sentinel还支持基于授权的限流(AuthorityRule),其父类为
AbstractRule
。
二、网关限流原理
另外,Sentinel还支持网关限流,说到底就是Filter限流,控制限流资源范围。其实现原理为为Servlet添加了一个CommonFilter,doFilter方法如下:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest sRequest = (HttpServletRequest)request; Entry urlEntry = null; try { String target = FilterUtil.filterTarget(sRequest); UrlCleaner urlCleaner = WebCallbackManager.getUrlCleaner(); if (urlCleaner != null) { target = urlCleaner.clean(target); } if (!StringUtil.isEmpty(target)) { String origin = this.parseOrigin(sRequest); String contextName = this.webContextUnify ? "sentinel_web_servlet_context" : target; ContextUtil.enter(contextName, origin); //=============标记请求路径为资源 start=============== if (this.httpMethodSpecify) { String pathWithHttpMethod = sRequest.getMethod().toUpperCase() + ":" + target; urlEntry = SphU.entry(pathWithHttpMethod, 1, EntryType.IN); } else { urlEntry = SphU.entry(target, 1, EntryType.IN); } //=============标记请求路径为资源 end=============== } chain.doFilter(request, response); } catch (BlockException var15) { HttpServletResponse sResponse = (HttpServletResponse)response; WebCallbackManager.getUrlBlockHandler().blocked(sRequest, sResponse, var15); } catch (ServletException | RuntimeException | IOException var16) { Tracer.traceEntry(var16, urlEntry); throw var16; } finally { if (urlEntry != null) { urlEntry.exit(); } ContextUtil.exit(); } }
三、自问自答QA
-
“资源”在一个系统中是唯一的吗?即不同接口上的资源名称可以重复吗?
答:可以重复。resource相当于是一个分类,可以加在不同的接口上。 -
相同名称的rule可以加载成功吗?
答:不可以,同一种类型的rule名称应保持唯一,规则会被放到一个Map中,key为resource名称。源码:com.alibaba.csp.sentinel.slots.block.flow.FlowRuleUtil#buildFlowRuleMap(java.util.List<com.alibaba.csp.sentinel.slots.block.flow.FlowRule>, com.alibaba.csp.sentinel.util.function.Function<com.alibaba.csp.sentinel.slots.block.flow.FlowRule,K>, com.alibaba.csp.sentinel.util.function.Predicate<com.alibaba.csp.sentinel.slots.block.flow.FlowRule>, boolean)
-
一个资源名称,在两个接口上一起使用时,限流统计规则是两个接口一起还是独立计算?
答:独立计算。 -
是否允许通配的方式批量添加到controller层?
答:可以。具体操作方法见第四节《网关限流》,其原理是基于Filter,请求进来的时候就被标记了资源。 -
资源定义的方式有很多种,建议通过注解。
-
通用异常处理方式?
答:平台可以添加统一的异常处理,违反限流规则会抛出FlowException。源码追溯:com.alibaba.csp.sentinel.slots.block.flow.FlowRuleChecker#checkFlow
。 -
定义规则名称,与实际注解资源不匹配会报错吗?即注解使用了错误的规则。
答:流控失败,且不会报错。 -
注解使用一定要放在Controller方法上吗?
答:不一定,也可以在Service、工具类中,其本质为抛出了FlowException异常。 -
设置了全局范围资源点,且在接口上未定义其他资源,那么设置的资源规则、系统规则、降级规则还生效吗?
答:1-资源规则不生效,检查过程是根据资源名称获取规则后再校验的,如图得到的规则未空,实际上是配置了资源规则的。
public void checkFlow(Function<String, Collection<FlowRule>> ruleProvider, ResourceWrapper resource, Context context, DefaultNode node, int count, boolean prioritized) throws BlockException { if (ruleProvider == null || resource == null) { return; } Collection<FlowRule> rules = ruleProvider.apply(resource.getName()); if (rules != null) { for (FlowRule rule : rules) { if (!canPassCheck(rule, context, node, count, prioritized)) { throw new FlowException(rule.getLimitApp(), rule); } } } }
2-系统规则生效。
com.alibaba.csp.sentinel.slots.system.SystemRuleManager#checkSystem
3-降级规则不生效。public static void checkDegrade(ResourceWrapper resource, Context context, DefaultNode node, int count) throws BlockException { Set<DegradeRule> rules = degradeRules.get(resource.getName()); if (rules == null) { return; } for (DegradeRule rule : rules) { if (!rule.passCheck(context, node, count)) { throw new DegradeException(rule.getLimitApp(), rule); } } }
四、总结
Sentinel的官网文档已经很是完整了,此处仅是在下做的一些小总结。当然Sentinel的功能还是非常强大的,参数类型也众多,未能测试全面。大家在测试过程中可以使用测试工具JMeter进行测试。
顺便说两句,关于如何学习一个工具有两种思路:
- 第一种是基于测试,按照不同的用例来了解当前组件的功能;
- 第二种是看源码,了解工具的设计细节。
大家在学习的过程中,建议2种方式结合一下。通过
测试
来了解
基本功能,通过读源码
来解释测试结果
。这样双管齐下,便可进一步加深理解,学习软件背后的学习思路~
大家如有问题欢迎与我交流~ -
-
redis限流算法.zip
2020-07-03 11:13:15具体基于redis实现了计数法(zset 有序集合)和令牌桶算法(list 链表),并提供了基于redis的漏斗算法的思路(hash 与锁) -
Sentinel限流基本使用
2022-01-19 16:43:46(注意:想限流哪个接口就点击哪个接口的流控,无论是否是关联模式),链路模式则需要使用注解@SentinelResource进行埋点 8.对于流控效果选项, 快速失败表示如果QPS超限,那么后续请求则直接失败; warm up表示在...1.下载sentinel的jar包并使用命令启动sentinel,参考文章
https://lizz6.blog.csdn.net/article/details/115859770
java -Dserver.port=8858 -Dsentinel.dashboard.auth.username=root -Dsentinel.dashboard.auth.password=123456 -jar sentinel-dashboard-1.8.1.jar
2.在子项目中加入pom依赖并在yml进行配置
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency>
spring: cloud: sentinel: transport: dashboard: http://localhost:8858 # 如果sentinel和项目的ip不同则需加上下面这个clientIP # clientIp: localhost
3.进入sentinel控制台
http://localhost:8858/
并手动进行需要限流的接口的调用以将其注册进sentinel
4.多次调用接口即可在sentinel中看到图表数据
5.点击“簇点链路
”中的“流控
”对每个端点进行流量控制
6.只设置单机阀值为10则表示当QPS为10以上时则会拒绝多余的请求
7.高级选项中的直接
模式与上述相同,关联
则表示当关联接口达到该对话框中的单机阀值
时,则会拒绝掉此接口的访问。(注意:想限流哪个接口就点击哪个接口的流控,无论是否是关联
模式),链路
模式则需要使用注解@SentinelResource
进行埋点
8.对于
流控效果
选项,
快速失败
表示如果QPS超限,那么后续请求则直接失败;
warm up
表示在项目刚启动时,最大QPS为设置的三分之一,当过一段时间后(在预热时常中设置)则会逐渐上升到QPS设置的值;
排队等待
表示多余的请求将排队,如果某请求排队时长超过设置的值,将会拒绝该请求
-
api接口限流(限制请求次数)
2021-03-24 01:32:45有时候我们需要给我们写的接口来定义请求限制次数(限流) 如多长时间之内只能请求多少次。这样可以防止某些恶意用户一直请求我们的接口 给服务器减轻压力。应用场景:app端 用户收藏文章 取消收藏文章(某些恶意用户...有时候我们需要给我们写的接口来定义请求限制次数(限流) 如多长时间之内只能请求多少次。这样可以防止某些恶意用户一直请求我们的接口 给服务器减轻压力。
应用场景:app端 用户收藏文章 取消收藏文章(某些恶意用户一直在app端重复点击收藏或取消收藏 这样对我们的数据库会造成很大的压力)
/**
* 限制接口请求次数
* @param string $key key名称
* @param int $time 过期时间 单位:秒
* @count int 限制请求次数
* @author zhouyulin@smzdm.com
* @date 2018-06-11
*/
public function redis_limit($key,$time = 20,$count = 3)
{
$result = array(
'error_code' => 0,
'error_msg' => '',
'data' => [],
);
$redis = new Redis();
$redis->connect('127.0.0.1',6379);
//$redis->auth('xxxxxx'); //Redis链接密码 如没有可不用写这一步
$key_res = $redis->exists($key); //key是否存在
if($key_res)
{
$redis->incr($key); //key对应的值自增1
$nums = $redis->get($key); //获取key的值
//key的值超过了请求次数
if($nums > $count)
{
$result['error_code'] = 1;
$result['error_msg'] = '操作频繁!请稍后重试!';
goto ARCHOR_RESULT;
}
}
else
{
//key不存在 写入redis
$redis->setex($key,$time,1); //key 时间 值
}
ARCHOR_RESULT:
return $result;
}
这样就可以了 在用户相关地方调用以上方法即可 传入的key可以是当前登录用户的主键id值 只要是唯一的 能够在redis中标识这是唯一的key就可以了。
-
hyperfTest:hyperf限流,中间件,hyperf案例
2021-03-10 18:24:59限流,熔断,中间件,模型缓存,异常处理,定时任务 应用场景是根据用户组的键,产生不同的限流效果,即不同的令牌桶。 坑很多,慢慢踩 runtime下面的文件是启动的时候生成的,修改了代码,启动前记得要删除,可以... -
PHP+laravel 高并发下接口限流方案
2021-11-10 15:27:10一、什么是接口限流 那么什么是限流呢?顾名思义,限流就是限制流量,包括并发的流量和一定时间内的总流量,就像你宽带包了1个G的流量,用完了就没了,所以控制你的使用频率和单次使用的总消耗。 通过限流,我们可以... -
php实战kong做微服务架构四(插件之网关限流)
2021-02-23 18:20:39php实战kong做微服务架构四(插件之限流、负载均衡、黑白名单)序言kong插件介绍插件列表限流粒度算法配置负载均衡配置黑白名单配置运行示例 序言 为了在多项目管理过程中,让部分统一业务集中管理,比如鉴权、限流... -
php实现接口限流
2019-04-22 22:21:22php接口限流主要是防止高并发造成服务器扛不住的情况下,需要限制数据的获取,简单实现就是结合redis实现。 <?php /** * api 接口限流 * */ class api { public function get_client_ip($type = 0) { $... -
imiratelimit是imi框架的限流组件基于bandwidththrottletokenbucket开发
2019-08-08 05:00:28imi 框架的限流组件,可以针对方法、接口设置限流,通过设置总容量、单位时间内生成填充的数量、每次扣除数量实现限流。 -
java中的限流
2022-04-26 21:39:17文章目录限流参考地址前言一、为什么要限流在限流中有两个概念需要了解二、限流算法实现分类限流的分类:6种具体的实现限流的手段:限流按照规模来分类:Tomcat配置maxThreads限流Nginx 限流**控制速率****控制并发... -
php使用redis来实现限流和并发控制
2019-07-03 12:34:35比如抢购、限时活动等等,如果不对并发量进行控制,瞬时的高并发可能会导致系统崩溃,这时我们就需要把一部分请求挡掉,可以结合redis来实现一个基本的限流功能。 function makeOrder(\Redis $redis, $... -
nginx限流与配置管理
2021-12-20 11:23:12一、nginx限流 1.控制单IP并发连接数 //$binary_remote_addr 表示通过remote_addr这个标识来做限制 //zone=addr:10m 表示生成一个大小为10M,名字为addr的内存区域 limit_conn addr 1; #限制并发数 limit_... -
基于redis实现的ip限流方案
2022-02-25 16:46:22需求: 同一个IP在 一定的时间内只能访问制定的次数,否则就不处理请求 具体思路: 这里借助的是redis的string数据类型,用 key保存IP地址, ...其中 KEYS[1]是保存 IP地址的 key值,ARGV[1]是过期时间,ARGV[2]是限 -
laravel+redis实现接口限流
2021-05-26 17:06:06php // 已Laravel框架为例 namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Illuminate\Http\Response as SymfonyResponse; use Illuminate\Support\Facades\Response; /** * ... -
PHP基于redis实现滑动窗口式的短信发送接口限流
2020-07-14 14:07:30滑动窗口短信发送限流算法 1.有两条规则 基于IP的限制和基于手机号的限制 IP规则: 1分钟限制5 10分钟限制30 1小时限制50 手机号规则: 1分钟限制1 10分钟限制5 1小时限制10 2.滑动窗口就是随着时间... -
聊聊 TokenBucket 限流器的基本原理及实现
2022-01-24 10:10:19本文我们介绍另外一种限流器—令牌桶(TokenBucket)。 令牌桶(TokenBucket)简介 令牌桶实现的基本思想 令牌桶,顾名思义,是一种通过让请求被处理前先行获取令牌,只有获取到令牌的请求才能被放行处理的一种限流... -
Laravel throttle限流中间件
2019-09-08 08:36:29文章目录自定义限流记录中间件替换默认的中间件 Laravel默认的限流是针对IP,频率为60次/分钟,经过测试发现,如果多个IP属于同一个局域网,比如连接同一个WI-FI,则会判定为同一个IP,进行限流。 也就是说如果同一... -
Linux企业运维--nginx限流与配置管理
2022-04-16 16:59:47一、nginx限流 https://docs.nginx.com/nginx/admin-guide/security-controls/controlling-access-proxied-http/ 1.最大连接数限制 修改配置文件,nginx中通过limit_comm_zone 和limit_req_zone两个组建来对... -
php 基于redis使用令牌桶算法实现流量控制
2018-02-23 12:46:24每当国内长假期或重要节日时,国内的景区或地铁都会人山人海,导致负载过大,部分则会采用限流措施,限制进入的人数,当区内人数降低到一定值,再允许进入。 例如: 区内最大允许人数为 M 区内当前人数为 N 每... -
nginx+lua实现限流降级(使用lua的lua-resty-limit-traffic)
2022-04-03 15:50:50虽然nginx中自带了限流的模块,只能直接限定超出的数量,但对于允许范围内的流量如何进行限流是个问题。nginx的限流方式! limit_conn perserver 100; limit_conn perip 15; limit_rate 512k; 但是比如这100的... -
Easyswoole 令牌桶IP限流实现(企业实用)
2021-04-28 14:26:08使用Easyswoole 开发项目有一段时间了,官方的ip 限流方法比较简陋,我这里自己手动实现了一套基于令牌桶算法限流的方案,这里记录分享下 实现功能 1:根据ip 限速 2:可以配置缓冲池,防止突发流量 3:可以配置黑白名单,... -
Redis 简单限流、漏斗限流
2019-03-22 14:57:34简单限流 实现代码: 漏斗限流 -
简单两步解决nginx+php 的高并发502问题(nginx限流,定时重启php-fpm)
2022-03-25 18:02:39简单两步解决nginx+php 的高并发502问题(nginx限流,定时重启php-fpm) -
nginx的那些模块,用来实现高并发,负载均衡策略, 限流策略:
2022-03-25 14:55:15对Nginx返回的数据压缩,属于性能优化模块 4、ngx_http_fastcgi_module #FastCGI模块,和 动态应用相关的模块,例如PHP 5、ngx_http_proxy_module #Proxy代理模块 6、ngx_http_upstream_module #负载均衡模块,... -
nginx在CDN加速或使用SLB代理后,获取真实IP,做并发访问限制的方法(限流)
2018-07-20 18:27:36站点在运行时,为了防止DDoS 攻击、或内部接口调用造成的数据迸发,nginx提供了limit限流模块: HttpLimitZoneModule 限制同时并发访问的数量 HttpLimitReqModule 限制访问数据,每秒内最多几个请求 一、普通... -
Swoft 2.x 微服务基础(Consul、RPC 服务发现、限流与熔断器)
2020-02-20 17:51:572.4 限流功能的使用、令牌桶; 2.5 熔断器基本使用; 2.5.1 Break 注解、降级函数的使用; 2.5.2 Break 熔断器参数设置、状态。 1. Swoft 服务注册与发现; 1.1 Consul 概况; 服务的发现与注册 配置共享:调用端... -
Redis 利用 incr 和 expire 来限流, 并发导致过期时间失效问题
2021-04-26 21:42:36当某一个接口需要限流时,可以采用redis的incr来递增,记录访问次数, 以及 expire 来设置失效时间.大概的代码如下:r = redis.Redis.connect()key = "linyk3"query_times = redis.Redis.get_data(r, key)if query_times... -
PHP接收二进制流文件并保存
2020-05-16 12:00:05PHP通过二进制流判断文件类型 去看看 二、实现 1、通过postman工具发送请求 请求方式:get,post,put,patch,delete,options…这些都可以(注意get有传输大小限制) 2、框架TP 就这一句用到了TP的方法,改成你框架的...