Git Commant Summary

1.git checkout

  • 撤销

使用– filte 可以撤销文件修改到上一次commit或者add状态

1
git checkout -- readme.md
  • 切换分支

直接跟分支名称,可以切换到指定分支上

1
git checkout master

2.git rebase

将指定分支合并到当前分支

1
git rebase origin

3.git remote

添加远程仓库

1
git add origin https://github.com/TrumanDu/nav-dashboad.git

4.git fetch

1
git fetch origin

丢弃本地改动与提交,从指定地方获取最新版代码到本地主分支

5.git reset

1
git reset --hard origin/master

丢弃本地改动与提交,从指定地方获取最新版代码到本地主分支

在express站点中使用ejs模板引擎

选择ejs 是因为使用类似jsp技术,使用方式很像,页面可读性要比jade要好,个人习惯使用ejs。

配置模板

1
2
3
4
5
6
7
var express = require('express');

var app = express();
app.set('views', './views')
app.engine('.html', require('ejs').__express);
app.set('view engine', 'html');

后台代码

1
2
3
app.use('/demo', function (req, res, next) {
res.render('demo', {'template':"ejs});
});

模板代码

demo.html

1
2
3
4
5
6
7
<!DOCTYPE html>
<html lang="en">
<body>
hello <%=template %>
</body>
</html>

node.js读取json文件

目的

在node.js项目中如何获取json文件,本篇文章主要讲述两个方面:1.客户端 2.服务端。

实践

本次采用web框架为express

1.客户端
目录结构为:

1
2
3
4
5
/
/public/conf/demo.json
/index.js
/package.json
/index.html

index.js内容如下:

1
2
3
4
5
6
var express = require('express');
var app = express();
app.use(express.static('public'));
app.listen(80, function () {
console.log('Example app listening on port 80!');
});

在index.html中获取如下:

1
2
3
$.getJSON('conf/demo.json', function (data) {
console.log(data);
})

2.服务端
index.js内容如下:

1
2
3
4
5
6
7
8
9
var express = require('express');
var app = express();
var CONFPATH = "./public/conf/demo.json";
var fs = require('fs');
var result = JSON.parse(fs.readFileSync(CONFPATH));
console.log(result);
app.listen(80, function () {
console.log('Example app listening on port 80!');
});

Kibana之sentinl slack使用教程

简介

Slack是一个团队协作沟通平台,至于它的强大,就不在这里多说了,sentinl 集成slack,可以将监控告警发送至其中,这个平台支持PC和APP,可以让开发运维人员实时获取监控服务状态。

申请slack

  1. 注册账户
  2. 点击右上方按钮创建workspace
  3. 新建channel ,进入创建好的workspace,在左侧菜单栏创建,将该chanel设置成public
  4. 集成incoming-webhook,获取Webhook URL。详细步骤详见此处

kibana配置

在kibana.yml配置文件中增加以下内容

1
2
3
4
5
6
7
8
sentinl:
settings:
slack:
active: true
username: truman
hook: 'https://hooks.slack.com/services/******/*****/*****'
channel: '#messagesend'

其中hook配置项为Webhook URL

sentinl 配置slack action

在sentinl中增加slack action

1
2
3
4
5
6
7
"slack action": {
"throttle_period": "0h0m1s",
"slack": {
"channel": "#messagesend",
"message": "payload.hits.total:{{payload.hits.total}}",
"stateless": false
}

nodejs邮件发送

介绍

node.js发送邮件有多种第三方模块,比较有名的是emailjs,nodemailer,个人感觉emailjs更轻量级,使用更简单,nodemailer关注人更多,功能更加完善。

实践

本次选用这两种,仅实现简单发送邮件功能,更多功能,请查询官网API.
首先新建文件夹node,然后在该文件夹下新建package.json文件,在其中增加以下配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"name": "node_email_demo",
"description": "application created by truman",
"version": "1.0.0",
"dependencies": {
"emailjs": "^1.0.8",
"nodemailer": "^4.1.0"
},
"repository": "",
"license": "MIT",
"engines": {
"node": ">=6.0.0"
},
"readmeFilename": "README.md"
}

在node 目录下执行命令

1
npm install
  • emailjs
    新建myemailjs.js文件,添加如下内容:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    var email       = require("emailjs");
    var server = email.server.connect({
    user: "aibibang@sohu.com",
    password:"*********",
    host: "smtp.sohu.com",
    ssl: false
    });

    // send the message and get a callback with an error or details of the message that was sent
    server.send({
    text: "i hope this works",
    from: "aibibang@sohu.com",
    to: "aibibang@sohu.com",
    subject: "testing emailjs"
    }, function(err, message) { console.log(err || message); });

执行即可发送成功!

1
node myemailjs.js
  • nodemailer
    新建mynodemailer.js文件,添加如下内容:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const nodemailer=require("nodemailer");

let transporter = nodemailer.createTransport({
host: 'smtp.sohu.com',
port: 25,
auth: {
user: "aibibang@sohu.com", // generated ethereal user
pass: "*********" // generated ethereal password
},
secure: false // true for 465, false for other ports
});
var message = {
from: 'aibibang@sohu.com',
to: 'aibibang@sohu.com',
subject: 'nodemailer test',
text: 'i hope this works'
};

transporter.sendMail(message, function(err){
if(err){
console.log(err);
}
});

执行即可发送成功!

1
node mynodemailer.js

总结

  1. 如果SMPT服务器没有进行安全校验,那么一定要去掉用户与密码,这点要和java API区别,切记,为了这个问题,花费了一天代价。
    例如如下问题:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    { Error: no form of authorization supported
    at module.exports (/data/truman/node/node_modules/emailjs/smtp/error.js:2:13)
    at initiate (/data/truman/node/node_modules/emailjs/smtp/smtp.js:543:44)
    at caller (/data/truman/node/node_modules/emailjs/smtp/smtp.js:48:14)
    at attempt (/data/truman/node/node_modules/emailjs/smtp/smtp.js:415:14)
    at caller (/data/truman/node/node_modules/emailjs/smtp/smtp.js:48:14)
    at response (/data/truman/node/node_modules/emailjs/smtp/smtp.js:345:13)
    at caller (/data/truman/node/node_modules/emailjs/smtp/smtp.js:48:14)
    at response (/data/truman/node/node_modules/emailjs/smtp/smtp.js:201:11)
    at caller (/data/truman/node/node_modules/emailjs/smtp/smtp.js:48:14)
    at Socket.response (/data/truman/node/node_modules/emailjs/smtp/smtp.js:181:11)
    code: 7,
  2. 对于本地是否可以访问SMTP服务器,可以使用telnet,进行查验,如果都无法telnet通,肯定是无法发送邮件的。
    1
    telnet smtp.sohu.com 25

Sentinl-(Kibana Alert&Report App for Elasticsearch)

前言

最近公司ES集群升级到5.5.1,新版增加了许多新的功能,也废弃了一些特性,同时整合一些插件,做了一个统一的封装,ES栈也越来越丰富,强大了。

最近有增加X-PACK,X-Pack是一个Elastic栈扩展,将安全性,警报,监视,报告和图形功能捆绑到一个易于安装的软件包中。 X-Pack组件旨在无缝协同工作,您可以轻松地启用或禁用要使用的功能。

然并卵,这个东西是要收费的,但是这个并不妨碍开源方案,Sentinl就是一个开源方案,作为kibana插件,集成在kibana中,主要提供了预警和报告功能,在架构设计上往X-PACK上靠拢,只提供了一些基本功能,但对于目前一些简单业务需求,完全可以满足需求,这个软件开源不久,期待更多完善。

Sentinl简介

Sentinl 5扩展自Kibi / Kibana 5,具有警报和报告功能,可使用标准查询,可编程验证器和各种可配置操作来监控,通知和报告数据系列更改 - 将其视为一个独立的“观察者” “报告”功能(PNG / PDFs快照)。

SENTINEL还旨在通过直接在Kibana UI中整合来简化在Kibi / Kibana中创建和管理警报和报告的过程。

功能模块

  • Watchers
  • Alarms
  • Reports

Watchers是Sentinl核心,主要由 input,Condition,Transform,Actions几大块组成,可以和X-Pack一一对应,部分文档可参考X-Pack,但需要注意的是它和X-Pack还有一些区别,主要体现在input只实现了search,其他并未实现,Actions也并未都实现

Sentinl安装与配置

1. 安装

1
/opt/kibana/bin/kibana-plugin install https://github.com/sirensolutions/sentinl/releases/download/tag-5.5/sentinl-v5.5.1.zip

2. 配置
在kibana.yml添加以下内容,可以根据具体需求删减

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
sentinl:
es:
timefield: '@timestamp'
default_index: watcher
type: watch
alarm_index: watcher_alarms
sentinl:
history: 20
results: 50
settings:
email:
active: false
user: username
password: password
host: smtp.server.com
ssl: true
timeout: 10000 # mail server connection timeout
slack:
active: false
username: username
hook: 'https://hooks.slack.com/services/<token>'
channel: '#channel'
report:
active: false
tmp_path: /tmp/
pushapps:
active: false
api_key: '<pushapps API Key>'

使用案例

业务需求:

监控指定索引1小时内数量大于1w,控制台提醒

实践:

  1. 配置General

输入名称和监控频率
2. 配置input

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
"search": {
"request": {
"index": [
"shoppingcartapi-*"
],
"body": {
"_source": false,
"query": {
"bool": {
"filter": {
"range": {
"post_date": {
"from": "now-1h"
}
}
}
}
}
}
}
}
}

其中shoppingcartapi-*为索引模糊名称,post_date为时间字段
3. 配置Condition

1
payload.hits.total > 10
  1. 配置Action

配置一个console action message填写以下内容

1
payload.hits.total:{ {payload.hits.total} }

Tip:通过{ { } }可以拿出search结果中的值,此处有空格是避免hexo问题,正常使用无需如此。

node.js简介

what node.js?

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。
Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型,使其轻量又高效。
Node.js 的包管理器 npm,是全球最大的开源库生态系统。

node.js 原理

NodeJS的工作原理其实就是事件循环。可以说每一条NodeJS的逻辑都是写在回调函数里面的,而回调函数都是有返回之后才异步执行的!

应用场景

既然NodeJS处理并发的能力强,但处理计算和逻辑的能力反而很弱,因此,如果我们把复杂的逻辑运算都搬到前端(客户端)完成,而NodeJS只需要提供异步I/O,这样就可以实现对高并发的高性能处理。情况就很多啦,比如:RESTFUL API、实时聊天、客户端逻辑强大的单页APP,具体的例子比如说:本地化的在线音乐应用,本地化的在线搜索应用,本地化的在线APP等。

node.js优缺点

优点

  1. 采用事件驱动、异步编程,为网络服务而设计。其实Javascript的匿名函数和闭包特性非常适合事件驱动、异步编程。而且JavaScript也简单易学,很多前端设计人员可以很快上手做后端设计。
  2. Node.js非阻塞模式的IO处理给Node.js带来在相对低系统资源耗用下的高性能与出众的负载能力,非常适合用作依赖其它IO资源的中间层服务。
  3. Node.js轻量高效,可以认为是数据密集型分布式部署环境下的实时应用系统的完美解决方案。Node非常适合如下情况:在响应客户端之前,您预计可能有很高的流量,但所需的服务器端逻辑和处理不一定很多。

缺点

  1. 可靠性低
  2. 单进程,单线程,只支持单核CPU,不能充分的利用多核CPU服务器。一旦这个进程崩掉,那么整个web服务就崩掉了。

最近做docker image,编写shell 脚本,遇到以下问题,做个记录

1.问题一:

1
2
3
if [ "${1:0:1}" = '-' ]; then
set -- elasticsearch "$@"
fi

解释:以上if 条件是指第一个参数的第一个字符为-,则符合条件

2.问题二:

1
exec "$@"

解释:exec执行命令

3.问题三:

1
set -- elasticsearch "$@"

解释:set设置环境,这句话的意思其实是将elasticsearch 作为第一个参数补充到”$@”中
例如:
demo.sh

1
2
3
#!/bin/bash
set -- elasticsearch "$@"
echo "$@"

执行脚本

1
bash demo.sh hello truman

输出结果为:elasticsearch hello truman

4.问题四:

1
"$(id -u)"

解释:输出当前shell 环境UID(用户ID)

RediSearch 探索

简介

RediSearch是一个高性能的全文搜索引擎,可作为一个Redis Module 运行在Redis上,是由RedisLabs团队开发的。

特性

  • 多字段全文检索
  • 增量索引无性能损失
  • 文档排序
  • 复杂的子查询 and,or,not
  • 可选查询子句。
  • 基于前缀的搜索
  • 字段权重
  • 自动完成建议(使用模糊前缀建议)
  • 精确词组搜索,基于Slop的搜索
  • 基于Stemming的查询扩展在许多语言(使用Snowball)
  • 支持用于查询扩展和评分的自定义函数(请参阅扩展)。
  • 限制搜索到特定文档字段(最多支持8个字段)。
  • 数字过滤以及范围查找
  • 使用Redis自己的地理命令进行地理过滤
  • 支持任何utf-8编码文本
  • 检索完整的文档内容或只是ids
  • 将现有的HASH键自动索引为文档
  • 使用索引垃圾回收文档删除和更新

入门

安装/运行

1
2
3
4
5
wget https://github.com/RedisLabsModules/RediSearch/archive/v0.19.1.tar.gz
tar xvf v0.19.1.tar.gz
cd RediSearch-0.19.1/src
make all
nohup redis-server --loadmodule ./redisearch.so &

1. 创建索引

1
2
3
127.0.0.1:6379> FT.CREATE myIDs SCHEMA title TEXT WEIGHT 5.0 body TEXT url TEXT
OK

2. 增加文档到该索引

1
2
3
127.0.0.1:6379> FT.ADD myIDs doc1 1.0 FIELDS title "hello world" body "lorem ipsum" url "http://redis.io"
OK

3. 在该索引中搜索

1
2
3
4
5
6
7
8
9
10
127.0.0.1:6379> ft.search myIDs "hello world" limit 0 10
1) (integer) 1
2) "doc1"
3) 1) "title"
2) "hello world"
3) "body"
4) "lorem ipsum"
5) "url"
6) "http://redis.io"

4. 删除索引

1
2
3
127.0.0.1:6379> ft.drop myIDs
OK

5. 添加并获取自动完成建议

1
2
3
4
5
127.0.0.1:6379> ft.sugadd autocomplete "hello truman" 100
(integer) 1
127.0.0.1:6379> ft.sugget autocomplete "he"
1) "hello truman"

引用

  1. redisearch.io

Redis 运维shell 工具

介绍

在Redis 集群运维过程中,经常需要做一些重复性工作,因为Redis 无中心设计,这就需要在每个节点中执行相同命令,对于这些重复性劳动工作完全可以通过shell处理,降低运维难度,减少工作量,以下是我在工作冲总结的脚本,仅供大家参考。

工具集

1. 集群健康状态检测

新建脚本redis_tool.sh,然后执行

1
sh redis_tool.sh clusterStatus 127.0.0.1 7000

2. 移除fail节点

新建脚本redis_tool.sh,然后执行

1
sh redis_tool.sh forget 127.0.0.1 7000

脚本内容

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
#!/bin/sh

function clusterStatus(){
instans=`redis-cli -c -h $1 -p $2 cluster nodes|grep -v fail|awk '{print $2}'`
for var in ${instans[@]};
do
echo $var
host=${var%:*}
port=${var#*:}
redis-cli -c -h $host -p $port cluster info |grep cluster_state:fail
done
}

function forget(){
instans=`redis-cli -c -h $1 -p $2 cluster nodes|grep -v fail|awk '{print $2}'`
for var in ${instans[@]};
do
echo $var
host=${var%:*}
port=${var#*:}
failnodes=`redis-cli -c -h $host -p $port cluster nodes|grep fail|awk '{print $1}'`
for nodeid in ${failnodes[@]};
do
echo $nodeid
redis-cli -c -h $host -p $port cluster forget $nodeid
done

done
}

# main start
case $1 in
clusterStatus)
echo "check redis cluster cluster_state..."
clusterStatus $2 $3;
;;
forget)
echo "forget redis fail nodes ..."
forget $2 $3;
;;
*)
echo "Usage: the options [clusterStatus|forget]"
;;
esac
0%