ELK
什么是ELK
https://www.elastic.co/cn/what-is/elk-stack
ELK 全称 ELK Stack,它的更新换代产品叫 Elastic Stack
ELK = Elasticsearch + Logstash + Kibana
- Elasticsearch:搜索和分析引擎
- Logstash:服务器端数据处理管道,能够同时从多个来源采集数据,转换数据,然后将数据发送到诸如 Elasticsearch 等“存储库”中
- Kibana:让用户在 Elasticsearch 中使用图形和图表对数据进行可视化
什么是Elasticsearch
https://www.elastic.co/cn/what-is/elasticsearch
什么是 Logstash
Logstash 是 Elastic Stack 的核心产品之一,可用来对数据进行聚合和处理,并将数据发送到 Elasticsearch。Logstash 是一个开源的服务器端数据处理管道,允许您在将数据索引到 Elasticsearch 之前同时从多个来源采集数据,并对数据进行充实和转换。
什么是 kibana
https://www.elastic.co/cn/what-is/kibana
为什么使用ELK
ELK 组件在海量日志系统的运维中,可用于解决以下主要问题:
- 分布式日志数据统一收集,实现集中式查询和管理
- 故障排查
- 安全信息和事件管理
- 报表功能
elasticsearch
基本概念
参考博客:https://www.cnblogs.com/qdhxhz/p/11448451.html
重点理解 index 和 document 这两个概念:index(索引)类似kafka的topic,oss的bucket,要尽量控制 index 的数量;index中的单条数据称为document(文档),相当于mysql表中的行
之前的版本中,索引和文档中间还有个type(类型)的概念,每个索引下可以建立多个type,document存储时需要指定index和type,因为一个index中的type并不隔离,document不能重名,所以type并没有多少意义。从7.0版本开始,一个index只能建一个名为_doc的type,8.0.0 以后将完全取消
下面是一个document的源数据:
_index
:文档所属索引名称_type
:文档所属类型名_id
:doc主键,写入时指定,如果不指定,则系统自动生成一个唯一的UUID值_version
:doc版本信息,保证doc的变更能以正确的顺序执行,避免乱序造成的数据丢失_seq_no
:严格递增的顺序号,shard级别严格递增,保证后写入的doc的_seq_no
大于先写入的doc的_seq_no_primary_term
:和_seq_no
一样是一个整数,每当primary shard发生重新分配时,比如重启,primary选举等,_primary_term会递增1found
:查询的ID正确那么ture, 如果 Id 不正确,就查不到数据,found字段就是false_source
:文档的原始JSON数据
apt安装
elasticsearch 集群中 master 与 slave 的区别:
master:统计各节点状态信息、集群状态信息统计、索引的创建和删除、索引分配的管理、关闭节点等
slave:从 master 同步数据、等待机会成为 master
apt 安装
1
[root@elk2-ljk src]$dpkg -i elasticsearch-7.11.1-amd64.deb
主要目录:
1
2
3/usr/share/elasticsearch # 主目录
/etc/elasticsearch # 配置文件目录
...修改hosts
1
2
3
4
5[root@elk2-ljk src]$vim /etc/hosts
...
10.0.1.121 elk1-ljk.local
10.0.1.122 elk2-ljk.local
10.0.1.123 elk3-ljk.local修改配置文件 elasticsearch.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15[root@elk2-ljk /]$grep '^[a-Z]' /etc/elasticsearch/elasticsearch.yml
cluster.name: es-cluster # ELK的集群名称,名称相同即属于是同一个集群
node.name: node-2 # 当前节点在集群内的节点名称
path.data: /data/elasticsearch/data # ES数据保存目录
path.logs: /data/elasticsearch/logs # ES日志保存目
bootstrap.memory_lock: true # 服务启动的时候锁定足够的内存,防止数据写入swap
network.host: 10.0.1.122 # 监听本机ip
http.port: 9200 # 监听端口
# 集群中node节点发现列表,最好使用hostname,这里为了方便,使用ip
discovery.seed_hosts: ["elk1-ljk.local", "elk2-ljk.local", "elk3-ljk.local"]
# 集群初始化那些节点可以被选举为master
cluster.initial_master_nodes: ["node-1", "node-2", "node-3"]
gateway.recover_after_nodes: 2 # 一个集群中的 N 个节点启动后,才允许进行数据恢复处理,默认是 1
# 设置是否可以通过正则或者_all 删除或者关闭索引库,默认 true 表示必须需要显式指定索引库名称,生产环境建议设置为 true,删除索引库的时候必须指定,否则可能会误删索引库中的索引库
action.destructive_requires_name: true修改内存限制
1
2
3[root@elk2-ljk src]$vim /usr/lib/systemd/system/elasticsearch.service
...
LimitMEMLOCK=infinity # 无限制使用内存1
2
3[root@elk2-ljk src]$vim /usr/local/elasticsearch/config/jvm.options
-Xms2g # 最小内存限制
-Xmx2g # 最大内存限制创建数据目录并修改属主
1
2[root@elk2-ljk src]$mkdir -p /data/elasticsearch
[root@elk3-ljk src]$chown -R elasticsearch:elasticsearch /data/elasticsearch启动
1
2
3
4
5
6[root@elk1-ljk src]$systemctl start elasticsearch.service # 稍等几分钟
[root@elk1-ljk ~]$curl http://10.0.1.121:9200/_cat/nodes
10.0.1.123 13 96 0 0.14 0.32 0.22 cdhilmrstw - node-3
10.0.1.122 28 97 0 0.01 0.02 0.02 cdhilmrstw * node-2 # master
10.0.1.121 26 96 2 0.13 0.07 0.03 cdhilmrstw - node-1
源码编译
启动总是失败,各种报错,解决不了…
安装 elasticsearch 插件
插件是为了完成不同的功能,官方提供了一些插件但大部分是收费的,另外也有一些开发爱好者提供的插件,可以实现对 elasticsearch 集群的状态监控与管理配置等功能
head 插件
在 elasticsearch 5.x 版本以后不再支持直接安装 head 插件,而是需要通过启动一个服务方式
github 地址:https://github.com/mobz/elasticsearch-head
1 | # git太慢,这里用迅雷下载zip包,然后上传 |
kopf 插件
过时的插件,只支持 elasticsearc 1.x 或 2.x 的版本
cerebro 插件
新开源的 elasticsearch 集群 web 管理程序,需要 java11 或者更高版本
github 地址:https://github.com/lmenezes/cerebro
1 | [root@elk2-ljk src]$unzip cerebro-0.9.3.zip |
监控 elasticsearch 集群状态
1 | [root@elk3-ljk ~]$curl http://10.0.1.122:9200/_cluster/health?pretty=true |
zabbix 添加监控
logstash
官方参考文档:https://www.elastic.co/guide/en/logstash/current/index.html
logstash是一个具有3个阶段的处理管道:输入 –> 过滤器 –> 输出
输入生成事件,过滤器修改数据(日志),输出将数据(日志)发送到其他地方
安装
logstash 依赖 java,可以自己配置 java 环境,如果不配置,logstash 会使用其自带的 openjdk
1 | [root@elk2-ljk src]$dpkg -i logstash-7.11.1-amd64.deb |
命令
1 | [root@elk2-ljk bin]$./logstash --help |
- -n:node name,就是节点的hostname,例如:elk2-ljk.local
- -f:从特定的文件或目录加载logstash配置。如果给定一个目录,该目录中的所有文件将按字典顺序合并,然后作为单个配置文件进行解析。您还可以指定通配符(globs),任何匹配的文件将按照上面描述的顺序加载。如果不指定,默认读取 /etc/logstash/pipelines.yml
- -e:从命令行加载logstash配置,一般不用
- -t:检查配置文件是否合法,重启logstash之前,建议先检查一遍配置文件
- …
插件
logstash 的输入和输出都依赖插件
不同的插件使用不同的配置,但是所有输入插件都支持以下配置选项:
配置项 | 类型 | 说明 |
---|---|---|
add_field |
hash | Add a field to an event |
codec |
codec | 用于输入数据的编解码器。输入编解码器是一种方便的方法,可以在数据进入输入之前对其进行解码,而不需要在Logstash管道中使用单独的过滤器 |
enable_metric |
boolean | Disable or enable metric logging for this specific plugin instance by default we record all the metrics we can, but you can disable metrics collection for a specific plugin. |
id |
string | 唯一的ID,如果没有指定,logstash会自动生成一个,尤其是多个相同类型的插件时,强烈建议配置此项,例如有多个file输入,应当配置此项防止混淆 |
tags |
array | Add any number of arbitrary tags to your event. This can help with processing later. |
type |
string | 类型,例如收集 /var/log/syslog 日志,type可以设置为 “system”;收集网站日志,type可以设置为 “web”。 此项用的较多,一般会根据判断 type 值来进行输出或过滤 |
所有输出插件都支持以下配置选项:
配置项 | 类型 | 说明 |
---|---|---|
codec |
codec | 用于输出数据的编解码器。输出编解码器是一种方便的方法,可以在数据离开输出之前对数据进行编码,而不需要在Logstash管道中使用单独的过滤器 |
enable_metric |
boolean | Disable or enable metric logging for this specific plugin instance. By default we record all the metrics we can, but you can disable metrics collection for a specific plugin. |
id |
string | 唯一的ID,如果没有指定,logstash会自动生成一个,尤其是多个相同类型的插件时,强烈建议配置此项,例如有多个file输出,应当配置此项防止混淆 |
配置
配置:https://www.elastic.co/guide/en/logstash/current/configuration.html
配置文件结构:https://www.elastic.co/guide/en/logstash/current/configuration-file-structure.html
配置文件语法:https://www.elastic.co/guide/en/logstash/current/event-dependent-configuration.html
使用环境变量:https://www.elastic.co/guide/en/logstash/current/environment-variables.html
配置文件示例:https://www.elastic.co/guide/en/logstash/current/config-examples.html
数据发送到es:https://www.elastic.co/guide/en/logstash/current/connecting-to-cloud.html
1 | input { |
多配置文件:
https://www.elastic.co/guide/en/logstash/current/multiple-pipelines.html
https://elasticstack.blog.csdn.net/article/details/100995868
1 | [root@elk2-ljk logstash]$cat pipelines.yml |
测试
标准输入输出
stdin:标准输入插件
output:标准输出插件
1 | [root@elk2-ljk conf.d]$cat /etc/logstash/conf.d/test.conf |
输出到文件
输出到 elasticsearch
kibana
开源的数据分析和可视化平台,可以 对 Elasticsearch 索引中的数据进行搜索、查看、交互操作,可以很方便的利用图表、表格及地图对数据进行多元化的分析和呈现
安装
1 | [root@elk1-ljk src]$tar zxf kibana-7.11.1-linux-x86_64.tar.gz |
因为笔记本的性能问题,将elasticsearch集群缩减为elasticsearch单节点,这导致kibana无法连接到elasticsearch,启动失败。解决办法:将elasticsearch的数据目录清空,然后重启
1 | [root@elk1-ljk data]$systemctl stop elasticsearch.service # 停止elasticsearch |
查看状态
通过 logstash 收集日志
postgresql
SonarQube
SonarQube 是一个用于代码质量管理的开放平台,通过插件机制,SonarQube 可以集成不同的测试
工具,代码分析工具,以及持续集成工具,例如Hudson/Jenkins 等
部署SonarQube
略…
jenkins服务器部署扫描器 sonar-scanner
官方文档: https://docs.sonarqube.org/latest/analysis/scan/sonarscanner/
部署sonar-scanner
顾名思义,扫描器的具体工作就是扫描代码,sonarqube通过调用扫描器sonar-scanner进行代码质量分析
下载地址: https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/
1 | [root@jenkins src]$unzip sonar-scanner-cli-4.6.0.2311.zip |
准备测试代码
1 | [root@jenkins src]$unzip sonar-examples-master.zip ^C |
在源代码目录执行扫描
在 sonar-project.properties 这个文件的目录下,执行 sonar-scanner 即可:
1 | [root@jenkins php-sonar-runner]$ll |
web 看测试结果:
jenkins 执行代码扫描
上面是命令行执行 sonar-scanner 命令进行测试,可以结合 jenkins 进行测试,无非就是将命令写到脚本里,让jenkins 自动执行
Jenkins
官方网站: https://jenkins.io/zh/
Jenkins是开源CI&CD软件领导者, 提供超过1000个插件来支持构建、部署、自动化, 满足任何项目的需要。
部署jenkins
Jenkins 支持各种运行方式,可通过系统包、Docker 或者通过一个独立的 Java 程序
安装 JDK
Jenkins 基于 JAVA 实现,安装 Jenkins 前需要先安装 JDK
1 | [root@jenkins ~]$java -version |
安装 jenkins
1 | $wget https://mirrors.tuna.tsinghua.edu.cn/jenkins/debian-stable/jenkins_2.263.4_all.deb # 清华源下载dep包 |
主要文件:
1 | /etc/default/jenkins |
修改 jenkins 服务的用户
默认jenkins服务使用 jenkins 帐号启动,将文件复制到生产服务器可能会遇到权限问题,需要先su到对应的用户,这里学习环境为了方便,修改为root用户,注意:工作中还是使用 jenkins 普通用户
1 | [root@jenkins src]$vim /etc/default/jenkins |
访问jenkins 页面
创建管理员用户
先创建用户,然后使用刚创建的用户登录
安装插件
Jenkins 是完全插件化的服务,我们想实现什么功能,不是改配置文件,而是下载插件
修改更新源为国内清华源:
1 | [root@jenkins src]$cat /var/lib/jenkins/hudson.model.UpdateCenter.xml |
有以下几种安装插件的方式:
在线安装:官网,也是默认的方式,比较慢
在线安装:清华大学镜像源,sed或者编辑器把 update-center.json 中的Jenkins网址替换为清华源
1
2
3
4# 将:
https://updates.jenkins.io/download/plugins/warnings/5.0.1/warnings.hpi
# 替换为:
https://mirrors-i.tuna.tsinghua.edu.cn/jenkins/plugins/warnings/5.0.1/warnings.hpi离线安装:手动下载插件,然后放到
/var/lib/jenkins/plugins/
,重启 Jenkins 即可通过web界面安装
搜索需要 gitlab(和gitlab相连)和 Blue Ocean(显示信息更加好看)的相关插件并安装
配置 jenkins 权限管理
默认jenkins用户可以执行所有操作,为了更好的分层控制,可以实现基于角色的权限管理,先创建角色和用户,给角色授权,然后把用户管理到角色
安装插件
安装插件:Role-based Authorization Strategy
如果直接下载失败,可以直接清华源下载,将插件放在 /var/lib/jenkins/plugins 目录下
创建新用户
新建 xiaoming 和 xiaogang 两个用户:
更改认证方式
新建任务
通常选择“构建一个自由风格的软件项目”,新建四个任务:test1-job1、test1-job2、test2-job1、test2-job2
创建角色并对角色分配权限
创建全局角色
创建全局读角色,只有读权限创建 item 角色
创建两个 item 角色,test1-role、test2-role,通过正则匹配分配任务
将用户关联到角色
测试普通用户登录
xiaogang 用户只能看到 test1.* 匹配的项目:test1-job1、test1-job2
xiaoming 用户只能看到 test2.*匹配的项目:test2-job1、test2-job2
jenkins 邮箱配置
邮件发送到组邮件地址,组邮件会转发到组内所有人
配置jenkins到gitlab非交互式拉取代码
需要配置 ssh key (公钥)和 凭据(私钥)
配置 ssh key
实现 jenkins 服务器到 gitlab 服务器的基于密钥的验证,可以让 jenkins 连接到 gitlab 执行操作
- 在 jenkins 服务上生成 ssh key
- 在 gitlab 服务器上添加上面生成的 ssh key
- 在 jenkins 服务器上测试 ssh key
配置凭据
凭据就是私钥,clone项目的时候,可选择不同的凭据(私钥),只要他在gitlab上配置了key(公钥),如果不指定,就以当前用户的私钥作为凭据去clone项目
管理凭据:系统管理 -> 安全 -> Manage Credentials
构建触发器
构建触发器(webhook),有的人称为钩子,实际上是一个HTTP回调,其用于在开发人员向 gitlab 提交代码后能够触发 jenkins 自动执行代码构建操作
以下为新建一个开发分支,只有在开发人员向开发(develop)分支提交代码的时候才会触发代码构建,而向主分支提交的代码不会自动构建,需要运维人员手动部署代码到生产环境
生产中千万不要用,测试一般也不用,都是由开发登陆自己的账号,只能看到自己的job,然后开发自己手动部署
项目关联
用于多个 job 相互关联,需要串行执行多个 job 的场景,不过这个操作基本不用
例如:克隆代码、编译代码、停止tomcat、部署代码、启动tomcat 这些操作使用不同的job执行,这些job需要串行执行
视图
job 太多需要分类
视图可用于归档 job 进行分组显示,比如将一个业务的 job 放在一个视图显示,最常用的是列表视图
jenkins 分布式
在众多Job的场景下,单台jenkins master同时执行代码clone、编译、打包及构建,其性能可能会出现瓶颈从而会影响代码部署效率,影响jenkins官方提供了jenkins分布式构建,将众多job分散运行到不同的jenkins slave节点,大幅提高并行job的处理能力
配置slave节点环境
slave节点需要配置与master一样的基础运行环境,另外也要创建与master相同的数据目录,因为脚本中调用的路径只有相对于master的一个路径,此路径在master与各node节点必须保持一致
1 | # 配置java环境 |
添加slave节点
可以限制项目只能在指定的节点中执行:
流水线 pipline
流水线 pipline 是 Jenkins 中的头等公民,官方介绍;https://www.jenkins.io/zh/doc/book/pipeline/
本质上,Jenkins 是一个自动化引擎,它支持许多自动模式。 流水线向Jenkins中添加了一组强大的工具, 支持用例 简单的持续集成到全面的CD流水线。通过对一系列的相关任务进行建模, 用户可以利用流水线的很多特性:
- 代码:流水线是在代码中实现的,通常会检查到源代码控制,使团队有编辑,审查和迭代他们的交付流水线的能力
- 可持续性:jenkins的重启或者中断后不影响已经执行的Pipline Job
- 支持暂停:pipline可以选择停止并等待人工输入或批准后再继续执行
- 可扩展:通过groovy的编程更容易的扩展插件
- 并行执行:通过groovy脚本可以实现step,stage间的并行执行,和更复杂的相互依赖关系
流水线概念
流水线 pipeline
流水线是用户定义的一个CD流水线模型 。流水线的代码定义了整个的构建过程, 他通常包括构建, 测试和交付应用程序的阶段
节点 node
每个 node 都是一个 jenkins 节点,可以是 jenkins master 也可以是 jenkins agent,node 是执行 step 的具体服务器
阶段 stage
一个 pipline 可以划分为若干个 stage,每个 stage 都是一个操作,比如 clone 代码、代码编译、代码测试和代码部署,阶段是一个逻辑分组,可以跨多个 node 执行
步骤 step
step 是 jenkins pipline 最基本的操作单元,从在服务器创建目录到构建容器镜像,由各类 Jenkins 插件提供实现,例如: sh “make”
流水线语法概述
对 Jenkins 流水线的定义被写在一个文本文件中: Jenkinsfile,该文件可以被提交到项目的源代码的控制仓库。 这是”流水线即代码”的基础;将CD 流水线作为应用程序的一部分,像其他代码一样进行版本化和审查。
Jenkinsfile 能使用两种语法进行编写,声明式和脚本化。
声明式和脚本化的流水线从根本上是不同的。 声明式流水线的是 Jenkins 流水线更近的特性。
声明式流水线基础
在声明式流水线语法中, pipeline
块定义了整个流水线中完成的所有的工作。
示例:
1 | Jenkinsfile (Declarative Pipeline) |
- pipeline 是声明式流水线的一种特定语法,他定义了包含执行整个流水线的所有内容和指令的 “block” 。
- agent是声明式流水线的一种特定语法,它指示 Jenkins 为整个流水线分配一个执行器 (在节点上)和工作区。
- stage 是一个描述 stage of this Pipeline的语法块。在 Pipeline syntax 页面阅读更多有关声明式流水线语法的
stage
块的信息。如 above所述, 在脚本化流水线语法中,stage 块是可选的。 - steps 是声明式流水线的一种特定语法,它描述了在这个 stage 中要运行的步骤。
- sh 是一个执行给定的shell命令的流水线 step (由 Pipeline: Nodes and Processes plugin提供) 。
- junit 是另一个聚合测试报告的流水线 step (由 JUnit plugin提供)。
- node 是脚本化流水线的一种特定语法,它指示 Jenkins 在任何可用的代理/节点上执行流水线 (和包含在其中的任何阶段)这实际上等效于 声明式流水线特定语法的
agent
。
脚本化流水线基础
…
pipline 语法
官方文档:https://www.jenkins.io/zh/doc/book/pipeline/syntax/
pipline job
创建pipline job
测试简单pipline job运行
1 | node { |
立即构建,查看输出信息:
自动生成拉取代码的pipline脚本
案例
git命令
说明
1 | master分支:稳定的分支 |
master分支是上线的代码,develop是开发中的代码,lujinkai、xiaoming等是开发人员分支,开发在自己的分支里面写代码,然后下班前提交、合并到develop分支,等项目开发、测试完,最后再合并到master分支,然后上线
常用命令
1 | [root@kafka2 testproject]$git branch # 查看本地分支 |
流程
在 gitlab 创建个人分支 lujinkai
克隆 master 分支到本地
1
[root@dev ~]$git clone git@gitlab.ljk.local:testgroup/testproject.git
切换到自己分支
1
[root@dev ~]$git checkout lujinkai
将develop分支拉下来和个人分支合并
1
2
3
4[root@dev ~]$git pull origin develop
# git pull <远程主机名> <远程分支名>:<本地分支名>
# 如果与当前分支合并,则冒号后面的部分可以省略以上命令是把远程分支develop拉下来,然后合并到当前分支lujinkai,或者可以拆分成以下步骤:
1
2
3
4git checkout develop # 切换到分支develop
git pull origin develop # 远程develop拉下来和本地develop合并
git checkout lujinkai # 切换到分支lujinkai
git merge develop --no-commit # 将本地分支develop和当前分支lujinkai合并开发代码
下班了,需要提交代码,但是在提交之前最好再执行一遍上一步,因为在你写代码的过程中,develop分支可能有其他人提交
1
[root@dev ~]$git pull origin develop
添加文件到本地缓存区
1
[root@dev ~]$git add . # . 表示当前目录下的所有文件
提交内容到本地分支上
1
git commit -m "注释, 提交说明"
上传本地分支到远程分支
1
2
3
4git push
# 默认提交到本地分支对应的远程分支,或者可以显式指定
git push origin lujinkai
之后每天 3 - 9 步骤走一遍
GitLab
DevOps
DevOps 是Development和Operations的组合,也就是开发和运维的简写
什么是持续集成(CI-Continuous integration)
持续集成是指多名开发者在开发不同功能代码的过程当中,可以频繁的将代码行合并到一起并切相互不影响工作
什么是持续部署(CD-continuous deployment)
是基于某种工具或平台实现代码自动化的构建、测试和部署到线上环境以实现交付高质量的产品,持续部署在某种程度上代表了一个开发团队的更新迭代速率
什么是持续交付(Continuous Delivery)
持续交付是在持续部署的基础之上,将产品交付到线上环境,因此持续交付是产品价值的一种交付,是产品价值的一种盈利的实现
GitLab
GitLab 和 GitHub一样属于第三方基于Git开发的作品,免费且开源,与Github类似,可以注册用户,任意提交你的代码,添加SSHKey等等。不同的是,GitLab是可以部署到自己的服务器上,简单来说可把 GitLab 看作个人版的GitHub
Git在每个用户都有一个完整的服务器,然后在有一个中央服务器,用户可以先将代码提交到本 地,没有网络也可以先提交到本地,然后在有网络的时候再提交到中央服务器,这样就大大方便了开发者,而相比CVS和SVN都是集中式的版本控制系统,工作的时候需要先从中央服务器获 取最新的代码,改完之后需要提交,如果是一个比较大的文件则需要足够快的网络才能快速提交完成,而使用分布式的版本控制系统,每个用户都是一个完整的版本库,即使没有中央服务器也可以提交代码或者回滚,最终再把改好的代码提交至中央服务器进行合并即可
SVN
每次提交的文件都单独保存, 即按照文件的提交时间区分不同的版本, 保存至不同的逻辑存储区域,后期恢复时候直接基于之前版本恢复。
Git
Gitlab 与 SVN的数据保存方式不一样,gitlab 虽然 也会在内部 对数据进行逻辑划分保存,但是当后期提交的数据如和之前交的数据没有变化,其就直接 快照之前的文件 ,而不是再将文件重新上传一份再保存一遍,这样既节省 了空间又加快了代码提交速度 。
git 缓存区与工作区等概念
- 工作区 :clone 的代码或者开发自己编写代码文件所在 的目录 ,通常是代码所在的一 个服务的目录名称
- 暂存区 :用于存储在工作区中对代码进行修改后的文件所保存的地方,使用
git add
添加 - 本地仓库: 用于提交存储在工作区和暂存区中改过的文件地方,使
git commit
提交 - 远程仓库 :多个开发人员共同协作提交代码的仓库,即 gitlab 服务器
Gitlab部署与使用
测试环境:内存4G以上
生产环境:建议CPU2C,内存8G,磁盘10G以上配置,和用户数有关
清华源 centos7:https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/
清华源 ubuntu18.04:https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/ubuntu/pool/bionic/main/g/gitlab-ce/
安装
1 | [root@gitlab src]$dpkg -i gitlab-ce_13.8.4-ce.0_amd64.deb # 得等一会 |
配置
1 | # 需要配置gitlab服务器地址和邮件地址 |
gitlab 相关目录:
1 | /etc/gitlab #配置文件目录 |
初始化服务
修改完配置文件要执行此操作
1 | [root@gitlab src]$gitlab-ctl reconfigure |
常用命令:
1 | gitlab-rails #用于启动控制台进行特殊操作,如修改管理员密码、打开数据库控制台( gitlab-rails dbconsole)等 |
gitlab web 界面
username:root
注意,使用域名访问需要做hosts
关闭账号注册
默认情况下可以直接注册账号,一般都关闭此功能,由管理员统一注册用户
修改邮箱地址
新添加的邮箱不是默认的通知邮箱,下面是设置新邮箱为默认邮箱
设置完后,需要重新登录才能生效,然后可以把之前的默认邮箱删除
创建gitlab账户
创建成功后,需要查看邮件,在邮件链接中重置密码
创建组
使用管理员root创建组,一个组里面可以有多个项目分支,可以将开发添加到组里,再进行设置权限,不同的组对应公司不同的开发项目或者服务模块,不同的组中添加不同的开发人员帐号,即可实现对开发设置权限的管理
管理员创建项目
有三种方式:创建空项目、使用模板、导入项目
将用户添加到组
更多权限:https://docs.gitlab.com/ee/user/permissions.html
gitlab仓库developer权限无法push
默认develop权限无法merge和push到master分支的,可以修改:
在这里,也可以设置也可以保护其他分支
在项目中新建测试页面
使用 陆东生 用户登录,新建分支,继承自master:
git客户端测试clone项目
ssh认证
1
2ssh-keygen -t rsa
cat ~/.ssh/id_rsa.pub # 将公钥复制到给gitlabclone
1
git clone git@gitlab.ljk.local:testgroup/testproject.git
git 常用命令
运维常用:git pull
、git clone
、git reset
gitlab数据备份恢复
备份前必须先停止gitlab两个服务
1
2[root@gitlab ~]$gitlab-ctl stop unicorn
[root@gitlab ~]$gitlab-ctl stop sidekiq备份数据
1
2
3
4
5
6
7
8
9[root@gitlab ~]$gitlab-rake gitlab:backup:create
...
Warning: Your gitlab.rb and gitlab-secrets.json files contain sensitive data
and are not included in this backup. You will need these files to restore a backup.
Please back them up manually.
# 以上warning表示gitlab.rb和gitlab-secrets.json两个文件包含敏感信息。未被备份到备份文件中。需要手动备份,这两个文件位于 /etc/gitlab
[root@gitlab ~]$gitlab-ctl start # 备份完成后启动gitlab备份数据位于
/var/opt/gitlab/backups/
1
2[root@gitlab ~]$ls /var/opt/gitlab/backups/
1614392268_2021_02_27_13.8.4_gitlab_backup.tar查看要恢复的文件
1
2
3/var/opt/gitlab/backups/ # Gitlab数据备份目录,需要使用命令备份的
/var/opt/gitlab/nginx/conf # nginx配置文件
/etc/gitlab/gitlab.rb # gitlab配置文件删除项目和用户信息
执行恢复
1
2
3
4
5# 恢复前先停止两个服务
[root@gitlab ~]$gitlab-ctl stop unicorn
[root@gitlab ~]$gitlab-ctl stop sidekiq
# 恢复时指定备份文件的时间部分,不需要指定文件的全名
[root@gitlab ~]$gitlab-rake gitlab:backup:restore BACKUP=备份文件名恢复后再将之前停止的两个服务启动
1
gitlab-ctl start
gitlab汉化
虽然不推荐,但是有需求,基于第三方开发爱好者实现
汉化包地址: https://gitlab.com/xhang/gitlab
1 | git clone https://gitlab.com/xhang/gitlab.git |
常见的代码部署方式
- 蓝绿部署
- 金丝雀发布
- 滚动发布
- A/B测试
Nexus
Nexus 是一个强大的 Maven 仓库管理器,它极大地简化了自己内部仓库的维护和外部仓库的访问
官方下载:https://help.sonatype.com/repomanager3/download/download-archives---repository-manager-3
部署Nexus
下载、解压、创建用户
1
2
3
4
5
6
7
8[root@nexus src]$useradd -r -s /sbin/nologin nexus # 创建nexus用户
[root@nexus src]$tar zxf nexus-3.29.2-02-unix.tar.gz
[root@nexus src]$mv nexus-3.29.2-02 /usr/local/nexus
[root@nexus src]$mv sonatype-work/ /usr/local/
[root@nexus src]$cd /usr/local/
[root@nexus local]$chown -R nexus:nexus ./nexus/
[root@nexus local]$chown -R nexus:nexus ./sonatype-work/
[root@nexus local]$echo 'nexus - nofile 65536' >> /etc/security/limits.confService启动文件,官方提供
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18[root@nexus ~]$cat /lib/systemd/system/nexus.service
[Unit]
Description=nexus service
After=network.target
[Service]
Type=forking
LimitNOFILE=65536
ExecStart=/usr/local/nexus/bin/nexus start
ExecStop=/usr/local/nexus/bin/nexus stop
User=nexus
Restart=on-abort
TimeoutSec=600
[Install]
WantedBy=multi-user.target
[root@nexus ~]$systemctl start nexus.service # 需要几分钟时间启动设置向导:
验证默认仓库
- Hosted:本地仓库,通常我们会部署自己的构件到这一类型的仓库,比如公司的第三方库
- Proxy:代理仓库,它们被用来代理远程的公共仓库,如 maven 中央仓库(官方仓库)
- Group:仓库组,用来合并多个 hosted/proxy 仓库,当你的项目希望在多个repository使用资源时就不需要多次引用了,只需要引用一个 group 即可
构建私有 yum 仓库
配置仓库的数据目录
仓库配置,以 zabbix 为例
centos 7.x 配置 yum 仓库
1
2
3
4
5
6
7[root@c71 ~]$vim /etc/yum.repos.d/zabbix.repo
[root@c71 ~]$cat /etc/yum.repos.d/zabbix.repo
[zabbix-nexus]
name=zabbix
baseurl=http://10.0.1.103:8081/repository/zabbix-proxy/
enabled=1
gpgcheck=0测试:
下载过的包会缓存下来
数据备份
Nexus 中普通数据信息和元数据是分开存储的,普通数据是保存在 blob 中,而元数据保存在数据库中,所以在备份的时候必须同时进行备份普通数据和元数据,才能在后期恢复数据的时候保证数据的最终完整性
数据量太大,而且不影响用户业务,数据备份没什么意义
常见端口
默认 tcp
端口 | 服务 | 备注 |
---|---|---|
20 | FTP | 源连接,20或更高TCP端口1024以上 |
21 | FTP | 侦听端口 |
69 / udp | FTP | |
22 | ssh | |
23 | telnet | |
25 | smtp | 不开启 tls 验证 |
465 | smtp | 开启 tls 验证 |
53 | dns | |
69 | tftp | |
161 | snmp | |
8080 | vue、tomcat | |
8443 | tomcat | |
80 | http | |
443 | https | |
953 | rndc | 利用rndc工具可以实现管理DNS功能 |
6443 | k8s api server | |
3306 | mysql | |
6379 | redis | |
8005 | tomcat | tomcat 默认监听8005端口,这是一个后门,可通过这个端口关闭 tomcat 服务 |
1100 | JMX | |
10050 | zabbix agent | |
10051 | zabbix server | |
5672 | RabbitMQ | 消费者访问的端口 |
15672 | RabbitMQ | web 管理端口 |
25672 | RabbitMQ | 集群状态通信端口 |
2181 | Zookeeper | Zookeeper会监听这个端口,接受客户端的访问请求 |
2888 | Zookeeper | LF数据同步端口 |
3888 | Zookeeper | LF选举端口 |
9092 | kafka | |
2049 | nfsd | |
873 | rsync | |
67 | DHCP Server | |
68 | DHCP Client(ipv4) | |
546 | DHCP Client(ipv6) | |
ActiveMQ
ActiveMQ 是一种开源的基于 JMS(Java Message Servie)规范的一种消息中间件的实现,采用 Java 开发,设计目标是提供标准的、面向消息的、能够跨越多语言和多系统的应用集成消息通信中间件
kafka
阿里云兼容 kafka 消息队列:https://www.aliyun.com/product/ons
Kafka 是一种高吞吐量的分布式发布订阅消息系统,其具备分布式功能、并可以结合 zookeeper 可以实现动态扩容,用于构建实时数据管道和流应用程序
它具有水平可伸缩性、容错性、快速性
常用消息队列对比:
kafka 优势
kafka为什么性能高?
- 顺序写入,kafka数据写入磁盘,不是保存在内存,默认保存168小时
- kafka通过O(1)的磁盘数据结构提供消息的持久化,即使数以TB的消息存储也能够保持长时间的稳定性能
- O(1)是最低的时间复杂度,哈希算法就是典型的 O(1) 时间复杂度,无论数据规模多大,都可以在一次计算后找到目标
- 高吞吐量,即使是非常普通的硬件 Kafka 也可以支持每秒数百万的消息
- 支持通过 Kafka 服务器分区消息,可以将数据保存到不同的服务器
- 支持 Hadoop 并行数据加载
kafka 角色
broker:中文直译“中间人”,实际就是消息代理,是生产者和消费者中间代理保存消息的中转站,集群中每个 kafka 的 broker 都有唯一的 id,由 server.properties 中的 broker.id 指定,可以把每个kafka节点抽象的看成是一个broker,也可以把整个kafka集群抽象的看成是一个broker
topic:话题,生产者和消费者监听同一个topic,生产者往里写消息,消费者从里面读消息
partition:分区,也叫分片,物理上的概念,每个分区对应一个文件夹,topic 可以将其消息分片储存,提高性能,然后每个分片做多个副本,保证高可用。
注意:分片数量不要超过kafka节点数量;副本数量也不要超过kafka节点数量;
- leader:分片副本的角色,主
- follower:分片副本的角色,从
对于一个分片,其副本只有一个是leader,其他的都是follower,leader不能和follower在同一个节点,这样就失去了高可用的意义
高可用:当一个节点故障,其他的follower会选举出一个作为leader
1
2
3
4上图中 topic1 分了两片:topic1-part1、topic1-part2;
上图中 topic2 只有一片:topic2-part1
上图中 topic1 和 topic2 的分片都做了三个副本:topicX-part1、topicX-part2、topicX-part3Producer:生产者,负责发布消息到 Kafka broker
Consumer:消费者,每个 consumer 属于一个特定的 consuer group(若不指定 group name 则属于默认 group),使用 consumer high level API 时,同一 topic 的一条消息只能被同一个 consumer group内的一个 consumer 消费,但多个 consumer group 可同时消费这一消息
kafka 和 zookeeper 的关系:
kafka 自身无法实现集群和高可用,kafka 依赖 zookeeper 实现集群和高可用
zookeeper 和 kafka 都可以存储数据,zookeeper储存单个数据在1MB以内,只用来保存服务的元数据,不保存业务信息
- Broker 依赖于 Zookeeper,每个 Broker 的 id 和 Topic、Partition 这些元数据信息都会写入 Zookeeper 的 ZNode 节点中
- Consumer 依赖于 Zookeeper,Consumer 在消费消息时,每消费完一条消息,会将产生的 offset 保存到 Zookeeper 中,下次消费在当前 offset 往后继续消费。注意:kafka0.9 之前 Consumer 的 offset 存储在 Zookeeper 中,kafka0,9 以后 offset存储在本地
- Partition 依赖于 Zookeeper,Partition 完成 Replication 备份后,选举出一个Leader,这个是依托于 Zookeeper 的选举机制实现的
kafka 部署
1 | kakfa1.ljk.cn:10.0.1.101 |
快速部署:http://kafka.apache.org/quickstart
安装 zookeeper,这里就不配置集群了,安装单机zookeeper
安装 kafka
1
2
3
4
5
6# kafka 下载页面:http://kafka.apache.org/downloads
[root@kakfa1 src]$tar -xzf kafka_2.13-2.7.0.tgz
[root@kakfa1 src]$mv kafka_2.13-2.7.0 /usr/local/kafka
[root@kakfa1 src]$cd /usr/local/
[root@kakfa1 local]$scp -r ./kafka/ 10.0.1.102:/usr/local
[root@kakfa1 local]$scp -r ./kafka/ 10.0.1.103:/usr/local配置 kafka
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[root@kakfa1 ~]$vim /etc/hosts
...
10.0.1.101 kafka1.ljk.cn
10.0.1.102 kafka2.ljk.cn
10.0.1.103 kafka3.ljk.cn
10.0.1.101 zk1.ljk.cn # zookeeper地址域名解析
[root@kakfa1 local]$vim kafka/config/server.properties
21 broker.id=1 # 每个 broker 在集群中的唯一标识,正整数
31 listeners=PLAINTEXT://kafka1.ljk.cn:9092
60 log.dirs=/usr/local/kafka/kafka-logs # kakfa用于保存数据的目录,所有的消都会存储在该目录当中
65 num.partitions=1 # 设置创建新topic的默认分区数量
103 log.retention.hours=168 # 设置kafka中消息保留时间,默认为168小时,即7天
# 指定连接的zookeeper的地址,zk中存储了broker的元数据信息,如果zk是集群,多个zk地址使用逗号分割,这里为了方便,使用单机zookeeper,推荐使用域名,如果使用ip可能无法启动,不知道为什么
123 zookeeper.connect=zk1.ljk.cn:2181
126 zookeeper.connection.timeout.ms=6000 # 设置连接zookeeper的超时时间,默认6s
[root@kakfa2 local]$vim kafka/config/server.properties
21 broker.id=2
31 listeners=PLAINTEXT://10.0.1.102:9092
60 log.dirs=/usr/local/kafka/kafka-logs
103 log.retention.hours=168
123 zookeeper.connect=zk1.ljk.cn:2181
126 zookeeper.connection.timeout.ms=6000
[root@kakfa3 local]$vim kafka/config/server.properties
21 broker.id=3
31 listeners=PLAINTEXT://10.0.1.103:9092
60 log.dirs=/usr/local/kafka/kafka-logs
103 log.retention.hours=168
123 zookeeper.connect=zk1.ljk.cn:2181
126 zookeeper.connection.timeout.ms=6000启动 kafka
1
2
3
4
5
6
7[root@kakfa1 bin]$pwd
/usr/local/kafka/bin
[root@kakfa1 bin]$./kafka-server-start.sh -daemon ../config/server.properties
[root@kakfa2 bin]$./kafka-server-start.sh -daemon ../config/server.properties
[root@kakfa3 bin]$./kafka-server-start.sh -daemon ../config/server.properties
测试 kafka 读写数据
http://kafka.apache.org/quickstart
创建 topic
1 | [root@kakfa1 bin]$./kafka-topics.sh --create \ |
- –create:创建topic
- –zookeeper:指定zk地址,虽然配置文件中已经指定了,但是命令行还要指定
- –partitions:指定一个topic包含几个partition,就是对topic分片,分片可以提高性能,但是一般不用分片,保持默认值1就可以,如果分片,也不要超过节点的数量
- –replication-factor:指定partition的副本数量,kafka实现高可用全靠partition的副本,如果设置3,则一个partition就存储3份,注意不是4份
- –topic:指定名称
假设集群有4个broker,一个topic有4个partition,每个partition有3个副本。下图是每个broker上的副本分配情况:
验证 topic
1 | [root@kakfa1 bin]$./kafka-topics.sh --describe \ |
说明:lujinkai 这个 topic 有三个分区分别为 0、1、2,分区 0 的 leader 是 3(broker.id),分区 0 有三个副本,并且状态都为 lsr(ln-sync,表示可以参加选举成为 leader)
获取所有 topic
1 | [root@kakfa1 bin]$./kafka-topics.sh --list --zookeeper zk1.ljk.cn:2181 |
测试发送消息
1 | [root@kakfa1 bin]$./kafka-console-producer.sh --topic lujinkai \ |
测试获取消息
1 | [root@kafka2 bin]$./kafka-console-consumer.sh --topic lujinkai \ |
- –bootstrap-server:kafak集群的地址,实际只写一个地址也行
- –from-beginning:从最开始的数据进行消费
删除 topic
1 | [root@kakfa1 bin]$./kafka-topics.sh --delete \ |
ZooKeeper
ZooKeeper 是一个分布式服务框架,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:命名服务、状态同步、配置中心、集群管理等
命名服务
命名服务是分布式系统最基本的公共服务之一。在分布式系统中,被命名的实体通常可以是集群中的机器、提供的服务地址或远程对象等,这些我们都可以统称它们为名字(Name),其中较为常见的就是一些分布式服务框架(如 RPC、RMI)中的服务地址列表,通过使用命名服务,客户端应用能够根据指定名字来获取资源的实体、服务地址和提供者的信息等
状态同步
每个节点除了存储数据内容和 node 节点状态信息之外,还存储了已经注册的APP 的状态信息,当有些节点或 APP 不可用,就将当前状态同步给其他服务
配置中心
现在我们大多数应用都是采用的是分布式开发的应用,搭建到不同的服务器上,可以使用 ZooKeeper 来实现配置中心,ZooKeeper 采用的是推拉相结合的方式: 客户端向服务端注册自己需要关注的节点,一旦该节点的数据发生变更,那么服务端就会向相应的客户端发送 Watcher 事件通知,客户端接收到这个消息通知后,需要主动到服务端获取最新的数据
集群管理
所谓集群管理,包括 集群监控 与 集群控制 两部分,前者侧重对集群运行时状态的收集,后者则是对集群进行操作与控制
- 客户端如果对 ZooKeepe 的一个数据节点注册 Watcher 监听,那么当该数据节点的内容或是其子节点列表发生变更时,ZooKeeper 服务器就会向订阅的客户端发送变更通知
- 对在 ZooKeeper 上创建的临时节点,一旦客户端与服务器之间的会话失效,该临时节点也就被自动除
1 | Watcher(事件监听器):Zookeeper中很重要的特性。Zookeeper允许用户在指定节点上注册一些Watcher,并且在一些特定事件触发的时候,ZooKeeper服务端会将事件通知到感兴趣的客户端上去,该机制是 Zookeeper实现分布式协调服务的重要特性 |
0、生产者启动
1、生产者注册至 zookeeper
2、消费者启动并订阅频道
3、zookeeper 通知消费者事件
4、消费者调用生产者
5、监控中心负责统计和监控服务状态
ZooKeeper 单机安装
ZooKeeper 依赖 Java 环境,要求 JDK1.7 及以上
配置java环境
1
2
3
4[root@zk1 ~]$java -version
java version "1.8.0_271"
Java(TM) SE Runtime Environment (build 1.8.0_271-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.271-b09, mixed mode)部署 ZooKeeper
官网下载地址:https://archive.apache.org/dist/zookeeper/
注意,要下载带 bin 的包,不带 bin 的只是源码包,不包含必要的 jar 包1
2
3
4
5
6
7
8
9
10
11
12[root@zk1 src]$tar zxf apache-zookeeper-3.5.9-bin.tar.gz
[root@zk1 src]$mv apache-zookeeper-3.5.9-bin
[root@zk1 src]$mv apache-zookeeper-3.5.9-bin /usr/local/zookeeper
[root@zk1 src]$cd /usr/local/zookeeper/conf/
[root@zk1 conf]$cp zoo_sample.cfg zoo.cfg
[root@zk1 conf]$grep ^[a-Z] ./zoo.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/tmp/zookeeper
clientPort=2181
admin.serverPort=8180 # AdminServer监听的端口,默认8080,因为tomcat默认端口也是8080,为了避免冲突,这里修改为8180关于AdminServer:https://zookeeper.apache.org/doc/r3.5.0-alpha/zookeeperAdmin.html#sc_adminserver_config
启动 ZooKeeper
1
2
3
4
5
6
7# zkServer.sh 用于启动、重启、停止 ZooKeeper
[root@zk1 bin]$pwd
/usr/local/zookeeper/bin
[root@zk1 bin]$./zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED验证 Zookeeper 状态
1
2
3
4
5[root@zk1 bin]$./zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost. Client SSL: false.
Mode: standalone
ZooKeeper 集群简介
集群架构:
集群角色:
Zookeeper 集群部署
整个集群中只要有超过集群数量一半的 zookeeper 工作只正常的,那么整个集群对外就是可用的
1 | zk1.ljk.cn:10.0.1.101 |
各个节点安装 zookeeper,参考上面单机部署,但是先不要启动
各个节点创建数据目录
1
2
3
4
5
6
7
8[root@zk1 ~]$cd /usr/local/zookeeper/
[root@zk1 zookeeper]$mkdir data
[root@zk2 ~]$cd /usr/local/zookeeper/
[root@zk2 zookeeper]$mkdir data
[root@zk3 ~]$cd /usr/local/zookeeper/
[root@zk3 zookeeper]$mkdir data各个节点配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15[root@zk1 conf]$grep ^[a-Z] ./zoo.cfg
tickTime=2000 # 心跳检测周期,单位为毫秒
initLimit=10 # leader与follower初始连接心跳次数,即多少个2000毫秒
syncLimit=5 # leader与follower连接完成之后,后期检测发送和应答的心跳次数,即该follower在5*2000毫秒内不能与leader进行通信,那么此follower将被视为不可用
dataDir=/usr/local/zookeeper/data # 自定义的zookeeper保存数据的目录
clientPort=2181 # 客户端连接Zookeeper服务器的端口,Zookeeper会监听这个端口,接受客户端的访问请求
maxClientCnxns=128 # 单个客户端IP可以和zookeeper保持的连接数
autopurge.snapRetainCount=3 # 保存快照的数量,启用后ZooKeeper只保存最新的几个快照,其余的会自动清除,最新快照和相应的事务日志分别保留在dataDir和dataLogDir中,默认值为 3。最小值为 3
autopurge.purgeInterval=1 # 自动清理日志和快照文件的频率,单位小时,默认0,不开启自动清理
server.1=10.0.1.101:2888:3888 # server.服务器编号=服务器IP:LF数据同步端口:LF选举端口
server.2=10.0.1.102:2888:3888 # hostname也可以,只要dns能解析到就行
server.3=10.0.1.103:2888:3888
[root@zk1 conf]$scp ./zoo.cfg 10.0.1.102:/usr/local/zookeeper/conf
[root@zk1 conf]$scp ./zoo.cfg 10.0.1.103:/usr/local/zookeeper/conf集群id
1
2
3
4
5[root@zk1 data]$echo 1 > myid
[root@zk2 data]$echo 2 > myid
[root@zk3 data]$echo 3 > myid启动 zookeeper
1
2
3
4
5[root@zk1 bin]$./zkServer.sh start
[root@zk2 bin]$./zkServer.sh start
[root@zk3 bin]$./zkServer.sh start验证 Zookeeper 状态
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17[root@zk1 bin]$./zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost. Client SSL: false.
Mode: follower # follower
[root@zk2 bin]$./zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost. Client SSL: false.
Mode: follower # follower
[root@zk3 bin]$./zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost. Client SSL: false.
Mode: leader # leader
zookeeper 集群选举过程
节点角色状态:
1 | LOOKING # 寻找 Leader 状态,处于该状态需要进入选举流程 |
选举 ID:
1 | ZXID # zookeeper transaction id,每个改变Zookeeper状态的操作都会形成一个对应的zxid |
zookeeper 数据增删改查
任意一台zookeeper节点进行以下操作:
1 | [root@zk1 bin]$./zkCli.sh -server 10.0.1.102:2181 |
zookeeper 客户端 ZooInspector
Linux:https://github.com/zzhang5/zooinspector
Windows:https://www.cnblogs.com/weiyiming007/p/11951591.html
- 下载、解压、双击
build/zookeeper-dev-ZooInspector.jar
- 连接成功
RabbitMQ
阿里云消息队列:https://www.aliyun.com/product/ons
RabbitMQ 基于 erlang 语言开发,具有高并发优点、支持分布式具有消息确认机制、消息持久化机制,消息可靠性和集群可靠性高,简单易用、运行稳定、跨平台、多语言开源
Broker:接收和分发消息的应用,RabbitMQ Server 就是 Message Broker
Virtual host:出于多租户和安全因素设计的,把 AMQP 的基本组件划分到一个虚拟的分组中,类似于网络中的 namespace 概念,当多个不同的用户使用同一个 RabbitMQ server 提供的服务时,可以划分出多个 vhost,每个用户在自己的 vhost创建 exchange/queue 等
Connection:publisher/consumer 和 broker 之间的 TCP 连接。
Channel:如果每一次访问 RabbitMQ 都建立一个 Connection,在消息量大的时候建立 TCP Connection 的开销将是巨大的,效率也较低。Channel 是在 connection 内部建立的逻辑连接,如果应用程序支持多线程,通常每个 thread 创建单独的channel 进行通讯,AMQP method 包含了 channel id 帮助客户端和 message broker 识别 channel,所以 channel 之间是完全隔离的。Channel 作为轻量级的 Connection 极大减少了操作系统建立 TCP connection 的开销。
Exchange:message 到达 broker 的第一站,根据分发规则,匹配查询表中的 routing key,分发消息到 queue 中去。常用的类型有:direct (point-to-point), topic (publish-subscribe) and fanout (multicast)。
Queue:消息最终被送到这里等待 consumer 取走,先进先出,可以持久化到磁盘节点服务器
Binding:exchange 和 queue 之间的虚拟连接,binding 中可以包含 routing key。Binding 信息被保存到 exchange 中的查询表中,用于 message 的分发依据。
RabbitMQ 中的生产者消费者示例
生产者发送消息到 broker server(RabbitMQ),在 Broker 内部,用户创建Exchange/Queue,通过Binding 规则将两者联系在一起,Exchange 分发消息,根据类型/binding 的不同分发策略有区别,消息最后来到 Queue 中,等待消费者取走
RabbitMQ 单机部署
快速部署示例:https://www.rabbitmq.com/install-debian.html#apt-bintray-quick-start
主机名解析
1
2
3
4
5
6
7[root@mq1 ~]$hostname
mq1.ljk.cn
[root@mq1 ~]$hostname -I
10.0.1.101
[root@mq1 ~]$vim /etc/hosts
...
10.0.1.101 mq1.ljk.cn mq1时间原因,选择 apt 安装,直接执行以下脚本
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#!/bin/sh
## If sudo is not available on the system,
## uncomment the line below to install it
# apt-get install -y sudo
sudo apt-get update -y
## Install prerequisites
sudo apt-get install curl gnupg -y
## Install RabbitMQ signing key
curl -fsSL https://github.com/rabbitmq/signing-keys/releases/download/2.0/rabbitmq-release-signing-key.asc | sudo apt-key add -
## Install apt HTTPS transport
sudo apt-get install apt-transport-https
$distribution='bionic' # ubuntu18.04
sudo tee /etc/apt/sources.list.d/bintray.rabbitmq.list <<EOF
## 默认安装最新版本的 erlang 23.x,可以指定版本例如:erlang-22.x
deb https://dl.bintray.com/rabbitmq-erlang/debian $distribution erlang
## Installs latest RabbitMQ release
deb https://dl.bintray.com/rabbitmq/debian $distribution main
EOF
## Update package indices
sudo apt-get update -y
## Install rabbitmq-server and its dependencies
sudo apt-get install rabbitmq-server -y --fix-missing安装成功
1
2
3
4
5
6
7
8
9
10
11
12
13
14[root@zabbix src]$systemctl status rabbitmq-server.service
● rabbitmq-server.service - RabbitMQ broker
Loaded: loaded (/lib/systemd/system/rabbitmq-server.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2021-02-21 02:41:45 UTC; 1h 26min ago
Main PID: 5992 (beam.smp)
Status: "Initialized"
Tasks: 22 (limit: 2289)
CGroup: /system.slice/rabbitmq-server.service
├─5992 /usr/lib/erlang/erts-11.1.8/bin/beam.smp -W w -MBas ageffcbf -MHas ageffcbf -MBlmbcs 512 -MHlmbcs 512 -MMmcs 30 -P 1048576 -t 5000000 -stbt db -zd
├─6013 erl_child_setup 32768
├─6039 /usr/lib/erlang/erts-11.1.8/bin/epmd -daemon
├─6058 inet_gethost 4
└─6059 inet_gethost 4
...插件管理
https://www.rabbitmq.com/management.html
开启 web 管理界面1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20[root@zabbix src]$which rabbitmq-plugins
/usr/sbin/rabbitmq-plugins
[root@zabbix src]$rabbitmq-plugins enable rabbitmq_management
Enabling plugins on node rabbit@mq1:
rabbitmq_management
The following plugins have been configured:
rabbitmq_management
rabbitmq_management_agent
rabbitmq_web_dispatch
Applying plugin configuration to rabbit@mq1...
The following plugins have been enabled:
rabbitmq_management
rabbitmq_management_agent
rabbitmq_web_dispatch
started 3 plugins.
# 5672 消费者访问的 端口
# 15672 web 管理端口
# 25672 集群状态通信端口1
2
3
4
5
6
7
8
9
10
11
12
13
14
15[root@mq1 ~]$rabbitmqctl list_users
Listing users ...
user tags
guest [administrator] # guest是初始化的用户,账号密码都是guest,但是只能使用localhost访问
[root@mq1 ~]$rabbitmqctl add_user ljk 123456 # 添加用户
Adding user "ljk" ...
Done. Don't forget to grant the user permissions to some virtual hosts! See 'rabbitmqctl help set_permissions' to learn more.
[root@mq1 ~]$rabbitmqctl set_user_tags ljk administrator # 用户授权
Setting tags for user "ljk" to [administrator] ...
[root@mq1 ~]$rabbitmqctl list_users
Listing users ...
user tags
ljk [administrator] # 授权成功
guest [administrator]使用账号 ljk,密码 123456,成功登录web管理界面:
登录之后,我们很少进行更改,主要是查看rabbitmq的运行状态
RabbitMQ 集群部署
- 普通模式:创建好 RabbitMQ 集群之后的默认模式
所有的mq节点保存相同的元数据,即消息队列,但队列里的数据仅保存一份,消费者从A节点拉取消息,如果消息在B节点,那么B会将消息发送给A节点,然后消费者就能拉取到数据了
缺点:单点失败 - 镜像模式:把需要的队列做成镜像队列
在普通模式的基础上,增加一些镜像策略,消息实体会主动在镜像节点间同步,而不是在 consumer 取数据时临时拉取,解决了单点失败的问题,但是性能下降,增加集群内部网络消耗一个
队列想做成镜像队列,需要先设置 policy,然后客户端创建队列的时候,rabbitmq 集群根据“队列名称”自动设置是普通集群模式或镜像队列
推荐设计架构:
在一个 rabbitmq 集群里,有 3 台或以上机器,其中 1 台使用磁盘模式(数据保存到内存和磁盘),其它节点使用内存模式(数据只保存到内存),使用磁盘模式的节点,作为数据备份使用
Ubuntu 1804 安装集群版 RabbitMQ
1 | 10.0.1.101 mq1.ljk.cn mq1 |
Rabbitmq 的集群是依赖于 erlang 的集群来工作的,所以必须先构建起 erlang 的集群环境,而 Erlang 的集群中各节点是通过一个 magic cookie 来实现的,这个cookie 存放在 /var/lib/rabbitmq/.erlang.cookie 中,文件是 400 的权限,所以必须保证各节点 cookie 保持一致,否则节点之间就无法通信
各节点安装RabbitMQ并安装插件,参考上面单机部署
各服务器关闭 RabbitMQ
1
2
3[root@mq1 ~]$systemctl stop rabbitmq-server.service
[root@mq2 ~]$systemctl stop rabbitmq-server.service
[root@mq3 ~]$systemctl stop rabbitmq-server.service在 mq1 同步.erlang.cookie 至其他两台服务器
1
2
3[root@mq1 ~]$cd /var/lib/rabbitmq/
[root@mq1 rabbitmq]$scp .erlang.cookie 10.0.1.102:/var/lib/rabbitmq
[root@mq1 rabbitmq]$scp .erlang.cookie 10.0.1.103:/var/lib/rabbitmq各服务器启动 RabbitMQ
1
2
3[root@mq1 ~]$systemctl start rabbitmq-server.service
[root@mq2 ~]$systemctl start rabbitmq-server.service
[root@mq3 ~]$systemctl start rabbitmq-server.service查看当前集群状态
1
2
3[root@mq1 ~]$rabbitmqctl cluster_status
[root@mq2 ~]$rabbitmqctl cluster_status
[root@mq3 ~]$rabbitmqctl cluster_status创建 RabbitMQ 集群:mq1、mq2作为内存节点,mq3作为磁盘节点
1
2
3
4[root@mq1 ~]$rabbitmqctl stop_app #停止 app 服务
[root@mq1 ~]$rabbitmqctl reset #清空元数据
[root@mq1 ~]$rabbitmqctl join_cluster rabbit@mq3 --ram #将mq1添加到集群中,并成为内存节点,不加--ram默认是磁盘节点
[root@mq1 ~]$rabbitmqctl start_app #启动 app 服务1
2
3
4[root@mq2 ~]$rabbitmqctl stop_app
[root@mq2 ~]$rabbitmqctl reset
[root@mq2 ~]$rabbitmqctl join_cluster rabbit@mq3 --ram
[root@mq2 ~]$rabbitmqctl start_app将集群设置为镜像模式,任意节点执行以下命令
1
[root@mq1 ~]$rabbitmqctl set_policy ha-all "#" '{"ha-mode":"all"}'
查看集群状态
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62[root@mq1 ~]$rabbitmqctl cluster_status
Cluster status of node rabbit@mq1 ...
Basics
Cluster name: rabbit@mq3.ljk.cn
Disk Nodes
rabbit@mq3
RAM Nodes
rabbit@mq1
rabbit@mq2
Running Nodes
rabbit@mq1
rabbit@mq2
rabbit@mq3
Versions
rabbit@mq1: RabbitMQ 3.8.12 on Erlang 23.2.5
rabbit@mq2: RabbitMQ 3.8.12 on Erlang 23.2.5
rabbit@mq3: RabbitMQ 3.8.12 on Erlang 23.2.5
Maintenance status
Node: rabbit@mq1, status: not under maintenance
Node: rabbit@mq2, status: not under maintenance
Node: rabbit@mq3, status: not under maintenance
Alarms
(none)
Network Partitions
(none)
Listeners
Node: rabbit@mq1, interface: [::], port: 15672, protocol: http, purpose: HTTP API
Node: rabbit@mq1, interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communication
Node: rabbit@mq1, interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0
Node: rabbit@mq2, interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communication
Node: rabbit@mq2, interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0
Node: rabbit@mq2, interface: [::], port: 15672, protocol: http, purpose: HTTP API
Node: rabbit@mq3, interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communication
Node: rabbit@mq3, interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0
Node: rabbit@mq3, interface: [::], port: 15672, protocol: http, purpose: HTTP API
Feature flags
Flag: drop_unroutable_metric, state: enabled
Flag: empty_basic_get_metric, state: enabled
Flag: implicit_default_bindings, state: enabled
Flag: maintenance_mode_status, state: enabled
Flag: quorum_queue, state: enabled
Flag: user_limits, state: enabled
Flag: virtual_host_metadata, state: enabled
RabbitMQ 常用命令
创建 vhost
1
2[root@mq1 ~]$rabbitmqctl add_vhost test
Adding vhost "test" ...列出所有 vhost
1
2
3
4
5[root@mq1 ~]$rabbitmqctl list_vhosts
Listing vhosts ...
name
/
test列出所有队列
1
2
3[root@mq1 ~]$rabbitmqctl list_queues
Timeout: 60.0 seconds ...
Listing queues for vhost / ...删除指定 vhost
1
2[root@mq1 ~]$rabbitmqctl delete_vhost test
Deleting vhost "test" ...添加账户 jack 密码为 123456
1
2
3[root@mq1 ~]$rabbitmqctl add_user jack 123456
Adding user "jack" ...
Done. Don't forget to grant the user permissions to some virtual hosts! See 'rabbitmqctl help set_permissions' to learn more.更改用户密码
1
2[root@mq1 ~]$rabbitmqctl change_password jack 654321
Changing password for user "jack" ...设置 jack 用户对 test 的 vhost 有读写权限,三个点为配置正则、读和写
1
[root@mq1 ~]$rabbitmqctl set_permissions -p test jack ".*" ".*" ".*"
RabbitMQ API
RabbitMQ Cluster Monitor
集群状态监控
1 | #!/bin/env python |
内存使用监控
1 | # cat rabbitmq_memory.py |
MQ
MQ:Message Queuing,消息队列
Message Queue 的需求由来已久,在 19 世纪 80 年代金融交易中,美国高盛等公司采用 Teknekron 公司的产品,当时的 Message queuing 软件叫做(the informationbus(TIB),后来 TIB 被电信和通讯等公司采用,然后路透社收购了 Teknekron 公司,再然后 IBM 公司开发了 MQSeries,并且微软也开发了Microsoft Message Queue(MSMQ),但是这些商业 MQ 供应商的问题是厂商锁定及使用价格高昂,于是 2001 年,Java Message queuing 试图解决锁定和交互性的问题,但对应用来说反而更加麻烦了,于是 2004 年,摩根大通和 iMatrix 开始着手 Advanced MessageQueuing Protocol (AMQP)开放标准的开发,2006 年,AMQP 规范发布,2007年,Rabbit 技术公司基于 AMQP 标准开发的 RabbitMQ1.0 发布。
消息队列的目的是实现各个APP之间的通信(包括跨网咯通信),APP基于MQ实现消息的发送和接收,实现应用程序之间的通信,实现业务的解耦的异步机制
消息队列作为高并发系统的核心组件之一,能够帮助业务系统解构,提升开发效率和系统稳定性。消息队列主要具有以下优势:
- 削峰填谷:主要解决瞬时写压力大于应用服务能力导致消息丢失、系统奔溃等问题
- 系统解耦:解决不同重要程度、不同能力级别系统之间依赖导致一死全死
- 提升性能:当存在一对多调用时,可以发一条消息给消息系统,让消息系统通知相关系统
- 蓄流压测:线上有些链路不好压测,可以通过堆积一定量消息再放开来压测
目前主流的消息队列软件有 RabbitMQ、kafka、ActiveMQ、RocketMQ 等,还有小众的消息队列软件如ZeroMQ、Apache Qpid 等
dubbo
微服务这个概念是从单体服务(单体应用)演化而来的
微服务:micro server,把单体服务拆分成多个小服务,这些小服务就是微服务,每个小服务运行在单独的运行环境,早期一般用虚拟机,现在都是容器(docker + k8s)
- 微服务落地:容器,k8s + docker
- 微服务发现对方:注册中心、服务发现,zookeeper
- 微服务之间相互调用:API
- 微服务扩容:服务治理,k8s实现服务编排
- 微服务监控:监控微服务的API等
- 微服务代码升级和回滚:CI / CD jenkings + gitlab
- 微服务日志查看:ELK,统一收集和展示
服务是相互调用的,一个服务可以即是服务提供方,同时又是服务消费方
微服务框架
这个开发比较关注微服务框架,作为运维,了解即可
spring boot
spring cloud
dubbo
阿里云微服务:https://promotion.aliyun.com/ntms/act/edasdubbo.html
dubbo 官网:https://dubbo.apache.org/zh/
阿里云 dubbo 简介:https://help.aliyun.com/document_detail/99299.html
dubbo 架构
https://dubbo.apache.org/zh/docs/v2.7/user/preface/architecture/
节点角色说明:
节点 | 角色说明 |
---|---|
Provider |
暴露服务的服务提供方 |
Consumer |
调用远程服务的服务消费方 |
Registry |
服务注册与发现的注册中心 |
Monitor |
统计服务的调用次数和调用时间的监控中心 |
Container |
服务运行容器 |
调用关系说明:
- 服务容器负责启动,加载,运行服务提供者。
- 服务提供者在启动时,向注册中心注册自己提供的服务。
- 服务消费者在启动时,向注册中心订阅自己所需的服务。
- 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
- 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
- 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
Dubbo 架构具有以下几个特点,分别是连通性、健壮性、伸缩性、以及向未来架构的升级性。
连通性
- 注册中心负责服务地址的注册与查找,相当于目录服务,服务提供者和消费者只在启动时与注册中心交互,注册中心不转发请求,压力较小
- 监控中心负责统计各服务调用次数,调用时间等,统计先在内存汇总后每分钟一次发送到监控中心服务器,并以报表展示
- 服务提供者向注册中心注册其提供的服务,并汇报调用时间到监控中心,此时间不包含网络开销
- 服务消费者向注册中心获取服务提供者地址列表,并根据负载算法直接调用提供者,同时汇报调用时间到监控中心,此时间包含网络开销
- 注册中心,服务提供者,服务消费者三者之间均为长连接,监控中心除外
- 注册中心通过长连接感知服务提供者的存在,服务提供者宕机,注册中心将立即推送事件通知消费者
- 注册中心和监控中心全部宕机,不影响已运行的提供者和消费者,消费者在本地缓存了提供者列表
- 注册中心和监控中心都是可选的,服务消费者可以直连服务提供者
健壮性
- 监控中心宕掉不影响使用,只是丢失部分采样数据
- 数据库宕掉后,注册中心仍能通过缓存提供服务列表查询,但不能注册新服务
- 注册中心对等集群,任意一台宕掉后,将自动切换到另一台
- 注册中心全部宕掉后,服务提供者和服务消费者仍能通过本地缓存通讯
- 服务提供者无状态,任意一台宕掉后,不影响使用
- 服务提供者全部宕掉后,服务消费者应用将无法使用,并无限次重连等待服务提供者恢复
伸缩性
- 注册中心为对等集群,可动态增加机器部署实例,所有客户端将自动发现新的注册中心
- 服务提供者无状态,可动态增加机器部署实例,注册中心将推送新的服务提供者信息给消费者
升级性
当服务集群规模进一步扩大,带动IT治理结构进一步升级,需要实现动态部署,进行流动计算,现有分布式服务架构不会带来阻力。下图是未来可能的一种架构:
节点角色说明:
节点 | 角色说明 |
---|---|
Deployer |
自动部署服务的本地代理 |
Repository |
仓库用于存储服务应用发布包 |
Scheduler |
调度中心基于访问压力自动增减服务提供者 |
Admin |
统一管理控制台 |
Registry |
服务注册与发现的注册中心 |
Monitor |
统计服务的调用次数和调用时间的监控中心 |
示例
生产者示例
zk 配置:https://dubbo.apache.org/zh/docs/v2.7/user/references/registry/zookeeper/
注册中心除了zookeeper,还有其他方式:Nacos、Multicast、Redis、Simple
1 | [root@provider1 src]$tar zxf dubbo-demo-provider-2.1.5-assembly.tar.gz # 开发写的包 |
消费者示例
1 | [root@consumer1 src]$tar zxf dubbo-demo-consumer-2.1.5-assembly.tar.gz # 开发写的包 |
以上示例是一个provider,如果是多个provider,则consumer会轮询读取
zookeeper 验证
dubbo admin
基于 zookeeper 发现并管理 provider 和 consumer
1 | [root@kakfa1 webapps]$systemctl stop tomcat.service # 先关闭tomcat,否则自动解压会出错 |
这个 duboadmin 版本比较老,如果需要新版的 dubboadmin,需要手动编译
微服务编译
https://dubbo.apache.org/zh/docs/v2.7/dev/build/
maven
编译c、c++,使用 make、cmake,编译java,使用maven
maven是一个项目管理工具,可以对Java项目进行构建、解决打包依赖等
POM:Project Object Model,项目对象模型,是 Maven 工程的基本工作单元,是一个 XML 文件,包含了项目的基本信息,用于描述项目如何构建,声明项目依赖等,在执行任务或目标时,Maven 会在当前目录中查找 pom 文件,通过读取 pom 文件获取所需的配置信息,然后执行目标
Pom 文件中可以指定以下配置:
1 | 项目依赖 |
部署Maven:
1 | # 官方文档:http://maven.apache.org/install.html |
Maven打包命令:
进入到包含有“pom.xml”的路径,执行:
1
mvn clean install package
有的时候受到测试的干扰,导致无法正在进行编译,这时候可以选择跳过测试:
1
2
3
4mvn clean install package -Dmaven.test.skip=true
-Dmaven.test.skip=true # 跳过测试,并且不编译测试下的源代码;
-DskipTests # 不执行测试,但是会进行测试代码的编译;如果需要编译的代码异常庞大,需要考虑对编译环境做一些处理,提高编译效率
1
2
3mvn -T 4 clean install package -Dmaven.test.skip=true # 启动多线程编译
mvn -T 2C clean install package -Dmaven.test.skip=true # 分配编译的CPU个数
mvn clean install package -Dmaven.test.skip=true -Dmaven.compile.fork=true # 启用多线程编译所有的 Maven 都是建立在 JVM 上的,所以进行编译的时候还需要考虑 JVM 参数优化
1
2
3# bin/mvn是shell文件,配置参数:“MAVEN_OPTS”
$ export MAVEN_OPTS="-Xmx6g -Xms6g" >> /etc/profile
$ . /etc/profile
示例
以 dubbo admin 为例:https://github.com/apache/dubbo-admin/blob/develop/README_ZH.md
下载代码:
1
$ git clone https://github.com/apache/dubbo-admin.git
指定注册中心地址
1
2
3
4
5
6
7$ vim dubbo-admin-server/src/main/resources/application.properties
...
# centers in dubbo2.7
admin.registry.address=zookeeper://10.0.1.101:2181
admin.config-center=zookeeper://10.0.1.101:2181
admin.metadata-report.address=zookeeper://10.0.1.101:2181
...构建:
1
$ mvn clean package -Dmaven.test.skip=true
启动:
1
2
3
4$ mvn --projects dubbo-admin-server spring-boot:run
# 或
$ cd dubbo-admin-distribution/target;
$ java -jar dubbo-admin-0.2.0.jar --server.port=8080 # 注意端口冲突访问:浏览器访问 http://10.0.1.101:8080
zabbix_proxy.conf
1 | # vim /apps/zabbix_proxy/etc/zabbix_proxy.conf |
1 | ProxyMode=0 # proxy模式,0:主动模式;1:被动模式 |
zabbix_agentd.conf
大部分同 zabbix_server.conf,以下是不同的参数
1 | EnableRemoteCommands=0 # 0/1,是否允许执行远程命令 |
zabbix_server.conf
1 | # zabbix_server.conf |
以上所有参数的设置,可以先设置一个较小的保守的值,然后通过测试,一点点调整,最终优化到合适的值
Zabbix
监控服务介绍
逻辑布局
整体布局
常见的监控服务
开源监控软件:cacti、naglos、zabbix、smokeping、open-falcon等
Cacti
官网:https://www.cacti.net/
github:https://github.com/Cacti/cacti
1 | Cacti是基于LAMP平台展现的网络流量监测及分析工具,通过SNMP技术或自定义脚本从目标设备/主机获取监控指标信息;其次进行数据存储,调用模板将数据存到数据库,使用rrdtool存储和更新数据,通过rrdtool绘制结果图形;最后进行数据展现,通过Web方式将监控结果呈现出来,常用于在数据中心监控网络设备 |
缺点:只针对物理设备、虚拟机这样有固定IP地址的设备,不适合容器
Nagios
1 | Nagios用来监视系统和网络的开源应用软件,利用其众多的插件实现对本机和远端服务的监控,当被监控对象发生异常时,会及时向管理员告警,提供一批预设好的监控插件,用户可以之间调用,也可以自定义Shell脚本来监控服务,适合各企业的业务监控,可通过Web页面显示对象状态、日志、告警信息,分层告警机制及自定义监控相对薄弱 |
缺点:报警机制比较简单,无法实现分组报警、递归报警等功能
SmokePing
官网地址:https://oss.oetiker.ch/smokeping/
1 | Smokeping是一款用于网络性能监测的开源监控软件,主要用于对IDC的网络状况,网络质量,稳定性等做检测,通过rrdtool制图方式,图形化地展示网络的时延情况,进而能够清楚的判断出网络的即时通信情况 |
可以监测全国各地连接到网站的网速,类似 站长之家 的某些测速功能
Open-falcon
官网:https://www.open-falcon.org/
github:https://github.com/XiaoMi/open-falcon
文档:https://book.open-falcon.org/zh_0_2/contributing.html
1 | 小米公司开源出来的监控软件open-falcon(猎鹰),监控能力和性能较强 |
夜莺
1 | 滴滴出品,一款经过大规模生产环境验证的、分布式高性能的运维监控系统,基于 Open-falcon 二次开发 |
Zabbix
1 | Zabbix是一个企业级解决方案,支持实时监控数千台服务器,虚拟机和网络设备,采集百万级监控指标,适用于任何IT基础架构、服务、应用程序和资源的解决方案 |
缺点:zabbix使用mysql,数据库部分容易成为瓶颈
Prometheus
针对容器环境的开源监控软件
商业监控解决方案
- 监控宝:https://www.jiankongbao.com/ 推荐使用
- 听云:https://www.tingyun.com/
Zabbix使用场景及系统概述
https://www.zabbix.com/cn/features
使用场景
系统概述
主要功能
数据采集、问题检测、可视化、告警 & 修复、安全 & 认证、轻松部署、自动发现、分布式监控、Zabbix API
数据采集
所有监控系统的工作原理都类似,都需要采集被监控对象的数据
周期性时序数据
1 | - 主机/对象:服务器、路由器、交换机、存储、防火墙、IP、PORT、URL、自定义监控对象… |
数据采集方式:
- zabbix-agent 采集本机数据,然后发送给 zabbix-proxy
- zabbix-proxy 将数据发送给 zabbix-server
注意:不是实时转发,zabbix-proxy 也搭配 mysql,负责临时存储数据 - zabbix-server 只和zabbix-proxy保持连接即可,将数据存储到 mysql,结束采集
如果不安装(或者无法安装)agent客户端,可以使用特定的协议进行数据采集:
1 | - SNMP:适用于路由器、交换机等网络设备 |
数据存储
监控数据存储系统
1 | - SQL: MySQL/MariaDB(Zabbix) |
数据类型
1 | - 历史数据: 每个监控项采集到的每个监控值,查询时可能会造成数据库负载过大,开发和测试也会查看 |
阈值
可按照预定义的阈值等级实现分层报警,可以80%,不过要考虑基数,Zabbix用的好不好,就看阈值设置的好不好,需要慢慢优化
告警机制
email、短信、微信、语音、故障自治愈(zabbix通知服务器重启,需事先写好脚本,针对物理机和虚拟机)
初级运维 –> 中级运维/高级运维 –> 架构师 –> 总监 –> CTO
1 | host (host groups) <- templates # 从模板继承告警配置 |
数据展示
1 | - zabbix web:基于nginx+php |
Zabbix 规划及部署
目前最新的LTS版本是5.0,5.0和之前版本有明显区别,但是文档还是英文的,所以目前学习还是以4.0为准
下载页面:https://www.zabbix.com/cn/download
规划
- 数据库:CPU和磁盘IO一定要快,内存最好32G,磁盘要大,zabbix的监控数据会远大于业务数据量
- zabbix server:zabbix server 直接装在物理机
- CPU:16核
- 磁盘:RAID10、500G
- 内存:8G(监控几十个节点),16G(监控几百个节点),32G(监控两千个节点)
实验:
部署环境:服务器系统 ubuntu 18.04.5 / Centos 7.x
主机类型 | IP地址 |
---|---|
zabbix server | 10.0.1.21 |
zabbix 主动代理 | 10.0.1.22 |
zabbix 被动代理 | 10.0.1.23 |
mysql master | 10.0.1.24 |
mysql slave | 10.0.1.25 |
web server1 | 10.0.1.26 |
web server2 | 10.0.1.27 |
yum/apt 安装
Install Zabbix repository
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15$wget https://repo.zabbix.com/zabbix/4.0/ubuntu/pool/main/z/zabbix-release/zabbix-release_4.0-3+bionic_all.deb
$ls
zabbix-release_4.0-3+bionic_all.deb
$dpkg -c zabbix-release_4.0-3+bionic_all.deb #查看dep包的内容
...
#zabbix.list:官方提供的源
-rw-r--r-- root/root 118 2019-07-30 16:34 ./etc/apt/sources.list.d/zabbix.list
...
$dpkg -i zabbix-release_4.0-3+bionic_all.deb #安装dep包
$vim /etc/apt/sources.list.d/zabbix.list #修改zabbix源
#deb http://repo.zabbix.com/zabbix/4.0/ubuntu bionic main
#deb-src http://repo.zabbix.com/zabbix/4.0/ubuntu bionic main
deb https://mirrors.aliyun.com/zabbix/zabbix/4.0/ubuntu bionic main #替换为阿里云的源
deb-src https://mirrors.aliyun.com/zabbix/zabbix/4.0/ubuntu bionic main
$apt update安装Zabbix server,Web前端,agent
1
2
3[root@zabbix-server ~]$apt install zabbix-server-mysql zabbix-frontend-php zabbix-agent
[root@zabbix-server ~]$systemctl disable mysql.service # 数据库单独装,把自带的禁用掉
[root@zabbix-server ~]$systemctl stop mysql.service安装、配置 mysql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15[root@mysql-master ~]$apt search mysql-server # 确保mysql版本不低于5.7
[root@mysql-master ~]$apt install mysql-server mysql-client
[root@mysql-master ~]$mysql -uroot -p
# 创建 zabbix_server 数据库
mysql> create database zabbix_server character set utf8 collate utf8_bin;
# 创建 zabbix_server 用户
mysql> create user zabbix_server@'10.0.%.%' identified by '123456';
mysql> grant all privileges on zabbix_server.* to zabbix_server@'10.0.%.%';
[root@mysql-master ~]$vim /etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
bind-address = 0.0.0.0 # 修改监地址,默认监听127.0.0.1,修改为0.0.0.0
[root@mysql-master ~]$systemctl restart mysql.service数据库初始化:
1
[root@zabbix-server ~]$zcat /usr/share/doc/zabbix-server-mysql*/create.sql.gz | mysql -uzabbix_server -p123456 -h10.0.1.24 zabbix_server
为 Zabbix server 配置数据库
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23# 编辑配置文件 /etc/zabbix/zabbix_server.conf
[root@zabbix-server ~]$vim /etc/zabbix/zabbix_server.conf
DBHost=10.0.1.24
DBName=zabbix_server
DBUser=zabbix_server
DBPassword=123456
[root@zabbix-server ~]$grep '^[a-Z]' /etc/zabbix/zabbix_server.conf
LogFile=/var/log/zabbix/zabbix_server.log
LogFileSize=0
PidFile=/var/run/zabbix/zabbix_server.pid
SocketDir=/var/run/zabbix
DBHost=10.0.1.24
DBName=zabbix_server
DBUser=zabbix_server
DBPassword=123456
SNMPTrapperFile=/var/log/snmptrap/snmptrap.log
Timeout=4
AlertScriptsPath=/usr/lib/zabbix/alertscripts
ExternalScripts=/usr/lib/zabbix/externalscripts
FpingLocation=/usr/bin/fping
Fping6Location=/usr/bin/fping6
LogSlowQueries=3000为Zabbix前端配置PHP
1
2
3
4
5
6
7# 编辑配置文件 /etc/zabbix/apache.conf
[root@zabbix-server ~]$vim /etc/zabbix/apache.conf
# php_value date.timezone Europe/Riga
php_value date.timezone Asia/Shanghai # 修改时区
# 重启 zabbix 和 apache 服务
[root@zabbix-server ~]$systemctl restart zabbix-server zabbix-agent apache2浏览器访问 http://10.0.1.21/zabbix,然后根据提示一步步配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14Database type MySQL
Database server 10.0.1.24
Database port 3306
Database name zabbix_server
Database user zabbix_server
Database password 123456
Zabbix server 10.0.1.21 # ip 和 主机名 均可
Zabbix server port 10051
Zabbix server name zabbix_server # 这里随便写
# 如果以后更改配置,需要修改两个文件
# /etc/zabbix/zabbix_server.conf
# /usr/share/zabbix/conf/zabbix.conf.php # 生成的配置在此文件中默认的账号 Admin,密码 zabbix
默认只能显示英文,所以需要汉化
1
2
3
4
5
6
7
8# 安装简体中文语言环境
[root@zabbix-server ~]$apt install language-pack-zh*
# 增加中文语言环境变量
[root@zabbix-server ~]$vim /etc/environment
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"
LANG="zh_CN.UTF-8" # 添加此行
# 重新设置本地配置
[root@zabbix-server ~]$dpkg-reconfigure locales1
2# 配置好后,需要重启apacha、php-fpm
[root@zabbix-server ~]$systemctl restart apache2 php-fpm但是,还有部分页面乱码,需要更换默认的字体包:
从 windows(位于 C:\Windows\Fonts) 系统中挑一个顺眼的字体包,上传到服务器
1
2
3
4
5
6
7
8
9
10
11
12
13[root@zabbix-server fonts]$pwd
/usr/share/zabbix/assets/fonts # 注意目录
[root@zabbix-server fonts]$ls | tr ' ' \n
graphfont.ttf # 默认字体
simhei.ttf # 刚上传的 黑体
simkai.ttf # 刚上传的 楷体,这两个都可以,其他的不一定可以
[root@zabbix-server include]$pwd
/usr/share/zabbix/include # 注意目录
# 修改默认字体为黑体,楷体也可以
[root@zabbix-server include]$sed -i 's/graphfont/simkai/' defines.inc.php
[root@zabbix-server include]$systemctl restart apache2 php-fpm编译安装
官方文档:https://www.zabbix.com/documentation/4.0/zh/manual/installation/install
把 apt 安装的 zabbix-server、zabbix-proxy、zabbix-agent 等软件的 service 文件拷贝出来备用,然后恢复快照
具体详见脚本 script-apt
注意:
server 和 proxy 不能安装在同一台主机
如果是centos,安装依赖参考:
1
yum install gcc libxml2-devel net-snmp net-snmp-devel curl curl-devel php phpbcmath php-mbstring mariadb mariadb-devel -y
汉化操作需要手动执行,脚本没有实现这个功能,不要忘记重启php-fpm
Zabbix 监控入门基础
- 了解业务结构
- 监控
- 业务优化
zabbix 概念
配置
模板:
- 键值(key):最基础的指令,每个键值表示一项数据,比如
system.hostname
表示主机名,zabbix内置了 一些,如果不够用,可以自定义(需要在zabbix_agentd.conf中指定) - 监控项(item):主要是由 键值 + 更新周期 组成
- 应用集:对监控项分组,功能类似的监控项的合集
- 触发器:据监控项的返回值对比预先设置的阈值,触发器会触发动作
- 表达式:功能一般选择 last
- 图形:
- 自动发现:
- web场景/web检测:
- 键值(key):最基础的指令,每个键值表示一项数据,比如
主机群组
- 1
主机
- d
维护
- w
动作
动作:动作由触发器触发,触发动作选项用来限制触发器的范围,一般选主机群组,只有该主机群组中的主机的触发器可以触发动作,多个触发条件可以选择和/或的关系
操作:动作的操作会调用报警媒介,发送到指定用户,毕竟数据库出问题,需要发给DBA,发给网络工程师也不管用
默认操作步骤持续时间:发送周期,一般配置 60s,即60秒发一次
默认标题 和 消息内容:用{}包裹的变量是宏,zabbix所有内置的宏,参考:官方文档
1
2
3
4# 示例:
{ALERT.SENDTO} # 报警脚本参数,值来自于用户报警媒介配置,可能是邮件、手机号等等
{ALERT.SUBJECT} # 报警脚本参数,默认值由动作配置
{ALERT.MESSAGE} # 报警脚本参数,默认值由动作配置
恢复操作:解决完报警信息后,恢复信息也要发送
更新操作:
关联事件
- 4
自动发现:添加/移除/更改元素时执行自动操作
https://www.zabbix.com/cn/auto_discovery
https://www.zabbix.com/documentation/4.0/zh/manual/discovery/network_discovery- 网络发现:定期扫描、发现设备类型,IP,状态,运行时间/停机时间等,并采取预定义的操作。
- 低级别发现(LLD):自动为设备上不同元素创建监控项,触发器和图形。
- 主动agent自动注册 使用Zabbix agent自动开始监控新设备
服务
- 2
管理
- agent代理程序:即 proxy
- 报警媒介类型:把报警信息通知给用户的方式,可以配置邮件、短信、微信(通过脚本实现)等方式,以qq邮件为例,将qq邮箱和用户关联起来,发生报警后,qq邮箱作为发件人将报警信息发送到用户的邮箱中
- 用户
zabbix server
官方文档:https://www.zabbix.com/documentation/4.0/zh/manual/concepts/server
zabbix server 是整个 zabbix 软件的核心程序。
zabbix server是所有配置、统计和操作数据的中央存储中心,也是zabbix监控系统的告警中心。
基本的 zabbix server 的功能分解成为三个不同的组件。他们是:zabbix server、web前端和数据库。
zabbix proxy
官方文档:https://www.zabbix.com/documentation/4.0/zh/manual/concepts/proxy
zabbix proxy 代表 zabbix server 采集监控数据,减轻 zabbix server 的 cpu 和 io 开销。
zabbix proxy 从受监控设备采集监控数据,先将数据缓存到本机数据库,然后传输到所属的 zabbix server。
zabbix agent
官方文档:https://www.zabbix.com/documentation/4.0/zh/manual/concepts/agent
proxy 和 agent 都是代理,但前者是 服务端,后者是客户端
zabbix agent 部署在被监控目标上,以主动监控本地资源和应用程序(硬盘、内存、处理器统计信息等)。
zabbix agent 收集本地的操作信息并将数据报告给 zabbix server 用于进一步处理。一旦出现异常 (例如硬盘空间已满或者有崩溃的服务进程),zabbix server 会主动警告管理员指定机器上的异常。
zabbix agents 的极高效率缘于它可以利用本地系统调用来完成统计数据的采集。
默认监听在 10051 端口。
sender
主要用于测试的命令,例如:如果 Zabbix agent 收集不到数据,可以用这个命令发一下测试数据,看一下是 Zabbix agent 的问题还是网络问题
get
主要用于测试的命令,可以与 Zabbix agent 进行通信,并从 Zabbix agent 那里获取所需的信息
注意:只有 zabbix_agentd.conf 中 Server 配置的 ip 才能从该主机上 get 到数据
监控tomcat
所有的监控,配置步骤都是一样的:
- 创建主机
- 给主机添加模板
主动与被动监控模式
主动和被动都是相对 agent 来说的,被动模式配置简单,所以默认是被动模式
- 被动检查:zabbix server(或 proxy)向 agent 要数据,agent 才工作,否则就不工作
- 主动检查:agent 从 zabbix server 获取监控项列表,然后定期采集数据,主动发送给 zabbix server
被动模式
被动模式下,zabbix server会根据主机关联的模板中的监控项和数据采集间隔时间,周期性的打开随机端口并向zabbix agent服务器的10050发起tcp连接,然后发送获取监控项数据的指令,即zabbix server发送什么指令,zabbix agent就收集什么数据,zabbix server什么时候发送zabbix agent就什么时候采集,zabbix server不发送zabbix agent就闲着,所以zabbix agent也不用关心其监控项和数据采集周期间隔时间
优点就是配置简单,缺点是会加大 zabbix server 的工作量,在数百甚至数千台服务器的环境下会导致 zabbix server 需要轮训向每个 zabbix agent 发送数据采集指令,如果 zabbix server 负载很高还会导致不能及时获取到最新数据
主动模式
主动模式下,zabbix agent 主动向 zabbix server 的10051端口发起 tcp 连接请求(zabbix agent配置文件中指定zabbix server的IP或者主机名),获取到自己的监控项和数据采集周期等信息,然后再周期性的采集指定的数返回给 zabbix server
主动模式可以有效减轻 zabbix server 的压力,推荐使用主动模式
配置主动模式:
修改 zabbix agent 配置文件
1
2
3
4
5
6
7
8
9
10# zabbix_agentd.conf
PidFile=/usr/local/zabbix/run/zabbix_agentd.pid
LogFile=/tmp/zabbix_agentd.log
LogFileSize=0
Server=10.0.1.21 # 被动模式下,指定zabbix server的ip,如果全部监控项都是主动模式,则可注释此项
StartAgents=3
ServerActive=10.0.1.21 # 重点,开启主动模式,指定zabbix server的ip
Hostname=10.0.1.26 # zabbix agent本机的ip
Timeout=30
Include=/usr/local/etc/zabbix_agentd.conf.d/*.conf生成主动模式模板
完全克隆zabbix内置的Template OS Linux模板,命名为:Template OS Linux-active,修改监控项的类型,可以单独改,也可以批量更新最后把主动模式模板添加到主机上
zabbix proxy
zabbix proxy架构
zabbix proxy对比zbbbix server
功能 | zabbxy proxy | zabbix server |
---|---|---|
量级 | 请量级 | 相对重量级 |
图形 | 无 | 带图形控制界面 |
可以独立工作 | 是,可以独立采集数据并存储 | 是,即数据采集、存储、分析、展示于一体 |
易维护 | 是,配置完成后基本无需管理 | 维护也不难 |
独立数据库 | 保留少量最近数据 | 保留指定时间内的所有数据 |
报警通知 | 不支持发送邮件通知 | 支持邮件、短信等告警机制(基于调用脚本) |
zabbix proxy部署与使用
zabbix proxy 的大版本必须要和 zabbix server 版本一致,否则会出现兼容性问题
apt/yum安装zabbix proxy
https://www.zabbix.com/documentation/4.0/zh/manual/installation/install_from_packages/debian_ubuntu
1 | # 安装软件仓库配置包 |
编译安装zabbix proxy
- 编译安装,参考脚本…
- 修改被监控主机的配置文件,Server 和 ServerActive
- 管理 -> agent代理程序 -> 创建代理(注意名称要和zabbix_proxy.conf中的hostname对应起来) -> 修改主机的“由agent代理程序监测”参数
zabbix 监控案例实战
- 自定义监控项
- 通过脚本采集监控项数据
- zabbix agent获取监控项数据
- 自定义模板和图形及触发器
- 验证数据
监控Linux TCP连接状态
监控TCP连接数脚本
1
2
3[root@zabbix-web1 ~]#cat /usr/local/zabbix/data/tcp_conn.sh
#!/bin/bash
ss -ant | awk -v TCP_STAT=$1 -v s=0 '$1==TCP_STAT {++s} END {print s}'zabbix agent添加自定义监控项
1
2
3
4
5
6[root@web1 etc]$vim zabbix_agentd.conf
...
UserParameter=tcp_status[*],/bin/bash /usr/local/zabbix/data/tcp_conn.sh $1 $2
...
[root@web1 etc]$chmod a+x zabbix_agentd.conf
[root@web1 etc]$systemctl restart zabbix-agentzabbix server测试监控项数据
1
2
3
4
5
6[root@zabbix bin]$./zabbix_get -s 10.0.1.26 -p 10050 -k tcp_status[TIME-WAIT]
1
[root@zabbix bin]$./zabbix_get -s 10.0.1.26 -p 10050 -k tcp_status[ESTAB]
2
[root@zabbix bin]$./zabbix_get -s 10.0.1.26 -p 10050 -k tcp_status[LISTEN]
9zabbix web导入模板
配置-模板-导入将TCP监控模板关联至主机
验证监控数据
监控Memcached
安装 memcached
监控脚本
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94[root@web1 data]$grep '^[^#]' /etc/memcached.conf
-d
logfile /var/log/memcached.log
-m 64
-p 11211
-u memcache
-l 127.0.0.1
-P /var/run/memcached/memcached.pid
[root@web1 data]$echo -e "stats\nquit" | nc 127.0.0.1 11211
STAT pid 5590
STAT uptime 725
STAT time 1613618905
STAT version 1.5.6 Ubuntu
STAT libevent 2.1.8-stable
STAT pointer_size 64
STAT rusage_user 0.072870
STAT rusage_system 0.048580
STAT max_connections 1024
STAT curr_connections 1
STAT total_connections 4
STAT rejected_connections 0
STAT connection_structures 2
STAT reserved_fds 20
STAT cmd_get 0
STAT cmd_set 0
STAT cmd_flush 0
STAT cmd_touch 0
STAT get_hits 0
STAT get_misses 0
STAT get_expired 0
STAT get_flushed 0
STAT delete_misses 0
STAT delete_hits 0
STAT incr_misses 0
STAT incr_hits 0
STAT decr_misses 0
STAT decr_hits 0
STAT cas_misses 0
STAT cas_hits 0
STAT cas_badval 0
STAT touch_hits 0
STAT touch_misses 0
STAT auth_cmds 0
STAT auth_errors 0
STAT bytes_read 35
STAT bytes_written 3795
STAT limit_maxbytes 67108864
STAT accepting_conns 1
STAT listen_disabled_num 0
STAT time_in_listen_disabled_us 0
STAT threads 4
STAT conn_yields 0
STAT hash_power_level 16
STAT hash_bytes 524288
STAT hash_is_expanding 0
STAT slab_reassign_rescues 0
STAT slab_reassign_chunk_rescues 0
STAT slab_reassign_evictions_nomem 0
STAT slab_reassign_inline_reclaim 0
STAT slab_reassign_busy_items 0
STAT slab_reassign_busy_deletes 0
STAT slab_reassign_running 0
STAT slabs_moved 0
STAT lru_crawler_running 0
STAT lru_crawler_starts 1275
STAT lru_maintainer_juggles 774
STAT malloc_fails 0
STAT log_worker_dropped 0
STAT log_worker_written 0
STAT log_watcher_skipped 0
STAT log_watcher_sent 0
STAT bytes 0
STAT curr_items 0
STAT total_items 0
STAT slab_global_page_pool 0
STAT expired_unfetched 0
STAT evicted_unfetched 0
STAT evicted_active 0
STAT evictions 0
STAT reclaimed 0
STAT crawler_reclaimed 0
STAT crawler_items_checked 0
STAT lrutail_reflocked 0
STAT moves_to_cold 0
STAT moves_to_warm 0
STAT moves_within_lru 0
STAT direct_reclaims 0
STAT lru_bumps_dropped 0
END
[root@web1 data]$cat memcache_monitor.sh
#!/bin/bash
echo -e "stats\nquit" | nc 127.0.0.1 11211 | grep "STAT $1" | awk '{print $3}'zabbix agent添加自定义监控项
zabbix server测试监控项数据
zabbix web制作模板
- 创建模板
- 创建监控项
- 创建触发器
- 创建图形
模板关联主机
验证监控项数据
监控Redis
安装Redis
监控脚本
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[root@web1 data]$redis-cli -h 127.0.0.1 -p 6379 info # 所有info
...
[root@web1 data]$redis-cli -h 127.0.0.1 -p 6379 info clients # 客户端相关info
# Clients
connected_clients:1 # 当前连接数
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0
[root@web1 data]$redis-cli -h 127.0.0.1 -p 6379 info memory # 内存相关info
# Memory
used_memory:839288 # 已用内存
used_memory_human:819.62K
used_memory_rss:3846144
used_memory_rss_human:3.67M
used_memory_peak:841288
used_memory_peak_human:821.57K
used_memory_peak_perc:99.76%
used_memory_overhead:832134
used_memory_startup:782504
used_memory_dataset:7154
used_memory_dataset_perc:12.60%
total_system_memory:2065870848
total_system_memory_human:1.92G
used_memory_lua:37888
used_memory_lua_human:37.00K
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
mem_fragmentation_ratio:4.58
mem_allocator:jemalloc-3.6.0
active_defrag_running:0
lazyfree_pending_objects:0zabbix agent添加自定义监控项
zabbix server测试监控项数据
zabbix web模板制作
- 创建模板
- 创建触监控项:当前连接数监控项、已用内存监控项
- 创建触发器:当前连接数触发器、已用内存触发器
- 创建图形:Redis当前连接数图形、Redis已用内存图形
模板关联主机
验证监控项数据
监控 Nginx
安装nginx
监控脚本
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#!/bin/bash
nginx_active() {
curl "http://127.0.0.1:/nginx_status/" 2>/dev/null | grep 'Active' | awk '{print $NF}'
}
nginx_reading() {
curl "http://127.0.0.1:/nginx_status/" 2>/dev/null | grep 'Reading' | awk '{print $2}'
}
nginx_writing() {
curl "http://127.0.0.1:/nginx_status/" 2>/dev/null | grep 'Writing' | awk '{print $4}'
}
nginx_waiting() {
curl "http://127.0.0.1:/nginx_status/" 2>/dev/null | grep 'Waiting' | awk '{print $6}'
}
nginx_accepts() {
curl "http://127.0.0.1:/nginx_status/" 2>/dev/null | awk NR==3 | awk '{print $1}'
}
nginx_handled() {
curl "http://127.0.0.1:/nginx_status/" 2>/dev/null | awk NR==3 | awk '{print $2}'
}
nginx_requests() {
curl "http://127.0.0.1:/nginx_status/" 2>/dev/null | awk NR==3 | awk '{print $3}'
}
case $1 in
active)
nginx_active
;;
reading)
nginx_reading
;;
writing)
nginx_writing
;;
waiting)
nginx_waiting
;;
accepts)
nginx_accepts
;;
handled)
nginx_handled
;;
requests)
nginx_requests
;;
esaczabbix agent添加自定义监控项
1
2
3
4[root@web1 etc]$cat zabbix_agentd.conf
...
UserParameter=nginx_status[*],/usr/local/zabbix/data/nginx_status.sh $1
...导入Nginx监控模板
模板关联主机
验证监控数据
SNMP 监控
SNMP:Simple Network Management Protocol,简单网络管理协议,TCP/IP协议簇的一个应用层协议
Linux 设备通过 agent 监控,网络设备通过 SNMP 协议监控,主要用于监控华为、思科等网络设备
SNMP有三个版本:目前主要使用的是 v2c 版本
1 | SNMP v1 # 团体名(Community Name)认证 |
SNMP数据交互
SNMP管理进程与代理进程之间为了交互信息,定义了5种报文:
1 | get-request # 从代理进程处提取一个或多个参数值 |
SNMP组织结构
SNMP结构非常复杂,一套完整的SNMP系统主要包括以下几个方面:
- SNMP报文协议
- 管理信息结构(SMI, Structure of Management Information),一套公用的结构和表示符号
- 管理信息库(MIB,Management Information Base),管理信息库包含所有代理进程的所有可被查询和修改的参数
- OID(Object Identifiers),一个OID是一个唯一的键值对,用于标识具体某一个设备的某个具体信息(对象标识),如端口信息、设备名称等
SNMP MIB
MIB是OID的集合。MIB是基于对象标识树的,对象标识是一个整数序列,中间以”.”分割,这些整数构成一个树型结构,类似于 DNS或Unix的文件系统,MIB被划分为若干个组,如system、 interfaces、 a t(地址转换)和ip组等。iso. org.dod.internet.private.enterprises(1.3 .6 .1.4.1)这个标识,是给厂家自定义而预留的,比如华为:1.3.6.1.4.1.2011,华三:1.3.6.1.4.1.25506
SNMP OID
OID 就是对象标识
snmpwalk工具可以使用SNMP的get请求查询指定OID入口的所有OID树信息。通过snmpwalk也可以查看支持SNMP协议(可网管)的设备的一些其他信息,比如cisco交换机或路由器IP地址、内存使用率等,也可用来协助开发SNMP功能
ubuntu中版本较新,这里以centos7为例:
1 | $yum -y install net-snmp-utils |
配置zabbix
使用zabbix 自带的SNMP,要先修改团体名称,否则 会因为团体名不一致导致zabbix没有权限去获取被监控服务器的snmp利用率
监控 MySQL
监控MySQL连接数、主从同步、同步延迟等
percona-monitoring-plugins
percona 官方出了专门的监控管理软件,所以已经停止维护 percona-monitoring-plugins,以下使用旧的版本
监控脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18[root@mysql-master src]$wget https://downloads.percona.com/downloads/percona-monitoring-plugins/percona-monitoring-plugins-1.1.8/binary/debian/artful/x86_64/percona-zabbix-templates_1.1.8-1.artful_all.deb
$dpkg -c percona-zabbix-templates_1.1.8-1.artful_all.deb | awk '{print $NF}'
...
./var/lib/zabbix/percona/scripts/get_mysql_stats_wrapper.sh # 监控脚本,修改手动修改
./var/lib/zabbix/percona/scripts/ss_get_mysql_stats.php # 设置mysql的用户名和密码
./var/lib/zabbix/percona/templates/userparameter_percona_mysql.conf # userparameter
./var/lib/zabbix/percona/templates/zabbix_agent_template_percona_mysql_server_ht_2.0.9-sver1.1.8.xml # 模板文件,直接导入即可
...
$dpkg -i percona-zabbix-templates_1.1.8-1.artful_all.deb
$cp /var/lib/zabbix/percona/scripts/get_mysql_stats_wrapper.sh /usr/local/zabbix/data/
$vim /var/lib/zabbix/percona/scripts/ss_get_mysql_stats.php
<?php
...
$mysql_user = 'root';
$mysql_pass = '123456';
...新建模板:直接导入
zabbix_agent_template_percona_mysql_server_ht_2.0.9-sver1.1.8.xml
即可新建主机,并连接到刚创建的模板
自定义脚本监控MySQL
编写脚本监控脚本MySQL主从同步及延迟
slave机器上有两个关键的进程:
- Slave_SQL_Running:负责自己的slave mysql进程
- Slave_IO_Running:负责与主机的io通信
1 | # 主从延迟,实际上只靠 Seconds_Behind_Master 这一个参数是不够的 |
自定义端口和进程监控
zabbix 内置相关key:
1 | # 检查 TCP 端口 是否处于侦听状态。返回 0 - 未侦听;1 - 正在侦听 |
故障自治愈功能
当zabbix 监控到指定的监控项异常的时候,通过指定的操作使故障自动恢复,通常是重启服务等一些简单的操作,也可以调用脚本执行比较复杂的操作
设置监控项和触发器,新建动作,在触发条件里面添加操作,在远程主机通过zabbix 客户端执行命令
zabbix agent需要开启远程命令执行
1
2
3# zabbix_agentd.conf
EnableRemoteCommands=1 # 开启远程执行命令
UnsafeUserParameters=1 # 允许远程执行命令的时候使用不安全的参数(特殊字符串)zabbix用户授权
1
2# /etc/sudoers
zabbix ALL = NOPASSWD: ALL # 授权指定用户执行特殊命令不再需要密码,比如sudo等创建动作
配置–动作–创建动作执行远程操作
验证自治愈功能
将被测试的服务手动停止运行,验证能否自动启动或重启,更多操作可以远程执行脚本
手动将Nginx、Tomcat等web服务停止后,验证zabbix agent能否自动启动或重启
grafana图形展示
grafana 本身只是一个图形显示工具,它独立于zabbix之外,通过zabbix提供的api获取数据,进行展示,其实不只是zabbix,它还可以搭配 prometheus、elasticsearch、mysql 等等,只要你提供数据,它都能给你展示出来
grafana 相比 zabbix 自带的web界面,更加好看
安装grafana服务
https://grafana.com/grafana/download?platform=linux1
2
3sudo apt-get install -y adduser libfontconfig1
wget https://dl.grafana.com/oss/release/grafana_7.4.2_amd64.deb
sudo dpkg -i grafana_7.4.2_amd64.debgrafana安装并启用zabbix插件
https://grafana.com/grafana/plugins/alexanderzobnin-zabbix-app1
2
3
4
5
6
7
8grafana-cli plugins install alexanderzobnin-zabbix-app
# 以上方式可能失败,推荐直接下载,然后移动到插件目录
$wegt https://storage.googleapis.com/plugins-community/alexanderzobnin-zabbix-app/release/4.1.2/alexanderzobnin-zabbix-app-4.1.2.zip
$unzip alexanderzobnin-zabbix-app-4.1.2.zip
$mv alexanderzobnin-zabbix-app /var/lib/grafana/plugins/
$systemctl restart grafana-server.service启动zabbix插件
添加zabbix 数据源
添加mysql数据源
添加zabbix数据源
添加Dashboard
自定义基础监控模板
略…
结合pyhton脚本监控案例
kubernetes 集群状态监控脚本
1 | [root@kubernetes-master1 ~]# cat /usr/local/zabbix/data/k8s_monitor.py |
监控MongodbDB复制集状态
1 | #cat /usr/local/zabbix/data/mongodb_cluster_monitor.py |
监控Redis列表长度
1 | [root@redis ~]#cat /usr/local/zabbix/data/redis_llen.py |
监控ELK集群状态
1 | [root@elk-s1 ~]# vim /usr/local/zabbix/data/els_status.py |
监控RabbitMQ集群节点状态
1 | #cat /usr/local/zabbix/data/rabbit_cluster_monitor.py |
Zabbix 事件通知机制
出现故障报警的时候,可以通过不同方式通知管理员进行故障处理,尽快恢复业务
1 | # zabbix_server.conf |
报警的最核心就是把报警媒介配置好,包括它前后的部分
- 添加报警媒介(邮件、短信、微信)
- 将报警媒介添加到动作的操作中,这样通过动作,就将触发器和报警媒介关联起来了
- 将报警媒介添加到用户,这样,当有触发器报警,就会通过报警媒介通知到用户
邮件通知
短信通知
微信通知
略..,和短信通知差不多
Zabbix 自动化运维
批量部署 Agent
使用agent,实现agent的自动化批量安装,可以通过源码或apt等方式安装
API
通过 zabbix web 进行的操作,都提供对应的API,可以通过编程的方式实现
API简介:https://www.zabbix.com/documentation/4.0/zh/manual/api
API列表:https://www.zabbix.com/documentation/4.0/zh/manual/api/reference