FileBeat 基础配置

  |  
阅读次数
  |  
字数 1,179
  |  
时长 ≈ 6 分钟

由FileBeat负责统一读取多机服务的日志到redis,再统一由LogStash解析日志内容,放到ElasticSeach。

不同类型的日志,需要抓取的重点不一样,可统一建立各类型日志记录规范,然后在FileBeat读取的时候在fields字段做标识,然后在LogStash获取到记录的时候通过fields的字段来编写逻辑,判断该日志为什么类型,然后进行grok表达式匹配。

Filebeat 如何读取多个日志目录?

如果 Filebeat 所在 server 上运行有多个 application servers,各自有不同的日志目录,那 Filebeat 如何同时读取多个目录,这是一个非常典型的问题。

解决方案:通过配置多个 prospector 就能达到要求。在配置文件的 prospectors 下,每个”-“表示一个 prospector,每个 prospector 包含一些配置项,指明这个 prospector 所要读取的日志信息。如下所示:

1
2
3
4
5
6
7
8
9
prospectors:
-
paths:
- /home/BizLog/*.log
# 其他配置项,具体参考 Elastic 官网
-
paths:
- /home/ApacheLog/*.log
# 其他配置项,具体参考 Elastic 官网

Filebeat 如何区分不同日志来源?

还是上题中提到的场景,Filebeat 虽然能读取不同的日志目录,但是在 Logstash 这边,或者是 Elasticsearch 这边,怎么区分不同 application server 的日志数据呢?

解决方案:Filebeat 的配置项 fields 可以实现不同日志来源的区分。用法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
prospectors:
-
paths:
- /home/BizLog/*.log
fields:
log_source: Biz
log_type: interface
-
paths:
- /home/ApacheLog/*.log
fields:
log_source: Apache
log_type: system

在 fields 配置项中,用户可以自定义域来标识不同的 log。比如上例中的”log_source”就是笔者自定义的。如此,从 Filebeat 输出的 log 就有一个叫做 log_source 的域表明该 log 的实际来源。log_type来区分日志解析类型,在LogStash 解析的时候通过该字段匹配不同的grok表达式。

Read More

J2EE Spring redirect导致内存溢出问题

  |  
阅读次数
  |  
字数 1,041
  |  
时长 ≈ 5 分钟

最近发现线上的一个应用跑一段周期之后就会出现内存溢出问题,需要重启,所以以此分析一下原因并修复。

1.获取内存快照

使用jdk自带工具jmap获取内存快照文件,如下:

1
2
3
4
5
jmap -dump:format=b,file=快照保存路径 进程id

如:

jmap -dump:format=b,file=/opt/27245.hprof 27245

2.使用工具进行分析

获取到内存快照文件27245.hprof后,我们需要对此进行分析,这里使用的分析工具为Eclipse Memory Analyzer Tool,我们使用工具打开27245.hprof文件。

2.1 Main View

主界面显示有一大块内存占用高达1.3G,基本可以确定是这一块出现了问题。

J2EE Spring redirect导致内存溢出问题_图例1

Read More

LogStash 基础配置

  |  
阅读次数
  |  
字数 361
  |  
时长 ≈ 2 分钟

LogStash 基础配置记录

下载解压包,并配置以下配置文件。

启动命令(指定配置文件):

1
2
3
cd ~/Documents/elk-6.2.4/logstash/logstash-6.2.4

./bin/logstash -f logstash-simple.conf

logstash-simple.conf

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
45
46
47
input {
#指定redis为输入流,从redis中读取数据进行解析
redis {
data_type => "list"
key => "filebeat"
host => "localhost"
port => 6379
threads => 5
db => 15
}
}

filter {
#使用GrokDebugger调试Grok表达式后再filter添加Grok,匹配日志格式并输出到指定字段,日志格式如下
#18-08-30 16:05:26 INFO pool-2-thread-1 c.t.w.c.o.i.LoggingInterceptor.intercept(39) | url: https://api.weixin.qq.com/cgi-bin/user/info?access_token=13_qvMXVHYu_hwt0r4fGLfck8lP-seK0NXNE3UMQTeWppzpW_1Z0-SsPY4kR5kTjPwjKi_icM3nXcoUuAjoakbPBKUQArMru4e8efcFFvkpcLilZkywtHSz9CHUjX-Aoehc9inNlsBts18MEYSMAAPkCFAGGV&openid=oBBmBjijP3MN6m0uNf_9Z66TglmM&lang=zh_CN, method: GET, time: 134, request(), response({"subscribe":1,"openid":"oBBmBjijP3MN6m0uNf_9Z66TglmM","nickname":"小萝卜","sex":0,"language":"zh_CN","city":"","province":"","country":"","headimgurl":"","subscribe_time":1508819231,"unionid":"oxAVa1F-E3GmhjquNqxk3Xyk1bGA","remark":"","groupid":139,"tagid_list":[139],"subscribe_scene":"ADD_SCENE_SEARCH","qr_scene":0,"qr_scene_str":""})
grok {
match => { "message" => "\s*%{TIMESTAMP_ISO8601:time}\s*%{LOGLEVEL:level}\s*%{JAVAFILE:thread}\s*%{JAVAFILE:class}\(%{NUMBER:lineNumber}\)\s*\|%{GREEDYDATA:result}"}
}
#替换默认@timestamp字段
date {
match => [ "time", "yy-MM-dd HH:mm:ss"]
#默认的替换字段为@timestamp,所以省略以下配置
#target => "@timestamp"
}
json {
#使用json插件解析responseBody
source => "responseBody"
#解析的字段前面带上字段名
target => "responseBody"
}
mutate {
#删除message字段
remove_field => ["message"]
}
}

output {
#指定es为输出流,并指定创建的索引格式
elasticsearch {
hosts => "localhost:9200"
action => "index"
index => "filebeat-%{+YYYY.MM.dd}"
}
stdout {
codec => rubydebug
}
}

ElasticSearch 基础命令

  |  
阅读次数
  |  
字数 1,600
  |  
时长 ≈ 8 分钟

mac使用brew安装,使用默认端口。

启动命令:

1
elasticsearch

ElasticSearch 基础命令记录,分es和kibana两种。

一个代码块分为三块,上面一行为es中间一行为kibana最后行为执行结果。

索引操作

创建一个索引weather

1
2
3
4
5
6
7
8
9
curl -X PUT 'localhost:9200/weather'

put weather

{
"acknowledged": true,
"shards_acknowledged": true,
"index": "weather"
}

删除一个索引weather

1
2
3
4
5
6
7
curl -X DELETE 'localhost:9200/weather'

delete weather

{
"acknowledged": true
}

数据操作

新建一个accounts索引下的文档类型为person的记录1

手动指定id,则创建的索引_id字段会被指定为1

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
curl -X PUT 'localhost:9200/accounts/person/1' -d '
{
"user": "张三",
"title": "工程师",
"desc": "数据库管理"
}'

put accounts/person/1
{
"user": "张三",
"title": "工程师",
"desc": "数据库管理"
}

{
"_index": "accounts",
"_type": "person",
"_id": "1",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 1
}

Read More

IDEA 编程风格规范

  |  
阅读次数
  |  
字数 153
  |  
时长 ≈ 1 分钟

为了统一规范代码风格,规定团队均使用下列插件以及设置。

编程规范统一使用: google-java-format
代码规范统一使用: Alibaba Java Coding Guidelines
快速格式优化使用: Save Actions

设置

1)google-java-format

1.1)Tab键统一4个空格

Editor -> Code Style -> Java

Tab size:4

1.2)行宽120

Editor -> Code Style

Hard wrap at 120 columns

2)Alibaba Java Coding Guidelines

根据项目自行开启

3)Save Actions

general

  • 1.activate save actions on sace (before saving each file, performs the …)

formatting actions

  • 1.organize imports
  • 2.reformat file
  • 3.reformat only changed code

java inspection and quick fix

  • 6.add missing @Override annotations
  • 7.add blocks in if/while/for sattements

建站 HEXO发布到github时出现卡顿

  |  
阅读次数
  |  
字数 231
  |  
时长 ≈ 1 分钟

使用以下命令构建发布时,一直循环出现该错误,导致发布不了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ hexo clean && hexo g && hexo d -debug

INFO Deleted database.
INFO Deleted public folder.
INFO Start processing
INFO Files loaded in 1.63 s
INFO Generated: index.html
...
INFO 359 files generated in 5.06 s
INFO Start processing
INFO Files loaded in 826 ms
INFO 0 files generated in 3.65 s
INFO Start processing
INFO Files loaded in 339 ms
INFO 0 files generated in 3.59 s
INFO Start processing
INFO Files loaded in 295 ms
...

无奈之下,只能重新构建一个项目,将源码拷贝到新的项目进行重新构建。

发现就可以了。

1
2
3
4
5
hexo init hexoblog

cd hexoblog

npm install

然后复制老项目现有的 _config.yml 到新项目路径下,

再复制 hexoblog/source 下面的 categoriestagsCNAME 到新项目底下,

然后复制 themes/shana 到新项目的themes底下,重新执行发布命令即可。

Linux 机器之间 zssh, rz, sz互相传输

  |  
阅读次数
  |  
字数 274
  |  
时长 ≈ 2 分钟

服务器端安装lrzsz:

1
sudo  yum install lrzsz

本地客户端安装lrzsz:

1
brew install lrzsz

本地客户端安装zssh:

1
brew install zssh

1)下载

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
# tidy @ TidydeMBP in ~ [15:56:24]
$ zssh finder@10.121.22.201
Press ^@ (C-Space) to enter file transfer mode, then ? for help

finder@10.121.22.201's password:
Last login: Mon Jul 30 15:56:20 2018 from 10.121.80.1
-bash: ulimit: open files: cannot modify limit: 不允许的操作
[finder@im2-gf-test ~]$ ssh imhtp@localhost
imhtp@localhost's password:
Last login: Mon Jul 30 15:56:49 2018 from 10.121.80.1
[imhtp@im2-gf-test ~]$ cd /opt/20180728/
[imhtp@im2-gf-test 20180728]$ sz tmp.txt
�*B00000000000000

# ctrl+@
zssh > pw
pw: No such file or directory
zssh > pwd
/Users/tidy
zssh > cd Downloads
zssh > rz
Receiving: tmp.txt
Bytes received: 0/ 0 BPS:0
Retry 0: Got TIMEOUT

Transfer complete

2)上传

1
2
3
4
5
6
7
8
9
10
11
[imhtp@im2-gf-test 20180728]$

#ctrl+@

zssh > pwd
/Users/tidy/Downloads
zssh > sz 新模板微信.txt
Sending: 新模板微信.txt
Bytes Sent: 2505 BPS:1191

Transfer complete

3)SCP

简单使用SCP,复制远程服务器文件夹到本地

1
scp -r finder@10.121.22.201:/opt/20180728 ~/Downloads

Dubbo 内核SPI源码学习

  |  
阅读次数
  |  
字数 8,673
  |  
时长 ≈ 39 分钟

先从配置文件开始,dubbo基于Spring的可扩展Schema提供了一套简明的自定义配置标签,用于简化配置流程。

具体原理可参考以下链接:
基于Spring可扩展Schema提供自定义配置支持

于是,当我们配置了以下一段代码的时候其实最后通过解析之后就相当于变成了一个个的<bean/>配置,生成了实例。

1
2
3
4
5
<!-- service implementation, as same as regular local bean -->
<bean id="demoService" class="org.apache.dubbo.demo.provider.DemoServiceImpl"/>

<!-- declare the service interface to be exported -->
<dubbo:service interface="org.apache.dubbo.demo.DemoService" ref="demoService"/>

当加载以上配置 <dubbo:service/> 的时候,基于 dubbo.jar 内的 META-INF/spring.handlers 配置,Spring在遇到dubbo命名空间时,会回调 DubboNamespaceHandler。

所有dubbo的标签,都统一用 DubboBeanDefinitionParser 进行解析,基于一对一属性映射,将XML标签解析为一个 ServiceConfig Bean 对象。

在 ServiceConfig.export() 或者 ReferenceConfig.get() 初始化时,将会将bean对象转化为URL格式,所有的Bean属性转化为URL的参数,然后将URL传给协议扩展点,基于扩展点的扩展点自适应机制,根据前面转化的URL的协议头,进行不同协议的服务暴露或者引用。

所有扩展点参数都包含 URL 参数,URL 作为上下文信息贯穿整个扩展点设计体系。
URL 采用标准格式:protocol://username:password@host:port/path?key=value&key=value

1)SPI内核实现

前言:

SPI机制主要用于系统集成,dubbo提供了许多扩展点,允许开发者基于内置的扩展点对框架功能作特性定制,
dubbo的SPI机制就是将不同的实现方案进行集成装配,这样可以消除模块集成的代码,平等看待第三方扩展,以增强框架的扩展性。
dubbo的SPI机制参考了JDK中标准的SPI机制思想,加入一些增强功能,以适应dubbo特殊化的应用场景。

上面说到,所有Bean都将转化为URL对象,传给扩展点,基于自适应机制进行不同协议的暴露或引用。

这句话可才分为以下步骤:

1
2
3
4
5
6
7
8
// 1.转化为URL
这里是上面的步骤

// 2.传给扩展点,(所以这里需要生成一个扩展点,代码如下)
private static final Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();

// 3.基于自适应机制进行不同协议的暴露或引用(上面已经获取到一个扩展点的代理类,他将通过代理类方法里面的URL自适应不同协议,然后执行具体逻辑)
protocol.export(wrapperInvoker);

Read More

Java Mac配置Java环境变量

  |  
阅读次数
  |  
字数 186
  |  
时长 ≈ 1 分钟

如果用bash,修改~/.bash_profile 或 ~/.profile;
如果用zsh,修改~/.zshrc

修改这些文件之后,重修打开terminal,配置不会丢

1)首先确保已经安装了jdk

1
2
3
4
5
## check the present running java
which java

## check java version
java -version

2)以zsh为例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
## check all the available jdk
/usr/libexec/java_home -V

## check the top jdk
/usr/libexec/java_home

## check some jdk (eg. version 1.7)
/usr/libexec/java_home -v 1.7

## edit .zshrc to set java_home variable
vim ~/.zshrc

## add the following line into the file
export JAVA_HOME=$(/usr/libexec/java_home)

## you can also use the following line to set the variable, which is not recommended, only for older mac os.
## export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home

##let the configuration in .zshrc take effect
source ~/.zshrc

## check if configure succeed
echo $JAVA_HOME