百万QPS下热点数据的收集方案

高并发场景下,如京东、淘宝的秒杀活动开始时候,会有很多的用户同时抢购秒杀商品,由于同一个场次成百上千种商品参与秒杀活动,但是热点的商品往往就只有那么几十个左右,此时系统的90%的流量都是来自于这几十个热点商品,极端情况下因为这几十个热度商品导致服务器宕机,因此针对热点商品需要做一些应对的措施。常见的应对措施有缓存热点商品数据、热点数据和非热点数据做隔离等等。

如何在高并发下识别热点商品数据呢?下面我们将通过OpenResty+Lua+Kafka+ES方案实现热点数据收集的方案。

1、方案的实现流程

(1)当用户访问(如http://www.longxia.com/web/item/index.html)的时候,请求进入到OpenResty中。

(2)OpenResty中的Nginx上location拦截到请求,它会做去掉请求地址上的特定部分(如/web/item/index.html —-> /item/index.html),然后访问真实的服务获取数据。

(3)Lua组装用户访问的数据(如商品信息)发送消息到Kafka中,Kafka随后将数据推送到Logstash中,Logstash会把数据推送到ES中存储起来。

2、核心的实现过程

(1)配置lua-resty-kafka

地址:https://github.com/doujiang24/lua-resty-kafka

插件配置到Nginx模块上

(2)编写lua脚本

--依赖导入 
local cjson = require "cjson" 
local client = require "resty.kafka.client" 
local producer = require "resty.kafka.producer" 
--配置kafka的服务地址 
local broker_list = { 
  { host = "192.168.203.237",port = 9092} 
} 
--创建kafka的生产者 
local bp = producer:new(broker_list, { producer_type = "async" }) 
--先获取用户的请求头 然后获取IP的信息 
local headers=ngx.req.get_headers() 
local ip=headers["X-REAL_IP"] or headers["X_FORWARDED_FCR"] or ngx.var.remote_addr or "0.0.0.0" 
--创建消息 
local message={} 
message["uri"]=ngx.var.uri 
message["ip"]=ip 
message["token"]="987654" 
message["actime"]=os.date("%y-%M-%d %H:%m:%S") 
--发送消息 
local ok, err = bp:send("collection_hot_item",nil, cjson.encode(message)) 
--把请求中的/web去掉 
local uri = ngx.var.uri 
uri = string.gsub(uri,"/web","") 
--将去掉的路径再次执行转发查找静态页 
ngx.exec(uri)

(3)页面的请求被Nginx拦截的配置

#拦截/web/item的请求 然后交给lua文件处理 
  location /web/item/ { 
      content_by_lua_file /usr/local/openresty/nginx/lua/item-access.lua; 
  } 
   location /item/ { 
       root /usr/local/web; 
   }

(4)kafka消息推送到Logstash

input { 
  kafka { 
    bootstrap_servers => "192.168.203.237:9092" # Kafka 服务器地址和端口 
    topics => ["collection_hot_item"] # 需要消费的 Kafka 话题 
    group_id => "logstash_group" # Kafka 消费者组ID 
    consumer_threads => 3 # 消费者线程数 
    codec =>json 
  } 
} 

filter { 

} 

output { 
#数据推送到es 
  elasticsearch { 
    hosts => ["http://192.168.203.238:9200"] 
    index => "hot_item" 
  } 
}

总结:运营人员通过Kibana可以查询到热点商品数据,定位到热点的商品数据后可以有针对性地做一些应对措施。本文是通过ES存储热点数据,也可以使用Druid来实现,Druid有更好的数据处理分析能力。

3