0%

gradle ssh plugin使用的jsch library并不能识别debian系统~/.ssh/known_hosts里面的hostkey格式,从而报reject hostkey错误。

使用如下命令获取主机的hostkey

1
$ ssh-keyscan -t rsa -p port host_ip_or_name

将输出的主机key指纹添加到~/.ssh/known_hosts即可。

References:
[1]Remote tomcat deployment with Gradle
[2]Solution for com.jcraft.jsch.JSchException: reject HostKey problem on Ubuntu

===
[erq]

gulp-debug插件可以显示哪些文件经过了gulp的流水线(pipeline)

安装

1
$ npm install --save-dev gulp-debug

使用

1
2
3
4
5
6
7
8
var gulp = require('gulp');
var debug = require('gulp-debug');

gulp.task('default', function () {
return gulp.src('foo.js')
.pipe(debug())
.pipe(gulp.dest('dist'));
});

gulp运行时就会输出流中所有处理的文件名:

1
\[22:20:36\] gulp-debug: foo.js

使用gulp-util输出错误

1
2
3
4
5
6
7
// minify js
gulp.task('minifyJs', \['clean'\], function(){
return gulp.src(\['**/*.js'\])
.pipe(uglify().on('error', util.log))
.pipe(debug())
.pipe(gulp.dest('dist'));
});

References:
[1]gulp-debug
[2]Utilities for gulp plugins

===
[erq]

数据库高可用是为了降低停机时间,提高数据库服务器的持续服务能力,减少数据丢失,减少服务恢复时间。

大体可以有以下几个分类:

  • cold standby
    最传统的备份/恢复模式属于此类。主库定期备份,备份数据可以存储到主库以外的其他存储介质上。当主库当机时,启动备机,从备份中恢复主库最近的一次备份,然后接替主库对外提供服务。这种模式数据丢失的风险极大,最后一次备份到当机之间的数据丢失的可能性很大。而且,当数据库很大时,备机的恢复时间可能会相当长,达几个小时甚至几十个小时。
  • warm standby
    主备库同时运行,主库数据以同步或异步方式复制到备库,主库崩溃时的恢复时间很短,但是备库在正常状态下是无法提供服务的。
  • hot standby
    主备库同时运行,主库数据以同步或异步方式复制到备库,主库崩溃时的恢复时间很短,备库可以提供只读查询服务。如果是流式复制方式,一般提交的事务都不会丢失。数据丢失的风险很低。
  • active-active
    这就是传说中的双活或多活,或叫master-master模式,多个数据库互为主备,一起对外提供服务,一个崩溃,不影响系统对外提供服务,只是服务的性能会有下降。这种模式又可以称作负载均衡load balance。

postgresql对warm standby和hot standby的定义:

A standby server that cannot be connected to until it is promoted to a master server is called a warm standby server, and one that can accept connections and serves read-only queries is called a hot standby server.

===
[erq]

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
var gulp = require('gulp');
var jshint = require('gulp-jshint');
var concat = require('gulp-concat');
var rename = require('gulp-rename');
var uglify = require('gulp-uglify');
var usemin = require('gulp-usemin');
var minifyCss = require('gulp-minify-css');
var minifyHtml = require('gulp-minify-html');
var rev = require('gulp-rev');
var del = require('del');

// lint JS,静态检查js语法错误
gulp.task('lint', function(){
return gulp.src('js/**/*.js')
.pipe(jshint())
.pipe(jshint.reporter('default'));
});

// Concat & Minify JS,合并压缩重命名js
gulp.task('minify', function(){
return gulp.src('js/*.js')
.pipe(concat('dwz.js'))
.pipe(gulp.dest('dist'))
.pipe(rename('dwz.min.js'))
.pipe(uglify())
.pipe(gulp.dest('dist'));
});

// clean,清理输出目录
gulp.task('clean', function(){
return del('dist/*');
});

rename插件还可以接收一个函数对重命名进行更复杂的控制:

1
2
3
4
.pipe(rename(function(path){
path.basename += '.min';
path.extname = '.js';
}))

===
[erq]

一般前端页面上线时,需要进行js,css等资源的合并、压缩,以便提高网络性能,而开发版本的html页面中添加了很多未合并压缩前的js,css资源。gulp插件gulp-usemin可以自动化的完成这一切。

js,css资源的合并、压缩习惯上称做minify,所以替换html文件中js,css的路径顺利成章的就叫做usemin了。

构建标记块build block

html文件中需要使用usemin可以识别的注释格式来标记需要压缩、合并和替换的资源

1
2
3
<!-- build:<pipelineId>(alternate search path) <path> -->
... HTML Markup, list of script / link tags.
<!-- endbuild -->

其中:

  • piplelineId
    调用usemin时,可以通过pipelineId来指定此build block,从而为其指定相应的处理动作。如果piplelineId指定为关键词remove,则将在输出的html文件直接删除掉该构件块。
  • alternate search path
    默认的输入文件,比如js或css文件,是相对于当前处理的html文件的,alternate search path可以指定搜索路径。
  • path
    合并、压缩优化之后文件的输出路径。如果不指定path,则将处理之后的输出内联入html文件。

usemin选项

  • assetsDir
    输出文件的根目录,build block中path指定的路径就是相对于此路径。
  • path
    默认的alternate search path,可以被build block中的alternate search path覆盖。
  • pipelineId
    用于标识build block的标识符
  • outputRelativePath
    压缩合并后的输出文件相对于html文件的路径
  • enableHtmlComment
    保留html注释

比如有如下的目录结构:

1
2
3
4
5
6
7
8
9
10
11

+- app
+- index.html
+- assets
+- js
+- foo.js
+- bar.js
+- css
+- clear.css
+- main.css
+- dist

我们需要将foo.js和bar.js合并压缩为optimized.js,两个css文件合并压缩为style.css
index.html文件是这样定义构件块的:

1
2
3
4
5
6
7
8
9
<!-- build:css_whatever style.css -->
<link rel="stylesheet" href="css/clear.css"/>
<link rel="stylesheet" href="css/main.css"/>
<!-- endbuild -->

<!-- build:js_whatever js/optimized.js -->
<script src="assets/js/foo.js"></script>
<script src="assets/js/bar.js"></script>
<!-- endbuild -->

输出文件路径为dist,gulpfile.js中定义usemin任务如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
var gulp = require('gulp');
var usemin = require('gulp-usemin');
var uglify = require('gulp-uglify');
var minifyCss = require('gulp-minify-css');

gulp.task('usemin', function () {
return gulp.src('./app/index.html')
.pipe(usemin({
js_whatever: \[uglify()\],
css_whatever: \[minifyCSS()\]
}))
.pipe(gulp.dest('dist/'));
});

将会产生如下的目录结构:

1
2
3
4
5
6
7
8
9
10
11
12

+- app
+- index.html
+- assets
+- js
+- foo.js
+- bar.js
+- dist
+- index.html
+- js
+- optimized.js
+- style.css

而dist/index.html将会是这个样子的:

1
2
3
<link rel="stylesheet" href="style.css"/>

<script src="js/optimized.js"></script>

References:
[1]gulp-usemin

===
[erq]

修改了/etc/fstab添加新的自动挂载设备后,可以使用

1
# mount -a

命令使其立即挂载,而不必重新启动机器。

dmesg有如下类似错误提示:

1
2
3
4
kernel: device-mapper: table: 253:3: multipath: error getting device
kernel: device-mapper: ioctl: error adding target to table
kernel: device-mapper: table: 253:3: multipath: error getting device
kernel: device-mapper: ioctl: error adding target to table

极有可能是因为multipathd试图在一个已经打开的设备上创建多路径设备,通常是因为这些设备并不是多路径设备,应该在配置文件中屏蔽掉而没有屏蔽的原因。

Are most likely due to multipathd attempting to create a multipath device on top of an already opened device. This is usually because there are device that should be blacklisted which are not.

References:
[1]multipath: error getting device

===
[erq]

外部CSS文件中相对URL的相对起始路径是CSS文件的路径,也就是相对URL是相对于CSS文件路径的。而js文件中的相对路径则是以导入此js的网页文件所在的位置为基准的。