0%

ELKF

ELKF是指ELK+Filebeat,流程为Filebeat->Logstash->(Elasticsearch<->Kibana),由应用程序产生日志,Filebeat进行处理,将日志输出到Logstash中

  • Elasticsearch: 能对大容量的数据进行接近实时的存储,搜索和分析操作。
  • Logstash: 数据收集引擎,它支持动态的的从各种数据源获取数据,并对数据进行过滤,分析,丰富,统一格式等操作,然后存储到用户指定的位置。
  • Kibana: 数据分析与可视化平台,对Elasticsearch存储的数据进行可视化分析,通过表格的形式展现出来。
  • Filebeat: 轻量级的开源日志文件数据搜集器。通常在需要采集数据的客户端安装Filebeat,并指定目录与日志格式,Filebeat就能快速收集数据,并发送给logstash进行解析,或是直接发给Elasticsearch存储

修改配置filebeat.yml:

1
2
3
4
5
6
filebeat.inputs:
type: log
# Paths that should be crawled and fetched. Glob based paths.
paths:
- /var/log/*.log
- /opt/ywxt/log/*.log #修改扫描输入路径(可以配置多个路径)

分布式session

为了解决单点问题,现在很多的大型网站都用的是分布式集群来进行项目搭建的,但是分布式集群会出现很多的分布式问题,这篇文章说的是分布式session问题

分布式session是指的当一个带有session标识的HTTP请求到了web服务器后,需要在http请求的处理过程中找到对应的会话数据,但是有一个问题,会话数据是需要保存在服务器上的,如果每次访问的服务器不同的话,如何获取到session呢,这里给大家说几种解决的思路

阅读全文 »

Hystrix执行流程

  • 每次调用创建一个新的HystrixCommand,把依赖调用封装在run()方法中
  • 执行execute()/queue做同步或异步调用
  • 判断熔断器(circuit-breaker)是否打开,如果打开则执行fallback进行降级策略,如果关闭继续执行
  • 判断线程池/队列/信号量是否跑满,如果跑满执行fallback进行降级策略,否则继续后续步骤
  • 调用HystrixCommand的run方法,运行依赖逻辑,如果逻辑调用超时,则执行fallback逻辑
  • 判断逻辑是否调用成功,如果调用成功,则返回调用结果;如果调用出错,则执行fallback逻辑
  • 计算熔断器状态,所有的运行状态(成功、失败、拒绝、超时)上报给熔断器,用于统计从而判断熔断器状态

有四种情况将触发fallback逻辑

  • run()方法抛出非HystrixBadRequestException异常
  • run()方法调用超时
  • 熔断器开启拦截调用
  • 线程池/队列/信号量是否跑满

性能优化

  • 设置操作系统禁止swap

  • 对于不需要聚合和排序的索引字段禁止doc_values,可以节省存储空间

  • 对于不需要模糊检索的字段使用keyword而不是text,可以避免建立索引时对文本进行分词

  • 减少映射字段,只提供需要检索、聚合或排序的字段,其他字段存储在hbase中,通过rowkey进行查询

    为了使es的file system cache可以存储更多的数据,让es存储尽量少的字段信息(最好是写入es的数据小于等于es的file system cache大小,这样就可以直接在内存查找了)

  • es数据量过大导致查询速度变慢,可以将es的数据进行冷热分离,冷数据单独写入一个索引,热数据写入另一个索引

SpringApplicationRunListener

在看源码的时候经常看到

1
2
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();

这个SpringApplicationRunListeners是用来干嘛的呢

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public interface SpringApplicationRunListener {

/**
* run方法首次启动的时候立刻调用,可以进行早期的初始化操作
*/
void starting();

/**
* 环境被准备好的时候被调用,但是在ApplicationContext创建之前
*/
default void environmentPrepared(ConfigurableEnvironment environment) {
}

/**
* ApplicationContext已经被创建且准备好了,但是源还没被加载
*/
default void contextPrepared(ConfigurableApplicationContext context) {
}

/**
* ApplicationContext已经被加载但是在刷新之前
*/
default void contextLoaded(ConfigurableApplicationContext context) {
}

/**
* @since 2.0.0 ApplicationContext已经被刷新且启动但是CommandLineRunner和ApplicationRunner还没有被调用
*/
default void started(ConfigurableApplicationContext context) {
}

/**
* @since 2.0.0 run方法完成之前被调用,ApplicationContext已经被刷新且启动,CommandLineRunner和ApplicationRunner已经被调用
*/
default void running(ConfigurableApplicationContext context) {
}

/**
* @since 2.0.0 运行ApplicationContext出错
*/
default void failed(ConfigurableApplicationContext context, Throwable exception) {
}

}