本文将带领大家精读3个Nginx Lua编程实战案例,学不会就来砍我(1)

最后

毕竟工作也这么久了 ,除了途虎一轮,也七七八八面试了不少大厂,像阿里、饿了么、美团、滴滴这些面试过程就不一一写在这篇文章上了。我会整理一份详细的面试过程及大家想知道的一些问题细节

美团面试经验

美团面试
字节面试经验
字节面试
菜鸟面试经验
菜鸟面试
蚂蚁金服面试经验
蚂蚁金服
唯品会面试经验
唯品会

因篇幅有限,图文无法详细发出

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

(2)一个基于Nginx+Redis+Java容器架构的高并发访问实战案例。

(3)一个基于Nginx+Redis架构的黑名单拦截实战案例。

Nginx+Redis进行分布式访问统计

=====================

接口(或者页面)的访问统计是网站运营和优化的一个重要参考数据,对于分布式接口可以通过Nginx+Redis架构来简单实现分布式受访统计。

得益于Nginx的高并发性能和Redis的高速缓存,基于Nginx+Redis的受访统计的架构设计比纯Java实现受访统计的架构设计在性能上高出很多。

作为参考案例,这里使用前面定义的RedisOperator基础操作类编写了一个简单的受访统计类,具体的代码如下:

—启动调试,正式环境请注释

local mobdebug = require(“luaScript.initial.mobdebug”);

mobdebug.start();

–导入自定义的RedisOperator模块

local redisOp = require(“luaScript.redis.RedisOperator”);

–创建自定义的redis操作对象

local red = redisOp:new();

–打开连接

red:open();

–获取访问次数

local visitCount = red:incrValue(“demo:visitCount”);

if visitCount == 1 then

–10秒内过期

red:expire(“demo:visitCount”, 10);

end

–将访问次数设置到Nginx变量

ngx.var.count = visitCount;

–归还连接到连接池

red:close();

在nginx-redis-demo.conf配置文件中编写一个location配置块来使用该脚本,建议将该脚本执行于access阶段而不是content阶段,具体代码如下:

#点击次数统计的演示

location /visitcount {

#定义一个Nginx变量,用于在Lua脚本中保存访问次数

set $count 0;

access_by_lua_file luaScript/redis/RedisVisitCount.lua;

echo "10s内总的访问次数为: " $count;

}

修改nginx-redis-demo.conf文件后重启Openrestry,然后使用浏览器访问其地址/visitcount,并且在浏览器中不断刷新,发现每刷新一次,页面的统计次数会加一,其结果如图8-23所示。

本文将带领大家精读3个Nginx Lua编程实战案例,学不会就来砍我

图8-23 访问统计效果图

Nginx+Redis+Java容器实现高并发访问

==========================

在不需要高速访问的场景下,运行在Java后端的容器(如Tomcat)会直接从DB数据库(如MySQL)查询数据,然后返回给客户端。

由于数据库的连接数限制、网络传输延迟、数据库的IO频繁等多方面的原因,Java后端容器直接查询DB的性能会很低,这时会进行架构的调整,采用“Java容器+Redis+DB”的查询架构。针对数据一致性要求不是特别高但是访问频繁的API接口(实际上大部分都是),可以将DB数据放入Redis缓存,Java API可以优先查询Redis,如果缓存未命中,就回源到DB查询,从DB查询成功后再将数据更新到Redis缓存。

“Java容器+Redis+DB”的查询架构既起到Redis分流大量查询请求的作用,又大大提升了API接口的处理性能,可谓一举两得。该架构的请求处理流程如图8-24所示。

本文将带领大家精读3个Nginx Lua编程实战案例,学不会就来砍我

图8-24 “Java容器+Redis+DB”查询架构的请求处理流程

大家知道,常用的后端Java容器(如Tomcat、Jetty等)的性能其实不是太高,QPS性能指标一般会在1000以内。从笔者经历过的很多次性能攻关的数据来看,Nginx的性能是Java容器的10倍左右(甚至以上),并且稳定性更强,还不存在FullGC卡顿。

为了应对高并发,可以将“Java容器+Redis+DB”架构优化为“Nginx+Redis+Java容器”查询架构。新架构将后端Java容器的缓存判断、缓存查询前移到反向代理Nginx,通过Nginx直接进行Redis缓存判断、缓存查询。

“Nginx+Redis+Java容器”的查询架构不仅为Java容器减少了很多请求,而且能够充分发挥Nginx的高并发优势和稳定性优势。该架构的请求处理流程如图8-25所示。

本文将带领大家精读3个Nginx Lua编程实战案例,学不会就来砍我

图8-25 “Nginx+Redis+Java容器”查询架构的请求处理流程

这里以秒杀系统的商品数据查询为例提供一个“Nginx+Redis+Java容器”查询架构的参考实现。首先定义两个接口:一个模拟Java容器的商品查询接口;另一个模拟供外部调用的商品查询接口:

·模拟Java容器的商品查询接口:/java/good/detail。·模拟供外部调用的商品查询接口:/good/detail。

然后提供一个Lua操作缓存的类RedisCacheDemo,主要定义如下3个方法:

(1)getCache(self,goodId):根据商品id取得Redis商品缓存。

(2)goUpstream(self):通过capture内部请求访问上游接口获取商品数据。

(3)setCache(self,goodId,goodString):设置商品缓存,此方法用于模拟后台Java代码。

缓存操作类RedisCacheDemo的核心代码如下:

—启动调试,正式环境请注释

local mobdebug = require(“luaScript.initial.mobdebug”);

mobdebug.start();

–导入自定义的基础模块

local basic = require(“luaScript.module.common.basic”);

–导入自定义的RedisOperator模块

local redisOp = require(“luaScript.redis.RedisOperator”);

local PREFIX = “GOOD_CACHE:”

–RedisCacheDemo类

local _RedisCacheDemo = { }

_RedisCacheDemo.__index = _RedisCacheDemo

–类的方法new

function _RedisCacheDemo.new(self)

local object = {}

setmetatable(object, self)

return object;

end

–根据商品id取得缓存

function _RedisCacheDemo.getCache(self,goodId)

–创建自定义的redis操作对象

local red = redisOp:new();

–打开连接

if not red:open() then

basic:error(“redis连接失败”);

return nil;

end

–获取缓存数据 local json = red:getValue(PREFIX … goodId);

red:close();

if not json or json==ngx.null then

basic:log(goodId … “的缓存没有命中”);

return nil;

end

basic:log(goodId … “缓存成功命中”);

return json;

end

–通过capture方法回源上游接口

function _RedisCacheDemo.goUpstream(self)

local request_method = ngx.var.request_method

local args = nil

–获取参数的值

if “GET” == request_method then

args = ngx.req.get_uri_args()

elseif “POST” == request_method then

ngx.req.read_body()

args = ngx.req.get_post_args()

end

–回源上游接口,比如Java后端rest接口

local res = ngx.location.capture(“/java/good/detail”,{

method = ngx.HTTP_GET,

args = args --重要:将请求参数原样向上游传递

})

basic:log(“上游数据获取成功”);

–返回上游接口的响应体body

return res.body;

end

–设置缓存,此方法主要用于模拟Java后台代码

function _RedisCacheDemo.setCache(self, goodId ,goodString)

–创建自定义的redis操作对象

local red = redisOp:new();

–打开连接

if not red:open() then

basic:error(“redis连接失败”);

return nil;

end

–set缓存数据

red:setValue(PREFIX … goodId,goodString);

–60秒内过期

red:expire(PREFIX … goodId, 60);

basic:log(goodId … “缓存设置成功”);

–归还连接到连接池

red:close();

return json;

end

return _RedisCacheDemo;

在nginx-redis-demo.conf配置文件中编写一个location配置块来使用该脚本,该配置块是提供给外部调用的商品查询接口/good/detail,具体代码如下:

首先从缓存中查询商品

未命中再回源到

后台 #首先从缓存中查询商品,未命中再回源到Java后台

location = /good/detail {

content_by_lua_block {

local goodId=ngx.var.arg_goodid;

–判断goodId参数是否存在

if not goodId then

ngx.say(“请输入goodId”);

return;

end

–首先从缓存中根据id查询商品

local RedisCacheDemo = require “luaScript.redis.RedisCacheDemo”;

local redisCacheDemo = RedisCacheDemo:new();

local json = redisCacheDemo:getCache(goodId);

–判断缓存是否被命中

if not json then

ngx.say(“缓存是否被命中,回源到上游接口
”);

–若没有命中缓存,则回源到上游接口

json = redisCacheDemo:goUpstream();

else

ngx.say(“缓存已经被命中
”);

end

ngx.say(“商品信息:”,json);

}

}

出于调试方便,在nginx-redis-demo.conf配置文件中再编写一个location配置块来模拟Java容器的后台商品查询接口/java/good/detail。

理论上,后台接口的业务逻辑是从数据库查询商品信息并缓存到Redis,然后返回商品信息。这里为了方便演示对其进行简化,具体的代码如下:

#模拟Java后台接口查询商品,然后设置缓存

location = /java/good/detail {

#指定规则为internal内部规则,防止外部请求命中此规则

internal;

content_by_lua_block {

local RedisCacheDemo = require “luaScript.redis.RedisCacheDemo”;

–Java后台将从数据库查找商品,这里简化成模拟数据

local json=‘{goodId:商品id,goodName:商品名称}’;

–将商品缓存到Redis

local redisCacheDemo = RedisCacheDemo:new();

redisCacheDemo:setCache(ngx.var.arg_goodid, json);

–返回商品到下游网关

ngx.say(json);

}

}

}

Kafka实战笔记

关于这份笔记,为了不影响大家的阅读体验,我只能在文章中展示部分的章节内容和核心截图

image.png

  • Kafka入门
  • 为什么选择Kafka
  • Karka的安装、管理和配置

image.png

  • Kafka的集群
  • 第一个Kafka程序
  • image.png

afka的生产者

image.png

  • Kafka的消费者
  • 深入理解Kafka
  • 可靠的数据传递

image.png

image.png

  • Spring和Kalka的整合
  • Sprinboot和Kafka的整合
  • Kafka实战之削峰填谷
  • 数据管道和流式处理(了解即可)

image.png

  • Kafka实战之削峰填谷

image.png

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

img-b2plPJWX-1715688092046)]

[外链图片转存中…(img-W8mzCQSR-1715688092046)]

  • Spring和Kalka的整合
  • Sprinboot和Kafka的整合
  • Kafka实战之削峰填谷
  • 数据管道和流式处理(了解即可)

[外链图片转存中…(img-83IYSI5G-1715688092046)]

  • Kafka实战之削峰填谷

[外链图片转存中…(img-D8kF1uT0-1715688092047)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 19
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值