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. JAVA NIO 之Channel

    缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存.Channel 通道就是将数据传输给 ByteBuffer 对象或者从 ByteBuffer 对象获取数据进行传输. Channel 用于在 ...

  2. P3383 【模板】线性筛素数 洛谷

    https://www.luogu.org/problem/show?pid=3383#sub 题目描述 如题,给定一个范围N,你需要处理M个某数字是否为质数的询问(每个数字均在范围1-N内) 输入输 ...

  3. 定义SAP Portal Url别名

    Defining URL Aliases Use A URL alias is the part of the portal URL after the section that specifies ...

  4. zabbix全方位监控MySQL +cacti监控mysql

    http://www.linuxidc.com/Linux/2015-02/112690.htm http://john88wang.blog.51cto.com/2165294/1596272?ut ...

  5. vijos- P1383盗窃-黑珍珠 (python + 代码优化)

    P1383盗窃-黑珍珠 Accepted 标签:怪盗基德 VS OIBH[显示标签] 背景 怪盗基德 VS OIBH 第二话 描写叙述 今次怪盗基德再次对阵OIBH,目标是Black Star!基德已 ...

  6. JAVA学习(三):Java基础语法(变量、常量、数据类型、运算符与数据类型转换)

    Java基础语法(变量.常量.数据类型.运算符与数据类型转换) 1.变量 Java中.用户能够通过指定数据类型和标识符来声明变量.其基本的语法为: DataType identifier; 或 Dat ...

  7. 一个样例看清楚JQuery子元素选择器children()和find()的差别

    近期在我们的hybrid app项目开发中定位出了一个问题.通过这个问题了解下JQuery选择器find()和children()的差别.问题是这种:我们的混合app是一个单页面应用(main.htm ...

  8. JavaSE入门学习10:Java修饰符

    Java语言提供了非常多修饰符,主要分为下面两类: 訪问修饰符 非訪问修饰符 修饰符用来定义类.方法或者变量.通常放在语句的最前端.我们通过以下的样例来说明: <span style=" ...

  9. LeetCode 234. Palindrome Linked List (回文链表)

    Given a singly linked list, determine if it is a palindrome. Follow up:Could you do it in O(n) time ...

  10. Android自定义用户控件简单范例(一)

    一款优秀的移动应用需要具有自己独特统一的风格,通常情况下UI设计师会根据产品需求和使用人群的特点,设计整体的风格,界面的元素和控件的互效果.而原生态的Android控件为开发人员提供的是最基本的积木元 ...