强哥的vimrc大宝剑

.vimrc

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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
" vimrc begin
" Author Caiqiang Yu <ycqiangboy@gmail.com>

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => Vundle and Plugin
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
set nocompatible " be iMproved, required
filetype off " required

" set the runtime path to include Vundle and initialize
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()
" alternatively, pass a path where Vundle should install plugins
"call vundle#begin('~/some/path/here')

" let Vundle manage Vundle, required
Plugin 'VundleVim/Vundle.vim'

" plugin on GitHub repo
Plugin 'tpope/vim-fugitive'
Plugin 'scrooloose/nerdtree' "目录数
Plugin 'majutsushi/tagbar'
Plugin 'flazz/vim-colorschemes' "集成各配色主题
Plugin 'christoomey/vim-tmux-navigator' "tmux跳转工具
Plugin 'tpope/vim-surround' " 加括号加引号方便
Plugin 'benmills/vimux' "vim下得tmux
Plugin 'shawncplus/phpcomplete.vim'
Plugin 'jlanzarotta/bufexplorer' "打开历史文件列表以达到快速切换文件的目的

" vim-scripts repos
" Plugin 'taglist.vim'

" non github repos



" All of your Plugins must be added before the following line
call vundle#end() " required
filetype plugin indent on " required
" To ignore plugin indent changes, instead use:
"filetype plugin on
"
" Brief help
" :PluginList - lists configured plugins
" :PluginInstall - installs plugins; append `!` to update or just :PluginUpdate
" :PluginSearch foo - searches for foo; append `!` to refresh local cache
" :PluginClean - confirms removal of unused plugins; append `!` to auto-approve removal
"
" see :h vundle for more details or wiki for FAQ
" Put your non-Plugin stuff after this line


"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => General
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
syntax on
filetype plugin indent on
set incsearch " 开启实时搜索功能
set hlsearch " 高亮度搜寻
set ruler " 打开状态栏标尺
set showcmd " 显示正在输入的命令
set csto=0
set showmatch " 高亮显示匹配的括号
set guifont=Courier\ New:h10 " 设置字体
set nu " 设置行数
set t_Co=256 " 设置256色
set ff=unix " 这个文件就以 Unix 格式存盘
set tabstop=4 shiftwidth=4 softtabstop=4 expandtab " Tab键的宽度,统一缩进为4,用空格代替制表符
" 自动缩进 cindent(c风格)、smartindent(智能模式,其实不觉得有什么智能)、autoindent(简单的与上一行保持一致)
"set autoindent
set smartindent
"set cindent

" 解决插入模式下delete/backspce键失效问题
set backspace=2

"让回溯命令历史时的快捷键拥有up和down一样对历史命令进行过滤的优点
cnoremap <C-p> <Up>
cnoremap <C-n> <Down>


" vimrc文件修改之后自动加载
autocmd! bufwritepost .vimrc source %


"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => F2-F12快捷键
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 去空行
" nnoremap <F2> :g/^\s*$/d<CR>
" nmap <F3> <Esc>:append<CR>var_dump($<c-r>=expand("<cword>")<CR>);exit;<CR>.<CR>:w<CR>
" " 是否显示行号切换, 方便复制
" nmap <F4> :set nonumber!<CR>:set foldcolumn=0<CR>
" nmap <F5> :tabnew<CR>
" nmap <F6> :NERDTree<CR>
" nmap <F7> <Esc>:append <CR>error_log(print_r($<c-r>=expand("<cword>")<CR>,true)."\n", 3, '/tmp/ycq.log');<CR>.<CR>:w<CR>
" nmap <F8> <ESC>:cs kill -1 <CR> <ESC>:cs add $AVATAR_HOME/project/cscope.out<CR>
" nmap <F9> <Esc>:! $AVATAR_HOME/project/create_scope.sh <CR> <ESC>:cs kill -1 <CR> <ESC>:cs add $AVATAR_HOME/project/cscope.out <CR>
" nmap <F10> :Tlist<CR>
" nmap <leader> 7 <ESC>:cs kill -1 <CR> <ESC>:cs add $AVATAR_HOME/project/cscope.out <CR>

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => Learder键映射
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
let mapleader=" "

nmap <leader>2 :g/^\s*$/d<CR>
nmap <leader>3 <Esc>:append<CR>var_dump($<c-r>=expand("<cword>")<CR>);exit;<CR>.<CR>:w<CR>
"是否显示行号切换, 方便复制
nmap <leader>4 :set nonumber!<CR>:set foldcolumn=0<CR>
nmap <leader>5 <ESC>:cs kill -1 <CR> <ESC>:cs add $AVATAR_HOME/project/cscope.out<CR>
nmap <leader>6 <Esc>:! $AVATAR_HOME/project/create_scope.sh <CR> <ESC>:cs kill -1 <CR> <ESC>:cs add $AVATAR_HOME/project/cscope.out <CR>
nmap <leader>7 <Esc>:append <CR>error_log(print_r($<c-r>=expand("<cword>")<CR>,true)."\n--".__LINE__."--\n", 3, '/data/webroot/ycq/tmp/my.log');<CR>.<CR>:w<CR>

nmap <leader>t :NERDTree<CR>
nmap <leader>w :w!<CR>
nmap <leader>q :qa<CR>

" 执行当前php文件
nmap <leader>r :!php %<CR>
nmap <leader>u :!phpunit %<CR>

nmap <leader>m :TagbarToggle<CR>
nmap <leader>t :NERDTree %<CR>

" 切换tab
nmap <leader>n :tabnext<CR>

" 取消高亮
nmap <leader><CR> :nohl<CR>

"对齐格式
nmap <leader>= gg=G<ESC>

" 删除所有的行尾的空格
nmap <leader>v :%s/\s\+$//<CR>:let @/=''<CR>

" 方便切换
nmap <leader>j <C-W>j
nmap <leader>k <C-W>k
nmap <leader>h <C-W>h
nmap <leader>l <C-W>l
nmap <leader>n :tabnext<CR>


"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => flazz/vim-colorschemes 主题配色
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" colorscheme molokai
colorscheme desertEx
" colorscheme solarized
" colorscheme desert


"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => cscope
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" s: 查找C语言符号,即查找函数名、宏、枚举值等出现的地方
" g: 查找函数、宏、枚举等定义的位置,类似ctags所提供的功能
" d: 查找本函数调用的函数
" c: 查找调用本函数的函数
" t: 查找指定的字符串
" e: 查找egrep模式,相当于egrep功能,但查找速度快多了
" f: 查找并打开文件,类似vim的find功能
" i: 查找包含本文件的文
nmap <leader>cs :cs find s <C-R>=expand("<cword>")<CR><CR>
nmap <leader>cg :cs find g <C-R>=expand("<cword>")<CR><CR>
nmap <leader>cd :cs find d <C-R>=expand("<cword>")<CR><CR>
nmap <leader>cc :cs find c <C-R>=expand("<cword>")<CR><CR>
nmap <leader>ct :cs find t <C-R>=expand("<cword>")<CR><CR>
nmap <leader>ce :cs find e <C-R>=expand("<cword>")<CR><CR>
nmap <leader>cf :cs find f <C-R>=expand("<cfile>")<CR><CR>
nmap <leader>ci :cs find i ^<C-R>=expand("<cfile>")<CR>$<CR>


"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => nerdtree
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
let NERDTreeMinimalUI = 0
" let NERDTreeWinPos = 'right'


"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => php
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" php注释
inoremap <C-P> <ESC>:call PhpDocSingle()<CR>i
nnoremap <C-P> :call PhpDocSingle()<CR>
vnoremap <C-P> :call PhpDocRange()<CR>
" 检查php语法
autocmd FileType php noremap <C-N> :!/Data/apps/php/bin/php -l %<CR>


"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => phpcomplete
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
let g:phpcomplete_relax_static_constraint = 1




"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => TagList
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" " 设置ctags命令的位置
" let Tlist_Ctags_Cmd = '/usr/bin/ctags'
" " 设置为1时,taglist窗口横向显示。默认纵向显示
" let Tlist_Exit_OnlyWindow = 1
" " 设置taglist窗口的高度
" let Tlist_WinHeight = 100
" " 设置taglist窗口的宽度
" let Tlist_WinWidth = 40
" " 设置Tlist_Show_One_File为1则只显示当前文件的taglist,缺省显示多个文件中的tag
" let Tlist_Show_One_File = 1
" " taglish默认按tag在文件中出现的顺序进行排序,设置为"name",taglist将以tag名字进行排序
" let Tlist_Sort_Type = "name"
" " 设置为1时,如果taglist是最后一个窗口,则退出vim
" let Tlist_Exit_OnlyWindow = 1
" " 设置为1时,taglist窗口出现在右侧,缺省显示在左侧
" let Tlist_Use_Right_Window = 1
" " 如果想在启动VIM后自动打开taglist窗口,该参数设置为1
" " let Tlist_Auto_Open = 1
" " 如果想在选择了tag后自动关闭taglist窗口,该参数设置为1
" let Tlist_Close_On_Select = 1
" " 设置为1时,打开taglist光标保留在taglist窗口
" let Tlist_GainFocus_On_ToggleOpen = 1
" " taglist始终解析文件中的tag
" let Tlist_Process_File_Always = 1
" let tlist_php_settings = 'php;c:class;i:interface;d:constant;f:function'

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" => Tagbar
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" " 使用这个选项来指定ctags可执行文件的位置
" let g:tagbar_ctags_bin = '/usr/bin/ctags'
" " tagbar窗口宽度,默认40
" let g:tagbar_width = 30
" " 如果想在选择了tag后自动关闭taglist窗口
" let g:tagbar_autoclose = 1
" " 打开vim是自动打开
" let g:tagbar_autofocus = 1

2进制10进制转换

一、基本

  • 不允许隐式类型转换

    常用集合

  • 基本声明使用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    fmt.Printf("hello word" + "\n")
    // 声明字符串
    var str1 = "njdkanjkdns"
    fmt.Printf(str1 + "\n")
    // 声明字符串2
    var str2 string
    str2 = "ndsjak13132"
    fmt.Printf(str2 + "\n")
    // 声明字符串3
    var str3 string
    fmt.Printf(str3 + "\n")
    // 声明字符串4
    str4 := "1234fdsf"
    fmt.Printf(str4 + "\n")
    // 声明字符串5
    var (
    str5 string = "dajkdnsjk11"
    )
    fmt.Printf(str5 + "\n")
    // 标常用 var str3 string="1232"; str4:="12323";var str3,str4:="12323",'12323";
  • 变量交换

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    // 二进制与方式变量交换(省内存)
    fmt.Println("二进制与方式变量交换(省内存))")
    var a int = 100
    var b int = 200
    a = a ^ b
    b = b ^ a
    a = a ^ b

    fmt.Println(a, b)
    // 变量交换(常规)
    fmt.Println("变量交换(常规)")
    var c int = 100
    var d int = 200
    c, d = d, c
    fmt.Println(c, d)
  • 匿名变量

    1
    2
    3
    4
    5
    // 匿名变量 (变量不被用到时会报错 所以用_来代替)
    fmt.Println("匿名变量")
    e, _ := 100, 200
    _, f := 100, 200
    fmt.Println(e, f)
  • 常量

    1
    2
    3
    4
    5

    // 常量
    const const1 int = 1
    fmt.Println("常量")
    fmt.Println("常量", const1)
  • 变量作用域
    全局变量和局部变量 函数题外 var声明 全局 函数体内如果有同名局部变量 则局部变量优先

  • 数组 :
    初始化固定长度

    1
    2
    3
    4
    5
    6
    var tmpArr = [10]int{}
    var a [3]int
    a[0] = 1

    b := [3]int{1,2,3}
    c := [2][3]int{{1,2,4},{4,5,6}}
  • 切片:
    可变长度,容量不够按照2的倍数增长容量空间,共享存储结构 (len()获取元素个数,cap获取容量)

  • map:
    相当于js 的json对象 形式可以自定义k {“asd”:1,”qwe”:2}

    1
    2
    3
    4
    5
    6
    //声明
    m := map[string]int{"asd":1,"qwe":2}
    m1 := map[string]int{}
    m1["one"] = 1

    m2 := make(map[string]int,10)
  • 循环

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // 循环
    fmt.Println("循环")
    for i := 1; i <= 10; i++ {
    fmt.Println(i)
    }

    // for each 循环
    var tmpArr = [10]int{}
    tmpArr = [10]int{2, 3, 5, 5}
    tmpArr[4] = 1
    for i, x := range tmpArr {
    fmt.Println(i, x)
    }
  • 指针
    指针 1、指针存储 变量的内存地址 2、变量加&获取地址 3、指针前家* 获取指针指向的变量的值 4、修改指针变量的值,所有指向改内存的变量都会被修改

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    var ipa int = 312
    var ipInt *int /* 指向整型*/
    var fpFloat *float32 /* 指向浮点型 */
    ipInt = &ipa
    *ipInt = 23
    fmt.Println(ipInt, fpFloat, ipa)

    // z指针数组
    var tmpArr5 = [3]int{1, 2, 3}
    var fpArr [3]*int
    for i := 0; i < 3; i++ {
    fpArr[i] = &tmpArr5[i]
    }
    fmt.Println(*fpArr[0], fpArr[0])
  • struct结构体

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    //自定义数据结构类型
    type Result struct {
    Code int `json:"code_json"`
    Message string `json:"msg_json"`
    }
    type testp int

    var res1 = Result{Code: 123, Message: "qwe123"}
    fmt.Println(res1)
    var res1Json, err = json.Marshal(res1)
    fmt.Println("输出json后:", string(res1Json), err)
    /*
    也可以这么写
    if res1Json, err = json.Marshal(res1); err != nil{
    fmt.Println("输出json后报错了:", err)
    }
    fmt.Println("输出json后成功了:", string(res1Json))
    */

    var res2 Result
    err = json.Unmarshal(res1Json, &res2)
    fmt.Println("json解密后:", res2, err)

管理Goroutine的三种方式

管理Goroutine的三种方式waitGroup, channel, context的区别

waitGroup

  • 使用范围:
    1、当一个工作需要被拆分成多个子工作,需要等待全部的子工作处理完成后才能进行下一步工作的时候,一般使用waitGroup。

    channel

  • 使用范围:
    1、用于关闭goroutine。当有一个或几个Goroutine在后台执行一些任务的时候,在主程序结束前通过channel来通知这些goroutine关闭。
    2、用于在主程序获取当有一个或者任意个数的协程执行完毕,然后执行后续操作

    context

  • 描述
    done channel 可以在你的程序中流动并取消所有阻塞的并发操作。 看起来不错,但是还不完美,还不是很够用。
    如果我们可以在简单的通知上附加传递额外的信息; 如 为什么取消发生, 函数是否有需要完成的最后期限(超时), 这些情况下这些功能 非常有用。
  • 函数中取消有三种情况:
    1。 goroutine 的 父 goroutine 可能想要取消它。
    2。 一个goroutine 可能想要取消它的 子goroutine
    3。 goroutine 中呢任何阻塞操作都必须是可抢占的, 以便它可以被取消。
  • 适用范围:
    context相比于单独使用channel来通知goroutine关闭有着更加复杂的功能,适用于通知有多层的goroutine关闭。

http、tcp、udp

网络概念

1、七层模型:
有应用层 表示层 会话层 传输层 网络层 数据链路层 物理层
1LWZC6
大致举例
BzTWFr
2、4层模型(tcp/ip协议族):
应用层,传输层,网络层,网络接入层四个层次
mCRJF1
3、http属于应用层、tcp和udp属于传输层
4、IP (网际协议)、TCP(传输控制协议)、HTTP(应用层协议)、UDP(用户数据报协议)
5、传输层用来传输网络数据,应用层用来定义传输的网络数据的规则使其有意义

http

1、属于应用层
2、http基于tcp通过三次握手建立链接
3、www浏览的一个协议
4、http/1.1开始使用长链接

重要概念

1.连接(Connection):一个传输层的实际环流,它是建立在两个相互通讯的应用程序之间。
2.消息(Message):HTTP通讯的基本单位,包括一个结构化的八元组序列并通过连接传输。
3.请求(Request):一个从客户端到服务器的请求信息包括应用于资源的方法、资源的标识符和协议的版本号
4.响应(Response):一个从服务器返回的信息包括HTTP协议的版本号、请求的状态(例如“成功”或“没找到”)和文档的MIME类型。
5.资源(Resource):由URI标识的网络数据对象或服务。
6.实体(Entity):数据资源或来自服务资源的回映的一种特殊表示方法,它可能被包围在一个请求或响应信息中。一个实体包括实体头信息和实体的本身内容。
7.客户机(Client):一个为发送请求目的而建立连接的应用程序。
8.用户代理(Useragent):初始化一个请求的客户机。它们是浏览器、编辑器或其它用户工具。
9.服务器(Server):一个接受连接并对请求返回信息的应用程序。
10.源服务器(Originserver):是一个给定资源可以在其上驻留或被创建的服务器。
11.代理(Proxy):一个中间程序,它可以充当一个服务器,也可以充当一个客户机,为其它客户机建立请求。请求是通过可能的翻译在内部或经过传递到其它的服务器中。一个代理在发送请求信息之前,必须解释并且如果可能重写它。
代理经常作为通过防火墙的客户机端的门户,代理还可以作为一个帮助应用来通过协议处理没有被用户代理完成的请求。
12.网关(Gateway):一个作为其它服务器中间媒介的服务器。与代理不同的是,网关接受请求就好象对被请求的资源来说它就是源服务器;发出请求的客户机并没有意识到它在同网关打交道。
网关经常作为通过防火墙的服务器端的门户,网关还可以作为一个协议翻译器以便存取那些存储在非HTTP系统中的资源。
13.通道(Tunnel):是作为两个连接中继的中介程序。一旦激活,通道便被认为不属于HTTP通讯,尽管通道可能是被一个HTTP请求初始化的。当被中继的连接两端关闭时,通道便消失。当一个门户(Portal)必须存在或中介(Intermediary)不能解释中继的通讯时通道被经常使用。
14.缓存(Cache):反应信息的局域存储。

tcp

1、属于传输层
2、面向链接,三次握手进行链接通信
3、对比udp速度慢、传输可靠、适用传输大量数据

重要概念

  1. *源端口和目的端口字段—— socket(IP+端口号)。TCP的包是没有IP地址的,那是IP层上的事。但是有源端口和目标端口。
  2. *序列号 SEQ ——当前报文段的序号。
  3. 确认应答号 AN ——期望收到对方的下一个报文段的数据的第一个字节的序号;
  4. 紧急 URG ——当 URG = 1 时,表明紧急指针字段有效。它告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据);
  5. *确认 ACK ——当 ACK = 1 时。表示确认应答号 AN 有效。
  6. 推送 PSH (PuSH) —— 接收 TCP 收到 PSH = 1 的报文段,就尽快地交付接收应用进程,而不再等到整个缓存都填满了后再向上交付;
  7. 复位 RST (ReSeT) —— 当 RST = 1 时,表明 TCP 连接中出现严重差错(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立传输连接;
  8. *同步 SYN —— 同步 SYN = 1 表示这是一个连接请求报文。
  9. 终止 FIN (Finish) —— 用来释放一个连接。FIN= 1 表明发送端的数据已发送完毕,并要求释放传输连接;
  10. 窗口字段 —— 占 2 字节,用来让对方设置发送窗口的依据,单位为字节。窗口值是[ 0, 216-1 ]之间的整数;
  11. 检验和 —— 占 2 字节。检验和字段检验的范围包括首部和数据这两部分。在计算检验和时,要在TCP 报文段的前面加上 12 字节的伪部(协议字段为6,表示TCP);
  12. 紧急指针字段 —— 占 16 位,指出在本报文段中紧急数据共有多少个字节(紧急数据放在本报文段数据的最前面);
  13. 选项字段 —— 长度可变。① 最大报文段长度 MSS:MSS是指在TCP连接建立时,收发双发协商的通信时每一个报文段所能承载的数据字段的最大长度(并不是TCP报文段的最大长度,而是:MSS=TCP报文段长度-TCP首部长度),单位为字节(双方提供的MSS中的最小值,为本次连接的最大MSS值);② 窗口扩大选项;③ 时间戳选项; ④ 选择确认选项;

    tcp三次握手

  • 第一次握手:客户端向服务器发送请求报文段,其中同步位SYN=1,序号SEQ=x(表明传送数据时的第一个数据字节的序号是x),等待服务器确认;
  • 第二次握手:服务器收到客户端发来的请求,如果同意建立连接,就发回一个确认报文段,该报文段中同步位SYN=1,确认号ACK=x+1,序号SEQ=y;
  • 第三次握手:客户端收到服务器的确认报文段后,还需要向服务器给出确认,向其发送确认包ACK(ack=y+1),进而完成三次握手。
  • 通过这样的三次握手,客户端与服务端建立起可靠的双工的连接,开始传送数据。
  • 为了保证服务端能收接受到客户端的信息并能做出正确的应答而进行前两次(第一次和第二次)握手
  • 为了保证客户端能够接收到服务端的信息并能做出正确的应答而进行后两次(第二次和第三次)握手。

    udp

    1、属于传输层
    2、非面向链接,直接通过ip发送消息
    3、速度快、传输不可靠、适用传输少量数据允许丢包

docker安装php开发环境

序言

  • 本文继续mac os系统演示
  • 本文基于本地开发安装环境用于演示
  • nginx-1.19.3、php-7.3、redis:6.0

    一、安装docker

    1
    $ brew cask install docker

    二、安装需要了解的概念和基础命令

    1、docker的组成

    docker由 仓库、镜像、容器三大部分组成
    1)镜像:可以想想成为模版,例如windows系统的镜像,
    2)容器:通过启动镜像来生成容器,就是我们环境中真实要使用到的服务存储的地方 一般由 一个linux系统内包含一个应用服务组成(例如linux中安装了一个php)
    3)仓库:用来集中存储镜像的的地方,一般我们使用 docker hub (hub.docker.com)
    容器与镜像的关系类似于面向对象编程中的对象与类
  • 如果用git来对比举例:
    镜像则为一个维护好的master主分支
    容器则是我们自己定义使用的开发分支,但是不能合并到主分支
    仓库则为git的代码存放仓库了

    2、环境的安装方式

    1)使用docker安装一个linux虚拟机,然后在虚拟机中使用linux相关命令安装php相关开发环境,这就和docker没啥太大关系了
    2)使用docker分别nginx、PHP、redis等多个应用服务容器然后用docker的网关进行链接通信
    fLoeSW

    3、环境安装方法

  • 分为普通基础安装:
    一个一个安装,官方样例经常出现的方式
  • 使用docker-composer安装:
    使用docker compose 配置文件(yml文件),配置应用程序需要的所有服务,然后使用一个命令自动安装所有东西(例如php 的composer.json 和compose install)
  • 本文会先介绍基础安装,然后介绍 docker-composer 方式

    4、常用基础命令

    1) docker images(docker image ls) :来列出本地主机上已经下载的镜像
    2) docker pull :用来从远程仓库下载镜像
    3) docker search :在仓库中搜索镜像
    4)docker run :运行镜像生成并生成容器
    5)docker ps :查看正在运行的容器的列表
    6)docker ps -a:查看本地已经生成的容器(包含未运行的)
    7)docker exec :进入到容器中,可以想想未ssh进入到了一个linux系统

三、安装nginx

1、下载nginx镜像

1
$ docker pull nginx:1.19.3

这样nginx镜像就下载下来了,可以用 docker images 查看
iH1PtX

2、运行镜像生成容器

1
2
3
4
5
$ docker run --name nginx-1.19.3
-v ~/mycode:/usr/share/nginx/html
-v ~/docker-volumes/nginx/config:/etc/nginx/conf.d
-v /tmp/docker-log/nginx:/var/log/nginx
-p 80:80 -d nginx:1.19.3

参数说明:
-v 表示目录映射关系(前者是宿主机目录,后者是映射到宿主机上的目录),可以使用多个-v做多个目录或文件映射。注意:最好做目录映射,在宿主机上做修改,然后共享到容器上
–name nginx-1.19.3:设置容器名称。
-p 80:80: 端口进行映射,将本地 80 端口映射到容器内部的 80 端口。
-d: 设置容器在在后台一直运行。

sJ46Dc

3、创建配置文件、进入容器逛一逛

1
$ docker exec -it  nginx-1.19.3

进来后可以看看nginx的配置文件等信息,

现在我们已经把配置文件映射到宿主机上了我们可一到宿主机的对应目录调调改改nginx配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#宿主机 config
server {
listen 80;
server_name mytest.com;
root /usr/share/nginx/html;
location / {
index index.html index.htm index.php;
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_param APP_ENV dev;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}

然后exit退出 ,然后重启下nginx

1
$ docker restart  nginx-1.19.3

现在我们就可以运行我们的nginx了 127.0.0.1
但是现在只能运行查看html等静态文件,看不了php,这是为什么呢?因为我们还没装php

三、安装php

1、下载php

1
$ docker pull php:7.3

2、运行镜像生成容器

1
2
3
4
$ docker run --name  php-7.3
-v ~/mycode:/usr/share/nginx/html
--expose=9000
-d php:7.3

参数说明:
-expose 对其他容器报漏9000端口,但不能和主机通信 。
重点说明:
-此处php挂在的目录需要与nginx中的www目录相同,因为正常来说nginx和php在一台机器上,www目录要php和nginx都能访问到

-可以运行后发现好多扩展没有,可以使用进入docker容器使用docker提供的命令进行安装 例如mysql
因为使用的源是fpm包 所以很多扩展都没有装

1
2
$ docker-php-ext-install pdo
$ docker-php-ext-install pdo_mysql

四、容器和容器间通信

  • 现在已经安装了nginx和php了为啥还是不能解析php文件呢
    原因在于nginx和php两个容器之间还有没进行通信
    那么怎么进行通信呢
    1、我们要修修改nginx中fastcgi中请求php的地址参数 fastcgi_pass 127.0.0.1:9000; 改为 fastcgi_pass 172.25.0.2:9000;
    2、重启nginx,就可以了呀

  • 那么问题来了。这个php的ip哪来的。
    我们默认使用docker的bridge模式 此网络创建一个名为docker0的虚拟网桥,并将容器连接到一个docker0虚拟网桥,所有网桥下的容器共享Network Namespace

    五、使用docker compose 安装nginx、php

    上面已经大致的了解了怎么安装nginx和php了 ,mysql和上面的方法一样我就不举例了
    下面说如何使用compose进行安装呢?compose安装都需要什么呢?

1、compose安装环境的流程

使用 Dockerfile 定义应用程序的环境。
使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。
最后,执行 docker-compose up 命令来启动并运行整个应用程序。

Dockerfile 这个玩意没有也能装,他是用来自定义镜像的,我们用通用镜像就可以

2、上docker-compose.yml 文件

  • 随便找个地方件个文件夹,进去到里面创建的xxxx.yml文件,我的叫composetest.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
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
version: "3"
networks:
local_net:
external:
name: local_net

services:
nginx:
container_name: local-nginx-1.19.3
image: nginx:1.19.3
ports:
- "80:80"
volumes:
- ~/mycode:/usr/share/nginx/html
- ~/docker-volumes/nginx/config:/etc/nginx/conf.d
- /tmp/docker-log/nginx:/var/log/nginx
networks:
local_net:
ipv4_address: 172.25.0.3
extra_hosts:
- "local.testdoctor.meidaifu.com:127.0.0.1"
- "local.patient.meidaifu.com:127.0.0.1"

php:
container_name: local-php-7.3-fpm
image: php:7.3-fpm
volumes:
- ~/mycode:/usr/share/nginx/html
networks:
local_net:
ipv4_address: 172.25.0.2
stdin_open: true
tty: true
expose:
- 9000
redis:
container_name: local-redis-6.0
image: redis:6.0
networks:
local_net:
ipv4_address: 172.25.0.6
ports:
- "6379:6379"
expose:
- 6379
mysql:
container_name: local-mysql-8.0 # 指定容器的名称
image: mysql:8.0 # 指定镜像和版本
ports:
- "3306:3306"
expose:
- 3306
environment:
MYSQL_ROOT_PASSWORD: "root"
MYSQL_ROOT_HOST: "%"
networks:
local_net:
ipv4_address: 172.25.0.7
volumes:
- "~/docker-volumes/mysql/data:/var/lib/mysql" # 挂载数据目录
- "~/docker-volumes/mysql/config:/etc/mysql/conf.d" # 挂载配置文件目录
  • 参数解释
    version:这个是表示用哪个docker-compose版本来解析,不用版本模版语法有差异 这里用的3
    networks:用来声明所使用的网络环境
    services:这个就是服务容器的集合,里面每一块都是一个服务
    container_name:用来定一容器的名称
    image:表示锁使用镜像的,也可以使用build命令来指定dockerfile文件路径从上下文路径 ./Dockerfile 所构建镜像
    volumes:挂载
    services 中的networks这里来指定使用哪个网络,指定当前容器在当前网段的ip
    expose:对外报漏的端口
    ports:宿主机和容器的端口映射

  • 注意事项
    1) 如果指定ip需要自己创建一个网络空间 不能使用默认的,这也解决了每次容器ip变动的问题

    1
    docker network local_net bridge

    Fd7VpT
    2) 关于虚拟域名配置
    这就要做一下nginx容器的host配置如上yml文件中extra_hosts,当前宿主机的本地host也要加

然后修改nginx的配置 如下是我的meidaifu.conf的配置

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
server {
listen 80;
server_name local.testdoctor.meidaifu.com ;
root /usr/share/nginx/html/onepiece/public;
location / {
index index.html index.htm index.php;
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_param APP_ENV dev;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 172.25.0.2:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}

server {
listen 80;
server_name local.patient.meidaifu.com;
root /usr/share/nginx/html/onepiece_patient/public;
location / {
index index.html index.htm index.php;
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_param APP_ENV dev;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 172.25.0.2:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}

然后修改yml文件 中nginx的配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
nginx:
container_name: local-nginx-1.19.3
image: nginx:1.19.3
ports:
- "80:80"
volumes:
- ~/mycode:/usr/share/nginx/html
- ~/docker-volumes/nginx/config:/etc/nginx/conf.d
- /tmp/docker-log/nginx:/var/log/nginx
networks:
local_net:
ipv4_address: 172.25.0.3
extra_hosts:
- "local.testdoctor.meidaifu.com:127.0.0.1"
- "local.patient.meidaifu.com:127.0.0.1"
depends_on:
- php

3、运行docker compose

1
docker-compose up -d

rc1Frn
然后就可以运行了。

如果可以在果面版的docker中查看的更清楚
dIgSAi

docker-compose down 停止并删除容器
67lyX4

docker-compose stop 停止并不删除容器
wn49vN

4、使用dockerfile自动增加PHP扩展

当前目录创建 phpfile/Dockerfile

1
2
3
4
5
6
7
8
# base image
FROM php:7.3-fpm

# MAINTAINER
MAINTAINER tianfs

# running required command
RUN docker-php-ext-install pdo_mysql

然后修改 compose文件中php的配置为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
php:
container_name: local-php-7.3-fpm
build:
context: ./phpfile
dockerfile: Dockerfile
image: php:7.3-fpm-local
volumes:
- ~/mycode:/usr/share/nginx/html
networks:
local_net:
ipv4_address: 172.25.0.2
stdin_open: true
tty: true
expose:
- 9000

build 和image 同时出现 则image 将为build后镜像生成的名字和tag
然后

1
docker-compose up -d

然后你就可以拿这你的配置文件 到处耍了。

六、注意事项

查看另一片文章docker遇到的相关问题

七、延伸思考

1、这种搭建方式是否符合最佳事实践方案标准?
2、如果多台服务器需要部署如何管理?

docker遇到的一些问题

docker个人遇到的问题一些备注

1) 如果出现 bash: vim : command not found 需要安装下vim

1
2
$ apt-get update
$ apt-get install vim

2) 如果出现 bash: apt-get : command not found 尝试使用yum安装

1
$ yum install vim -y

3) 如果容器内出现 [Errno 13] Permission denied (错误描述如下)

1
2
3
4
5
$ yum install vim -y
Loaded plugins: fastestmirror, ovl
ovl: Error while doing RPMdb copy-up:
[Errno 13] Permission denied: '/var/lib/rpm/Basenames'
You need to be root to perform this command.
  • 是因为进入用户不是root权限,进入容器时增加 –user root 参数 (docker exec -it –user root 容器 bash)

4) 查看所有容器的ip

1
$ docker inspect --format='{{.Name}} - {{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -aq)

5) docker中安装php扩展

1
$ docker-php-ext-install pdo

6) 提示文件挂载目录不可使用
可以查看一下doc可以挂载的授权目录的列表可以在桌面版上看一下
4hNwhh
7) 如果创建网络出现 ERROR: Pool overlaps with other one on this address space
该错误的意思是docker已有一个容器占用了目前docker-compose里的subnet。

1
docker network prune

7) 创建一个自己的网络

1
docker network create --subnet=172.25.0.0/24 --driver=bridge local_net

docker网络模式

bridge模式(默认)(–network=bridge)

  • 创建一个名为docker0的虚拟网桥,并将容器连接到一个docker0虚拟网桥,所有网桥下的容器共享Network Namespace
  • 可以关闭容器见通信,在DOCKER_OPTS变量中设置–icc=false,这样只有使用–link才能使两个容器通信。
    vWMAEu

    host模式(–network=host)

  • 容器和宿主机共享Network,使用宿主机的IP和端口,容器可以直接使用宿主机的IP地址与外界通信
  • 网络性能比较好,网络的隔离性不好,
    ESCn9R

    none模式 (–network=none)

  • 拥有自己的Network Namespace,该模式默认关闭了容器的网络功能,需要自己配置。
    7Ojq4g

    container模式 (–network=container:NAME_or_ID)

  • 容器和另外一个容器共享Network namespace,而不是和宿主机共享
    CnSpBL

elasticsearch知识整理

ElasticSearch

elasticsearch 是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。

特点

  • 分布式,无需人工搭建集群(solr就需要人为配置,使用Zookeeper作为注册中心)
  • Restful风格,一切API都遵循Rest原则,容易上手
  • 近实时搜索,数据更新在Elasticsearch中几乎是完全同步的。

    一、安装

    1、docker方式安装elasticsearch

  • 安装
    1
    $ docker pull elasticsearch
  • 启动 (java程序访问可以在增加一个9300端口)
    1
    $ docker run --name elasticsearch -p 9200:9200  -e "discovery.type=single-node" -d elasticsearch
  • 进入容器修改配置
    1
    2
    3
    $ docker exec -it elasticsearch /bin/bash
    $ cd /usr/share/elasticsearch/config/
    $ vi elasticsearch.yml
  • 追加一下内容,解决跨域问题
    1
    2
    http.cors.enabled: true
    http.cors.allow-origin: "*"
  • 重启容器
    1
    2
    $ exit
    $ docker restart elasticsearch
    默认访问链接http://127.0.0.1:9200就可以打开kibana的界面了。

    2、安装ik分词器

    es自带的分词器对中文分词不是很友好,elasticsearch的版本和ik分词器的版本需要保持一致;
    1
    2
    3
    4
    $ cd /usr/share/elasticsearch/plugins/
    $ elasticsearch-plugin install 对应版本的安装包地址(https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.2.0/elasticsearch-analysis-ik-7.2.0.zip)
    $ exit
    $ docker restart elasticsearch 可以在kibana界面的dev tools中验证是否安装成功

    3、docker安装kibana

    可视化elasticsearch管理页面
  • 安装 (要与es版本对应)
    1
    $ docker pull kibana
  • 启动kibana(使用–link连接到elasticsearch容器 ,或者使用Network让其在同一个网络下)
    1
    2
    $ docker run --name kibana  -p 5601:5601 -d kibana
    $ docker start kibana
    浏览器输入http://127.0.0.1:5601就可以打开kibana的界面了。
  • 遇到问题
    1)访问提示 Kibana server is not ready yet
    第一:把KB和ES版本调整为统一版本
    第二:将配置文件kibana.yml中的elasticsearch.url改为正确的链接
    第三:保持kibana和elasticsearch在同一个网络模式下,可以使用默认的bridge网络下的段的地址172.17.0.x
    注意,默认为bridge网络,此网络下两个容器无法用127.0.0.x 的本地ip进行通信访问,如果想用要都切换到host模式

二、常用命令

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
GET _search
{
"query": {
"match_all": {}
}
}
GET _cluster/health
GET _cat/nodes

#创建,自动生成id
POST users/_doc
{
"user":"Mike",
"post_date":"2019-04-15T12:12:12",
"message":"trying out Kibana"
}
#创建,手动指定id,id存在报错
PUT users/_doc/1?op_type=create
{
"user":"Mike",
"post_date":"2019-04-15T12:12:12",
"message":"trying out Kibana123123"
}
#根据id查询一条
GET users/_doc/1

#(index方式创建)删除原来的文档,写入新的,版本加一
PUT users/_doc/1
{
"user":"MIke"
}
#根据ID修改文档的内容,没有的字段会新增
POST users/_update/1/
{
"doc":{
"post_date":"2019-04-15T12:12:12",
"message":"trying out Kibana123123"
}
}
#根据删除
DELETE users/_doc/1

#批量增删改
PUT _bulk
#根据id批量读
GET _mget
#读全部
POST kibana_sample_data_ecommerce/_msearch
{}
{"query":{"match_all":{}},"size":1}
#match:会将搜索田间分词,然后到索引里面找
#match_phrase:习语匹配,查询确切的phase,在对查询字段定义了分词器的情况下,会使用分词器对输入进行分词,然后返回满足下述两个条件的document:
#term 是代表完全匹配(相当mysql与全等用 )

三、索引settings和mappings

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
PUT loaravel-log-2020.11.05
{
"settings": {
"number_of_shards": 2,//主分片数
"number_of_replicas": 1 //每一个主分片有多少个副本分片
},
"mappings": {
"properties": {
"path": {
"type": "keyword"
},
"type": {
"type": "keyword"
},
"messgae": {
"type": "text"
},
"tags": {
"type": "text",//可以寸数组
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"host": {
"type": "keyword"
},
"@timestamp": { //带@的是系统预留字段 固定类型
"type": "date"
},
"@version": {
"type": "text"
}
}
}
}

四、重要知识点

查询搜索条件算分
索引的命名规则
创建一个新indx时 设置 setting mapping(字段类型,分词规则)
index template
聚合统计搜索使用(aggs) bucket按照规则诗句划分不同的组(相当于mysql group),metric 用于数据集的统计(可以统计bucket生成的数据集中的字段进行分析,例如平均值)
search -》协调节点-》查询所有分片-》取回id和排序合并-》去对应分片的数据节点取出具体doc信息
主节点 index(存储索引index信息,索引关联对应的分片) -》