API网关【gateway 】- 3
最近在公司进行API网关重写,公司内采用serverMesh进行服务注册,调用,这里结合之前学习对API网关服务进行简单的总结与分析。 由于采用了大量的nginx相关的东西,所以在此记录一下:
在nginx使用openresty
加入nginx模块
编辑nginx下conf配置文件nginx.conf
# vi nginx.conf
在server模块加上
location /helloworld {
default_type text/html;
content_by_lua 'ngx.say("hello world")';
}
检查配置文件是否正确
# /usr/local/openresty/nginx/sbin/nginx -t -c /usr/local/openresty/nginx/conf/nginx.conf
重启nginx
# ./nginx -s reload
访问http://ip/helloworld ,输出helloworld
nginx的内部变量
名称 说明
$arg_name 请求中的name参数
$args 请求中的参数
$binary_remote_addr 远程地址的二进制表示
$body_bytes_sent 已发送的消息体字节数
$content_length HTTP请求信息里的"Content-Length"
$content_type 请求信息里的"Content-Type"
$document_root 针对当前请求的根路径设置值
$document_uri 与$uri相同; 比如 /test2/test.php
$host 请求信息中的"Host",如果请求中没有Host行,则等于设置的服务器名
$hostname 机器名使用 gethostname系统调用的值
$http_cookie cookie 信息
$http_referer 引用地址
$http_user_agent 客户端代理信息
$http_via 最后一个访问服务器的Ip地址。
$http_x_forwarded_for 相当于网络访问路径
$is_args 如果请求行带有参数,返回“?”,否则返回空字符串
$limit_rate 对连接速率的限制
$nginx_version 当前运行的nginx版本号
$pid worker进程的PID
$query_string 与$args相同
$realpath_root 按root指令或alias指令算出的当前请求的绝对路径。其中的符号链接都会解析成真是文件路径
$remote_addr 客户端IP地址
$remote_port 客户端端口号
$remote_user 客户端用户名,认证用
$request 用户请求
$request_body 这个变量(0.7.+)包含请求的主要信息。在使用proxy_pass或fastcgi_pass指令的location中比较有意义
$request_body_file 客户端请求主体信息的临时文件名
$request_completion 如果请求成功,设为"OK";如果请求未完成或者不是一系列请求中最后一部分则设为空
$request_filename 当前请求的文件路径名,比如/opt/nginx/www/test.php
$request_method 请求的方法,比如"GET"、"POST"等
$request_uri 请求的URI,带参数; 比如http://localhost:88/test1/
$scheme 所用的协议,比如http或者是https
$server_addr 服务器地址,如果没有用listen指明服务器地址,使用这个变量将发起一次系统调用以取得地址(造成资源浪费)
$server_name 请求到达的服务器名
$server_port 请求到达的服务器端口号
$server_protocol 请求的协议版本,"HTTP/1.0"或"HTTP/1.1"
$uri 请求的URI,可能和最初的值有不同,比如经过重定向之类的
测试获取变量
location /test_url {
echo "url:$uri";
}
location /test_url {
echo "url:$uri";
echo "full url : $host$request_uri";
}
openresty 使用redis
连接redis服务器
---定义 redis关闭连接的方法
local function close_redis(red)
if not red then
return
end
local ok, err = red:close()
if not ok then
ngx.say("close redis error : ", err)
end
end
建立连接
local ip = "192.168.31.247"
local port =
local ok, err = red:connect(ip, port)
if not ok then
ngx.say("connect to redis error : ", err)
return close_redis(red)
end
调用API设置key
ok, err = red:set("msg", "hello world")
if not ok then
ngx.say("set msg error : ", err)
return close_redis(red)
end
调用API获取key值
local resp, err = red:get("msg")
if not resp then
ngx.say("get msg error : ", err)
return close_redis(red)
end
redis连接池
local function close_redis(red)
if not red then
return
end
--释放连接(连接池实现)
local pool_max_idle_time = --毫秒
local pool_size = --连接池大小
local ok, err = red:set_keepalive(pool_max_idle_time, pool_size)
if not ok then
ngx.say("set keepalive error : ", err)
end
end
访问频率控制:
我们用redis的key表示用户,value表示用户的请求频次,再利用过期时间实现单位时间
要求10秒内只能访问10次frequency请求,超过返回403
首先为nginx.conf配置文件,nginx.conf部分内容如下:
location /frequency {
access_by_lua_file /usr/local/lua/access_by_limit_frequency.lua;
echo "访问成功";
}
编辑access_by_limit_frequency.lua
local function close_redis(red)
if not red then
return
end
--释放连接(连接池实现)
local pool_max_idle_time = --毫秒
local pool_size = --连接池大小
local ok, err = red:set_keepalive(pool_max_idle_time, pool_size)
if not ok then
ngx.say("set keepalive error : ", err)
end
end local function errlog(...)
ngx.log(ngx.ERR, "redis: ", ...)
end local redis = require "resty.redis" --引入redis模块
local red = redis:new() --创建一个对象,注意是用冒号调用的 --设置超时(毫秒)
red:set_timeout()
--建立连接
local ip = "192.168.31.247"
local port =
local ok, err = red:connect(ip, port)
if not ok then
close_redis(red)
errlog("Cannot connect");
return ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
end local key = "limit:frequency:login:"..ngx.var.remote_addr --得到此客户端IP的频次
local resp, err = red:get(key)
if not resp then
close_redis(red)
return ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) --redis 获取值失败
end if resp == ngx.null then
red:set(key, ) -- 单位时间 第一次访问
red:expire(key, ) --10秒时间 过期
end if type(resp) == "string" then
if tonumber(resp) > then -- 超过10次
close_redis(red)
return ngx.exit(ngx.HTTP_FORBIDDEN) --直接返回403
end
end --调用API设置key
ok, err = red:incr(key)
if not ok then
close_redis(red)
return ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) --redis 报错
end close_redis(red)
请求地址:/frequency
10秒内 超出10次 ,返回403
10秒后,又可以访问了
如果我们想整个网站 都加上这个限制条件,那只要把
access_by_lua_file /usr/local/lua/access_by_limit_frequency.lua;
这个配置,放在server部分,让所有的location 适用就行了
API网关【gateway 】- 3的更多相关文章
- SpringCloud系列之API网关(Gateway)服务Zuul
1.什么是API网关 API网关是所有请求的入口,承载了所有的流量,API Gateway是一个门户一样,也可以说是进入系统的唯一节点.这跟面向对象设计模式中的Facet模式很像.API Gatewa ...
- SpringCloud微服务项目实战 - API网关Gateway详解实现
前面讲过zuul的网关实现,那为什么今天又要讲Spring Cloud Gateway呢?原因很简单.就是Spring Cloud已经放弃Netflix Zuul了.现在Spring Cloud中引用 ...
- 谈谈微服务中的 API 网关(API Gateway)
前言 又是很久没写博客了,最近一段时间换了新工作,比较忙,所以没有抽出来太多的时间写给关注我的粉丝写一些干货了,就有人问我怎么最近没有更新博客了,在这里给大家抱歉. 那么,在本篇文章中,我们就一起来探 ...
- 从0开始构建你的api网关--Spring Cloud Gateway网关实战及原理解析
API 网关 API 网关出现的原因是微服务架构的出现,不同的微服务一般会有不同的网络地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求,如果让客户端直接与各个微服务通信,会有以下的问题 ...
- 微服务中的 API 网关(API Gateway)
API 网关(API Gateway)提供高性能.高可用的 API 托管服务,帮助用户对外开放其部署在 ECS.容器服务等云产品上的应用,提供完整的 API 发布.管理.维护生命周期管理.用户只需进行 ...
- API网关性能比较:NGINX vs. ZUUL vs. Spring Cloud Gateway vs. Linkerd API 网关出现的原因
API网关性能比较:NGINX vs. ZUUL vs. Spring Cloud Gateway vs. Linkerd http://www.infoq.com/cn/articles/compa ...
- 服务中的 API 网关(API Gateway)
我们知道在微服务架构风格中,一个大应用被拆分成为了多个小的服务系统提供出来,这些小的系统他们可以自成体系,也就是说这些小系统可以拥有自己的数据库,框架甚至语言等,这些小系统通常以提供 Rest Api ...
- Spring Cloud 微服务三: API网关Spring cloud gateway
前言:前面介绍了一款API网关组件zuul,不过发现spring cloud自己开发了一个新网关gateway,貌似要取代zuul,spring官网上也已经没有zuul的组件了(虽然在仓库中可以更新到 ...
- .net core 微服务之Api网关(Api Gateway)
原文:.net core 微服务之Api网关(Api Gateway) 微服务网关目录 1. 微服务引子 2.使用Nginx作为api网关 3.自创api网关(重复轮子) 3.1.构建初始化 3.2. ...
- API网关spring cloud gateway和负载均衡框架ribbon实战
通常我们如果有一个服务,会部署到多台服务器上,这些微服务如果都暴露给客户,是非常难以管理的,我们系统需要有一个唯一的出口,API网关是一个服务,是系统的唯一出口.API网关封装了系统内部的微服务,为客 ...
随机推荐
- SSM_CRUD新手练习(9)显示分页数据
我们已经做好了用来显示数据的分页模板,现在只需要将我们从后台取出的数据填充好,显示出来. 我们使用<c:forEach>标签循环取出数据,所以需要先导入JSTL标签库 <%@ tag ...
- HTML之<meta>使用和说明
关于<meta>,我们都不陌生,随意打开一个网页查看源代码就可以看到<head>里出现它的身影. 简单来说,<meta>是描述 HTML 文档的元数据.例如网页描述 ...
- a标签使用href=”javascript:void(0); 在火狐浏览器跟chrome 不兼容
使用如下方式的链接.在Chrome中点击后行为符合预期,但在IE下会新开标签卡(根据参考资料,Firefox中有相同问题).<a href=”javascript:void(0);” targe ...
- java web中的异常处理
1.集中处理 参考:https://blog.csdn.net/weililansehudiefei/article/details/73691294
- git diff 理解
0. 理解 git diff 返回信息 1. 命令 $ git diff README.md 2. 返回信息,注解 diff --git a/README.md b/README.md ## 1. 表 ...
- Bootstrap轮播如何支持移动端左右滑动
一直觉得bootstrap的轮播用起来很好用,代码简单,又支持响应式,不过从来没想过,也不知道原来bootstrap的轮播竟然不支持在手机上左右滑动 解决方法就是:使用滑动手势js插件:hammer. ...
- vue 自学项目笔记
感觉小青推荐的学习网课, 利用vue 仿制一个去哪网, 学习的东西很多, 在食用之前,需要先确保js 和css 过关 js https://www.bilibili.com/video/av3009 ...
- 抽象语法树(AST)
AST描述 在计算机科学中,抽象语法树(AST)或语法树是用编程语言编写的源代码的抽象语法结构的树表示.树的每个节点表示在源代码中出现的构造.语法是“抽象的”,因为它不代表真实语法中出现的每个细节,而 ...
- Xamarin.Android 无法检索到 Resource 问题
错误提示:当前上下文中不存在名称"Resource" 解决方法: 1.看是否有其他错误,如果有其他错误优先解决.(其他错误导致无法感知到Resource) 2.重新生成解决方案.( ...
- 21天打造分布式爬虫-urllib库(一)
1.1.urlopen函数的用法 #encoding:utf-8 from urllib import request res = request.urlopen("https://www. ...