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

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
Elasticsearch Serverless通用抵扣包,测试体验金 200元
简介: 分布式实战 | 第一篇 :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的值


相关实践学习
通过日志服务实现云资源OSS的安全审计
本实验介绍如何通过日志服务实现云资源OSS的安全审计。
相关文章
|
5月前
|
安全 JavaScript 前端开发
HarmonyOS NEXT~HarmonyOS 语言仓颉:下一代分布式开发语言的技术解析与应用实践
HarmonyOS语言仓颉是华为专为HarmonyOS生态系统设计的新型编程语言,旨在解决分布式环境下的开发挑战。它以“编码创造”为理念,具备分布式原生、高性能与高效率、安全可靠三大核心特性。仓颉语言通过内置分布式能力简化跨设备开发,提供统一的编程模型和开发体验。文章从语言基础、关键特性、开发实践及未来展望四个方面剖析其技术优势,助力开发者掌握这一新兴工具,构建全场景分布式应用。
498 35
|
4月前
|
分布式计算 Java 大数据
Java 大视界 —— 基于 Java 的大数据分布式计算在气象数据处理与天气预报中的应用进展(176)
本文围绕基于 Java 的大数据分布式计算在气象数据处理与天气预报中的应用展开,剖析行业现状与挑战,阐释技术原理,介绍其在数据处理及天气预报中的具体应用,并结合实际案例展示实施效果。
Java 大视界 -- 基于 Java 的大数据分布式存储在视频监控数据管理中的应用优化(170)
本文围绕基于 Java 的大数据分布式存储在视频监控数据管理中的应用展开,分析管理现状与挑战,阐述技术应用,结合案例和代码给出实操方案。
|
8月前
|
人工智能 监控 开发者
阿里云PAI发布DeepRec Extension,打造稳定高效的分布式训练,并宣布开源!
阿里云PAI发布DeepRec Extension,打造稳定高效的分布式训练,并宣布开源!
147 0
|
8月前
|
机器学习/深度学习 存储
DeepSeek进阶开发与应用4:DeepSeek中的分布式训练技术
随着深度学习模型和数据集规模的扩大,单机训练已无法满足需求,分布式训练技术应运而生。DeepSeek框架支持数据并行和模型并行两种模式,通过将计算任务分配到多个节点上并行执行,显著提高训练效率。本文介绍DeepSeek中的分布式训练技术,包括配置与启动方法,帮助用户轻松实现大规模模型训练。数据并行通过`MirroredStrategy`同步梯度,适用于大多数模型;模型并行则通过`ParameterServerStrategy`异步处理大模型。DeepSeek简化了分布式环境配置,支持单机多卡和多机多卡等场景。
|
11月前
|
消息中间件 监控 数据可视化
Apache Airflow 开源最顶级的分布式工作流平台
Apache Airflow 是一个用于创作、调度和监控工作流的平台,通过将工作流定义为代码,实现更好的可维护性和协作性。Airflow 使用有向无环图(DAG)定义任务,支持动态生成、扩展和优雅的管道设计。其丰富的命令行工具和用户界面使得任务管理和监控更加便捷。适用于静态和缓慢变化的工作流,常用于数据处理。
Apache Airflow 开源最顶级的分布式工作流平台
|
10月前
|
存储 运维 数据可视化
如何为微服务实现分布式日志记录
如何为微服务实现分布式日志记录
580 1
|
11月前
|
缓存 NoSQL PHP
Redis作为PHP缓存解决方案的优势、实现方式及注意事项。Redis凭借其高性能、丰富的数据结构、数据持久化和分布式支持等特点,在提升应用响应速度和处理能力方面表现突出
本文深入探讨了Redis作为PHP缓存解决方案的优势、实现方式及注意事项。Redis凭借其高性能、丰富的数据结构、数据持久化和分布式支持等特点,在提升应用响应速度和处理能力方面表现突出。文章还介绍了Redis在页面缓存、数据缓存和会话缓存等应用场景中的使用,并强调了缓存数据一致性、过期时间设置、容量控制和安全问题的重要性。
199 5
|
12月前
|
人工智能 文字识别 Java
SpringCloud+Python 混合微服务,如何打造AI分布式业务应用的技术底层?
尼恩,一位拥有20年架构经验的老架构师,通过其深厚的架构功力,成功指导了一位9年经验的网易工程师转型为大模型架构师,薪资逆涨50%,年薪近80W。尼恩的指导不仅帮助这位工程师在一年内成为大模型架构师,还让他管理起了10人团队,产品成功应用于多家大中型企业。尼恩因此决定编写《LLM大模型学习圣经》系列,帮助更多人掌握大模型架构,实现职业跃迁。该系列包括《从0到1吃透Transformer技术底座》、《从0到1精通RAG架构》等,旨在系统化、体系化地讲解大模型技术,助力读者实现“offer直提”。此外,尼恩还分享了多个技术圣经,如《NIO圣经》、《Docker圣经》等,帮助读者深入理解核心技术。
SpringCloud+Python 混合微服务,如何打造AI分布式业务应用的技术底层?
|
26天前
|
消息中间件 Java Kafka
搭建ELK日志收集,保姆级教程
本文介绍了分布式日志采集的背景及ELK与Kafka的整合应用。传统多服务器环境下,日志查询效率低下,因此需要集中化日志管理。ELK(Elasticsearch、Logstash、Kibana)应运而生,但单独使用ELK在性能上存在瓶颈,故结合Kafka实现高效的日志采集与处理。文章还详细讲解了基于Docker Compose构建ELK+Kafka环境的方法、验证步骤,以及如何在Spring Boot项目中整合ELK+Kafka,并通过Logback配置实现日志的采集与展示。
216 12
搭建ELK日志收集,保姆级教程

热门文章

最新文章