前言:
大概一年多前写过一个部署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的管理界面里面进行配置。
如果需要以上的环境全套资源、以及后面的MQ的例子,可以扫码关注以下公众号,或者搜索【Dotnet Dancer】关注公众号,发送【ELKQ】即可获取。
公众号聊天框内回复【ELKQ】可以获取的工具环境、内容等,见下图: