前言:
大概一年多前写过一个部署 ELK 系列的博客文章,前不久刚好在部署一个 ELK 的解决方案,我顺便就把一些基础的部分拎出来,再整合成一期文章。大概内容包括:搭建 ELK 集群,以及写一个简单的 MQ 服务。
如果需要看一年多之前写的文章,可以详见下列文章链接(例如部署成 Windows 服务、配置浏览器插件、logstash 接收消费者数据等,该篇文章不再重复描述,可以点击下方链接自行参考):
ElasticSearch、head-master、Kibana 环境搭建:https://www.cnblogs.com/weskynet/p/14853232.html
给 ElasticSearch 添加 SQL 插件和浏览器插件:https://www.cnblogs.com/weskynet/p/14864888.html
使用 Logstash 通过 Rabbitmq 接收 Serilog 日志到 ES:https://www.cnblogs.com/weskynet/p/14952649.html
使用 nssm 工具将 ES、Kibana、Logstash 或者其他.bat 文件部署为 Windows 后台服务的方法:https://www.cnblogs.com/weskynet/p/14961565.html
安装包目录
将有关环境解压备用。如图:
说明:集群环境下,使用 4 个 elasticsearch 数据库。其中三个为 master,分别可用于选举主节点、存储数据使用;另外一个为 client,仅作为 es 的负载均衡使用。如果服务器配置环境太低的情况下,client 也可以不需要,不会产生影响;如果访问会比较频繁,建议可以加上。以下配置操作,均以使用 3+1 的集群策略进行配置。
各个环境/安装包说明
Elasticsearch:主要用来存储数据的一个非关系型文档数据库,基于 lucene 内核的搜索引擎,可以实现快速搜索数据的目的。一般用来存储日志数据比较常见。
Logstash:用于收集数据的管道, 例如此处用来收集消息队列的数据进行转储到 elasticsearch 里面。
Kibana:一个可视化的搜索引擎组件,用来查询 elasticsearch 的数据和展示使用。
OpenJDK:非官方版本的 JDK 环境,此处使用的是华为镜像下的定制过的 open JDK 19 版本。
Elasticsearch-analisis-ik: 一个中文分词工具,用于搜索引擎内搜索词汇时候,可以对词汇进行归集处理,而不至于导致搜索出来的结果是模糊查询。例如:如果没有分词,输入“大佬”进行查询,会把有“大”和“佬”的结果都查询出来。而实际上我们需要查的是“大
佬”这个词。IK 分词的目的就是这个作用。
Elasticsearch-sql: 一款用于提供 SQL 语句进行查询的工具。
Sqlsite:一款浏览器插件,用来集成到谷歌内核的浏览器上,可以通过 sql 语句进行查询 es 的数据集。
Otp_win64_xx : rabbitmq 环境的 erlang 语言包环境,安装 rabbitmq 服务之前,需要先安装该包
Rabbitmq-server: rabbitmq 安装包
JDK 环境配置
把解压缩的 open jdk 的 bin 目录,添加到【系统变量】的环境变量 Path 里面去。
打开 cmd,输入 java –version 查看版本,提示版本正确,说明 JDK 环境配置 OK
RabbitMQ 环境配置
安装 Otp 语言包:全部默认下一步到头,简单粗暴。如果有提示确认的,勾选确认即可。
安装 RabbitMQ 服务安装包:同上,直接下一步到底,完成。
备注:安装 rabbitmq 对应的服务器主机,服务器【主机的名称】和【用户名称】不能有中文字符,不能有中文字符,不能有中文字符,重要的事情说三遍,我年轻时候踩过坑。
配置环境变量。先新增一个 ERLANG_HOME,路径是安装 erlang 的目录:
环境变量的 Path 里面新增 ERLANG_HOME 的 bin 目录:
新增 RabbitMQ 服务的变量 RABBITMQ_SERVER,值是 rabbitmq 服务的安装目录:
把 rabbitmq 的 sbin 目录,加入到 path 环境变量里面去:
打开 cmd,输入 rabbitmq-plugins enable rabbitmq_management 进行安装 RabbitMQ-Plugins 的插件:
设置好以后,打开浏览器,在服务器上输入访问 http://127.0.0.1:15672
使用 guest 账号进行登录
进去以后,找到 Admin 菜单,新增一个用户。此处用户默认为 admin,密码默认为 admin。
也可以设为其他的,设为其他的。最后点击 set 旁边的 Admin,再点击左下角的 Add User
进行添加一个我们的用户。(不建议使用 guest 用户直接做消息队列的处理,可能有安全风
险)
默认添加完成以后,是没有权限的,需要进一步进行添加权限。点击表格下的 Name 字段,会自动进入到设置权限页面。
啥也不干,直接点下方第一个按钮【Set permission】即可
返回 Admin 菜单下,可以看到 admin 用户的黄色底色已经没有了,并且 access 权限也
变成了/
Elasticsearch 配置文件 elasticsearch.yml 说明
【以下内容摘自网络,如果不想科普可以跳过该部分】
cluster.name: elasticsearch
配置的集群名称,默认是 elasticsearch,es 服务会通过广播方式自动连接在同一网段下的 es 服务,通过多播方式进行通信,同一网段下可以有多个集群,通过集群名称这个属性来区分不同的集群。
node.name: “node-01”
当前配置所在机器的节点名,你不设置就默认随机指定一个 name 列表中名字,该 name 列表在 es 的 jar 包中 config 文件夹里 name.txt 文件中,其中有很多作者添加的有趣名字。当创建 ES 集群时,保证同一集群中的 cluster.name 名称是相同的,node.name 节点名称是不同的;
node.master: true
指定该节点是否有资格被选举成为 node(注意这里只是设置成有资格, 不代表该 node 一定就是 master),默认是 true,es 是默认集群中的第一台机器为 master,如果这台机挂了就会重新选举 master。
node.data: true
指定该节点是否存储索引数据,默认为 true。
index.number_of_shards: 5
设置默认索引分片个数,默认为 5 片。
index.number_of_replicas: 1
设置默认索引副本个数,默认为 1 个副本。如果采用默认设置,而你集群只配置了一台机器,那么集群的健康度为 yellow,也就是所有的数据都是可用的,但是某些复制没有被分配(健康度可用 curl ‘localhost:9200/_cat/health?v’ 查看, 分为绿色、黄色或红色。绿色代表一切正常,集群功能齐全,黄色意味着所有的数据都是可用的,但是某些复制没有被分配,红色则代表因为某些原因,某些数据不可用)
path.conf: /path/to/conf
设置配置文件的存储路径,默认是 es 根目录下的 config 文件夹。
path.data: /path/to/data
设置索引数据的存储路径,默认是 es 根目录下的 data 文件夹,可以设置多个存储路径,用逗号隔开,例:path.data: /path/to/data1,/path/to/data2
path.work: /path/to/work
设置临时文件的存储路径,默认是 es 根目录下的 work 文件夹。
path.logs: /path/to/logs
设置日志文件的存储路径,默认是 es 根目录下的 logs 文件夹
path.plugins: /path/to/plugins
设置插件的存放路径,默认是 es 根目录下的 plugins 文件夹, 插件在 es 里面普遍使用,用来增强原系统核心功能。
bootstrap.mlockall: true
设置为 true 来锁住内存不进行 swapping。因为当 jvm 开始 swapping 时 es 的效率会降低,所以要保证它不 swap,可以把 ES_MIN_MEM 和 ES_MAX_MEM 两个环境变量设置成同一个值,并且保证机器有足够的内存分配给 es。同时也要允许 elasticsearch 的进程可以锁住内存,linux 下启动 es 之前可以通过`ulimit -l unlimited`命令设置。
network.bind_host: 192.168.0.1
设置绑定的 ip 地址,可以是 ipv4 或 ipv6 的,默认为 0.0.0.0,绑定这台机器的任何一个 ip。
network.publish_host: 192.168.0.1
设置其它节点和该节点交互的 ip 地址,如果不设置它会自动判断,值必须是个真实的 ip 地址。(可以用不配)
network.host: 192.168.0.1
这个参数是用来同时设置 bind_host 和 publish_host 上面两个二手手机参数。(低版本时配置
0.0.0.0,不然启动会报错。1.7.1 和 1.3.1 版本亲测)
transport.tcp.port: 9300
设置节点之间交互的 tcp 端口,默认是 9300。如我搭建多节点,我的配置分别是 9300、9302、9304
transport.tcp.compress: true
设置是否压缩 tcp 传输时的数据,默认为 false,不压缩。
http.port: 9200
设置对外服务的 http 端口,默认为 9200。
http.max_content_length: 100mb
设置内容的最大容量,默认 100mb
http.enabled: false
是否使用 http 协议对外提供服务,默认为 true,开启。
gateway.type: local
gateway 的类型,默认为 local 即为本地文件系统,可以设置为本地文件系统,分布式文件系统,hadoop 的 HDFS,和 amazon 的 s3 服务器等。
gateway.recover_after_nodes: 1
设置集群中 N 个节点启动时进行数据恢复,默认为 1。
gateway.recover_after_time: 5m
设置初始化数据恢复进程的超时时间,默认是 5 分钟。
gateway.expected_nodes: 2
设置这个集群中节点的数量,默认为 2,一旦这 N 个节点启动,就会立即进行数据恢复。
cluster.routing.allocation.node_initial_primaries_recoveries: 4
初始化数据恢复时,并发恢复线程的个数,默认为 4。
cluster.routing.allocation.node_concurrent_recoveries: 2
添加删除节点或负载均衡时并发恢复线程的个数,默认为 4。
indices.recovery.max_size_per_sec: 0
设置数据恢复时限制的带宽,如入 100mb,默认为 0,即无限制。
indices.recovery.concurrent_streams: 5
设置这个参数来限制从其它分片恢复数据时最大同时打开并发流的个数,默认为 5。
discovery.zen.minimum_master_nodes: 1
设置这个参数来保证集群中的节点可以知道其它 N 个有 master 资格的节点。默认为 1,对于大的集群来说,可以设置大一点的值(2-4)
discovery.zen.ping.timeout: 3s
设置集群中自动发现其它节点时 ping 连接超时时间,默认为 3 秒,对于比较差的网络环境可以高点的值来防止自动发现时出错。
discovery.zen.ping.multicast.enabled: false
设置是否打开多播发现节点,默认是 true。
discovery.zen.ping.unicast.hosts: [“host1”, “host2:port”, “host3[portX-portY]”]
设置集群中 master 节点的初始列表,可以通过这些节点来自动发现新加入集群的节点。例如:discovery.zen.ping.unicast.hosts: [“127.0.0.1:9300″,”127.0.0.1:9302″,”127.0.0.1:9304”] 配置了三个节点
ES 集群配置文件配置
集群配置,采用 3+1 的部署方案,包括 3 个可选主节点,以及 1 个客户端节点。
其中:
cluster.name 的值保持一致
node.name 的值,可自定义,此处默认可以成为主节点的节点名称为 master1 master2 和 master3
path.data 和 path.log 用来存储 es 节点存储的数据和自身日志的路径使用。
path.data 的值不能一样,不同的节点,存储的地址需要分开,否则会报错。data 路径用于存放我们发送
给 es 的数据所存储的路径位置。
http.port 默认为 9200,用于外部访问 es 使用;四个节点,端口号此处分别设置为 9200、9201、9202、9203。其中 9203 端口号用于分配给 client 使用。
transport.tcp.port 默认为 9300,用于内部集群间通信使用;四个节点,端口号此处分别设置为 9300,9301,9302,92303。其中 9303 用于 client 节点使用。
discovery.seed_hosts 记录的是这四个集群节点的内部通信地址,我本地局域网内的一台服务器为 10.1.11.74,所以我此处为了好分辨,就全部写成 10.1.11.74 的地址。生产环境下,可以根据实际情况修改为生产环境的 ip 地址。
警告:如果 es 部署在同一个服务器上,请默认使用 127.0.0.1 这个 ip,其他 ip 可能会受到防火墙限制。例如上面我写的 10.1.11.74 的 ip,后面就会有集群关连失败的情况。
cluster.initial_master_nodes 此处默认主节点设置为 master1,当然也可以设为 master2 或者 3,但是不能是 client,因为 client 不能当做主节点。
node.master 和 node.data,3+1 集群模式下,【master 节点的值全是 true】,【client
节点的值全是 false】。
以下是我先前做的一个 master1 的配置文件截图:
以下是 master2 的配置文件截图,可以和以上的 master1 的配置文件进行比对查看不同点。master3 节点以此类推。
以下是 client 节点的配置文件截图,可以和 master 节点进行比较差异点。Client 节点不进行主节点的选举,也不进行存储数据,仅用于负载均衡,用于对 3 个主要节点进行压力分解的作用使用。
Jvm.options 环境配置
Jvm.options 文件在 config 文件夹下
该路径下用来配置单个 ES 的内存分配规则。最低可以配置 512m,最高 32g 此处以最高和最低内存使用量都是 512m 来配置(公司云服务器配置太低,没办法~)。如果是 g 为单位,注意都是小写,并且不带 b,例如 Xms512m Xmx4g 等等。Xms 代表最低分配内存,Xmx 代表最大分配内存。
以此类推,把 4 个 es 的内存都设置一下。
警告:以上 512m 只是因为我本地的局域网内的服务器上的配置比较低,所以在生产环境下,请配置大一点,例如,一台 64GB 内存的服务器,以 3+1 部署模式进行部署的情况下,最大可以对每个节点
分配(64/2)/5 ≈ 6g 的最大值,其中 5 代表的是 4 台 es 和一台 logstash。ELK 的总内存最大
占用建议不要超过服务器总内存的一半,留点面子。
通过 bat 文件启动 es 集群进行初始验证
进入到四个 es 的根目录下(esxxx/bin),打开 cmd,执行 elasticsearch.bat 文件:
启动以后,浏览器输入 localhost:端口号,例如 master1 的端口号是 9200,启动成功会有一段简单的提示信息,包括节点名称、集群名称,es 版本等等:
四个 es 都启动成功以后,浏览器输入 http://localhost:9200/_cat/nodes?v
可以看到集群内部的活动以及主节点信息。当然,上面的 ip 和端口号改成任意集群内
的一个节点的地址,都可以查出来。其中 master1 为现在的主节点。
做个测试,测试主节点宕机以后的效果。(以下内容仅用于测试观看,可以直接跳过)
停止 master1 节点,看看情况。
刷新一下页面,可以看到少了一个 master1,然后 master3 被自动选举为主节点。
重新启动 master1 节点,看下效果。如图所示,master1 自动成为了子节点,这个就是集群的魅力,挂了一个一点都不慌。
集成 sql 插件和 ik 插件
在所有的 es 的 plugins 文件夹下,新建两个文件夹,分别是 sql 和 ik
把 ik 解压后的内容,全部拷贝到各个 es 都 ik 文件夹下:
From
To:
ik 说明:如果有某个关键词汇查不出来,就可以在 ik 分词里面进行新增,例如“老吴”。
新增说明:在 ik 的 config 目录下,任意找一个词字典,在最后进行添加有关词汇。
把 sql 解压后的内容,全部拷贝到各个 es 都 sql 文件夹下:
From:
To:
添加完成以后,通过 bat 启动时候,可以看到有关的加载信息:
logstash 的 jvm 配置
Logstash 的 jvm 配置,同 elasticsearch 配置,也需要配置最大内存和最小内存的临界值。
此处写的是 2g,我改为了 512m(自行根据个人服务器配置进行设置)
logstash 的 config 配置文件设置
config 文件用于指定 logstash 使用何种方式进行监听数据流的输入和输出功能,当前使用监听 RabbitMQ 的方式来监听日志数据流,然后进行转存到 ElasticSearch 数据库上。
以下截图为预设置的配置文件接收端(config 目录下的 rabbitmq.conf 文件),预设三个监听数据来源的队列信息。采用 direct 模式,并且指定不同的日志内容走不同的队列,例如我之前项目上使用的 WCSLog、DeviceLog、ApiLog 等,配置信息可以当做参考。
以下截图配置的是每天新增一个索引,分别以 sys、device、api 开头。
注意事项:RabbitMQ 里面必须已经存在以上的队列以后,才可以启动 logstash,否则会启动失败。正确做法是,先启动你的程序,初始化一下或者创建一下 MQ 有关的队列信息以后,再启动 Logstash。
Kinaba 配置
打开 kibana 根目录下的 config 文件夹,下面的 kibana.yml 配置文件进行配置。
Kibana 配置比较简单,此处只配置三个地方:
其中,server.port 是对外开放的端口号,默认是 5601,此处改成了 15601,防止被人随
意登录。
然后是 es.hosts,有多少 es 的节点,就都配上去。
还一个是 il8n.locale 是默认的语言类型,默认是 en 英语,此处我们改为 zh-CN 中文。
本公众号文章原文地址是:https://www.cnblogs.com/weskynet/p/16890741.html
如果公众号内显得图片比较小,也可以转场去网上看博客原文。
快速开发 MQ 生产者和消费者基础服务
新建一个 webapi 项目进行测试。并添加引用:Wesky.Infrastructure.MQ
其中,这个包是我写的一个比较通用的基于 DIRECT 模式的简易版 MQ 生产者和消费者基础功能服务,也可以直接拿来做 MQ 的业务对接开发。
然后,在 program.cs 里面,添加对 WeskyMqService 的注册,里面注册了基础的生产者和消费者服务。
咱新增一个消费者消息消费的方法 ConsumeMessage 以及有关 interface 接口,该方法后面用来当作回调函数使用,用来传给 MQ 消费者,当监听到消息以后,会进入到该方法里面。
再然后,回到 program 里面,对刚才新增的方法进行依赖注入的注册;以及在里面做一个简单的 MQ 队列的配置信息。
其中,RabbitMqOptions 构造函数带有两个参数,分别是
RabbitMqConfiguration:它传入 MQ 的连接
RabbitMqMessageQueues[]:路由键以及对应的队列名称数组,有多少个队列,数组元素就是多少个一一对应。
以上创建了基础的连接,通过 direct 模式进行消息订阅和发布;并且创建两个队列,分别是 Test1 和 Test2
再然后,新建一个 API 控制器,并提供有关依赖注入进行实现的验证。
为了方便测试,新增两个 api 接口,用来检测 MQ 的连接以及消息发布和订阅。
其中,index 此处的作用是咱们配置的消息队列的队列数组里面的下标。
连接参数 isActive 代表是否消费者消费消息,如果不消费消息,那么就可以用来给我们上面的 logstash 来消费了;如果消费消息,那么消息就会进入到我们刚才创建的 ConsumeMessage 方法里面去,因为它通过回调函数参数丢进去了:
打开 MQ 面板,可以看到现在是都没有队列存在的。
此时启动程序,先调用连接的 API(API 里面,包括了生产者连接和消费者连接,平常如果只需要连接一个,也是可以屏蔽其他的,例如与第三方 MQ 做信息通信的话),再调用发布消息的 API,查看效果。咱先做一个不消费(允许消费参数设为 false)的例子:
然后再查看 MQ 面板,可以看到多了两个队列,这两个队列就是代码里面连接以后自动创建的:
调用生产者,发布一条消息,例如发给数组的第一个队列一条消息:
因为不允许消费,所以消息会一直在队列里面没有被消费掉:
我们先关闭 api 程序,然后重新做个连接,做成允许消费的,看下效果:
再切换到 MQ 面板,可以看到消息立马被消费了:
我们刚才写的一个输出控制台的消费消息的业务方法,此时也被执行了:
以上说明 MQ 的生产者与消费者服务是 OK 的了。然后就可以与上面的 EKL 集群进行配合使用,例如你的程序需要通过 MQ 的方式给 Logstash 发送消息,那么就可以使用传入不启用 MQ 客户端消费的功能来实现;如果需要与其他生产者对接,或者需要做 MQ 消息消费的业务,就可以通过类似方式,写一个回调函数当作参数丢进 MQ 消费者服务里面去即可。
最后,ELK 上面我没做其他的优化,大佬们感兴趣可以自己优化,例如信息的压缩、定时删除等等,这些都可以在 Kibana 的管理界面里面进行配置。