墨语的后花园

墨语的后花园

序言

迭代开发的基本要求:

  • 迭代要有固定时长——不能超过6个星期
  • 在没一次迭代的结尾,代码都必须经过QA的测试,能够正常工作

Nokia的Scrum标准:

  • Scrum团队必须要有产品负责人,而且团队都应该清楚这个人呢是谁
  • 产品复测人必须要有产品的Backlog,其中包括团队对它进行的估算
  • 团队必须要有燃尽图,而且要了解他们自己的生产率
  • 在一个Sprint中,外人不能干涉团队的工作

第一章

Scrum不是方法学,它是一个框架

第二章

对于实践中我遇到的情况最好是产品能将业务描述清楚,而不是考虑到技术与业务上实现的问题,有基本上的BDD描述,这样开发就能够根据产品的文档进行技术设计

第三章

在sprint计划会议之前,要确保产品backlog尽然有序

不是要求有完备的文档,而是对需要进行的工作有准确的描述,对产品边界上有准确的评估,并且能对自己所设计的功能有进行解释的准备,而不是 在和技术人员交流的时候死缠栏打

产品负责人之外的人能添加新的story,但是不能对功能的考核和工作量进行估计

第四章

制定sprint技术是在整个Scrum中最重要的活动

sprint会议应当产生的成果:

  • sprint目标
  • 团队成员名单(应当包括每个人能投入工作的程度)
  • sprint backlog
  • 确定号sprint演示日期
  • 确定好时间地点,供举行每日的scrum会议

当产品负责人坚持没时间不参加sprint会议以尝试的策略:

  • 试着让产品负责人理解,为什么他的直接参与事关项目成败
  • 试着在团队中找到某个人,让他在会议中充当产品负责人的代表
  • 试着说服管理团队为我们分配新的产品负责人
  • 推迟sprint的启动时间,直到产品负责人找到时间参会为止

牺牲内部质量是一个错误的决定,一旦牺牲内部质量,在后期就要 投入更多的精力取解决这些事情

学会按照时间盒安排工作,学会制定合乎情理的时间盒,这对会议长度和sprint长度同样有帮助

决定story进入到sprint里的方法:

  1. 本能反应
  2. 生产率计算

用生产率计算来估计包括两步:

  1. 得出估算生产率
  2. 计算在不超过估算生产率的情况下可以加入多少story

产品负责人应当对团队的生产率进行合理评估,控制好产品开发的进度(评估不是给出精确的结果,而是能对sprint的进度有所管控)

可以在进行项目决策的使用索引卡

不要将任务拆分出现在产品的backlog中,原因有:

  • 任务拆分的随机性较强
  • 产品负责人不需要关心这种细节程度

对于产品负责人说,任务的细分不是其职责,任务的划分应该下放到技术负责人中,由技术团队来对任务进行划分,在此过程中,技术负责人的目标应该是对所开发的产品和stroy进行解释

当Scrum团队中测试人员说可以,这个story就算是结束了

除此之外,其他人都无法决策这个story是否结束(除非这个sprint流产)

第五章

当sprint结束的时候,应该向全公司发送sprint的信息,应当包含这个sprint的目标,进度,相关文档和开发人员信息,以此让公司同事了解到团队正在做的事情

第六章

将sprint backlog的信息公开放置到团队人员能看到的地方,以便了解进度,可以考虑结合看板和燃尽图的模式

在使用燃尽图的时候,应当将休息时间排除在外

第七章

让团队坐在一期

当然产品负责人应该距离团队很近,就算不能在一起,也得尽量不合开发团队的整体分开

第八章

当一个个人经常不能完成sprint中的目标,这个时候应该进行单独的辅导,如果还是这样,在衡量他不是太重要之后,就试着将他从团队中挪走

第十章

在进行sprint回顾的时候,只要能清楚的指出问题的所在,到了下一个sprint,问题也许就自行解决了

第十一章

可以在两个sprint之间安排实验日,用于研究新的技术,学习新的技术,或者可以进行分享活动

第十二章

推荐书目:敏捷估计与规划

第十三章

测试驱动开发意味着要先写一个自动测试,然后编写恰好嫩巩固用的代码,让它通过这个测试,接着对代码进行重构,提高代码的可读性和消除重复,整理一下然后继续

第十四章

在一个sprint中及早发现并修复bug,要比sprint结束后再这样做的代价小得多

在没个sprint版本中加入一些上个sprint后来发现的bug是一个很好的解决办法

第十五章

将各个sprint团队的周期保持一致是一个很好的做法

使用跨组件的团队可以很好的对功能和任务进行分配

在一个sprint中的story中,一定得分出优先级,这样才能更好有序的开发(并且可以防止中间出现意外事件)

在开发中不可避免都需要对时间进行计算,尤其在处理财务方面的需求都时候,就经常需要
考虑时间的问题。由于Java8之前标准库在时间方面的问题,对于时间都处理就十分都麻烦,
甚至可以说是十分的恶心了,所以在Java8的时候就根据第三Jodo库实现了一个新的时间库
时间库(java.time),我现在就简单的介绍下使用,也算式我最近经常使用时间库进行编程操作都一个总结吧:

time库都操作基本都是函数式的

函数式

时间转换

在对时间进行处理都时候,最常见的两个操作就是将字符串转换成时间或者在各种时间格式之间机型转换,这在之前基本上是要依赖SimpleDateFormat来进行操作,但是这样会存在许多问题,其中时区就可以能是其中一个问题

字符串转换时间

对于年月日或者年月日时分秒这种比较标准都时间格式来说,我们可以直接使用自带都方法
进行转换,需要指定特定的时间格式可以使用$DateTimeFormatter$中的数据,如果这这都
不太合适,还可以自定义$DateTimeFormatter$的实现。

1
2
3
4
5
6
7
8
9
10

// 年-月-日
LocalDate.parse("date string");

// 年-月-日 时:分:秒
LocalDateTime.parse("date string");

// 年-月 这种一般在财务计算中常见
YearMonth.parse("date string");

对于一些需要自定义都时间格式来说,我们可以使用Java8自带都时间格式函数来进行转换:

1
2
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate.parse("date string", formatter);

时间转字符串

在转换成时间都时候,如果式向数据比较标准的时间格式,其实直接使用toString()方法或者String.valueOf()就可以很好的处理时间数据了。但是向转换到一写特使格式都时候,我们同样可以使用DateTimeFormatter来完成我们都操作:

1
2
3
LocalDate localDate = LocalDate.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd LLLL yyyy");
String formattedString = localDate.format(formatter);

时间处理

对于时间都处理,一般分为取间隔,时间的比较,时间的增加,这些操作在标准库中都有比较好的实现,我们可以直接取过来使用:

时间间隔

在使用这个方法取得时间的间隔都时候,会存在一个问题:按月都时候不是开闭包含都;精确到天或者月的时候,最后一个月不足自然的半个月都时候式不算一个月都。

1
long intervalMonth = ChronoUnit.MONTHS.between(startDate, endDate);

时间增减及比较

这个直接取时间库中都函数就可以完成:

1
2
3
4
5
// 在这里,时间都操作式函数式的,每次都返回一个新的时间对象
LocalDate newDate = oldDate.plusMonths(1);

// 比较精都和时间的精度有关,两个日期比较就精确到天
boolean isBefore = sourceDate.isBefore(targetDate);

特殊操作

在进行时间处理都时候,经常需要取这个月有多少天,这个月都月末是什么时候的操作

1
2
3
4
5
// 这个月都最后一天
YearMonth sourceDate = targetDate.with(TemporalAdjusters.lastDayOfMonth())

// 这个月的天数
int length = targetDate.lengthOfMonths();

时间转换

在以前,在对时间进行相互转换都时候需要借助字符串作为中间态,但是使用Java8的标准库之后,时间对象可以直接从大精度转换成小精度:

1
LocalDateTime -> LocalDate -> YearMonth

当由小精度转换成大精度都时候,只需要补全下精度就行了:

1
2
LocalDate sourceDate = LocalDate.now();
LocalDateTime targetDate = sourceDate.atTime(20, 11, 22);

今天想来介绍一下目前算是经常用的一个编辑器,那就是VIM。这个东西基本上自从我使用Linux开始就伴随着我使用Linux的过程,对于为什么使用这个上古编辑器,我会在下面解释。

为什么

在现在的那些IDE的功能都非常好的情况下,为什么我要使用这么一个上古级别的编辑器呢?难道只是为了装逼,还是为了其它的。我在配置Vim以及Emacs的时候想过一个问题,我们是需要一个简单的代码编辑器呢还是需要一个功能齐全的大杂烩,像许多IDE一样什么功能都有。在那么强的IDE下面写代码有的时候感觉写代码就像是在学习一个IDE在怎么使用,不是在进行编程,感觉像是IDE的努力奴隶一样。当然对于初学者来说使用IDE能省下许多的力气,可以将大部分的精力放在学习上面。

对于我使用Vim的需求来说,主要差不多就只有亮点,代码高亮以及补全,对于调试来说我基本不太需要,因为使用Vim的大部分场景都是在服务器上面,主要面对的语言还是Python之类的脚本语言为主,其他时候的编码我大部分是在VSCode以及Idea上面完成的。

配置

对于Vim的安装我不想做介绍,没有意义,我就来介绍一下我写的配置,完整配置位于我的Github上面:vimrc中。使用Vim,但是不是简单的使用它的快捷键,还应该使用其丰富的插件才行,这样感觉才爽。其实更多的时候使用vim键位其实比使用纯vim更加能提高开发的效率。并且我还建议参考下Spacevimspf13这两个的配置来编写适合自己的配置。

vim-plug

对于官方给的安装方式,需要使用的是Git手动安装,但是既然我们都使用了vim了,为什么我们不卸载Vim的配置文件中让其自动加载呢,所以我们可以在.vimrc中写入如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
if !filereadable(vimplug_exists)
if !executable("curl")
echoerr "You have to install curl or first install vim-plug yourself!"
execute "q!"
endif
echo "Installing Vim-Plug..."
echo ""
silent !\curl -fLo ~/.vim/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
let g:not_finish_vimplug = "yes"

autocmd VimEnter * PlugInstall
endif

这样在使用vim的时候会自动检查vimplug这个插件是否存在,当不存在的时候会去GitHub上面将Vim-plug这个插件下载下来,这样就可以使用了。

对于vim的插件来说,我使用的有这些:

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
call plug#begin(expand('~/.vim/plugged'))

"***********************
"" Plug install packages
"***********************
Plug 'scrooloose/nerdtree'
Plug 'tpope/vim-fugitive'
Plug 'airblade/vim-gitgutter' " git历史
Plug 'jiangmiao/auto-pairs' " 自动补全括号
Plug 'majutsushi/tagbar' " 代码组成
Plug 'w0rp/ale' " 语法检测
Plug 'Yggdroot/indentLine' " 对齐线
Plug 'sheerun/vim-polyglot' " 语言集合
Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --bin' }
Plug 'Shougo/vimproc.vim', {'do': 'make'}
Plug 'haya14busa/incsearch.vim' " 高亮搜索内容
Plug 'Valloric/YouCompleteMe', { 'do': './install.py --clang-completer --system-libclang --go-completer --js-completer --rust-completer' }
Plug 'junegunn/vim-easy-align' " 等号对齐
Plug 'luochen1990/rainbow' " 高亮括号
Plug 'ntpeters/vim-better-whitespace' " 去除多余括号
Plug 'scrooloose/nerdcommenter' " 代码注释
Plug 'ryanoasis/vim-devicons' " Vim Dev Icons

" themes
Plug 'vim-airline/vim-airline'
Plug 'vim-airline/vim-airline-themes'
Plug 'morhetz/gruvbox'

" fzf
Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' }
Plug 'junegunn/fzf.vim'

"" Snippets
Plug 'SirVer/ultisnips'
Plug 'honza/vim-snippets'

"" Color
Plug 'flazz/vim-colorschemes'

"" editconfig
Plug 'editorconfig/editorconfig-vim'

"" python
Plug 'raimon49/requirements.txt.vim'
Plug 'google/yapf', { 'rtp': 'plugins/vim', 'for': 'python' }
Plug 'fisadev/vim-isort'

"" html
Plug 'mattn/emmet-vim'
Plug 'hail2u/vim-css3-syntax'
Plug 'jelera/vim-javascript-syntax'

" vue
" Plug 'posva/vim-vue'

"" fcitx
Plug 'lilydjwg/fcitx.vim'

"" markdown
Plug 'plasticboy/vim-markdown', {'on_ft' : 'markdown'}

call plug#end()

对于我使用的大部分的插件我都不想细说,但是其中YouCompleteMe我想好好的说一说。

YouCompleteMe

对于补全,尤其是C/C++这类复杂的语言,尤其有模板和泛型的存在,基本上补全十分麻烦;还有就是像Python这样的动态语言,因为其没有类型检查,语义上的补全和推导十分麻烦,甚至pycharm在这方面都不好,但是YouCompleteMe这就做的比较好的。对于补全,我需要C的,python、Go以及Rust的,所以得先在系统中安装这些软件,并且构建的时候需要C环境,所以得先安装clang,并且需要cmake来构建编译过程。我的建议是使用系统的自带的clang,虽然官方建议使用最新的,那是因为可能编译不通过,但是对于国内这种情况就算了吧。

对于编译,我们只需要在Vim-plug的配置中加入如下代码就行:

1
Plug 'Valloric/YouCompleteMe', { 'do': './install.py --clang-completer --system-libclang --go-completer  --js-completer --rust-completer' }

对于补全,我开启了语义补全、注释补全以及字符串补全,并且从一个字符开始就除非,这个比较符合我们使用IDE的习惯,这些设置的配置如下:

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
let g:ycm_global_ycm_extra_conf = '~/.ycm_extra_conf.py'
let g:ycm_python_binary_path = '/usr/bin/python3'
let g:ycm_server_python_interpreter = '/usr/bin/python3'

" 补全
set completeopt=longest,menu " 下拉的补全菜单

" 回车选中当前项
let g:ycm_key_list_stop_completion = ['<CR>']

" 键位
nnoremap <leader>jd :YcmCompleter GoToDefinitionElseDeclaration<CR>

" 配置
let g:ycm_collect_identifiers_from_tags_files = 1 " 基于标签的引擎
let g:ycm_min_num_of_chars_for_completion = 1 " 1个字符开始补全
let g:ycm_cache_omnifunc = 0 " 禁止缓存
let g:ycm_seed_identifiers_with_syntax = 1 " 语法关键字补全
let g:ycm_complete_in_comments = 1 " 补全注释
let g:ycm_complete_in_strings = 1 " 补全字符串
let g:ycm_auto_trigger = 1
let g:ycm_collect_identifiers_from_comments_and_strings = 1 " 将注释和字符串收录到补全信息中
let g:ycm_confirm_extra_conf=0 " 关闭加载.ycm_extra_conf.py的提示

" 补全的开始位置的设置
let g:ycm_semantic_triggers = get(g:, 'ycm_semantic_triggers', {})

function! s:set_ft_triggers(ft, expr, override) abort
if a:override
let g:ycm_semantic_triggers[a:ft] = a:expr
elseif !has_key(g:ycm_semantic_triggers, a:ft)
let g:ycm_semantic_triggers[a:ft] = a:expr
endif
endfunction

call s:set_ft_triggers('c', ['->', '.'], 0)
call s:set_ft_triggers('cpp', ['->', '.', '::'], 0)
call s:set_ft_triggers('perl', ['->'], 0)
call s:set_ft_triggers('javascript,python,go', ['.'], 0)
call s:set_ft_triggers('java,jsp', ['.'], 0)
call s:set_ft_triggers('vim', ['re![_a-zA-Z]+[_\w]*\.'], 0)
call s:set_ft_triggers('sh', ['re![\w-]{2}', '/', '-'], 0)
call s:set_ft_triggers('zsh', ['re![\w-]{2}', '/', '-'], 0)

" 自动关闭窗口
let g:ycm_autoclose_preview_window_after_completion = 1
let g:ycm_autoclose_preview_window_after_insertion = 1

还有在安装好之后,需要在$HOME目录下面创建一个空的.tern_project文件(需要配置的请参考文档)和将$HOME/.vim/plugged/YouCompleteMe/third_party/ycmd/examples/.ycm_extra_conf.py拷贝到$HOME下,大部分的情况下这个已经能满足绝大部分的需求了。

至此,我对Vim的配置就完成了。

在我两年前写的博客的搭建博客的简单步骤的这篇博文中,我简单的介绍的如何搭建一个基于Github的Hexo博客,现在我来介绍一些其他的用法和部署的方式。

插件

以前使用Hexo而不是Wordpress搭建博客主要原因之一就是可以在Github之类的服务上搭建博客而不需要自己搭建服务器,这样就减少的在金钱方面的投资。如果是现在我还是会在这些方面进行投资的,在以前Hexo的插件不是特别的多,尤其是适合国内的插件和主题都不怎么多,所以我一直都是使用Next作为我的网站的主题的。

其实这个主题有许多的对国内支持的管理,我感觉十分的方便,如果需要其他的插件可以到官网上去看一下插件这个分类,下面有许多的目录值得我们去使用。

部署

在自己的服务器上部署Hexo的方式有许多,可以将服务器的文件打包成Dcoker的镜像进行使用,也可以将使用各种的静态转发的服务器使用,例如:http-server以及httpd等。我这介绍的将是使用Nginx进行部署并且使用cerbot生成SSL证书。

下面我将以我的博客的部署作为演示,并且服务器用的是Ubuntu 17.10

Nginx

我们先将数据从我们的GitHub或者其他的代码管理服务上面克隆下来,存到服务器的/var/www/mosdev.xyz的目录下面。然后在/etc/nginx/sites-available中建立一个新的配置文件,例如blog,在其中写入如下的配置内容:

1
2
3
4
5
6
7
8
9
10
11
12
server {
root /var/www/mosdev.xyz;

index index.html index.htm index.nginx-debian.html;

server_name www.mosdev.xyz;

location / {
try_files $uri $uri/ =404;
}
}

这个配置会默认监听80端口,如果休要监听其他的端口可以在配置文件中加入listen字段来进行监听。如果你的配置是正确的话,这个时候删除原来在/etc/nginx/sites-enabled的默认配置,然后重新建立软连接ln -sf ../sites-available/mosdev ./,如果配置都是正确的话,将在输入nginx -s reload的信号后访问你的域名将会看到你部署的博客了。

现在https已经是网站部署的主流了,所以我们也考虑将网站部署上SSL证书,启用https,最后将不是https的访问都强制转换成http的访问。

Cerbot

部署https的一个问题是我们得有SSL证书,以前的SSL证书都比较贵,并且对于个人来说应该不会愿意去购买这么一个证书去部署https的,但是从16年开始,Let’s Encrypt 提供了免费的SSL证书,这个时候我们就可以使用这么一个免费的服务去部署一个SSL证书了。

安装

首先当然得是先在服务器上安装cerbot,主要的安装方式有使用Docker或者直接从官方源安装两种:

  1. 从官方源安装,这个是没有Nginx插件的:

    1
    2
    3
    4
    5
    sudo apt-get update
    sudo apt-get install software-properties-common
    sudo add-apt-repository ppa:certbot/certbot
    sudo apt-get update
    sudo apt-get install certbot
  2. Docker安装,这个的前提当然是你得在服务器上面安装了个Dockers才行:

    1
    2
    3
    4
    sudo docker run -it --rm -p 443:443 -p 80:80 --name certbot \
    -v "/etc/letsencrypt:/etc/letsencrypt" \
    -v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
    certbot/certbot certonly

虽然我比较喜欢使用Docker进行部署,但是在cerbot这个上面我还是使用了官方源进行安装,这样可以在我更新系统的时候自动进行更新,并且这次我们使用了Nginx进行部署,所以我这次需要安装的是带有Nginx插件的cerbot,具体的安装步骤如下:

1
2
3
4
5
sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install python-certbot-nginx

使用

因为这次我们使用了带有Nginx插件的cerbot,我们首先得确定我们的配置文件是否是正确的nginx -t,然后我们执行一下的命令就可以新生成证书和切换 http流量到https了:

1
2
3
4
5
6
# 可以自动的修改原有的配置文件,并且在选项中有自动跳转
sudo certbot --nginx
# 如果只是想生成证书,不修改Nginx的配置,可以用如下代码
sudo certbot --nginx certonly
# 配置自动获取证书
sudo certbot renew --dry-run

如果使用的是没有Nginx插件的 cerbot,我们得运行如下代码生成证书:

1
sudo certbot certonly --webroot -w /var/www/mosdev.xyz -d www.mosdev.xyz

然后修改配置文件如下,也是最终的配置文件:

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
server {
root /var/www/mosdev.xyz;

# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;

server_name www.mosdev.xyz;

location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}

listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/www.mosdev.xyz/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/www.mosdev.xyz/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

server {
if ($host = www.mosdev.xyz) {
return 301 https://$host$request_uri;
} # managed by Certbot


listen 80 default_server;
listen [::]:80 default_server;

server_name www.mosdev.xyz;
return 404; # managed by Certbot


}

至此,你的网站已经在你的VPS上进行了部署,使用了Nginx作为服务器,并且在服务器上面部署了HTTPS,这样也就达成了我们的目标了。

参考文章

  1. How To Set Up Let’s Encrypt with Nginx Server Blocks on Ubuntu 16.04
  2. Cerbot Document

刚使用Linux的时候,对于下载东西会有种无力感,没了迅雷,没了常见的下载工具,那怎么办呢?wine环境下面搞一个,还是搞下其他的工具?后来在我几经尝试之下,我发现了Aria2这个下载工具,所以这篇博客就是来介绍这个下载工具的使用的。

那我们的目标是什么呢,那就是我们将其伪装成了一个BT客户端,还和百度云盘和Chrome进行了集成,还是做成了一个Systemd的服务,并且有个桌面客户端,想想是不是有点激动,那就开始吧。

安装

对于Aria2这个工具来说,绝大部分的发现版已经内置在官方维护的镜像中,最大的区别就是可能在不同发行版本之下的默认版本不同,但是一般情况下也没有什么影响,所以可以一行命令就搞定这个事情。

1
2
# 以ArchLinux作为示例
pacman -S aria2

配置

安装完成了,那我们就要说一下配置了,如果只是简单的使用,配置还是很简单的。但是我们的目标是伪装成一个BT客户端,能在Chrome中使用,还能使用百度云并且还能支持开机启动,这个在配置上来说就有点麻烦,所以我们得一步一步的来。

基本配置

对于基本的配置来说,最重要的几点就是下载的位置,下载任务进度的保存位置以及远程访问的密码等这些配置。 这里有个示例配置的网站,我们可以在这个配置的基础上进行修改后得到我们的配置。

我个人的建议是把下载任务的回话保存到/etc/aria2这个文件夹下面,并且把这个文件夹的权限调高,等之后的配置会使用到。

1
2
3
4
5
6
7
8
9
10
11
# 创建文件夹
mkdir /etc/aria2

# 更改文件夹权限
chmod 777 /etc/aria2

# 然后在次文件夹下面创建配置文件并保存
vim /etc/aria2/aria2.conf

# 创建一个空的回话文件,不然启动的时候可能会报错
touch /etc/aria2/aria2.conf

变身服务

当写好配置文件之后,我们就可以用aria2c这个指令来进行开启和使用了,但是这样不是很麻烦么,每次都要进入命令行进行操作,所以我们在/lib/systemd/system这个文件夹下面创建一个aria2.service的文件,并在其中写入如下内容(注意将其中的User一栏换成你保存位置用户的名称):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[Unit]
Description=Aria2c download manager
After=network.target

[Service]
Type=forking
User=user
RemainAfterExit=yes
ExecStart=/usr/bin/aria2c --conf-path=/etc/aria2/aria2.conf -D
ExecReload=/usr/bin/kill -HUP $MAINPID
RestartSec=1min
Restart=on-failure

[Install]
WantedBy=multi-user.target

在配置完成之后,我们就可以使用systemctl start aria2.service来启动任务了,如果需要开机启动,可以使用如下命令systemctl enable aria2.service

使用

百度云

百度云盘的离线下载是一个十分好的工具,我们要好好的利用。在使用百度云的时候,我们得使用一个Chrome的扩展:BaiduExporter,在安装完成之后,在百度云中进入简单的配置,然后可以使用他的RPC的导出方式了

Chrome集成

此时我们的下载还有一个十分不舒服的地方那就是没法右键导出下载,并且不能简单的对下载的 任务进行管理,这个时候yaaw这个扩展就十分的好用了,直接在Chrome商店中安装后就可以使用这个服务集成了。

webui-aria2

如果感觉这个还是有点简单了,有没有更加复杂点的了,有,那就是webui-aria2。这个网站可以在网页中进行aria2的控制,也给出了如何使用docker进行部署的方式,但是我还有一个更好的办法,那就是将其变成一个桌面应用,这个时候就要用到nativefier这个工具了。

1
2
3
4
5
6
7
8
# 安装nativefier
npm install -g nativefie

# 生成桌面客户端
nativefier --name 'aria2' 'https://ziahamza.github.io/webui-aria2/'

# 配置桌面图标,如果是使用Gnome就使用如下指令,否则就需要根据不同版本进行设置
gnome-desktop-item-edit ~/.local/share/applications --create-new

现在回过头一看,是不是发现aria2这个工具的强大之处呢,我们将其伪装成了一个BT客户端,还和百度云盘和Chrome进行了集成,还是做成了一个Systemd的服务,并且有个桌面客户端,是不是特别爽,那就尽情使用吧。

在使用ArchLinux的时候,我一直在想,能不能在ArchLinux之上打造一个简单的娱乐环境。虽然我安装Steam后也能玩游戏,但是我还是建议这个事情还是在Windows上进行比较好。

Markdown

程序员一般都离不开要写一些Markdown文件,对于程序员来说,编写Markdown有许多的选择,比如直接在IDE中安装插件编写,也可以在编辑器中安装插件写,也可以使用专门的Markdown编辑器进行编写。我尝试过许多的编辑器,但是我推荐的是一款可以跨平台的编辑器Typora来进行编辑。如果启用了ArchLinux源的话可以之间使用pacman下载,不然就要使用yaourt在AUR中下载。

1
2
3
4
5
# 直接使用pacman中进行安装
pacman -S typora

# 使用yaourt咱
yaourt -S typora

下载

普通下载

在Linux上,下载工具有许多选择,可以选择使用curl或者wget这种命令行的,也可以使用uget这种有图形界面的 ,但是我推荐的是aria2这个下载工具,直接下载就行,具体的使用和配置方法我会在以后的博文中介绍。

1
pacman -S aria2

bt

在国内这种使用迅雷并且不太乐意分享下载速度的情况下,使用除了迅雷的客户端下载其实效果不太好,但是也没太多的办法,谁叫他们只进不出。所以在ArchLinux上面我推荐两个BT的下载客户端,一个是qBittorrent和Deluge。

1
2
3
4
5
# 安装qBittorrent
pacman -S qbittorrent

# 安装Deluge
pacman -S deluge

音乐

在以前,在Linux听音乐的话,除了自己下载歌曲来听的话就只能使用网页来听歌。但是自从网易和深度合作后,我们就有了另外一种选择,就是使用网易云音乐。对于网易云音乐的安装,在启用archlinux情况下可以之间安装,不然就要在AUR中进行安装。

1
2
3
4
5
# 直接安装
pacman -S netease-cloud-music

# 使用aur安装
yaourt -S netease-cloud-music

视频

说起视频客户端的话,在ArchLinux上的选择还是挺多的,我推荐的是深度的播放器,但也有其他比较好的客户端,也是值得推荐的

1
2
3
4
5
6
7
8
# 深度电影院
pacman -S deepin-movie

# vlc
pacman -S vlc

# mpv
pacman -S mpv

聊天

许多人在使用Linux的时候遇到的最大问题不是安装,不是编程环境的使用,而是安装QQ和微信,所以我也来介绍这怎么安装。我们需要的就是安装wine环境,这会模拟大部分的Windows的接口,基本能完成Windows上的许多操作,所以这就为我们安装聊天软件成为了可能。我们之间安装其中的包的时候,其会自动解决依赖,假如提示wine包不存在的时候,这个时候就需要启用muitilib这个源。

1
2
3
4
5
# 安装Tim
yaourt deepin-wine-tim

# 安装微信
yaourt deepin-wechat

这基本上已经包含了绝大部分日常使用的东西了,如果还有其他需要日常使用的功能,我会继续在此博文中添加。

对于我用过的几个发行版本来说,ArchLinux算是天生对程序员亲和的,主要是有这几个原因,首先是官方源中维护了许多的编程环境的包,尤其是以Python维护的最多。其次是有AUR源,有许多人在共同的维护这个源,可以让开箱即用的包越来越多。最后的原因才是他是一个Linux的发行版本。

安装之前

在配置安装环境之前,我们得先对我们镜像源改造一下,这样才能继续我们之后的工作。我们得启用用multilibarchlinuxcn两个源。

multilib

对于multilib这个源,我们只需要简单的将/etc/pacman.conf中的multilib的注释取消了就行

arclinuxcn源

对于这个我们可以在/etc/pacman.conf加入如下配置:

1
2
3
[archlinuxcn]
SigLevel = Optional TrustedOnly
Server = https://mirrors.ustc.edu.cn/archlinuxcn/$arch

然后再安装archlinuxcn-keyring这个包导入秘钥就行。对于这其中可能存在的两个问题,也就是由使用硬件时钟造成秘钥导入不成功的问题(这个一般是时间的问题,硬件时间不是UTC时间的情况下造成的)
,可以使用以下方法进行解决:

  1. 立即同步时间,不用修改系统的时间设置
  2. 删除/etc/pacman.d/gnupg文件夹,然后运行pacman-key --initpacman-key --poplaute archlinuxpacman-key --refresh-keys就可以解决这一个问题

Python

对于Python编程环境来说,ArchLinux默认的Python环境是最新版本的Python3版本,所以在使用的时候需要注意这个问题,对于常见Python环境的安装方法如下:

1
2
3
4
5
6
7
8
# 安装Anaconda
pacman -S anaconda

# 安装pyenv
pacman -S pyenv

# 安装Pytcharm
yaourt -S pycharm-professional

Java

在ArchLinux中使用Java,可以选择两种JDK的版本,一种是使用openjdk,另外一个是使用Oracle jdk版本,并且在ArchLinux中,可以使用archlinux-java来切换不同的版本。对于Java环境的一些工具集,可以使用如下的命令进行安装。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 安装oracle jdk
pacman -S jdk

# 安装openjdk
pacman -S jdk9-openjdk

# 安装maven
pacman -S maven

# 安装gradle
pacman -S gradle

# 安装eclipse
pacman -S eclipse

# 安装Idea
pacman -S intellij-idea-ultimate-edition

Node环境

和大部分的平台的安装配置一样,就是有可能需要配置以下全局的npm包的安装位置和一些目录,可以使用pacman -S nodejs npm来进行安装,可以在~/.npmrc中写入如下配置:

1
2
3
# $HOME为你home目录路径的全写
cache=$HOME/.node_modules
prefix=$HOME/.node_modules

对于其他的一些编程环境来说,基本上也是大同小异。对于IDE的配置和选择我会在以后的博文中写出给大家作为参考。

在折腾了许多的Linux的发行版本之后,我最终选择的ArchLinux作为我的日常使用版本,具体的心路历程那就多了,反正上了Arch的这条船之后我就没想在下去了。在这之间我还玩了一段时间的Manjaro,但是9月份发生的一次系统更新mongo的版本发生问题导致我本地的测试数据发生错误之后我就没有再使用了,凭自己良心说,这其实是最好上手的Arch的发行版本了。

我使用的是Intel的CPU和NVIDIA的GPU,所以其他的我没折腾过,如果发现问题的话还是请参考官方的文档进行解决(其实我想说的是,官方的文档已经写的很好了,这个只是我的总结而已)。

安装准备

空间

在安装ArchLinux之前需要有一个没有被分过区的剩余空间,如果安装的时候发现没有的话,可以在安装的过程中删除没有文件的分区来解决这一个问题

安装盘

官方网站或者清华源上面下载最新的镜像进行刻录。理论上来说使用老的镜像进行安装也是可以的,但是安装的过程中会把安装的软件更新到最新的版本,所以没有意义。

然后使用rufus这个软件将下下来的镜像刻录成USB的启动盘,这是就需要选择UEFI还是BIOS启动了,这两个根据硬件来自行进行选择吧。如果是要装双系统的,应该优先安装Windows,并且需要关闭Windows的快速启动和安全启动功能,这样才能安全的安装ArchLinux。

安装

对于此安装过程,我默认是你用的是默认的键盘,默认的字体还有就是使用网线连接而不是WiFi进行网络连接进行安装,这会在安装过程中少去很多的麻烦,如果需要修改可以到安装完成之后才进行。

时间

首先要将本地的时间和网络的时间进行同步,时间同步在操作系统内部是十分重要的

1
timedatectl set-ntp true

设置安装源

由于众所周知的原因,我们得先设置安装的镜像源,这样才能不会花太多的时间咋安装的过程中,并且这个安装的配置还会应用到安装后的系统中。

1
sed -i '/China/!{n;/Server/s/^/#/};t;n' /etc/pacman.d/mirrorlist

分区

在Linux系统中,至少需要一个根分区,如果使用交换文件的话是不需要使用交换分区的,不适用交换问价的花需要单独的配置一个交换分区。如果配置双系统或者是UEFI的话,需要单独配置一个EFI分区,分区的类型为FAT32。使用lsblk来查看文件分区,我建议是使用cfdisk来进行分区,这个命令行软件比较人性化一点。在分区完成之后就需要将这些分区进行格式化。

1
2
3
4
5
6
7
8
# 格式化EFI分区
mkfs.vfat -F32 /dev/sdax

# 格式化普通分区
mkfs.ext4 /dev/sdax

# 格式化交换分区,为了防止交换分区不能挂载,还是进行格式化比较好一点
mkswap /dev/sdax

在格式化之后,就需要想各个分区进行挂载,使用UEFI的话需要将EFI分区挂载到/mnt/boot/EFI之下,这里的统一挂载点就为/mnt

安装基本系统

对于基本系统的安装,我建议安装完整的basebase-devel这两个安装集合

1
pacstrap /mnt base base-devel

生成fstab

如果这一部出了问题,如果只分了一个分区的话应该还能启动,如果不是的话启动的可能性就变低了。在生产之后,我认为还是使用cat命令看看比较合适

1
genfstab -U /mnt >> /mnt/etc/fstab

配置基础系统

进入基本系统

使用arch-root进入到安装的安装的系统进行配置

1
arch-root /mnt

设置时间

配置Locale,将需要的行前面的注释符号去掉,我建议只使用en_US,zh_CN,’zh_TW’的UTF-8的字符集

1
vim /etc/locale.gen

然后使用locale-gen生产locale,然后使用以下命令设置默认的Locale

1
echo LANG=en_US.UTF-8 > /etc/locale.conf

时区

国内可以使用上海的时区来进行时间的设置

1
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

硬件时间

如果不是双系统的话,强烈建议使用UTC时间,如果是双系统的话,我建议还是使用硬件时间,这主要是Linux和Windows对时间的计算方式不同造成的,不然会出现一些问题,最常见的就是GPG签名验证的问题。

1
2
3
4
5
# 使用硬件时间
hwclock --systohc

# 使用硬件时间
hwclock --systohc --localtime

主机名

1
echo <主机名> /etc/hostname

设置root密码

1
passwd

安装引导程序

我建议使用GRUB作为引导程序,如果是用其他的请查看官方文档

BIOS

1
2
3
pacman -S grub os-prober
grub-install --target=i386-pc /dev/sdx
grub-mkconfig -o /boot/grub/grub.cfg

UEFI

1
2
3
pacman -S dosfstools grub efibootmgr
grub-install --target=x86_64-efi --efi-directory=/mnt/boot/EFI --bootloader-id=grub
grub-mkconfig -o /boot/grub/grub.cfg

安装完成

对于网络,如果是只使用命令行的话,那就要开启dhcpcd来进行IP分配systemctl enable dhcpcd,如果使用图形界面的话,还是先启用这个,之后再进行配置。

使用exit退出安装环境,然后使用umount -R /mnt取消挂载,使用reboot重启后就可以基本使用了

基本配置

用户

日常使用root用户是相当危险的,所以配置一个普通用户进行日常操作还是一个明智的做法,我们这里配置一个在user和root之间的用户

1
2
uaeradd -m -G wheel -s /bin/bash username
passwd username

赋予其sudo权利,编辑/etc/sudoers,将%wheel ALL=(ALL) ALL取消注释就行

显卡配置

intel

1
pacman -S xf86-video-intel

nvidia

1
pacman -S nvidia

安装桌面环境

对于各种桌面环境都有其各自的特点,我就以Gnome的配置作为示例:

1
2
3
4
5
6
7
8
# 安装Gnome
pacman -S gnome

# 启动Gdm
systemctl enable gdm

# 启动NetworkManager
systemctl enable NetworkManager

到此为止,应该能进行基本的使用了。

算了算时间,从今年6月底的毕业到现在,正式工作的时间已经4个的时间了,如果算上我在大四实习的时间的话,应该有差不多10个月的时间了。在这期间,我从Java的开发转换到了Python的开发,期间一直都在进行后端的开发,所以一些运维方面的知识也有所涉猎。但是一直有个问题就是在这段时间内我会了什么,还有就是我以后的追求是什么。

这个问题以前我一直没有想过,在前段时间我去和朋友的交流中发现,这个问题我还是觉得我应该好好的去想一下的。那就先说一下我干了什么吧,在这段时间,我使用的语言也是比较多了,除了主要工作上使用的Java和Python外,C语言、shell脚本以及Go我都有所涉猎,但是这有一个最主要的问题就是,这对我的能力或者工作上有什么提高的么,除了我在日常的工作中对一些语言的用法以及工程开发中的一些区别有所了解外,其他的一些有什么提高和变化的么,貌似没有,或者是我还没有发现。

那再说一下我的追求吧,我今年年初的时候我写了一个我对我2016年整年的总结的时候,我就对今年要做的事情做了一个大体的计划,其实很简单,那就是今年能顺利的大学毕业,然后找到一个靠谱的正式工作(虽然大学实习的那个工作也挺靠谱的,但是不太适合我)。到现在一看,这个目标基本上算是完成了吧,这就造成了一个问题,我接下来要做什么,有什么想要去追求的么。

目前最主要的目标还是把自己的基础打好,这个是我这半年多的工作得出的一个结论,基础打好才是重要的,大学时候学习过程中的偷懒,对于一些基础性的东西理解的不够深入,现在是要解决这个问题的时候了,虽然比其他的人发现的晚,但是还是可以学习提高的。所以现在要在这几个方面入手进行学习和提高:

  1. 语言方面: 主要还是学习这三个语言Java、Python和C系列,因为在日常的工作过程中主要还是以这三门语言为主
  2. 系统层面:在操作系统上的学习,我决定还是主要看这三本书进行学习,一本是《深入理解计算机操作系统》、一本书是《现代操作系统》、还有一本就是《操作系统:精髓与设计原理》进行整个计算机操作系统方面知识的学习
  3. Linux:现在我日常的开发环境已经从Windows迁移到了Linux了,虽然我使用Linux已经两年了,但是这样全面的使用还是第一次,所以还是需要好好的进行学习
  4. 算法:这个也是一个十分重要的方面,以前我一直放弃在这方面进行深入的学习,但是这次我会在这方面进行深入的学习,主要的还是两本书籍的学习,一本是《算法图解》、一本是《算法导论》,虽然都是入门级别的书籍,但是这方面是我进行计算机学习的另外一个重点

像流水帐一样的写了这么多,主要的原因还是我最近有些焦虑。这个总结本身国庆假结束的时候就应该写好的,但是我一直在对我这半年多的工作进行思考,但是越是思考越是觉得后怕,我感觉基本上我就没有多大的变化,一切的工作就是以完成工作。自己工作外的八小时基本上要么在加班中度过,要么就是在娱乐中度过,自己学习提高的时间并不多,原来想要进行的番茄工作法也是没有进行下去,Github上的内容和代码,已经我本人的博客也是有四个月没有进行更新了,但是我会在接下来的几个月了改变这一个过程,在年底的时候我在写一个总结,看看我这段时间制定的计划有没继续进行下去。

原因

在Linux中使用Mongodb的时候,尤其是单机使用的时候,就会出现OOM(Out of Memory)的情况,当此进程是在root权限下执行的时候,系统在为了保证不出现重启这类的重大事件的情况下,就会选择将目前系统中的高消耗低优先级的进程被杀死,选择的方法是安装PID的序号来进行选择的,而不是按照用户来进行选择的。

出现这种的原因是因为Mongodb本身是不管了自己本身的内存的分配和回收的,而是内存管理的工作交给系统自己来进行处理。当系统本身的物理内存页消耗完的时候,如果应用本身还在请求内存,这个时候就会出现OOM,此时系统会进行一次内存管理,回收大部分的内存来减少系统自己的消耗。

解决办法

在这种情况下,如果不考虑使用主从服务器或者将Mongodb独立出来的方式的话,基本就只能考虑限制Mongodb自己本身的内存消耗或者在发现进程被杀之后将其重启。

cgroup限制内存使用

在现在的linux操作系统中,可以考虑使用cgroup来现在一个进程的使用。CGroup 技术被广泛用于 Linux 操作系统环境下的物理分割,是 Linux Container 技术的底层基础技术,是虚拟化技术的基础。作为cgroup本身来说,它完全可以被用来限制基于任何用户或者是任何应用程序的资源限制。

安装

执行以下命令安装cgroup的本体及其依赖:

1
sudo apt install cgroup-bin cgroup-lite cgroup-tools cgroupfs-mount libcgroup1

配置Cgroup

这里就以限制Mongodb的内存使用来进行配置示例,首先在cgroup的配置中增加对内存限制的配置,增加一个limitmongomem的组,在其中对Mongodb的内存限制为3G:

1
2
3
4
5
6
# vim /etc/cgconfig.conf
group limitmongomem{
memory {
memory.limit_in_bytes = 3G;
}
}

配置

  1. 启用这个配置

    1
    2
    # 在root用户执行
    cgconfigparser -l /etc/cgconfig.conf

    然后可以在/sys/fs/cgroup文件夹下中可以看到多了一个limitmongomem的配置

  2. 将用户、应用和cgroup绑定

    现在需要的是将Mongodb和limitmongomem绑定在一起:

    1
    2
    3
    4
    # vim /etc/cgrules.conf
    # user:process subsystems group
    root:mongod memory limitmongomem
    deploy:mongod memory limitmongomem
  3. 启用这配置

    1
    2
    # 在root用户下执行
    cgrulesengd

    此时会开启一个服务,它会自动监控符合规则的进程,然后将这些进程配置到对应的cgroup策略中从而达到限制资源的目的。

自动重启

如果在重启造成的损失影响不大的时候,其实在这种情况下还可以考虑使用自动重启的方式来解决这个问题。其实如果在合适的情况下,还是使用独立的服务器或者主从的方式来进行使用。

使用monit

  1. 安装

    1
    sudo apt install monit
  2. 创建一个monit配置目录放置配置文件:

    1
    sudo mkdir -p /etc/monit/conf.d
  3. 创建一个Mongodb的配置文件

    1
    2
    3
    4
    5
    6
    7
    8
    # vim /etc/monit/conf.d/mongod.conf
    check process mongod matching "/usr/bin/mongod"
    group database
    start program = "/sbin/start mongod"
    stop program = "/sbin/stop mongod"
    if failed host 127.0.0.1 port 27017 protocol http
    and request "/" with timeout 10 seconds then restart
    if 5 restarts within 5 cycles then timeout
  4. 重启服务使其生效:

    1
    sudo service monit restart

使用supervisor

  1. 使用Ubuntu自带的安装命令安装,而不使用pip安装时因为服务器中的python环境异常的混乱:

    1
    sudo apt install supervisor
  2. 创建配置文件夹:

    1
    sudo mkdir -p /etc/supervisor/conf.d
  3. 编写配置文件:

    1
    2
    3
    4
    5
    6
    7
    8
    # vim /etc/supervisor/conf.d/mongod.conf
    [program:mongod]
    command = mongod
    user = root
    autostart = true
    autorestart = true
    stderr_logfile = /var/log/mongod.log
    stdout_logfile = /var/log/mongod_error.log
  4. 重启supervisor服务:

    1
    sudo service supervisor start
  5. 启动配置:

    1
    sudo supervisorctl start

systemd的自动重启服务

当安装好Mongodb服务后,注册service服务后,就可在将其设置为自动重启了:

修改一下配置就行:

1
2
[Service]
Restart=always
0%