监控后传

这些年随着互联网的进步,监控系统也越来越完善,那接下来就谈谈如何理解监控,以及监控要做到什么

最近一直在思考,监控到底该是一个什么样子,为什么要监控?

为什么要监控,我认为监控一个系统有多个原因

  1. 分析长期趋势
    通过对监控样本数据的持续收集和统计,对监控指标进行长期趋势分析
  2. 周期的比较(环比)
    通过跨时间的比较,或者是观察实验组与控制组之间的区别
  3. 报警
    出现故障,需要立刻修复,或者可能很快会出故障,需要提前介入查看
  4. 监控大盘(黄金指标)
    系统的展示服务的一些基本问题,具体参考4个黄金指标
  5. 回溯分析
    经过对长期数据存储分析,并对数据进行多维度的回溯分析,能够帮助我们透视化了解系统的异常情况,主动发现潜在隐患

监控系统的核心本质是什么

大家都知道,无论故障发生的概率有多小,只要有出现的可能,它总会复现。

海恩法则指出:每一起严重事故的背后,必然有29次轻微事故和300期未遂先兆以及1000起事故隐患。

法则强调俩点:
一是事故的发生是量的积累的结果
二是再好的技术,再完美的规章,在实际操作层面,也无法取代人自身的素质和责任心

因此我们需要对自己质疑

  1. 什么东西出故障了(现象)
  2. 为什么出故障(原因)

<<SRE:Goole运维解密>> 一书指出,监控系统需要能够有效的支持白盒监控和黑盒监控

可能有点懵,简单介绍一下 白盒监控、黑盒监控。

白盒监控大量依赖对系统内部信息的监测,如系统日志、抓取提供指标信息的http节点等,因此可以监测到即将发生的问题及哪些重试所掩盖的问题等。

黑盒监控是面向现象的,代表了目前正在发生的,而非预测会发生的问题,即(系统现在有故障)。

监控系统的4个黄金指标(延迟、流量、错误、饱和度)

延迟:服务处理某个请求所需要的时间
流量:使用系统中的某个高层次的指标对系统负载需求所进行的度量
错误:请求失败的速率
饱和度:服务容量有多“满”

如果我们的度量所有这4个黄金指标,同时在某个指标出现故障时发出警报,能做到这些,服务的监控就基本差不多了。

怎么样免费申请证书

                    Let's Encrypt简介

Let’s Encrypt 是 ISRG (Internet Security Research Group) 提供的一个免费、开放、自动化的证书签发服务。

本文介绍了如何使用 Let’s Encrypt 签发工具、自动续签,用 Let’s Encrypt 官方推荐的 certbot 客户端以及 Webroot 验证方式。

  1. 安装certbot
$ yum -y install yum-utils
$ yum-config-manager --enable rhui-REGION-rhel-server-extras rhui-REGION-rhel-server-optional
$ yum -y install certbot python2-certbot-nginx
  1. 配置nginx验证
server {
    listen 80;
    server_name www.test.com;

    include common/cert.conf;
}
#common/cert.conf
location /.well-known/acme-challenge {
        root /var/www/html;
}
  1. certbot签发证书
#默认证书目录/etc/letsencrypt
#certonly:获取或更新证书,但是不安装
#--webroot:把身份认证文件放置在服务器的根目录下用于获取证书
#-w:指定根目录
#-d:指定域名,可以多次使用
#-m:接受通知邮箱地址
#--agree-tos:同意订阅协议
#--no-eff-email:不共享email with eff(--eff-email:共享email with eff)

$ certbot certonly --webroot -w /var/www/html -d www.test.com -m email --agree-tos --no-eff-email

#支持通配域名
$ certbot -a dns-plugin
  1. certbot续签证书
$ certbot renew
  1. certbot常用配置命令解析
#查看证书
$ certbot certificates
#--cert-path 证书路径
#--key-path 密钥路径
#--config-dir 配置文件目录

结合自动化ansible实现自动签约证书,续约证书,可以给公司省不少证书的money,赶紧让老板涨工资!

如何实时监控nginx

nginx 是什么?
nginx 是异步框架的 Web服务器,也可以用作反向代理,负载平衡器 和 HTTP缓存。

nginx 监控的主要指标?

  1. 包括每秒请求数

    Accepts(接受):客户端连接数
    Handled(已处理):成功的客户端连接数
Active(活跃):

Waiting(等待)
Reading(读)
Writing(写)

  1. 服务器错误率
    服务器错误率等于在单位时间内5xx错误状态的总数除以状态码(1XX,2XX,3XX,4XX,5XX)的总数。
    服务器错误率是衡量服务的重要的指标,是监控指标中有价值的一个。

  2. 请求处理时间
    请求处理时间指标记录了nginx处理每个请求的时间,从读到客户端的第一个请求字节到完成请求。较长的响应时间说明上游服务出现问题。

我们是如何收集的?
基于Openresty和Prometheus、Grafana设计的,实现了针对域名、接口级别的状态码、请求时间统计,Grafana做展示。

如何配置?
github: https://github.com/knyar/nginx-lua-prometheus.git

lua_shared_dict prometheus_metrics 10M;
lua_package_path "nginx-lua-prometheus/?.lua;;";


init_by_lua '
            prometheus = require("prometheus").init("prometheus_metrics")
            metric_requests = prometheus:counter("nginx_http_requests_total", "Number of HTTP requests", {"host", "status"})
            metric_api_requests = prometheus:counter("nginx_http_api_requests_total", "Number of HTTP requests", {"host", "api", "status"})
            metric_latency = prometheus:histogram("nginx_http_request_duration_seconds", "HTTP request latency", {"host"})
            metric_connections = prometheus:gauge("nginx_http_connections", "Number of HTTP connections", {"state"})
    ';


    log_by_lua '
            local server_name = ngx.var.server_name
            local status = ngx.var.status
            local request_time = ngx.var.request_time
            local uri = ngx.var.uri
            local regex = [[\.[a-z]+\.[a-z]+$]]
            local m = ngx.re.match(server_name, regex)
            if m then
                metric_requests:inc(1, {server_name, status})
                metric_latency:observe(tonumber(request_time), {server_name})
                code = {"400", "403", "404", "500", "502"}
                for _, v in ipairs(code) do
                    if status == v then
                        metric_api_requests:inc(1, {server_name, uri, status})
                    end
                end
            end
    ';


    server {
            listen 9145;
            server_name _;
            allow ip;
            deny all;
            location /metrics {
                    content_by_lua '
                            prometheus:collect()
                            ';
            }
            location /clean {
                content_by_lua '
                        ngx.shared.prometheus_metrics:flush_all()
                ';
            }
    }

prometheus配置pull获取监控数据
http://ip:9145/metrics

Grafana如何展示?
根据nginx收集指标配置

nginx共享内存分配是有大小限制的,如下配置是清理共享内存数据

location /clean {
                content_by_lua '
                        ngx.shared.prometheus_metrics:flush_all()
                ';
            }

科学上网

hi, 互联网的同学们基本都会遇到的难点是什么呢,想必大家都能猜到一、二、三,😄 不兜圈子了,直插主题,那就是通过互联网得到我们想要的答案。

我今天分享的主题是如何在浏览器、终端科学上网。
我介绍一下目前我用之最稳定的科学上网方式

不管是浏览器、还是终端,科学上网依赖的是Shadowsocks(简称SS)

Shadowsocks的运行原理是什么?
原理自己百度

我今天主要介绍技术实现的方式
首先需要准备一台阿里云香港的linux server

yum -y install epel-release -y
yum install python-pip -y
pip install shadowsocks
nohup ssserver -s 公网ip -k 密码 -m aes-256-cfb  > /dev/null 2>&1 &
nohup sslocal -s 公网ip —-l 1080 -k 密码 -m aes-256-cfb  > /dev/null 2>&1 &

然后client telnet测试

telnet 公网ip 1080

如果测试通过,下载科学上网工具Shadowsocks,根据提示输入相应配置,这样浏览器就可以科学上网。

但是这只是浏览器可以科学上网,好多码农,尤其是golang工程师,经常需要下载一些宇宙的包,就需要终端实现科学上网。

终端科学上网用到的工具是polipo

polipo运行原理是什么?
原理自己百度

主要介绍一下实现方式,首先在阿里云香港的server

yum install texinfo -y
git clone https://github.com/jech/polipo.git
cd polipo
make all
make install

mkdir /etc/polipo
vim /etc/polipo/config

daemonise = true
proxyAddress = "0.0.0.0"
socksParentProxy = "127.0.0.1:1080"
socksProxyType = socks5
chunkHighMark = 50331648
objectHighMark = 16384

polipo -c /etc/polipo/config

然后client telnet测试

telnet 公网ip 8123

如果测试通过,在终端设置proxy

export http_proxy="http://公网ip:8123"
export https_proxy="https://公网ip:8123"

最后golang的工程师可以尝试一下这种方式看是否可以满足你们的大部门科学上网的场景呢,如果可以,请不要记得我,因为我是雷锋

持续交付平台 spinnaker

Spinnaker是什么

Spinnaker是一个伟大的企业级发布管理方案。

Spinnaker 是 Google 与 Netflix 发布的企业级持续交付平台,是一个持续交付平台,它定位于将产品快速且持续的部署到多种云平台上。Spinnaker有两个核心的功能集群管理和部署管理。Spinnaker通过将发布和各个云平台解耦,来将部署流程流水线化,从而降低平台迁移或多云平台部署应用的复杂度,它可以无缝集成如Git、Jenkins、Travis CI、Docker registry、cron调度器。

Spinnaker 组件

Deck: 基于浏览器的 Spinnaker UI。

Gate: API 调用者和 Spinnaker UI 通过 API 网关(这里称为 Gate )和 Spinnaker 服务器进行通信。

Orca: 是一个编排引擎,被称为 Orca,用来管理流水线和其他特定的操作。

Clouddriver: 已经部署资源的索引和缓存由 Clouddriver 进行管理。

Echo: 负责发送通知,也作为传入的 web 回调(webhook)。

Igor: 用于在 Jenkins 或 Travis CI 等系统中通过持续集成的 job 触发部署流水线,并且允许在部署流水线中使用 Jenkins/Travis 的某些阶段。

Front50: 用于存储 Spinnaker 的元数据。它将持久化存储所有资源的元数据,比如:流水线、项目、应用程序和通知消息。

Rosco: 用于管理虚拟机的镜像。

Rush: Spinnaker 的脚本执行引擎。

特点:
1、通过灵活和可配置的管道实现可重复的自动部署
2、提供一个所有环境的全局视图,一个应用程序可以看见自己的在所属管道中的状态
3、通过一致且可靠的API,提供可编程配置
4、易于配置、维护和扩展

Spinnaker主要包含2块内容:
1、集群管理
集群管理功能,主要用于管理云上的资源。
集群管理将云上资源做了逻辑划分:

机器组

安全组

负载均衡器

2、部署管理

部署管理功能用于创建一个持续交付流程。部署管理的核心是管道,在Spinnaker的定义中,管道由一系列的阶段(stages)组成。管道可以 由Jenkins、定时器、其他管道或者人工触发。同时,管道可以配置参数和通知,可以在管道一些节点上发出消息。Spinnaker已经内置了一些阶段,如执行自定义脚本、触发Jenkins任务等。

OpenLDAP 原理、部署、应用

一、目录服务

目录是一个为查询、浏览和搜索而优化的专业分布式数据库,它呈树状结构组织数据,就好象Linux/Unix系统中的文件目录一样。目录数据库和关系数据库不同,它有优异的读性能,但写性能差,并且没有事务处理、回滚等复杂功能,不适于存储修改频繁的数据。所以目录天生是用来查询的,就好象它的名字一样。

目录服务是由目录数据库和一套访问协议组成的系统。

二、OpenLDAP 是什么
OpenLDAP 是一款轻量级目录访问协议(Lightweight Directory Access Protocol,LDAP)。

OpenLDAP 属于开源软件,且OpenLDAP 支持LDAP 最新标准、更多模块扩展功能、自定义schema、满足需求、权限管理、密码策略及审计管理、主机控制策略管理、第三方应用平台管理以及与第三方开源软件结合实现高可用负载均衡平台等功能,这也是商业化管理软件无可比拟的。

三、OpenLDAP 功能

查询操作(ldapsearch):允许查询目录并取得条目,其查询性能比关系数据库好。

更新操作(ldapupdate):目录树条目支持条目的添加、删除、修改等操作。

同步操作:OpenLDAP 是一种典型的分布式结构,提供复制同步,可将主服务器上的数据通过推或拉的机制实现在从服务器上更新,完成数据的同步,从而避免OpenLDAP 服务器出现单点故障,影响用户验证。

认证和管理操作:允许客户端在目录中识别自己,并且能够控制一个会话的性质。

四、OpenLDAP 目录架构

主要介绍互联网命名组织架构

LDAP 的目录信息是以树形结构进行存储的,在树根一般定义国家(c=CN)或者域名(dc=com),其次往往定义一个或多个组织(organization,o)或组织单元(organization unit,ou)。

五、OpenLDAP 安装部署
环境: centos 7

安装 OpenLDAP

[root@localhost ~]# yum -y install openldap compat-openldap openldap-clients openldap-servers openldap-servers-sql openldap-devel
[root@localhost ~]# systemctl start slapd
[root@localhost ~]# systemctl enable slapd

设置管理员密码

[root@localhost ~]# slappasswd
[root@localhost ~]# cd /etc/openldap/slapd.d/cn=config
[root@localhost ~]# vi olcDatabase={2}hdb.ldif
olcSuffix: dc=test,dc=com
olcRootDN: cn=Manager,dc=test,dc=com
olcRootPW:{SSHA}LvKLgOHmDx6gMTeqFCDnp+77u4m2C45s
[root@localhost ~]# vi /etc/openldap/slapd.d/cn=config/olcDatabase={1}monitor.ldif

olcAccess: {0}to * by dn.base=”gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth” read by dn.base=”cn=Manager,dc=test,dc=com” read by * none

[root@localhost ~]# slaptest -u

[root@localhost ~]# cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG

[root@localhost ~]# chown ldap:ldap /var/lib/ldap/*

[root@localhost ~]# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/cosine.ldif

[root@localhost ~]# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/nis.ldif

[root@localhost ~]# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/inetorgperson.ldif

[root@localhost ~]# vim /root/base.ldif

dn: dc=test,dc=com

dc: test

objectClass: top

objectClass: domain

dn: cn=ldapadm ,dc=test,dc=com

objectClass: organizationalRole

cn: Manager

description: LDAP Manager

dn: ou=People,dc=test,dc=com

objectClass: organizationalUnit

ou: People
[root@localhost ~]# ldapadd -x -W -D “cn=Manager,dc=test,dc=com” -f /root/base.ldif

增加用户
[root@localhost ~]# vim /root/user.ldif
dn: cn=lisi,ou=People,dc=test,dc=com
cn: lisi
givenname: lisi
mail: lisi@test.com
objectclass: inetOrgPerson
objectclass: organizationalPerson
objectclass: person
sn: li
uid: lisi
userpassword: {SSHA}d351u8sDyiX2fe8FGf2ZH0MarFp4RAo5

[root@localhost ~]# ldapadd -x -W -D "cn=Manager,dc=test,dc=com" -f /root/user.ldif

测试用户

[root@localhost ~]# ldapsearch -x cn=lisi -b dc=test,dc=com

EFK实践优化

  1. 什么是日志系统
    日志是由服务生成到服务器中,输出到不同的文件中,一般会分为系统日志、应用日志,这些日志存储在不同的服务器上。
    当开发人员分析应用发生故障时,需要登录不同的服务器查找故障原因。在没有日志系统的情况下,首先需要定位处理请求的服务器,去应用的日志目录下去查找日志文件内容。
    这样的流程下来,对于开发人员排查故障以及及时找到故障原因,造成了比较大的麻烦。因此,如果能把这些日志集中管理,并提供集中检索功能,可以提高诊断的效率。
    为了提供分布式的实时日志搜集和分析的系统,我们采用了通用的日志数据管理解决方案,Elasticsearch 、 Logstash 和 Kibana。简称为ELK,但是我们根据业务需求优化为EFK,F代表Filebeat。

  2. 系统架构

Filebeat: 轻量级数据收集引擎。

Kafka: 数据缓冲队列。提高了可扩展性。具有峰值处理能力,使用消息队列能够使关键组件顶住突发的访问压力,而不会因为突发的超负荷的请求而完全崩溃。

Logstash: 数据收集处理引擎。支持动态的从各种数据源搜集数据,并对数据进行过滤、分析、丰富、统一格式等操作,然后存储以供后续使用。

Elasticsearch: 分布式搜索引擎。具有高可伸缩、高可靠、易管理等特点。可以用于全文检索、结构化检索和分析,并能将这三者结合起来。Elasticsearch 基于 Lucene 开发,现在使用最广的开源搜索引擎之一。

Kibana: 可视化化平台。它能够搜索、展示存储在 Elasticsearch 中索引数据。使用它可以很方便的用图表、表格、地图展示和分析数据。

为什么用Filebeat,而不用Logstash?
原因很简单,资源消耗比较大。
由于 Logstash 是跑在 JVM 上面,资源消耗比较大,后来作者用GO写了一个功能较少但是资源消耗也小的轻量级的 Agent 叫 Logstash-forwarder。
后来作者加入 elastic.co 公司, Logstash-forwarder 的开发工作给公司内部 GO 团队来搞,最后命名为 Filebeat。

注意:
1. ES Master与Data节点分离,当Data节点大于3个的时候,建议分离。
2. Data Node内存不超过32G。
3. discovery.zen.minimum_master_nodes设置成( total / 2 + 1 ),避免脑裂情况。
4. 不要将 ES 暴露在公网中,建议都安装 X-PACK ,来加强其安全性

3.实践优化
本文基于 ES6.4,从性能和稳定性俩方面,介绍ES调优的基本方案,ES的调优不能一概而论,需要根据实际业务场景做适当的取舍和调整。

Linux参数调优:
1. 关闭交换分区,防止内存置换降低性能。 将/etc/fstab 文件中包含swap的行注释掉

sed -i '/swap/s/^/#/' /etc/fstab
swapoff -a

ES节点优化:
1. 调整translog同步策略
默认情况下,translog的持久化策略是,对于每个写入请求都做一次flush,刷新translog数据到磁盘上。这种频繁的磁盘IO操作是严重影响写入性能的,如果可以接受一定概率的数据丢失(这种硬件故障的概率很小),可以通过下面的命令调整 translog 持久化策略为异步周期性执行,并适当调整translog的刷盘周期。
PUT

{
  "settings": {
    "index": {
      "translog": {
        "sync_interval": "60s",
        "durability": "async",
        "flush_threshold_size": "1gb"
      }
    }
  }
}

原理:
Lucene只有在commit的时候才会把之前的变更持久化存储到磁盘(每次操作都写到磁盘的话,代价太大),在commit之前如果出现故障,上一次commit之后的变更都会丢失。
为了防止数据丢失,Lucene会把变更操作都记录在translog里,在出现故障的时候,从上次commit起记录在translog里的变更都可以恢复,尽量保证数据不丢失。
Lucene的flush操作就是执行一次commit,同时开始记录一个新的translog,所以translog是用来记录从上次commit到下一次commit之间的操作的。
flush操作的频率是通过translog的大小控制的,当translog大小达到一定值的时候就执行一次flush,对应参数为index.translog.flush_threshold_size,默认值是512mb,这里调整为1gb,减少flush的次数
translog本身是文件,也需要存储到磁盘,它的存储方式通过index.translog.durability和index.translog.sync_interval设定。默认情况下,index.translog.durability=request,意为每次请求都会把translog写到磁盘。这种设定可以降低数据丢失的风险,但是磁盘IO开销会较大。
这里采用异步方式持久化translog,每隔60秒写一次磁盘。
优化点: 减少写磁盘的频率
2. 调整refresh_interval
写入Lucene的数据,并不是实时可搜索的,ES必须通过refresh的过程把内存中的数据转换成Lucene的完整segment后,才可以被搜索。默认情况下,ES每一秒会refresh一次,产生一个新的segment,这样会导致产生的segment较多,从而segment merge较为频繁,系统开销较大。如果对数据的实时可见性要求较低,可以通过下面的命令提高refresh的时间间隔,降低系统开销。
PUT

{
  "settings": {
    "index": {
        "refresh_interval" : "60s"
    }
  }
}

优化点: 减少刷新频率,降低潜在的写磁盘性能损耗
3. merge并发控制
ES的一个index由多个shard组成,而一个shard其实就是一个Lucene的index,它又由多个segment组成,且Lucene会不断地把一些小的segment合并成一个大的segment,这个过程被称为merge。默认值是Math.max(1, Math.min(4, Runtime.getRuntime().availableProcessors() / 2)),当节点配置的cpu核数较高时,merge占用的资源可能会偏高,影响集群的性能,可以通过下面的命令调整某个index的merge过程的并发度:
PUT

{
    "index.merge.scheduler.max_thread_count": 1
}

优化点: 减少并发并发merge对磁盘的消耗
总结:
综上,实现 EFK 的整套组件,包含了日志收集、索引和可视化的全部流程,基于这套系统实现分析日志功能。同时,通过水平扩展 Kafka、Elasticsearch 集群,可以实现日均亿级的日志实时处理。

devops 自动化部署架构

1、自动化部署理解

很多人会理解为配置管理工具,像ansible、saltstack、puppet等,虽然这些工具辅助提高运维效率,但是在实际工作中,还是会遇到很多挑战

1.运维工具无法普及
2.开发人员无法参与系统的部署架构设计
3.云架构设计到最终上线,无法形成闭环

2、自动化部署的需求

为实现devops以产品为核心,以项目交付运维整个链路打通提供有力支撑

1.多环境部署,同时支持应用在云(公有、私有)、docker部署
2.多种部署模式、不同部署策略

3、自动化部署相关概念

1.什么是持续集成

持续集成(Continuous Integration,简称CI),意思是多频次的将代码merge master, 以便快速发现错误、防止branch偏离master
CI的主要目的是在产品快速迭代的同时保持代码质量,它的核心主要表现在2个方面:
1.代码merge master,必须通过相关测试
2.通过Code Review,分析工具对代码进行质量把关
CI 并不能消除Bug,而是让开发者非常容易发现和改正

2.什么是持续交付

持续交付(Continuous Delivery,简称CD),意思是为了快速安全的交付生产环境,需 要将最新版本先交付到预生产环境,进行验证,预生产环境验证通过,最新版本交付生产阶段
CD是CI的进一步。它强调的是,不管怎么更新,程序是随时随地可以交付的

3.什么是持续部署

持续部署(Continuous Deployment,简称CD),意思是最新版本通过预生产环境的验证,自动部署到生产环境
CD(3)的目标是为最终用户提供服务
CD(2)和CD(3)的区别就在于,CD(2): 最新版本交付生产环境是手动过程,CD(3): 最新版本交付生产环境是自动过程

4、什么是自动化部署

自动化部署(Automatic Deployment),通过自动化工具将程序部署到指定环境

后续自动化部署具体实现更新中。。。。。