文章目录

  • 1. prometheus报警设置:
    • . 介绍
  • 2.自定义告警规则
    • 定义告警规则
    • 模板化
    • 查看告警状态
  • 2.下载并报警组件alertmanager
    • 2.1 配置alertmanager
    • 2.2 邮件报警
    • 启动alertmanager服务
  • 2.3 定义告警规则
    • 2.4创建告警目录&添加报警规则(配置文件)
    • 2.5 警报三种状态:
  • 2.3钉钉报警
    • 安全设置
      • 1. 自定义关键词
      • 2. **加签**
        • 首先
        • 第二步
      • 3. IP 地址(段)
      • 在Kubernetes集群中运行
  • 推荐(自定义告警配置)

1. prometheus报警设置:

. 介绍

Prometheus的架构中被划分为两个部分

  1. Prometheus Server中定义告警规则以及产生告警,
  2. Alertmanager组件则用于处理这些由Prometheus产生的告警。Alertmanager即Prometheus体系中告警的统一处理中心。Alertmanager提供了多种内置第三方告警通知方式,同时还提供了对Webhook通知的支持,通过Webhook用户可以完成对告警更多个性化的扩展。

Alertmanager: 从 Prometheus server 端接收到 alerts 后,会进行去重,分组,并路由到相应的接收方,发出报警,常见的接收方式有:电子邮件,微信,钉钉, slack等。

prometheus触发一条告警的过程:
prometheus—>触发阈值—>超出持续时间—>alertmanager—>分组|抑制|静默—>媒体类型—>邮件|钉钉|微信等。

在Prometheus中一条告警规则主要由以下几部分组成

  1. 告警名称:用户需要为告警规则命名,当然对于命名而言,需要能够直接表达出该告警的主要内容
  2. 告警规则:告警规则实际上主要由PromQL进行定义,其实际意义是当表达式(PromQL)查询结果持续多长时间(During)后出发告警

Alertmanager的特性
Alertmanager除了提供基本的告警通知能力以外,还主要提供了如:分组、抑制以及静默等告警特性

分组(group): 将类似性质的警报合并为单个通知。
静默(silences): 是一种简单的特定时间静音的机制,
例如:服务器要升级维护可以先设置这个时间段告警静默。
抑制(inhibition): 当警报发出后,停止重复发送由此警报引发的其他警报即合并一个故障引起的多个报警事件,可以 消除冗余告警

2.自定义告警规则

Prometheus中的告警规则允许你基于PromQL表达式定义告警触发条件,Prometheus后端对这些触发规则进行周期性计算,当满足触发条件后则会触发告警通知。默认情况下,用户可以通过Prometheus的Web界面查看这些告警规则以及告警的触发状态。当Promthues与Alertmanager关联之后,可以将告警发送到外部服务如Alertmanager中并通过Alertmanager可以对这些告警进行进一步的处理。

定义告警规则

groups:
- name: examplerules:- alert: HighErrorRateexpr: job:request_latency_seconds:mean5m{job="myjob"} > 0.5for: 10mlabels:severity: pageannotations:summary: High request latencydescription: description info

可以将一组相关的规则设置定义在一个group下。
在每一个group中定义多个告警规则(rule)。

告警规则主要由以下几部分组成

alert:告警规则的名称。
expr:基于PromQL表达式告警触发条件,用于计算是否有时间序列满足该条件。
for:评估等待时间,可选参数。用于表示只有当触发条件持续一段时间后才发送告警。在等待期间新产生告警的状态为pending。
labels:自定义标签,允许用户指定要附加到告警上的一组附加标签。
annotations:用于指定一组附加信息,比如用于描述告警详细信息的文字等,annotations的内容在告警产生时会一同作为参数发送到Alertmanager。

让Prometheus启用定义的告警规则
在Prometheus全局配置文件中通过rule_files指定一组告警规则文件的访问路径,Prometheus启动后会自动扫描这些路径下规则文件中定义的内容,并且根据这些规则计算是否向外部发送通知:

rule_files:[ - <filepath_glob> ... ]

默认情况下Prometheus会每分钟对这些告警规则进行计算,
如果用户想自定义的告警计算周期,则可以通过evaluation_interval来覆盖默认的计算周期:

global:[ evaluation_interval: <duration> | default = 1m ]

模板化

在告警规则文件的annotations中使用summary描述告警的概要信息,description用于描述告警的详细信息。
同时Alertmanager的UI也会根据这两个标签值,显示告警信息。为了让告警信息具有更好的可读性,Prometheus支持模板化label和annotations的中标签的值

通过$labels.变量可以访问当前告警实例中指定标签的值。$value则可以获取当前PromQL表达式计算的样本值。

# To insert a firing element's label values:
{{ $labels.<labelname> }}
# To insert the numeric expression value of the firing element:
{{ $value }}

以通过模板化优化summary以及description的内容的可读性

- alert: KubeAPILatencyHighannotations:message: The API server has a 99th percentile latency of {{ $value }} secondsfor {{ $labels.verb }} {{ $labels.resource }}.expr: |cluster_quantile:apiserver_request_latencies:histogram_quantile{job="apiserver",quantile="0.99",subresource!="log"} > 4for: 10mlabels:severity: critical

这条警报的大致含义是,假如 kube-apiserver 的 P99 响应时间大于 4 秒,并持续 10 分钟以上,就产生报警。

首先要注意的是由 for 指定的 Pending Duration。这个参数主要用于降噪,很多类似响应时间这样的指标都是有抖动的,通过指定 Pending Duration,我们可以 过滤掉这些瞬时抖动,让 on-call 人员能够把注意力放在真正有持续影响的问题上。

那么显然,下面这样的状况是不会触发这条警报规则的,因为虽然指标已经达到了警报阈值,但持续时间并不够长:

查看告警状态

如下所示,用户可以通过Prometheus WEB界面中的Alerts菜单查看当前Prometheus下的所有告警规则,以及其当前所处的活动状态。


同时对于已经pending或者firing的告警,Prometheus也会将它们存储到时间序列ALERTS{}中。
可以通过表达式,查询告警实例:

ALERTS{alertname="<alert name>", alertstate="pending|firing", <additional alert labels>}

样本值为1表示当前告警处于活动状态(pending或者firing),当告警从活动状态转换为非活动状态时,样本值则为0。

示例:定义主机监控报警
修改Prometheus配置文件prometheus.yml,添加以下配置:

rule_files:- /usr/local/prometheus/*.rules

在目录/usr/local/prometheus/下创建告警文件alert.rules内容如下:

groups:
- name: hostStatsAlertrules:- alert: hostCpuUsageAlertexpr: sum(avg without (cpu)(irate(node_cpu_seconds_total{mode!='idle'}[1m]))) by (instance) > 0.5for: 1mlabels:severity: pageannotations:summary: "Instance {{ $labels.instance }} CPU usgae high"description: "{{ $labels.instance }} CPU usage above 50% (current value: {{ $value }})"- alert: hostMemUsageAlertexpr: (node_memory_MemTotal - node_memory_MemAvailable)/node_memory_MemTotal > 0.7for: 1mlabels:severity: pageannotations:summary: "Instance {{ $labels.instance }} MEM usgae high"description: "{{ $labels.instance }} MEM usage above 50% (current value: {{ $value }})"

重启Prometheus后访问Prometheus UI
http://127.0.0.1:9090/rules可以查看当前以加载的规则文件。这里我将阀值调小了,但是配置文件忘记修改不必在意


切换到Alerts标签http://127.0.0.1:9090/alerts可以查看当前告警的活动状态。

此时,我们可以手动拉高系统的CPU使用率,验证Prometheus的告警流程,在主机上运行以下命令:

cat /dev/zero>/dev/null

查看CPU使用率情况,

Prometheus首次检测到满足触发条件后,hostCpuUsageAlert显示由一条告警处于活动状态。由于告警规则中设置了1m的等待时间,当前告警状态为PENDING,如果1分钟后告警条件持续满足,则会实际触发告警并且告警状态为FIRING,如下图所示:

2.下载并报警组件alertmanager

Alertmanager: 从 Prometheus server 端接收到 alerts 后,会进行去重,分组,并路由到相应的接收方,发出报警,常见的接收方式有:电子邮件,微信,钉钉, slack等。

安装在prometheus中

tar xf alertmanager-0.21.0.linux-amd64.tar.gz -C /usr/local/ && cd /usr/local/
ln -s /usr/local/alertmanager-0.21.0.linux-amd64/ /usr/local/alertmanager
mkdir -p /usr/local/alertmanager/data/vim /etc/systemd/system/alertmanager.service
[Unit]
Description=alertmanager
After=network.target[Service]
Type=simple
User=prometheus
ExecStart=/usr/local/alertmanager/alertmanager --config.file=/usr/local/alertmanager/alert-test.yaml --storage.path=/usr/local/alertmanager/data/
Restart=on-failure[Install]
WantedBy=multi-user.target

2.1 配置alertmanager

官方配置文档
https://prometheus.io/docs/alerting/configuration/
Alertmanager的配置主要包含两个部分:路由(route)以及接收器(receivers)。所有的告警信息都会从配置中的顶级路由(route)进入路由树,根据路由规则将告警信息发送给相应的接收器。

在Alertmanager中通过路由(Route)来定义告警的处理方式。路由是一个基于标签匹配的树状匹配结构。根据接收到告警的标签匹配相应的处理方式。

Alertmanager主要负责对Prometheus产生的告警进行统一处理
Alertmanager配置包含以下几个主要部分

全局配置(global):用于定义一些全局的公共参数,如全局的SMTP配置,Slack配置等内容;模板(templates):用于定义告警通知时的模板,如HTML模板,邮件模板等;告警路由(route):根据标签匹配,确定当前告警应该如何处理;接收人(receivers):接收人是一个抽象的概念,它可以是一个邮箱也可以是微信,Slack或者Webhook等,接收人一般配合告警路由使用;抑制规则(inhibit_rules):合理设置抑制规则可以减少垃圾告警的产生

Alermanager会将数据保存到本地中,默认的存储路径为data/。因此,在启动Alertmanager之前需要创建相应的目录

2.2 邮件报警

cd /usr/local/alertmanager#这个名字对应service文件
cp alertmanager.yml alert-test.ymlcat alert-test.yml
global: resolve_timeout: 5m     #未接收到告警后标记告警状态为resolved(已解决)# 邮件报警smtp_smarthost: 'smtp.qq.com:465' smtp_from: '11573241340@qq.com' smtp_auth_username: '11573241340@qq.com' #这个为qq的授权码smtp_auth_password: 'udwtewqtcdhcj' smtp_hello: '@qq.com' smtp_require_tls: false route:  #route用来设置报警的分发策略,发送给哪一个receivergroup_by: ['alertname']    #采用哪个标签来作为分组依据 group_wait: 10s      #组告警等待时间。也就是告警产生后等待10s,如果有同组告警一起发出 group_interval: 10s   #两组告警的间隔时间 repeat_interval: 2m  #重复告警的间隔时间,减少相同邮件的发送频率 receiver: 'web.hook'    #设置接收人 receivers:
- name: 'web.hook' #webhook_configs: #- url: 'http://127.0.0.1:5001/' email_configs: - to: '11573241340@qq.com' -
#inhibit_rules: #禁止的规则
#  - source_match: #源匹配级别
#    severity: 'critical'
#  target_match:
#    severity: 'warning'
#  equal: ['alertname', 'dev', 'instance']

检查alertmanager配置文件

./amtool check-config alertmanager.yml

告警分组:group_by

当使用Prometheus监控多个集群以及部署在集群中的应用和数据库服务

route:receiver: 'default-receiver'group_wait: 30sgroup_interval: 5mrepeat_interval: 4hgroup_by: [cluster, alertname]#对于不同级别的告警routes:- receiver: 'database-pager'group_wait: 10smatch_re:service: mysql|cassandra- receiver: 'frontend-pager'group_by: [product, environment]match:team: frontend

启动alertmanager服务

chown -R prometheus:prometheus /usr/local/alertmanager-0.21.0.linux-amd64/systemctl status alertmanager.service

默认监听端口:9093 集群监听端口9094

 lsof -i:9093

访问:http://IP:9093

2.3 定义告警规则

告警配置链接

# Alertmanager configuration
alerting:alertmanagers:- static_configs:- targets:- alertmanager:9093

开启告警配置

rule_files:# 告警规则配置文件位置- "rules/*.yml"

监控Alertmanager

  - job_name: 'alertmanager'static_configs:- targets: ['172.20.32.218:9093']


检查并重新加载配置文件

./promtool check config prometheus.yml

2.4创建告警目录&添加报警规则(配置文件)

在prometheus.yml的同级目录下,创建rules目录,在该rules目录下创建node_alerts.yml文件,内容如下:

mkdir rules && cd rules/
vim  node_alerts.yml
# groups:组告警
groups:
# name:组名。报警规则组名称
- name: general.rules# rules:定义角色rules:# alert:告警名称。 任何实例5分钟内无法访问发出告警- alert: NodeFilesystemUsage# expr:表达式。 获取磁盘使用率 大于百分之80 触发expr: 100 - (node_filesystem_free_bytes{mountpoint="/",fstype=~"ext4|xfs"} / node_filesystem_size_bytes{fstype=~"ext4|xfs"} * 100) > 80# for:持续时间。 表示持续一分钟获取不到信息,则触发报警。0表示不使用持续时间for: 1m# labels:定义当前告警规则级别labels:# severity: 指定告警级别。severity: warning# annotations: 注释 告警通知annotations:# 调用标签具体指附加通知信息summary: "Instance {{ $labels.instance  }} :{{ $labels.mountpoint }} 分区使用率过高" # 自定义摘要description: "{{ $labels.instance  }} : {{ $labels.job  }} :{{ $labels.mountpoint  }} 这个分区使用大于百分之80% (当前值:{{ $value }})" # 自定义具体描述

重启alertmanager服务

再次访问

查看告警规则

查看告警

2.5 警报三种状态:

Inactive 警报未激活;

Pending:警报已满足测试表达式条件,但未达到for指定的持续时间;

Firing:警报满足测试表达式条件,且持续时间达到了for指定的持续时间;

最后查看邮件
QQ邮箱

2.3钉钉报警

自定义机器人唯一的 webhook,可以通过电脑端的钉钉申请,申请完成后记录下该机器人的 webhook。如图:



自定义功能


完成安全设置后,复制出机器人的 Webhook 地址,可用于向这个群发送消息,格式如下

https://oapi.dingtalk.com/robot/send?access_token=XXXXXX

保管好 Webhook 地址,避免后有安全风险。

安全设置

安全设置目前有 3 种方式:

1. 自定义关键词

最多可以设置 10 个关键字,消息中至少包含其中 1 个关键字才可以发送成功。

例如:添加了一个自定义关键字:监控报警

则这个机器人所发送的消息,必须包含监控报警 这个词,才能发送成功。

2. 加签

首先

timestamp +“ \ n” + 密钥当做签名密钥,使用 HmacSHA256 算法计算签名,然后进行 Base64 编码,最后再把签名参数再进行 urlEncode,得到最终的签名(需要使用 UTF-8 字符集)。

签名代码示例(Java

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import java.net.URLEncoder;public class Test {public static void main(String[] args) throws Exception {Long timestamp = System.currentTimeMillis();String secret = "this is secret替换为密钥";String stringToSign = timestamp + "\n" + secret;Mac mac = Mac.getInstance("HmacSHA256");mac.init(new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256"));byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));String sign = URLEncoder.encode(new String(Base64.encodeBase64(signData)),"UTF-8");System.out.println(sign);}}

签名代码示例Python

#python 3.8
import time
import hmac
import hashlib
import base64
import urllib.parsetimestamp = str(round(time.time() * 1000))
secret = 'this is secret'
secret_enc = secret.encode('utf-8')
string_to_sign = '{}\n{}'.format(timestamp, secret)
string_to_sign_enc = string_to_sign.encode('utf-8')
hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))
print(timestamp)
print(sign)
#python 2.7
import time
import hmac
import hashlib
import base64
import urllibtimestamp = long(round(time.time() * 1000))
secret = 'this is secret'
secret_enc = bytes(secret).encode('utf-8')
string_to_sign = '{}\n{}'.format(timestamp, secret)
string_to_sign_enc = bytes(string_to_sign).encode('utf-8')
hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
sign = urllib.quote_plus(base64.b64encode(hmac_code))
print(timestamp)
print(sign)

第二步

把 timestamp 和第一步得到的签名值分割到 URL 中。

https://oapi.dingtalk.com/robot/send?access_token=XXXXXX×&tamp=XXX&sign=XXX

3. IP 地址(段)

设定后,只有来自 IP 地址范围内的请求才会被正常处理。支持两种设置方式:IP,IP 段,暂不支持 IPv6 的地址白名单,格式如下:

安全设置的上述三种方式,需要至少设置其中一种,以进行安全保护。校正不通过的消息将会发送失败,错误如下:

 //消息内容中不包含任何关键词{“ERRCODE”:310000,“ERRMSG”: “关键字不是在内容”}//时间戳无效{“ERRCODE”:310000,“ ERRMSG “:”无效时间戳“}//签名不匹配{”ERRCODE“:310000,”ERRMSG“: ”符号不匹配“}// IP地址不在白名单{” ERRCODE“:310000,“ errmsg”:“ ip XXXX不在白名单中”}

python加签命令行测试

#钉钉收到消息即发送成功!
curl 'https://oapi.dingtalk.com/robot/send?access_token=XXXXXX&timestamp=XXXXXX&sign=XXXXXX' -H 'Content-Type: application/json' -d '{"msgtype": "text","text": {"content": " 我就是我, 不一样的烟火"}}'

使用docker运行

docker run -p 5000:5000 --name -e ROBOT_TOKEN=<钉钉机器人TOKEN> -e ROBOT_SECRET=<钉钉机器人安全SECRET> -e LOG_LEVEL=debug -e PROME_URL=prometheus.local dingtalk-hook -d cnych/alertmanager-dingtalk-hook:v0.3.5

环境变量配置
ROBOT_TOKEN:钉钉机器人
TOKEN PROME_URL:手动指定跳转后的 Promethues 地址,默认会是 Pod 的地址
LOG_LEVEL:日志级别,设置成 debug 可以看到 AlertManager WebHook发送的数据,方便调试使用,不需调试可以不设置该环境变量
ROBOT_SECRET:为钉钉机器人的安全设置密钥,机器人安全设置页面,加签一栏下面显示的 SEC 开头的字符串

在Kubernetes集群中运行

第一步建议将钉钉机器人TOKEN创建成Secret资源对象:

kubectl create secret generic dingtalk-secret --from-literal=token=<钉钉群聊的机器人TOKEN> --from-literal=secret=<钉钉群聊机器人的SECRET> -n kube-ops

定义Deployment和Service资源对象:(dingtalk-hook.yaml)

apiVersion: apps/v1
kind: Deployment
metadata:name: dingtalk-hooknamespace: kube-ops
spec:selector:matchLabels:app: dingtalk-hooktemplate:metadata:labels:app: dingtalk-hookspec:containers:- name: dingtalk-hookimage: cnych/alertmanager-dingtalk-hook:v0.3.6imagePullPolicy: IfNotPresentports:- containerPort: 5000name: httpenv:- name: PROME_URLvalue: prometheus.local- name: LOG_LEVELvalue: debug- name: ROBOT_TOKENvalueFrom:secretKeyRef:name: dingtalk-secretkey: token- name: ROBOT_SECRETvalueFrom:secretKeyRef:name: dingtalk-secretkey: secretresources:requests:cpu: 50mmemory: 100Milimits:cpu: 50mmemory: 100Mi---
apiVersion: v1
kind: Service
metadata:name: dingtalk-hooknamespace: kube-ops
spec:selector:app: dingtalk-hookports:- name: hookport: 5000targetPort: http

直接创建上面的资源对象

kubectl apply -f dingtalk-hook.yamlkubectl get pods -n kube-ops
NAME                            READY     STATUS      RESTARTS   AGE
dingtalk-hook-c4fcd8cd6-q22b6   1/1       Running     0          45m

最后在AlertManager中 webhook 地址直接通过 DNS 形式访问

receivers:
- name: 'webhook'webhook_configs:- url: 'http://dingtalk-hook.kube-ops.svc.cluster.local:5000'send_resolved: true

推荐(自定义告警配置)

参考

(二) prometheus报警-----自定义 / alertmanager监控,报警设置相关推荐

  1. java结合prometheus实现自定义数据监控

    一.配置prometheus prometheus.yml ...- job_name: 'my-service'metrics_path: /metricsstatic_configs:- targ ...

  2. 网络计算机自动巡检,奇辉巡检机器人 公安巡检机器人 自动巡检报警 安防监控报警...

    产品简介: "奇辉安防智能巡检机器人"具有夜视眼,360度全景无死角,昼夜清晰监测50米范围内的入侵影像. 通过自带AI系统,对闲杂人员.工作人员及车辆等进行识别,不受天气.地形等 ...

  3. [京东价格监控网站]自定义商品监控/品类商品监控/降价邮件提醒

    在京东购物时,你是否遇到如下情况: 心仪的商品降价了,你却一无所知,等发现了却只有四个大字"到货登记" 你设置了京东自带的降价提醒,结果京东在降价后很久才发邮件提醒你或者干脆没有提 ...

  4. prometheus监控报警部署Alertmanager

    Prometheus将告警分为两个部分:Prometheus 和 Alertmanager.其中Prometheus配置告警触发规则,对指标进行监控和计算,将再将告警信息发送到Alertmanager ...

  5. prometheus监控预警之AlertManager邮箱报警

    Alertmanager 主要用于接收 Prometheus 发送的告警信息,它支持丰富的告警通知渠道,例如邮件.微信.钉钉.Slack 等常用沟通工具,而且很容易做到告警信息进行去重,降噪,分组等, ...

  6. prometheus+alertmanager实现CPU、内存、磁盘的监控报警

    一.配置文件 在promethus安装目录下创建文件夹rules,在rules目录下创建文件host.rules vim host.rules 输入如下内容: groups: - name: Host ...

  7. 搭建Prometheus监控报警

    基于上一篇博客继续进行部署 一.Prometheus & AlertManager 介绍 Prometheus 是一套开源的系统监控.报警.时间序列数据库的组合,最初有 SoundCloud ...

  8. zabbix监控添加主机,报警、监控的设置

    根据使用zabbix这么久的经验,总结了一套zabbix比较实用的添加主机.监控报警的使用流程,供大家参考. 一:添加处理方法,就是如何报警 打开zabbix的管理------处理方法----crea ...

  9. 企业微信监控服务器数据接入,如何在alertmanager报警中添加企业微信监控报警

    如何在alertmanager报警中添加企业微信监控报警 发布时间:2020-06-17 15:19:06 来源:亿速云 阅读:535 作者:元一 栏目:云计算 Prometheus机器:172.27 ...

最新文章

  1. mysql 分号 存储过程_MySql 存储过程
  2. [C++再学习系列] 函数模板和类模板
  3. 【最后测试点超时】1063 Set Similarity (25 分)_22行代码AC
  4. Request download hierarchy check
  5. [luogu 4292][bzoj 1758][WC2010] 重建计划(点分治 + dp + 单调队列优化 + 启发式合并)
  6. java读取文件夹_Java读取某个文件夹下的所有文件(支持多级文件夹)
  7. spring官方文档列表
  8. csdn中让图片居中
  9. ArcGIS10.2的详细安装过程和下载方法
  10. oracle11g教程视频教程,最新oracle11g DBA 开发和应用数据库视频教程_IT教程网
  11. 计算机应用键盘的组成指导书,《计算机应用基础》实验指导书.doc
  12. Web后端开发入门(1)
  13. 2021爱分析·智慧城市厂商全景报告
  14. 现代魔法学院——闲聊哈希表及哈希表的链地址法实现
  15. Appium工作日记:Message: An element could not be located on the page using the given search parameters.
  16. sipp脚本撰写(二)
  17. 如何在Windows和Mac下挂载EFI分区
  18. (非常重要).Net Core应用框架Util介绍(学习Util)
  19. 【捡肥皂】Microsoft SQL Server 2000 MSSQL2000下载中文企业版个人版免费下载
  20. windows提权常用系统漏洞与对应的补丁编号

热门文章

  1. android卡为什么iOS不卡,同内存下苹果不卡,安卓却很卡,原因在这里
  2. 这几个条件教你选择靠谱的短信验证码平台!
  3. 简述静态时序分析的三种分析模式
  4. 短语动词(Phrasal Verb)
  5. 成都盛迈坤电商:店铺直通车要怎么操作
  6. Centos7 ping不通百度
  7. 声如其闻,DuerOS中的声音播放
  8. mysql修复表分区_mysql 分区表的管理操作
  9. c语言链表排序新增头指针法,C语言链表头插法,尾插法,排序
  10. 单总线LED灯 幻彩LED灯 控制代码,以及相关记录