1.前言

一般对外暴露的系统,在促销或者黑客攻击时会涌来大量的请求,为了保护系统不被瞬间到来的高并发流量给打垮, 就需要限流 .

本文主要阐述如何用nginx 来实现限流. 听说 Hystrix 也可以, 各位有兴趣可以去研究哈 .

2. 首先部署一个对外暴露接口的程序

我这里部署的是一个spring boot 项目 里面暴露了如下接口, 很简单

package com.anuo.app.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController; @RestController
@RequestMapping("/test")
public class TestController { Logger logger = LoggerFactory.getLogger(TestController.class); @RequestMapping(value = "/show/message", method = RequestMethod.GET)
public String test() {
return "hello world ";
} }

暴露了一个 get 请求返回 hello world 的restful 接口.

将此程序部署到 linux 服务器上. 部署步奏不再赘述, 自行百度 spring boot 部署 即可.

3.创建一个名称为 nginx.conf 的 nginx 配置文件

创建一个 名叫 nginx.conf 的配置文件, 完整内容如下

user  nginx;
worker_processes 1; error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid; events {
worker_connections 1024;
} http {
include /etc/nginx/mime.types;
default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on;
#tcp_nopush on; keepalive_timeout 65; #gzip on; #限流配置
limit_req_zone $binary_remote_addr zone=perip:10m rate=1r/s; #负载均衡配置
upstream myserver {
server 192.168.10.253:8090; }
server {
listen 80; location / {
limit_req zone=perip;
proxy_pass http://myserver; }
}
}

  

配置文件中限流部分解释:

如上, nginx 的限流配置 , 只有两行代码.

第一行:


#限流配置
limit_req_zone $binary_remote_addr zone=perip:10m rate=1r/s;

  

limit_req_zone : 是限流声明.

$binary_remote_addr: 表示根据客户端 ip 来 限流, 比如 上面的限流配置 限制每个客户端ip的请求频率为一秒一次, 你如果耍流氓一秒两次, 就会被限流 会返回一个http 503 错误给你.

zone=perip: 表示 用 perip 这个 名称 来标识 这行限流配置, 待会 会通过 perip 这个名称来引用这行限流配置(也就是说限流配置是可以定义为多个的)

10m: 表示存储客户端ip的空间为10MB, 1MB 大概存储1万多ip , 10 MB 大概 10多万Ip , 参考解释:  http://www.ttlsa.com/nginx/nginx-limiting-the-number-of-requests-ngx_http_limit_req_module-module/  在这篇文章中搜索 binary_remote_addr 即可定位相关解释.

rate=1r/s: 表示频率是 一秒一个请求.

第二行:

location / {
limit_req zone=perip;
proxy_pass http://myserver; }

即这行:

limit_req zone=perip;

表示在 myserver 这个集群上, 使用 名称为 perip 的限流配置

4.用docker 部署 nginx

将上一步创建的 nginx.conf 配置文件, 拷贝到linux 目录 , /root/nginx/ 下 (目录可以任意), 然后 一个docker 命令部署好 nginx 环境

docker run --name nginx -v /root/nginx/nginx.conf:/etc/nginx/nginx.conf:ro -p 8080:80 -d nginx

  

这里暴露的是 8080 端口, 通过 8080 端口可以访问到 nginx 配置中的负载均衡节点, 即 192.168.10.253:8090  ip端口, 这个 ip端口对应的就是 , 第一步创建部署的 hello world 程序.

5. 用代码访问 第一步定义的 helloworld 接口

package com.anuo.study.studydistributed;

import com.anuo.app.common.util.HttpUtil;

public class StudyNginx {
public static void main(String[] args) throws InterruptedException {
while (true) {
Thread.sleep(100);
String s= HttpUtil.sendGet("http://192.168.10.253:8080/test/show/message");
System.out.println(s);
}
}
}

  

我这里是 一秒 执行 10次 get 请求, 已经大于了 nginx中配置的 rate=1r/s  一秒一次的请求, 所以会看到 503 报错, 如下. 

如果改哈代码, 改为一秒执行一次get 请求, 就不会报错, 各位可以去试一下

至此 nginx 的限流 已实现. 

参考的优质文章:
http://www.ttlsa.com/nginx/nginx-limiting-the-number-of-requests-ngx_http_limit_req_module-module/
http://www.ttlsa.com/nginx/nginx-limited-connection-number-ngx_http_limit_conn_module-module/#comments
官方文档:
http://nginx.org/en/docs/http/ngx_http_limit_req_module.html#limit_req_log_level
https://www.nginx.com/blog/rate-limiting-nginx/

用nginx实现分布式限流的更多相关文章

  1. 限流(四)nginx接入层限流

    一.nginx限流模块 接入层指的是请求流量的入口,我们可以在这里做很多控制,比如:负载均衡,缓存,限流等. nginx中针对限流有两个模块可以处理: 1)ngx_http_limit_req_mod ...

  2. 限流(三)Redis + lua分布式限流

    一.简介 1)分布式限流 如果是单实例项目,我们使用Guava这样的轻便又高性能的堆缓存来处理限流.但是当项目发展为多实例了以后呢?这时候我们就需要采用分布式限流的方式,分布式限流可以以redis + ...

  3. 基于kubernetes的分布式限流

    做为一个数据上报系统,随着接入量越来越大,由于 API 接口无法控制调用方的行为,因此当遇到瞬时请求量激增时,会导致接口占用过多服务器资源,使得其他请求响应速度降低或是超时,更有甚者可能导致服务器宕机 ...

  4. Redis实现的分布式锁和分布式限流

    随着现在分布式越来越普遍,分布式锁也十分常用,我的上一篇文章解释了使用zookeeper实现分布式锁(传送门),本次咱们说一下如何用Redis实现分布式锁和分布限流. Redis有个事务锁,就是如下的 ...

  5. 【分布式架构】--- 基于Redis组件的特性,实现一个分布式限流

    分布式---基于Redis进行接口IP限流 场景 为了防止我们的接口被人恶意访问,比如有人通过JMeter工具频繁访问我们的接口,导致接口响应变慢甚至崩溃,所以我们需要对一些特定的接口进行IP限流,即 ...

  6. 分布式限流组件-基于Redis的注解支持的Ratelimiter

    原文:https://juejin.im/entry/5bd491c85188255ac2629bef?utm_source=coffeephp.com 在分布式领域,我们难免会遇到并发量突增,对后端 ...

  7. Sentinel整合Dubbo限流实战(分布式限流)

    之前我们了解了 Sentinel 集成 SpringBoot实现限流,也探讨了Sentinel的限流基本原理,那么接下去我们来学习一下Sentinel整合Dubbo及 Nacos 实现动态数据源的限流 ...

  8. NGINX 上的限流

    NGINX 上的限流(译) zlup YP小站  今天 前言 本文是对Rate Limiting with NGINX and NGINX Plus的主要内容(去掉了关于NGINX Plus相关内容) ...

  9. springboot + aop + Lua分布式限流的最佳实践

    整理了一些Java方面的架构.面试资料(微服务.集群.分布式.中间件等),有需要的小伙伴可以关注公众号[程序员内点事],无套路自行领取 一.什么是限流?为什么要限流? 不知道大家有没有做过帝都的地铁, ...

随机推荐

  1. ubuntu无法update

    ubuntu系统执行sudo apt-get update报错解决方法: 编辑源列表文件 sudo vi /etc/apt/sources.list 将原来的列表删除,添加如下内容(中科大镜像源) d ...

  2. vijos 1439 区间

    区间 背景 描述 给定n个闭区间 [ai,bi], i=1,2,...,n. 这些区间的和可以用两两不相交的闭区间的和来表示.你的任务是找到这样的区间数目最少的表示,且把它们按升序的方式写到输出文件中 ...

  3. 非常适合新手的jq/zepto源码分析07---ajax的封装

    复习下ajax吧! 1.创建XMLHttpRequest对象 xmlhttp=new XMLHttpRequest(); xmlhttp=new ActiveXObject("Microso ...

  4. v$log and v$logfiles

    v$log has one row for each group. v$logfile has one row for each file. There is a status column for ...

  5. HDU 4849 Wow! Such City!陕西邀请赛C(最短路)

    HDU 4849 Wow! Such City! 题目链接 题意:依照题目中的公式构造出临接矩阵后.求出1到2 - n最短路%M的最小值 思路:就依据题目中方法构造矩阵,然后写一个dijkstra,利 ...

  6. 猫猫学iOS 之CoreLocation反地理编码小Demo输入经纬度得到城市

    猫猫分享,必须精品 原创文章,欢迎转载.转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243 一:效果 输入经纬度,能够得到相应的地名 二:思路 跟地里编码差 ...

  7. js 实现对ajax请求面向对象的封装

             AJAX 是一种用于创建高速动态网页的技术.通过在后台与server进行少量数据交换.AJAX 能够使网页实现异步更新.这意味着能够在不又一次载入整个网页的情况下,对网页的某部分进行 ...

  8. 将一个对象相同的属性(不区分大小写)赋值给一个新对象 DataTable的一个简单的扩展

    将一个对象相同的属性(不区分大小写)赋值给一个新对象   1 public static T Mapper<S, T>(S source) 2 { 3 T t = Activator.Cr ...

  9. ZOJ 3888 Twelves Monkeys (预处理+优先队列)

    题目链接:ZOJ 3888 Twelves Monkeys 题意:题目描写叙述起来比較绕,直接讲案例 9 3 3 9 1 6 1 4 1 6 7 2 输入n,m,q.n限制了你询问的年份,m台时光机, ...

  10. bzoj1018

    线段树分治+并查集 线段树本身就是分治结构,碰见这种带删除修改的题目是再合适不过的,我们对于每段修改区间在线段树上打标记,每次路过就进行修改,叶子结点表及答案,先把所有修改在线段树上标记,然后dfs就 ...