在使用微服务架构中,我们已经克服许多微服务架构导致的遗留问题,它允许我们创建稳定的分布式应用程序,并对代码、团队规模、维护、发布周期、云服务等进行所需的控制。但它也带来了一些挑战其他领域,例如分布式日志管理和查看分布在许多服务之间的完整事务日志的能力以及一般的分布式调试。
实际上,难点在于微服务之间是相互隔离的,它们不共享公共数据库和日志文件。随着微服务数量的增加以及我们使用自动化持续集成工具启用云部署,当我们遇到任何问题时,非常有必要提供一些调试组件的功能。
感谢开源社区。我们已经有了一系列工具,如果一起使用,它们可以发挥神奇的作用。一组这样流行的工具是Elastic Search、Logstash和Kibana——统称为ELK Stack。它们用于实时搜索、分析和可视化日志数据。
1.什么是ELK Stack
- Elasticsearch是一个分布式、基于 JSON 的搜索和分析引擎,旨在实现水平可扩展性、最大可靠性和易于管理。
- Logstash是一个动态数据收集管道,具有可扩展的插件生态系统和强大的 Elasticsearch 协同作用。
- Kibana通过 UI提供数据的可视化。
1.1 ELK 堆栈架构
Logstash 根据我们设置的过滤条件处理应用程序日志文件并将这些日志发送到 Elasticsearch。通过 Kibana,我们在需要时查看和分析这些日志。
2.ELK栈配置
所有这三个工具都是基于 JVM 的,在开始安装它们之前,请验证 JDK 是否已正确配置。检查标准 JDK 1.8 安装,JAVA_HOME
并且PATH
设置已经完成。
2.1 Elasticsearch
- 从此下载页面下载最新版本的 Elasticsearch并将其解压缩到任何文件夹。
bin/elasticsearch.bat
从命令提示符运行。- 默认情况下,它将从http://localhost:9200开始
2.2. Kibana
- 从下载页面下载最新的发行版并解压缩到任何文件夹中。
config/kibana.yml
在编辑器中打开并设置elasticsearch.url
指向您的 Elasticsearch 实例。在我们的例子中,我们将使用本地实例,只需取消注释elasticsearch.url: "http://localhost:9200"
bin/kibana.bat
从命令提示符运行。- 成功启动后,Kibana 将在默认端口上启动,
5601
并且 Kibana UI 将在http://localhost:5601可用
2.3. Logstash
- 从下载页面下载最新的发行版并解压缩到任何文件夹中。
logstash.conf
根据配置说明创建一个文件。我们将在实际演示期间再次来到这一点以进行精确配置。现在运行bin/logstash -f logstash.conf
启动logstash
ELK 堆栈未启动并运行。现在我们需要创建一些微服务并将 logstash 指向 API 日志路径。
3. ELK栈示例——创建微服务
3.1 创建 Spring Boot 项目
让我们使用 Spring Boot 创建一个应用程序以加快开发时间。按照这些步骤启动此服务。
3.2 添加 REST 端点
添加一个RestController
将暴露几个端点的类,如/elk
, /elkdemo
, /exception
. 实际上,我们将只测试一些日志语句,因此请根据您的选择随意添加/修改日志。
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Date;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
public class ElkExampleSpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(ElkExampleSpringBootApplication.class, args);
}
}
@RestController
class ELKController {
private static final Logger LOG = Logger.getLogger(ELKController.class.getName());
@Autowired
RestTemplate restTemplete;
@Bean
RestTemplate restTemplate() {
return new RestTemplate();
}
@RequestMapping(value = "/elkdemo")
public String helloWorld() {
String response = "Hello user ! " + new Date();
LOG.log(Level.INFO, "/elkdemo - > " + response);
return response;
}
@RequestMapping(value = "/elk")
public String helloWorld1() {
String response = restTemplete.exchange("http://localhost:8080/elkdemo", HttpMethod.GET, null, new ParameterizedTypeReference() {
}).getBody();
LOG.log(Level.INFO, "/elk - > " + response);
try {
String exceptionrsp = restTemplete.exchange("http://localhost:8080/exception", HttpMethod.GET, null, new ParameterizedTypeReference() {
}).getBody();
LOG.log(Level.INFO, "/elk trying to print exception - > " + exceptionrsp);
response = response + " === " + exceptionrsp;
} catch (Exception e) {
// exception should not reach here. Really bad practice :)
}
return response;
}
@RequestMapping(value = "/exception")
public String exception() {
String rsp = "";
try {
int i = 1 / 0;
// should get exception
} catch (Exception e) {
e.printStackTrace();
LOG.error(e);
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
String sStackTrace = sw.toString(); // stack trace as a string
LOG.error("Exception As String :: - > "+sStackTrace);
rsp = sStackTrace;
}
return rsp;
}
}
3.3. 配置 Spring Boot 日志记录
在文件夹resources
下打开application.properties
并添加以下配置内容
logging.file=elk-example.log
spring.application.name = elk-example
3.4. 验证微服务生成的日志
使用命令进行最终的 maven 构建mvn clean install
并使用命令启动应用程序,java -jar target/elk-example-spring-boot-0.0.1-SNAPSHOT.jar
并通过浏览http://localhost:8080/elk进行测试。
不要害怕看到屏幕上的大堆栈跟踪,因为它是有意完成的,以查看 ELK 如何处理异常消息。
转到应用程序根目录并验证日志文件 ieelk-example.log
是否已创建并对端点进行几次访问并验证日志是否已添加到日志文件中。
4.Logstash 配置
我们需要创建一个 logstash 配置文件,以便它监听日志文件并将日志消息推送到Elasticsearch。这是示例中使用的logstash配置,请根据您的设置更改日志路径。
5. Kibana 配置
在 Kibana 中查看日志之前,我们需要配置 Index Patterns。我们可以配置logstash-*
为默认配置。我们总是可以在 logstash 端更改这个索引模式并在 Kibana 中配置。为简单起见,我们将使用默认配置。
索引模式管理页面如下所示。通过这种配置,我们将 Kibana 指向您选择的 Elasticsearch 索引。Logstash 使用名称模式创建索引,logstash-YYYY.MM.DD
我们可以在 Kibana 控制台http://localhost:5601/app/kibana中进行所有这些配置,然后转到左侧面板中的管理链接。
6. 验证 ELK 堆栈
现在,当所有组件都启动并运行时,让我们验证整个生态系统。
转到应用程序并测试端点几次,以便生成日志,然后转到 Kibana 控制台,查看日志在 Kibana 中正确堆叠,并具有许多额外功能,例如我们可以过滤、查看内置的不同图表等。
这是 Kibana 中生成的日志的视图。
7. ELK Stack 教程——总结
在这个ELK 示例中,我们学习了配置 ELK 堆栈,并了解了如何将应用程序日志文件指向 ELK 并在 Kibana 中查看和分析日志。我会建议你玩配置并与我们分享你的学习。例如
- 代替logstash来监听我们的日志,我们可以使用logback配置使用TCP appender通过TCP协议将日志发送到远程Logstash实例。
- 我们可以用 Logstash 指向多个日志文件。
- 我们可以在 logstash 配置文件中使用更复杂的过滤器来根据我们的需要做更多的事情。
- 我们可以使用远程 ELK 集群来指向我们的日志文件,或者将日志推送到,这基本上是所有应用程序都部署在云端时所需要的。
- 在 logstash 中创建不同的索引模式
ELK 堆栈需要正确配置 Java 1.8。由于系统路径中的 JDK 较旧,我在启动这些工具时遇到了困难。
下载本文源代码:elk-example-spring-boot.zip 密码:9987
原创文章,作者:kepupublish,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/243942.html