分布式实战 | 第一篇 :ELK在开源全栈项目【有来商城】的应用,不仅仅是分布式日志收集(一)

本文涉及的产品
Elasticsearch Serverless通用抵扣包,测试体验金 200元
日志服务 SLS,月写入数据量 50GB 1个月
简介: 分布式实战 | 第一篇 :ELK在开源全栈项目【有来商城】的应用,不仅仅是分布式日志收集(一)

一. 前言

其实早前就想计划出这篇文章,但是最近主要精力在完善微服务、系统权限设计、微信小程序和管理前端的功能,不过好在有群里小伙伴的一起帮忙反馈问题,基础版的功能已经差不多,也在此谢过,希望今后大家还是能够相互学习,一起进步~


OK,回正题,ELK是Elasticsearch、Logstash、Kibana三个开源软件的组合,相信很多童鞋使用ELK有去做过分布式日志收集。流程概括为:微服务应用把Logback输出的日志通过HTTP传输至LogStash,然后经过分析过滤,转发至ES,再由Kibana提供检索和统计可视化界面。


在本实战案例中,使用Spring AOP、Logback横切认证接口来记录用户登录日志,收集到ELK,通过SpringBoot整合RestHighLevelClient实现对ElasticSearch数据检索和统计。从日志搜集到数据统计,一次性的走个完整,快速入门ElasticSearch。


本篇涉及的前后端全部源码已上传gitee和github,熟悉有来项目的童鞋快速过一下步骤即可。


项目名称 Github 码云

后台 youlai-mall youlai-mall

前端 youlai-mall-admin youlai-mall-admin

二. 需求

基于ELK的日志搜集的功能,本篇实现的需求如下:


记录系统用户登录日志,信息包括用户IP、登录耗时、认证令牌JWT

统计十天内用户登录次数、今日访问IP和总访问IP

充分利用记录的JWT信息,通过黑名单的方式让JWT失效实现强制下线

实现效果:


访问地址:http://www.youlai.store


Kibana日志可视化统计

微信图片_20230709232551.png


登录次数统计、今日访问IP统计、总访问IP统计

微信图片_20230709232554.png


登录信息,强制用户下线,演示的是自己强制自己下线的效果

微信图片_20230709232616.gif


三. Docker快速搭建ELK环境

1. 拉取镜像

docker pull elasticsearch:7.10.1

docker pull kibana:7.10.1

docker pull logstash:7.10.1


2. elasticsearch部署

1. 环境准备


# 创建文件

mkdir -p /opt/elasticsearch/{plugins,data}  /etc/elasticsearch

touch /etc/elasticsearch/elasticsearch.yml

chmod -R 777 /opt/elasticsearch/data/  

vim /etc/elasticsearch/elasticsearch.yml

# 写入

cluster.name: elasticsearch

http.cors.enabled: true                              

http.cors.allow-origin: "*"                    

http.host: 0.0.0.0

node.max_local_storage_nodes: 100


2. 启动容器


docker run -d --name=elasticsearch --restart=always \

-e discovery.type=single-node \

-e ES_JAVA_OPTS="-Xms256m -Xmx256m" \

-p 9200:9200 \

-p 9300:9300 \

-v /etc/elasticsearch/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \

-v /opt/elasticsearch/data:/usr/share/elasticsearch/data \

-v /opt/elasticsearch/plugins:/usr/share/elasticsearch/plugins \

elasticsearch:7.10.1


3. 验证和查看ElasticSearch版本


curl -XGET localhost:9200

1


微信图片_20230709232628.png

2. kibana部署

1. 环境准备


# 创建文件

mkdir -p /etc/kibana

vim /etc/kibana/kibana.yml


# 写入

server.name: kibana

server.host: "0"

elasticsearch.hosts: [ "http://elasticsearch:9200" ]

i18n.locale: "zh-CN"


2. 启动容器


docker run -d --restart always -p 5601:5601 --link elasticsearch \

-e ELASTICSEARCH_URL=http://elasticsearch:9200 \

-v /etc/kibana/kibana.yml:/usr/share/kibana/config/kibana.yml \

kibana:7.10.1

3. logstash部署

1. 环境准备


配置 logstash.yml

# 创建文件

mkdir -p /etc/logstash/config

vim /etc/logstash/config/logstash.yml


# 写入

http.host: "0.0.0.0"

xpack.monitoring.elasticsearch.hosts: [ "http://elasticsearch:9200" ]

xpack.management.pipeline.id: ["main"]


配置pipeline.yml

# 创建文件

vim  /etc/logstash/config/pipeline.yml


# 写入(注意空格)

- pipeline.id: main

 path.config: "/usr/share/logstash/pipeline/logstash.config"


配置logstash.conf

# 创建文件

mkdir -p /etc/logstash/pipeline

vim /etc/logstash/pipeline/logstash.conf


# 写入

input {

   tcp {

     port => 5044

     mode => "server"

     host => "0.0.0.0"

     codec => json_lines

   }

}

filter{


}

output {

   elasticsearch {

       hosts => ["elasticsearch:9200"]

       # 索引名称,没有会自动创建

       index => "%{[project]}-%{[action]}-%{+YYYY-MM-dd}"

   }

}


2. 启动容器


docker run -d --restart always -p 5044:5044 -p 9600:9600 --name logstash --link elasticsearch \

-v /etc/logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml \

-v /etc/logstash/config/pipeline.yml:/usr/share/logstash/config/pipeline.yml \

-v /etc/logstash/pipeline/logstash.conf:/usr/share/logstash/pipeline/logstash.conf \

logstash:7.10.1


4. 测试

访问: http://localhost:5601/


微信图片_20230709232644.png


四. Spring AOP + Logback 横切打印登录日志

1. Spring AOP横切认证接口添加日志

代码坐标: common-web#LoginLogAspect


@Aspect

@Component

@AllArgsConstructor

@Slf4j

@ConditionalOnProperty(value = "spring.application.name", havingValue = "youlai-auth")

public class LoginLogAspect {


   @Pointcut("execution(public * com.youlai.auth.controller.AuthController.postAccessToken(..))")

   public void Log() {

   }


   @Around("Log()")

   public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {


       LocalDateTime startTime = LocalDateTime.now();

       Object result = joinPoint.proceed();


       // 获取请求信息

       ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

       HttpServletRequest request = attributes.getRequest();


       // 刷新token不记录

       String grantType=request.getParameter(AuthConstants.GRANT_TYPE_KEY);

       if(grantType.equals(AuthConstants.REFRESH_TOKEN)){

           return result;

       }


       // 时间统计

       LocalDateTime endTime = LocalDateTime.now();

       long elapsedTime = Duration.between(startTime, endTime).toMillis(); // 请求耗时(毫秒)


       // 获取接口描述信息

       MethodSignature signature = (MethodSignature) joinPoint.getSignature();

       String description = signature.getMethod().getAnnotation(ApiOperation.class).value();// 方法描述


       String username = request.getParameter(AuthConstants.USER_NAME_KEY); // 登录用户名

       String date = startTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); // 索引名需要,因为默认生成索引的date时区不一致


       // 获取token

       String token = Strings.EMPTY;

       if (request != null) {

           JSONObject jsonObject = JSONUtil.parseObj(result);

           token = jsonObject.getStr("value");

       }


       String clientIP = IPUtils.getIpAddr(request);  // 客户端请求IP(注意:如果使用Nginx代理需配置)

       String region = IPUtils.getCityInfo(clientIP); // IP对应的城市信息


       // MDC 扩展logback字段,具体请看logback-spring.xml的自定义日志输出格式

       MDC.put("elapsedTime", StrUtil.toString(elapsedTime));

       MDC.put("description", description);

       MDC.put("region", region);

       MDC.put("username", username);

       MDC.put("date", date);

       MDC.put("token", token);

       MDC.put("clientIP", clientIP);


       log.info("{} 登录,耗费时间 {} 毫秒", username, elapsedTime); // 收集日志这里必须打印一条日志,内容随便吧,记录在message字段,具体看logback-spring.xml文件

       return result;

   }

}


2. Logback日志上传至LogStash

代码坐标:common-web#logback-spring.xml


   localhost:5044

   

       

           

               Asia/Shanghai

           

           

           

               

                   {

                   "project": "${APP_NAME}",

                   "date": "%X{date}",

                   "action":"login",

                   "pid": "${PID:-}",

                   "thread": "%thread",

                   "message": "%message",

                   "elapsedTime": "%X{elapsedTime}",

                   "username":"%X{username}",

                   "clientIP": "%X{clientIP}",

                   "region":"%X{region}",

                   "token":"%X{token}",

                   "loginTime": "%date{\"yyyy-MM-dd HH:mm:ss\"}",

                   "description":"%X{description}"

                   }

               

           

       

   

   5 minutes



   



localhost:5044 Logstash配置的input收集数据的监听

%X{username} 输出MDC添加的username的值


相关实践学习
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
相关文章
|
2月前
|
运维 安全 数据可视化
日志审查安排工具实战攻略:中小团队如何通过日志审查安排工具建立可控、安全的审查机制?
在审计敏感时代,日志审查安排工具成为安全运维与合规管理的关键利器。它实现审查任务的流程化、周期化与可视化,支持多系统协作、责任到人,确保“可控、可查、可追”的日志治理。工具如板栗看板、Asana、Monday 等提供任务调度、问题闭环与合规对接能力,助力企业构建高效、透明的日志审查体系,提升安全与合规水平。
|
4月前
|
安全 JavaScript 前端开发
HarmonyOS NEXT~HarmonyOS 语言仓颉:下一代分布式开发语言的技术解析与应用实践
HarmonyOS语言仓颉是华为专为HarmonyOS生态系统设计的新型编程语言,旨在解决分布式环境下的开发挑战。它以“编码创造”为理念,具备分布式原生、高性能与高效率、安全可靠三大核心特性。仓颉语言通过内置分布式能力简化跨设备开发,提供统一的编程模型和开发体验。文章从语言基础、关键特性、开发实践及未来展望四个方面剖析其技术优势,助力开发者掌握这一新兴工具,构建全场景分布式应用。
479 35
|
3月前
|
分布式计算 Java 大数据
Java 大视界 —— 基于 Java 的大数据分布式计算在气象数据处理与天气预报中的应用进展(176)
本文围绕基于 Java 的大数据分布式计算在气象数据处理与天气预报中的应用展开,剖析行业现状与挑战,阐释技术原理,介绍其在数据处理及天气预报中的具体应用,并结合实际案例展示实施效果。
|
3月前
|
监控 安全 Linux
AWK在网络安全中的高效应用:从日志分析到威胁狩猎
本文深入探讨AWK在网络安全中的高效应用,涵盖日志分析、威胁狩猎及应急响应等场景。通过实战技巧,助力安全工程师将日志分析效率提升3倍以上,构建轻量级监控方案。文章详解AWK核心语法与网络安全专用技巧,如时间范围分析、多条件过滤和数据脱敏,并提供性能优化与工具集成方案。掌握AWK,让安全工作事半功倍!
91 0
Java 大视界 -- 基于 Java 的大数据分布式存储在视频监控数据管理中的应用优化(170)
本文围绕基于 Java 的大数据分布式存储在视频监控数据管理中的应用展开,分析管理现状与挑战,阐述技术应用,结合案例和代码给出实操方案。
|
3月前
|
人工智能 运维 监控
Aipy实战:分析apache2日志中的网站攻击痕迹
Apache2日志系统灵活且信息全面,但安全分析、实时分析和合规性审计存在较高技术门槛。为降低难度,可借助AI工具如aipy高效分析日志,快速发现攻击痕迹并提供反制措施。通过结合AI与学习技术知识,新手运维人员能更轻松掌握复杂日志分析任务,提升工作效率与技能水平。
|
6月前
|
存储 监控 算法
基于 PHP 语言的滑动窗口频率统计算法在公司局域网监控电脑日志分析中的应用研究
在当代企业网络架构中,公司局域网监控电脑系统需实时处理海量终端设备产生的连接日志。每台设备平均每分钟生成 3 至 5 条网络请求记录,这对监控系统的数据处理能力提出了极高要求。传统关系型数据库在应对这种高频写入场景时,性能往往难以令人满意。故而,引入特定的内存数据结构与优化算法成为必然选择。
143 3
|
6月前
|
SQL 数据库
【YashanDB知识库】应用绑定参数的慢查询,慢日志抓取不到
【YashanDB知识库】应用绑定参数的慢查询,慢日志抓取不到
|
1月前
|
存储 负载均衡 NoSQL
【赵渝强老师】Redis Cluster分布式集群
Redis Cluster是Redis的分布式存储解决方案,通过哈希槽(slot)实现数据分片,支持水平扩展,具备高可用性和负载均衡能力,适用于大规模数据场景。
187 2
|
1月前
|
存储 缓存 NoSQL
【📕分布式锁通关指南 12】源码剖析redisson如何利用Redis数据结构实现Semaphore和CountDownLatch
本文解析 Redisson 如何通过 Redis 实现分布式信号量(RSemaphore)与倒数闩(RCountDownLatch),利用 Lua 脚本与原子操作保障分布式环境下的同步控制,帮助开发者更好地理解其原理与应用。
91 0

热门文章

最新文章