-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathatom.xml
702 lines (393 loc) · 333 KB
/
atom.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
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>chuchu-z</title>
<link href="http://chuchu-z.com/atom.xml" rel="self"/>
<link href="http://chuchu-z.com/"/>
<updated>2024-12-31T06:57:56.021Z</updated>
<id>http://chuchu-z.com/</id>
<author>
<name>chuchu-z</name>
</author>
<generator uri="https://hexo.io/">Hexo</generator>
<entry>
<title>Supervisor 管理 Docker 容器内进程问题</title>
<link href="http://chuchu-z.com/posts/supervisor-docker-container-process-issues/"/>
<id>http://chuchu-z.com/posts/supervisor-docker-container-process-issues/</id>
<published>2024-07-24T09:49:33.000Z</published>
<updated>2024-12-31T06:57:56.021Z</updated>
<content type="html"><![CDATA[<p><strong>问题描述</strong>:在测试环境中发现,宿主机的 Supervisor 进程管理工具无法有效管理 Docker 容器内由 <code>docker exec php7</code> 命令创建的 PHP 进程。这导致 Supervisor 对 Docker 容器内的 PHP 进程无法进行有效的控制和重启</p><p><strong>预期行为</strong>:宿主机的 Supervisor 应能够控制 Docker 容器内由 <code>docker exec php7</code> 命令创建的 PHP 进程,包括启动、停止和重启</p><span id="more"></span><p>supervisor 配置如下:</p><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token punctuation">[</span>program:laikeduo_test_rabbitmq_processor<span class="token punctuation">]</span><span class="token assign-left variable">command</span><span class="token operator">=</span>docker <span class="token builtin class-name">exec</span> php7 php /var/www/laikeduo_test/artisan rabbitmq:process-messages<span class="token assign-left variable">directory</span><span class="token operator">=</span>/var/www/laikeduo_test<span class="token assign-left variable">autostart</span><span class="token operator">=</span>true<span class="token assign-left variable">autorestart</span><span class="token operator">=</span>true<span class="token assign-left variable">stopasgroup</span><span class="token operator">=</span>true<span class="token assign-left variable">killasgroup</span><span class="token operator">=</span>true<span class="token assign-left variable">stderr_logfile</span><span class="token operator">=</span>/var/www/laikeduo_test/storage/logs/laikeduo_test_rabbitmq_processor.err.log<span class="token assign-left variable">stdout_logfile</span><span class="token operator">=</span>/var/www/laikeduo_test/storage/logs/laikeduo_test_rabbitmq_processor.out.log</code></pre><h3 id="现象与分析"><a href="#现象与分析" class="headerlink" title="现象与分析"></a>现象与分析</h3><p><strong>现象</strong>:关闭或重启Supervisor, 只会对本身的<code>docker exec php7</code>命令生效, 容器内部已经启动的进程不受影响</p><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token punctuation">[</span>root@iZwz995otwrhk15lyjqnpkZ laikeduo_test<span class="token punctuation">]</span><span class="token comment"># ps -aux | grep artisan</span>root <span class="token number">19379</span> <span class="token number">0.0</span> <span class="token number">0.9</span> <span class="token number">1307524</span> <span class="token number">16776</span> ? Sl <span class="token number">16</span>:47 <span class="token number">0</span>:00 <span class="token function">docker</span> <span class="token builtin class-name">exec</span> php7 php /var/www/laikeduo_test/artisan queue:workroot <span class="token number">19380</span> <span class="token number">0.1</span> <span class="token number">0.9</span> <span class="token number">1307780</span> <span class="token number">16584</span> ? Sl <span class="token number">16</span>:47 <span class="token number">0</span>:00 <span class="token function">docker</span> <span class="token builtin class-name">exec</span> php7 php /var/www/laikeduo_test/artisan rabbitmq:process-messageswww <span class="token number">19407</span> <span class="token number">0.6</span> <span class="token number">1.7</span> <span class="token number">92228</span> <span class="token number">30780</span> ? Ss <span class="token number">16</span>:47 <span class="token number">0</span>:00 php /var/www/laikeduo_test/artisan queue:workwww <span class="token number">19416</span> <span class="token number">0.7</span> <span class="token number">1.6</span> <span class="token number">92228</span> <span class="token number">30200</span> ? Ss <span class="token number">16</span>:47 <span class="token number">0</span>:00 php /var/www/laikeduo_test/artisan rabbitmq:process-messageswww <span class="token number">19433</span> <span class="token number">0.0</span> <span class="token number">1.3</span> <span class="token number">92228</span> <span class="token number">23532</span> ? S <span class="token number">16</span>:47 <span class="token number">0</span>:00 php /var/www/laikeduo_test/artisan rabbitmq:process-messageswww <span class="token number">19434</span> <span class="token number">0.0</span> <span class="token number">1.3</span> <span class="token number">92228</span> <span class="token number">23528</span> ? S <span class="token number">16</span>:47 <span class="token number">0</span>:00 php /var/www/laikeduo_test/artisan rabbitmq:process-messageswww <span class="token number">19435</span> <span class="token number">0.0</span> <span class="token number">1.3</span> <span class="token number">92228</span> <span class="token number">23524</span> ? S <span class="token number">16</span>:47 <span class="token number">0</span>:00 php /var/www/laikeduo_test/artisan rabbitmq:process-messageswww <span class="token number">19436</span> <span class="token number">0.0</span> <span class="token number">1.3</span> <span class="token number">92228</span> <span class="token number">23532</span> ? S <span class="token number">16</span>:47 <span class="token number">0</span>:00 php /var/www/laikeduo_test/artisan rabbitmq:process-messagesroot <span class="token number">19441</span> <span class="token number">0.0</span> <span class="token number">0.0</span> <span class="token number">112816</span> <span class="token number">980</span> pts/0 R+ <span class="token number">16</span>:47 <span class="token number">0</span>:00 <span class="token function">grep</span> <span class="token parameter variable">--color</span><span class="token operator">=</span>auto artisan<span class="token punctuation">[</span>root@iZwz995otwrhk15lyjqnpkZ laikeduo_test<span class="token punctuation">]</span><span class="token comment"># systemctl stop supervisord</span><span class="token punctuation">[</span>root@iZwz995otwrhk15lyjqnpkZ laikeduo_test<span class="token punctuation">]</span><span class="token comment"># ps -aux | grep artisan</span>www <span class="token number">19407</span> <span class="token number">0.3</span> <span class="token number">1.7</span> <span class="token number">92228</span> <span class="token number">30780</span> ? Ss <span class="token number">16</span>:47 <span class="token number">0</span>:00 php /var/www/laikeduo_test/artisan queue:workwww <span class="token number">19416</span> <span class="token number">0.3</span> <span class="token number">1.6</span> <span class="token number">92228</span> <span class="token number">30200</span> ? Ss <span class="token number">16</span>:47 <span class="token number">0</span>:00 php /var/www/laikeduo_test/artisan rabbitmq:process-messageswww <span class="token number">19433</span> <span class="token number">0.0</span> <span class="token number">1.3</span> <span class="token number">92228</span> <span class="token number">23532</span> ? S <span class="token number">16</span>:47 <span class="token number">0</span>:00 php /var/www/laikeduo_test/artisan rabbitmq:process-messageswww <span class="token number">19434</span> <span class="token number">0.0</span> <span class="token number">1.3</span> <span class="token number">92228</span> <span class="token number">23528</span> ? S <span class="token number">16</span>:47 <span class="token number">0</span>:00 php /var/www/laikeduo_test/artisan rabbitmq:process-messageswww <span class="token number">19435</span> <span class="token number">0.0</span> <span class="token number">1.3</span> <span class="token number">92228</span> <span class="token number">23524</span> ? S <span class="token number">16</span>:47 <span class="token number">0</span>:00 php /var/www/laikeduo_test/artisan rabbitmq:process-messageswww <span class="token number">19436</span> <span class="token number">0.0</span> <span class="token number">1.3</span> <span class="token number">92228</span> <span class="token number">23532</span> ? S <span class="token number">16</span>:47 <span class="token number">0</span>:00 php /var/www/laikeduo_test/artisan rabbitmq:process-messagesroot <span class="token number">19451</span> <span class="token number">0.0</span> <span class="token number">0.0</span> <span class="token number">112812</span> <span class="token number">980</span> pts/0 R+ <span class="token number">16</span>:47 <span class="token number">0</span>:00 <span class="token function">grep</span> <span class="token parameter variable">--color</span><span class="token operator">=</span>auto artisan<span class="token punctuation">[</span>root@iZwz995otwrhk15lyjqnpkZ laikeduo_test<span class="token punctuation">]</span><span class="token comment"># ps -aux | grep 'artisan' | grep -v grep | awk '{print $2}' | xargs kill -9</span><span class="token punctuation">[</span>root@iZwz995otwrhk15lyjqnpkZ laikeduo_test<span class="token punctuation">]</span><span class="token comment"># ps -aux | grep artisan</span>root <span class="token number">19493</span> <span class="token number">0.0</span> <span class="token number">0.0</span> <span class="token number">112812</span> <span class="token number">980</span> pts/0 S+ <span class="token number">16</span>:48 <span class="token number">0</span>:00 <span class="token function">grep</span> <span class="token parameter variable">--color</span><span class="token operator">=</span>auto artisan</code></pre><p><strong>分析</strong>:</p><ul><li> <code>docker exec</code> 命令在宿主机上启动,并不能直接控制容器内的进程。Supervisor 对 <code>docker exec</code> 命令的控制只限于启动和停止 <code>docker exec</code> 进程,而不会直接影响容器内部的进程</li><li> Supervisor 对宿主机上的 <code>docker exec</code> 命令进行管理,但不具备对容器内 PHP 进程的控制能力,因此无法有效管理已经在容器内启动的 PHP 进程</li></ul><h3 id="解决方案"><a href="#解决方案" class="headerlink" title="解决方案"></a>解决方案</h3><p>如果容器内部已经存在过多相关的进程无法删除, 只能指定删除包含<code>artisan</code>关键词的所有进程或者直接关闭再启动php7容器</p><p><strong>方法 1</strong>:直接 kill 掉包含 <code>artisan</code> 关键词的进程</p><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token function">ps</span> <span class="token parameter variable">-aux</span> <span class="token operator">|</span> <span class="token function">grep</span> <span class="token string">'artisan'</span> <span class="token operator">|</span> <span class="token function">grep</span> <span class="token parameter variable">-v</span> <span class="token function">grep</span> <span class="token operator">|</span> <span class="token function">awk</span> <span class="token string">'{print $2}'</span> <span class="token operator">|</span> <span class="token function">xargs</span> <span class="token function">kill</span> <span class="token parameter variable">-9</span></code></pre><p><strong>方法 2</strong>:先关闭再启动 PHP 容器, 经测试, <code>docker-compose restart php7</code> 可能无效</p><pre class="language-none"><code class="language-none">docker-compose stop php7docker-compose start php7</code></pre>]]></content>
<summary type="html"><p><strong>问题描述</strong>:在测试环境中发现,宿主机的 Supervisor 进程管理工具无法有效管理 Docker 容器内由 <code>docker exec php7</code> 命令创建的 PHP 进程。这导致 Supervisor 对 Docker 容器内的 PHP 进程无法进行有效的控制和重启</p>
<p><strong>预期行为</strong>:宿主机的 Supervisor 应能够控制 Docker 容器内由 <code>docker exec php7</code> 命令创建的 PHP 进程,包括启动、停止和重启</p></summary>
<category term="Linux" scheme="http://chuchu-z.com/categories/linux/"/>
<category term="Docker" scheme="http://chuchu-z.com/categories/linux/docker/"/>
</entry>
<entry>
<title>Dockerfile 优化历程</title>
<link href="http://chuchu-z.com/posts/dockerfile-optimization-story/"/>
<id>http://chuchu-z.com/posts/dockerfile-optimization-story/</id>
<published>2024-02-28T01:53:59.000Z</published>
<updated>2024-12-31T06:57:56.013Z</updated>
<content type="html"><![CDATA[<p>使用dockerfile构建一个Python环境的容器, 但是构建出来的镜像太大了, 可以优化一下。</p><span id="more"></span><h2 id="原Dockerfile"><a href="#原Dockerfile" class="headerlink" title="原Dockerfile"></a>原Dockerfile</h2><pre class="language-docker" data-language="docker"><code class="language-docker"><span class="token instruction"><span class="token keyword">FROM</span> python:3.12</span><span class="token instruction"><span class="token keyword">WORKDIR</span> /app</span><span class="token instruction"><span class="token keyword">COPY</span> . /app</span><span class="token comment"># pip 安装 Python 依赖后, 使用 sed 注释 /usr/local/lib/python3.12/site-packages/django/db/backends/base/base.py 的 225行, 避免检查mysql版本</span><span class="token instruction"><span class="token keyword">RUN</span> apt-get update && <span class="token operator">\</span> apt-get install -y sed && <span class="token operator">\</span> pip install --no-cache-dir -r requirements.txt && <span class="token operator">\</span> sed -i <span class="token string">'225s/^/#/'</span> /usr/local/lib/python3.12/site-packages/django/db/backends/base/base.py</span><span class="token instruction"><span class="token keyword">EXPOSE</span> 9527</span><span class="token instruction"><span class="token keyword">CMD</span> [<span class="token string">"python"</span>, <span class="token string">"manage.py"</span>, <span class="token string">"runserver"</span>, <span class="token string">"0.0.0.0:9527"</span>]</span></code></pre><p>镜像大小: 1.35GB</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/posts/dockerfile-optimization-story/image-20240228095131880.png" alt title> </div> <div class="image-caption"></div> </figure><h2 id="优化1-多阶段构建"><a href="#优化1-多阶段构建" class="headerlink" title="优化1-多阶段构建"></a>优化1-多阶段构建</h2><pre class="language-docker" data-language="docker"><code class="language-docker"><span class="token comment"># 阶段1</span><span class="token instruction"><span class="token keyword">FROM</span> python:3.12 <span class="token keyword">AS</span> builder</span><span class="token instruction"><span class="token keyword">WORKDIR</span> /app</span><span class="token instruction"><span class="token keyword">COPY</span> . /app</span><span class="token comment"># 创建并激活虚拟环境</span><span class="token instruction"><span class="token keyword">RUN</span> python -m venv /venv && <span class="token operator">\</span><span class="token comment"># 使用 pip 安装 Python 依赖</span>/venv/bin/pip install --no-cache-dir -r requirements.txt && <span class="token operator">\</span><span class="token comment"># 更新 apt-get</span>apt-get update && <span class="token operator">\</span><span class="token comment"># 安装 sed</span> apt-get install -y sed && <span class="token operator">\</span> <span class="token comment"># 使用 sed 注释 /venv/lib/python3.12/site-packages/django/db/backends/base/base.py 的 225行,避免检查mysql版本</span> sed -i <span class="token string">'225s/^/#/'</span> /venv/lib/python3.12/site-packages/django/db/backends/base/base.py</span><span class="token comment"># 阶段2</span><span class="token instruction"><span class="token keyword">FROM</span> python:3.12</span><span class="token instruction"><span class="token keyword">WORKDIR</span> /app</span><span class="token instruction"><span class="token keyword">COPY</span> <span class="token options"><span class="token property">--from</span><span class="token punctuation">=</span><span class="token string">builder</span></span> /venv /venv</span><span class="token instruction"><span class="token keyword">COPY</span> <span class="token options"><span class="token property">--from</span><span class="token punctuation">=</span><span class="token string">builder</span></span> /app /app</span><span class="token comment"># 设置环境变量</span><span class="token instruction"><span class="token keyword">ENV</span> PATH=<span class="token string">"/venv/bin:$PATH"</span></span><span class="token instruction"><span class="token keyword">EXPOSE</span> 9527</span><span class="token instruction"><span class="token keyword">CMD</span> [<span class="token string">"python"</span>, <span class="token string">"manage.py"</span>, <span class="token string">"runserver"</span>, <span class="token string">"0.0.0.0:9527"</span>]</span></code></pre><p>镜像大小: 1.17GB</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/posts/dockerfile-optimization-story/image-20240228102909647.png" alt title> </div> <div class="image-caption"></div> </figure><h2 id="优化2-使用Alpine基础镜像"><a href="#优化2-使用Alpine基础镜像" class="headerlink" title="优化2-使用Alpine基础镜像"></a>优化2-使用Alpine基础镜像</h2><p>使用Alpine Linux 时, 由于缺少完整的扩展包依赖, 然后又遇到了安装 mysqlclient 时错误的问题, 折腾好久, 功夫不负有心人, 在 <a href="https://stackoverflow.com/questions/76533384/docker-alpine-build-fails-on-mysqlclient-installation-with-error-exception-can">Stack Overflow</a> 找到了一个可参考的, 然后稍作修改</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/posts/dockerfile-optimization-story/image-20240228175650361.png" alt title> </div> <div class="image-caption"></div> </figure><pre class="language-docker" data-language="docker"><code class="language-docker"><span class="token instruction"><span class="token keyword">FROM</span> python:3.12-alpine</span><span class="token instruction"><span class="token keyword">WORKDIR</span> /app</span><span class="token instruction"><span class="token keyword">COPY</span> requirements.txt .</span><span class="token comment"># 更新 Alpine Linux 软件包索引</span><span class="token instruction"><span class="token keyword">RUN</span> apk update && <span class="token operator">\</span> <span class="token comment"># 安装构建依赖和 MariaDB 开发依赖</span> apk add --no-cache --virtual build-deps gcc musl-dev libffi-dev pkgconf mariadb-dev && <span class="token operator">\</span> <span class="token comment"># 安装 mariadb-connector-c-dev 依赖</span> apk add --no-cache mariadb-connector-c-dev && <span class="token operator">\</span> <span class="token comment"># 使用 pip 安装 Python 依赖</span> pip install --no-cache-dir -r requirements.txt && <span class="token operator">\</span> <span class="token comment"># 使用 sed 注释 /usr/local/lib/python3.12/site-packages/django/db/backends/base/base.py 的 225行,避免检查mysql版本</span> sed -i <span class="token string">'225s/^/#/'</span> /usr/local/lib/python3.12/site-packages/django/db/backends/base/base.py && <span class="token operator">\</span> <span class="token comment"># 删除构建依赖,减小镜像体积</span> apk del build-deps</span><span class="token instruction"><span class="token keyword">COPY</span> . .</span><span class="token instruction"><span class="token keyword">EXPOSE</span> 9527</span><span class="token instruction"><span class="token keyword">CMD</span> [<span class="token string">"python"</span>, <span class="token string">"manage.py"</span>, <span class="token string">"runserver"</span>, <span class="token string">"0.0.0.0:9527"</span>]</span></code></pre><p>此时再看镜像大小, 已经来到了210MB</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/posts/dockerfile-optimization-story/image-20240228180117254.png" alt title> </div> <div class="image-caption"></div> </figure><h2 id="优化3-使用Alpine基础镜像-多阶段构建"><a href="#优化3-使用Alpine基础镜像-多阶段构建" class="headerlink" title="优化3-使用Alpine基础镜像+多阶段构建"></a>优化3-使用Alpine基础镜像+多阶段构建</h2><p>虽然210MB已经达到我的预期标准了, 但是我还想试试alpine+多阶段构建后有多大, 但是在分阶段这里总是遇到一些问题, 多次尝试还是未能攻克, 但是这个想法还是保留下来, 后期对docker构建流程更为精进再回来重新尝试。</p>]]></content>
<summary type="html"><p>使用dockerfile构建一个Python环境的容器, 但是构建出来的镜像太大了, 可以优化一下。</p></summary>
<category term="Docker" scheme="http://chuchu-z.com/categories/docker/"/>
</entry>
<entry>
<title>Dockerfile中的COPY与volume挂载冲突问题</title>
<link href="http://chuchu-z.com/posts/dockerfile-COPY-vs-Volume-Conflicts/"/>
<id>http://chuchu-z.com/posts/dockerfile-COPY-vs-Volume-Conflicts/</id>
<published>2024-02-21T02:52:28.000Z</published>
<updated>2024-12-31T06:57:56.013Z</updated>
<content type="html"><![CDATA[<p>闲来无事, 想起之前本地构建博客想看看效果时, 老是出现文章内容丢失的问题, 后来构建时尝试加上<code>--no-cache</code>可以解决该问题, 现在又想折腾一下容器静态文件挂载到宿主机</p><span id="more"></span><pre class="language-none"><code class="language-none">docker-compose build --no-cache && docker-compose up -d</code></pre><h2 id="Dockerfile"><a href="#Dockerfile" class="headerlink" title="Dockerfile"></a>Dockerfile</h2><pre class="language-docker" data-language="docker"><code class="language-docker"><span class="token instruction"><span class="token keyword">FROM</span> node:14 <span class="token keyword">AS</span> builder</span><span class="token instruction"><span class="token keyword">WORKDIR</span> /app</span><span class="token instruction"><span class="token keyword">COPY</span> . .</span><span class="token instruction"><span class="token keyword">RUN</span> npm install --no-fund && npx hexo clean && npx hexo generate</span><span class="token instruction"><span class="token keyword">FROM</span> nginx:alpine</span><span class="token instruction"><span class="token keyword">WORKDIR</span> /usr/share/nginx/html</span><span class="token instruction"><span class="token keyword">COPY</span> <span class="token options"><span class="token property">--from</span><span class="token punctuation">=</span><span class="token string">builder</span></span> /app/public /usr/share/nginx/html</span><span class="token instruction"><span class="token keyword">EXPOSE</span> 8080</span></code></pre><h2 id="docker-compose-yml"><a href="#docker-compose-yml" class="headerlink" title="docker-compose.yml"></a>docker-compose.yml</h2><pre class="language-yaml" data-language="yaml"><code class="language-yaml"><span class="token key atrule">version</span><span class="token punctuation">:</span> <span class="token string">'3'</span><span class="token key atrule">services</span><span class="token punctuation">:</span> <span class="token key atrule">hexo</span><span class="token punctuation">:</span> <span class="token key atrule">build</span><span class="token punctuation">:</span> <span class="token key atrule">context</span><span class="token punctuation">:</span> . <span class="token key atrule">dockerfile</span><span class="token punctuation">:</span> Dockerfile <span class="token key atrule">image</span><span class="token punctuation">:</span> chuchuzz426/blog<span class="token punctuation">-</span>hexo<span class="token punctuation">:</span><span class="token number">1.0</span> <span class="token key atrule">ports</span><span class="token punctuation">:</span> <span class="token punctuation">-</span> <span class="token string">"8080:80"</span><span class="token key atrule">volume</span><span class="token punctuation">:</span> <span class="token punctuation">-</span> ./public<span class="token punctuation">:</span>/usr/share/nginx/html <span class="token comment"># 挂载会把Dockerfile中的COPY覆盖</span></code></pre><h2 id="想法"><a href="#想法" class="headerlink" title="想法"></a>想法</h2><p>我想把 <code>COPY --from=builder /app/public /usr/share/nginx/html</code> 这一步的/usr/share/nginx/html目录下的静态资源挂载到宿主机</p><p>当时脑回路有点迷糊, 想着这样能方便查看或者在宿主机也能刷新静态资源? 但是犯傻忘了每次新的静态资源也是要先通过容器才能生成的😓, 还折腾了起来 </p><p>最后挂载没成功, 倒是遇到了个COPY与挂载的冲突问题。</p><h2 id="问题"><a href="#问题" class="headerlink" title="问题"></a>问题</h2><blockquote><p>如果已经在 Dockerfile 中使用<code>COPY --from=builder /app/public /usr/share/nginx/html</code>将一阶段的静态文件复制到Nginx阶段,然后在运行容器时再试图使用<code>-v</code>或<code>--volume</code>在宿主机上把./public目录挂载到容器的<code>/usr/share/nginx/html</code>,会导致挂载冲突, 具体表现方式为, COPY的文件被宿主机上挂载的目录覆盖。</p></blockquote><h2 id="原因"><a href="#原因" class="headerlink" title="原因"></a>原因</h2><blockquote><p>在Docker中,一旦使用<code>COPY</code>命令将文件复制到容器中,该文件就会被视为镜像的一部分,并且在运行容器时使用<code>-v</code>或<code>--volume</code>挂载宿主机目录到这个位置时,宿主机的内容将覆盖容器中的内容,导致挂载冲突。</p></blockquote><h2 id="方案"><a href="#方案" class="headerlink" title="方案"></a>方案</h2><h4 id="1-不挂载,只使用Dockerfile中的COPY:"><a href="#1-不挂载,只使用Dockerfile中的COPY:" class="headerlink" title="1. 不挂载,只使用Dockerfile中的COPY:"></a>1. 不挂载,只使用Dockerfile中的COPY:</h4><p>如果只关心构建时的操作而不需要在运行时修改文件,那么可以仅使用Dockerfile中的<code>COPY</code>命令,而不进行挂载。</p><pre class="language-yaml" data-language="yaml"><code class="language-yaml"><span class="token key atrule">version</span><span class="token punctuation">:</span> <span class="token string">'3'</span><span class="token key atrule">services</span><span class="token punctuation">:</span> <span class="token key atrule">hexo</span><span class="token punctuation">:</span> <span class="token key atrule">build</span><span class="token punctuation">:</span> <span class="token key atrule">context</span><span class="token punctuation">:</span> . <span class="token key atrule">dockerfile</span><span class="token punctuation">:</span> Dockerfile <span class="token key atrule">image</span><span class="token punctuation">:</span> chuchuzz426/blog<span class="token punctuation">-</span>hexo<span class="token punctuation">:</span><span class="token number">1.0</span> <span class="token key atrule">ports</span><span class="token punctuation">:</span> <span class="token punctuation">-</span> <span class="token string">"8080:80"</span></code></pre><p>这样构建时会将静态文件复制到镜像中,但在运行时对容器的<code>/usr/share/nginx/html</code>目录将不会受到冲突。</p><h4 id="2-分阶段处理"><a href="#2-分阶段处理" class="headerlink" title="2. 分阶段处理:"></a>2. 分阶段处理:</h4><p>之所以要分阶段处理, 是因为构建过程中, 是没办法把内部文件拷贝或挂载到宿主机的,只能等构建完成后单独处理。</p><p>Dockerfile.build</p><pre class="language-docker" data-language="docker"><code class="language-docker"><span class="token comment"># 第一阶段:构建阶段</span><span class="token instruction"><span class="token keyword">FROM</span> node:14 <span class="token keyword">AS</span> builder</span><span class="token instruction"><span class="token keyword">WORKDIR</span> /app</span><span class="token instruction"><span class="token keyword">COPY</span> . .</span><span class="token instruction"><span class="token keyword">RUN</span> npm install --no-fund && npx hexo clean && npx hexo generate</span><span class="token comment"># 第二阶段:导出静态资源到临时目录</span><span class="token instruction"><span class="token keyword">FROM</span> alpine <span class="token keyword">as</span> export</span><span class="token instruction"><span class="token keyword">WORKDIR</span> /export</span><span class="token instruction"><span class="token keyword">COPY</span> <span class="token options"><span class="token property">--from</span><span class="token punctuation">=</span><span class="token string">builder</span></span> /app/public /export/public</span></code></pre><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token comment"># 运行构建</span><span class="token function">docker</span> build <span class="token parameter variable">-t</span> myimage <span class="token parameter variable">-f</span> Dockerfile.build <span class="token builtin class-name">.</span><span class="token comment"># 创建一个临时容器,从中复制文件到宿主机</span><span class="token function">docker</span> create <span class="token parameter variable">--name</span> extract myimage<span class="token function">docker</span> <span class="token function">cp</span> extract:/export/public ./public<span class="token function">docker</span> <span class="token function">rm</span> <span class="token parameter variable">-f</span> extract</code></pre><p>Dockerfile.run</p><pre class="language-docker" data-language="docker"><code class="language-docker"><span class="token comment"># 第三阶段:Nginx阶段</span><span class="token instruction"><span class="token keyword">FROM</span> nginx:alpine</span><span class="token instruction"><span class="token keyword">WORKDIR</span> /usr/share/nginx/html</span><span class="token instruction"><span class="token keyword">COPY</span> <span class="token options"><span class="token property">--from</span><span class="token punctuation">=</span><span class="token string">export</span></span> /export/public /usr/share/nginx/html</span><span class="token instruction"><span class="token keyword">EXPOSE</span> 8080</span></code></pre><p>然而这样的做法虽然能实现挂载, 但对我来说已经没有意义了</p><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>我的初衷是新发布的文章能在本地执行编译, 然后生成的静态文件资源能够和容器中的/usr/share/nginx/html互通, 避免本地每次发布新文章都要重新构建容器很麻烦, 但是现在回头想想, 其实写完新文章不想重新构建的话直接进入容器执行<code>hexo g</code>效果也一样的, 没白折腾, 又学到了有用的知识。</p>]]></content>
<summary type="html"><p>闲来无事, 想起之前本地构建博客想看看效果时, 老是出现文章内容丢失的问题, 后来构建时尝试加上<code>--no-cache</code>可以解决该问题, 现在又想折腾一下容器静态文件挂载到宿主机</p></summary>
<category term="Docker" scheme="http://chuchu-z.com/categories/docker/"/>
</entry>
<entry>
<title>MySQL索引事务</title>
<link href="http://chuchu-z.com/posts/mysql-learn-02/"/>
<id>http://chuchu-z.com/posts/mysql-learn-02/</id>
<published>2024-02-19T01:53:36.000Z</published>
<updated>2024-12-31T06:57:56.019Z</updated>
<content type="html"><![CDATA[<h2 id="索引与引擎及其关系"><a href="#索引与引擎及其关系" class="headerlink" title="索引与引擎及其关系"></a>索引与引擎及其关系</h2><h3 id="索引"><a href="#索引" class="headerlink" title="索引"></a>索引</h3><blockquote><p>一种提高查询性能的数据结构, 类似于一本字典中的目录, 使得可以快速定位和检索数据位置, 具有以空间换时间的设计思想,</p><p>所以并不是任何情况都适合创建索引, 索引的价值是快速定位,如果起不到定位的字段通常是不需要创建索引的,因为索引会占用物理空间,</p><p>另外, 经常更新且不需要用作where条件的字段不必要创建索引, 数据频繁修改, 动态维护索引也需要额外的开销将影响数据库性能。</p></blockquote><span id="more"></span><h3 id="存储引擎"><a href="#存储引擎" class="headerlink" title="存储引擎"></a>存储引擎</h3><blockquote><p>解决如何存储数据, 如何为存储的数据建立索引以及如何更新、查询数据等技术。</p><p>MySQL 存储引擎有 MyISAM 、InnoDB、Memory等, 其中 InnoDB 是在 MySQL 5.5 之后成为默认的存储引擎。</p></blockquote><h3 id="关系"><a href="#关系" class="headerlink" title="关系"></a>关系</h3><blockquote><p>存储引擎决定表的物理存储结构, 包括: 数据文件的格式、索引文件的格式, 包括如何组织数据、如何处理索引、如何处理事务、如何处理并发等。</p><p>而索引则是在这个物理存储结构上建立的数据结构, 不同的存储引擎可以支持不同类型的索引,例如B+树索引、B树索引、HASH索引。</p></blockquote><h2 id="InnoDB"><a href="#InnoDB" class="headerlink" title="InnoDB"></a>InnoDB</h2><blockquote><p>InnoDB数据按[数据页]为单位进行读写</p><p>InnoDB数据页默认大小为16KB, 所以InnoDB每次I/O操作数据最少操作16KB数据</p></blockquote><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/posts/mysql-learn-02/243b1466779a9e107ae3ef0155604a17.png" alt="数据页(图片来源小林coding)" title> </div> <div class="image-caption">数据页(图片来源小林coding)</div> </figure><p><img src="/posts/mysql-learn-02/fabd6dadd61a0aa342d7107213955a72.png" alt="数据页说明(图片来源小林coding)"></p><h2 id="索引划分"><a href="#索引划分" class="headerlink" title="索引划分"></a>索引划分</h2><table><thead><tr><th align="center">分类</th><th align="center">索引类型</th><th align="center">特点</th><th align="center">说明</th></tr></thead><tbody><tr><td align="center">数据结构分类</td><td align="center">B+Tree 索引</td><td align="center">适用于等值查询和范围查询。</td><td align="center">B+Tree 索引是一种平衡树结构,适用于范围查询和排序,是 MySQL 默认的索引类型。</td></tr><tr><td align="center"></td><td align="center">HASH 索引</td><td align="center">适用于等值查询,不支持范围查询,对于大数据量的表性能较好。</td><td align="center">HASH 索引适用于等值查询,通过散列算法将索引列的值映射为散列值,对于大型数据集可以提供快速的查找。</td></tr><tr><td align="center"></td><td align="center">Full-Text 索引</td><td align="center">用于全文搜索,支持对文本数据进行高效的模糊查询。</td><td align="center">Full-Text 索引是为了支持全文搜索,可以在文本数据中执行模糊查询,适用于需要搜索关键词的场景。</td></tr><tr><td align="center">物理存储分类</td><td align="center">聚簇索引(主键索引)</td><td align="center">数据行的物理顺序与索引的顺序一致,InnoDB 存储引擎默认使用。</td><td align="center">聚簇索引决定了数据在磁盘上的物理存储顺序,通常是主键索引。在 InnoDB 存储引擎中,表的数据行实际上是按照主键顺序存储的。</td></tr><tr><td align="center"></td><td align="center">二级索引(辅助索引)</td><td align="center">非主键索引,存储实际数据行的引用而不是实际的数据。</td><td align="center">二级索引是不基于表的物理存储顺序的索引,而是存储指向实际数据行的引用。</td></tr><tr><td align="center">字段特性分类</td><td align="center">单列索引</td><td align="center">仅基于单个列创建的索引。</td><td align="center">单列索引是最基本的索引类型,没有唯一性或其他特殊约束,可以包含重复的值。</td></tr><tr><td align="center"></td><td align="center">联合索引(复合索引)</td><td align="center">基于多个列创建的索引,适用于同时查询多个列的情况。</td><td align="center">联合索引可以包含多个列,有助于优化多列的查询条件。</td></tr><tr><td align="center"></td><td align="center">唯一索引</td><td align="center">确保索引列的值唯一,可用于强制实施表的唯一性约束。</td><td align="center">唯一索引确保索引列中的值是唯一的,可用于强制表中的数据唯一性。</td></tr><tr><td align="center"></td><td align="center">普通索引</td><td align="center">基本索引类型,没有特殊约束,可以包含重复的值。</td><td align="center">普通索引是最基本的索引类型,没有唯一性或其他特殊约束,可以包含重复的值。</td></tr><tr><td align="center"></td><td align="center">前缀索引</td><td align="center">仅对列的前几个字符创建索引,可减小索引的大小。</td><td align="center">前缀索引是指对列的前几个字符创建的索引,用于减小索引的存储空间。</td></tr></tbody></table><h2 id="索引优化"><a href="#索引优化" class="headerlink" title="索引优化"></a>索引优化</h2>]]></content>
<summary type="html"><h2 id="索引与引擎及其关系"><a href="#索引与引擎及其关系" class="headerlink" title="索引与引擎及其关系"></a>索引与引擎及其关系</h2><h3 id="索引"><a href="#索引" class="headerlink" title="索引"></a>索引</h3><blockquote>
<p>一种提高查询性能的数据结构, 类似于一本字典中的目录, 使得可以快速定位和检索数据位置, 具有以空间换时间的设计思想,</p>
<p>所以并不是任何情况都适合创建索引, 索引的价值是快速定位,如果起不到定位的字段通常是不需要创建索引的,因为索引会占用物理空间,</p>
<p>另外, 经常更新且不需要用作where条件的字段不必要创建索引, 数据频繁修改, 动态维护索引也需要额外的开销将影响数据库性能。</p>
</blockquote></summary>
<category term="MySQL" scheme="http://chuchu-z.com/categories/mysql/"/>
</entry>
<entry>
<title>24-02 笔记</title>
<link href="http://chuchu-z.com/posts/24-02-note/"/>
<id>http://chuchu-z.com/posts/24-02-note/</id>
<published>2024-02-18T02:26:41.000Z</published>
<updated>2024-12-31T06:57:55.964Z</updated>
<content type="html"><![CDATA[<p>新年已过, 今日初九, 开工大吉, 祝新的一年, 身体健康, 事业顺利 !!! </p><span id="more"></span><blockquote><p>2.18</p><p>转眼2月已过半, 制定的计划仍未实施, 令人堪忧啊~</p><p>2.19</p><p>打游戏</p><p>2.20</p><p>打游戏</p><p>2.21</p><p>打游戏</p><p>2.22</p><p>初初啊初初, 你怎能如此玩物丧志这样下去, 说好的计划呢😂</p></blockquote><hr><h3 id="January"><a href="#January" class="headerlink" title="January"></a>January</h3><ul><li>群友推荐 <a href="https://www.bilibili.com/video/BV1Gt4y1y721/?spm_id_from=333.999.0.0">php:laravel 底层核心代码分析</a>, 讲的挺好, 对反射类和依赖注入和控制反转等有进一步认识</li><li>在 <a href="https://www.xiaolincoding.com/">小林coding</a> MySQL基础篇深入理解一条sql的执行流程</li><li>把OSI 七层模型及TCP/IP 模型整理成<a href="https://chuchu-z.com/posts/osi-model-and-tcp-ip-model/">表格</a></li><li><a href="https://docs.djangoproject.com/en/5.0/">Django</a> 框架学习</li></ul>]]></content>
<summary type="html"><p>新年已过, 今日初九, 开工大吉, 祝新的一年, 身体健康, 事业顺利 !!! </p></summary>
<category term="岁月杂感" scheme="http://chuchu-z.com/categories/%E5%B2%81%E6%9C%88%E6%9D%82%E6%84%9F/"/>
</entry>
<entry>
<title>MySQL执行流程</title>
<link href="http://chuchu-z.com/posts/mysql-learn-01/"/>
<id>http://chuchu-z.com/posts/mysql-learn-01/</id>
<published>2024-02-02T07:24:19.000Z</published>
<updated>2024-12-31T06:57:56.019Z</updated>
<content type="html"><![CDATA[<h2 id="MySQL执行流程"><a href="#MySQL执行流程" class="headerlink" title="MySQL执行流程"></a>MySQL执行流程</h2><blockquote><p>连接器-查询缓存(如果是select才查询缓存, MySQL8.0废弃)-解析器(词法分析, 语法分析)-预处理器(判断表/字段是否存在)-优化器-执行器(验证权限, 调用存储引擎API, 如果有索引下推则携带索引条件给存储引擎判断-存储引擎查询数据并利用索引下推过滤数据, 然后执行回表查询数据, 向执行器(server层)返回结果)</p></blockquote><span id="more"></span><p><img src="/posts/mysql-learn-01/format,webp.webp" alt="MySQL执行流程图"></p><h2 id="分析器"><a href="#分析器" class="headerlink" title="分析器"></a>分析器</h2><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/posts/mysql-learn-01/db-mysql-sql-parser-2.png" alt="分析器, 来自小林coding" title> </div> <div class="image-caption">分析器, 来自小林coding</div> </figure><h2 id="varchar字段最大取值计算公式"><a href="#varchar字段最大取值计算公式" class="headerlink" title="varchar字段最大取值计算公式"></a>varchar字段最大取值计算公式</h2><blockquote><p>65535 - 变长字段字节数列表所占用的字节数 - NULL值列表所占用的字节数 = 65535 - 2 - 1 = 65532</p><p>如果有多个字段的话,要保证所有字段的长度 + 变长字段字节数列表所占用的字节数 + NULL值列表所占用的字节数 <= 65535</p></blockquote><h2 id="InnoDB-行格式及数据溢出处理方式"><a href="#InnoDB-行格式及数据溢出处理方式" class="headerlink" title="InnoDB 行格式及数据溢出处理方式"></a>InnoDB 行格式及数据溢出处理方式</h2><table><thead><tr><th>行格式</th><th>适用场景</th><th>存储空白列</th><th>行头大小</th><th>溢出处理</th></tr></thead><tbody><tr><td>Compact</td><td>适用于索引列,OLAP 场景</td><td>不存储</td><td>固定</td><td>部分真实数据存储在数据页,溢出数据存储在溢出页中,通过指针连接溢出页</td></tr><tr><td>Dynamic</td><td>适用于非索引列,OLTP 场景</td><td>存储</td><td>可变</td><td>完全的行溢出方式,记录的真实数据处不存储该列的一部分数据,只存储 20 个字节的指针来指向溢出页</td></tr><tr><td>Compressed</td><td>适用于需要压缩存储的场景,Barracuda</td><td>存储</td><td>可变</td><td>完全的行溢出方式,记录的真实数据处不存储该列的一部分数据,只存储 20 个字节的指针来指向溢出页</td></tr></tbody></table><p>在 <code>Compressed</code> 行格式中,如果数据行的大小超过了页的大小,InnoDB 存储引擎会使用分页压缩算法来减小数据的存储空间,但这并不是通过将溢出的数据存储在溢出页中来实现的。</p>]]></content>
<summary type="html"><h2 id="MySQL执行流程"><a href="#MySQL执行流程" class="headerlink" title="MySQL执行流程"></a>MySQL执行流程</h2><blockquote>
<p>连接器-查询缓存(如果是select才查询缓存, MySQL8.0废弃)-解析器(词法分析, 语法分析)-预处理器(判断表/字段是否存在)-优化器-执行器(验证权限, 调用存储引擎API, 如果有索引下推则携带索引条件给存储引擎判断-存储引擎查询数据并利用索引下推过滤数据, 然后执行回表查询数据, 向执行器(server层)返回结果)</p>
</blockquote></summary>
<category term="MySQL" scheme="http://chuchu-z.com/categories/mysql/"/>
</entry>
<entry>
<title>OSI 七层模型及TCP/IP 模型</title>
<link href="http://chuchu-z.com/posts/osi-model-and-tcp-ip-model/"/>
<id>http://chuchu-z.com/posts/osi-model-and-tcp-ip-model/</id>
<published>2024-01-30T09:46:43.000Z</published>
<updated>2024-12-31T06:57:56.020Z</updated>
<content type="html"><![CDATA[<p>把OSI模型以及TCP/IP模型做成表格</p><span id="more"></span><h2 id="OSI模型"><a href="#OSI模型" class="headerlink" title="OSI模型"></a>OSI模型</h2><table><thead><tr><th>层次</th><th>名称</th><th>功能作用</th><th>代表性协议</th></tr></thead><tbody><tr><td>第七层(应用层)</td><td>应用层 (Application)</td><td>提供网络服务和用户接口,实现特定网络应用的通信</td><td>HTTP, FTP, SMTP, DNS, Telnet, SNMP</td></tr><tr><td>第六层(表示层)</td><td>表示层 (Presentation)</td><td>处理数据格式、编码和加密解密等,确保数据在不同系统之间的正确解释</td><td>SSL/TLS, JPEG, GIF, MPEG</td></tr><tr><td>第五层(会话层)</td><td>会话层 (Session)</td><td>管理会话或对话控制,建立、维护和终止应用程序之间的通信</td><td>NetBIOS, RPC, PPTP</td></tr><tr><td>第四层(传输层)</td><td>传输层 (Transport)</td><td>负责数据流的端到端通信,提供可靠的数据传输和错误检测,同时进行流量控制</td><td>TCP, UDP, SCTP</td></tr><tr><td>第三层(网络层)</td><td>网络层 (Network)</td><td>处理数据包的逻辑传输,提供路径选择和逻辑寻址,实现不同网络之间的路由</td><td>IP, ICMP, OSPF, BGP</td></tr><tr><td>第二层(数据链路层)</td><td>数据链路层 (Data Link)</td><td>提供物理寻址,错误检测和纠正,以及对物理介质的访问控制。分为逻辑链路控制(LLC)和介质访问控制(MAC)两个子层</td><td>Ethernet, PPP, HDLC, ARP</td></tr><tr><td>第一层(物理层)</td><td>物理层 (Physical)</td><td>在物理媒体上传输原始比特流,负责定义硬件设备和传输媒体的规范</td><td>Ethernet, USB, DSL, Bluetooth</td></tr></tbody></table><h2 id="TCP-IP-模型"><a href="#TCP-IP-模型" class="headerlink" title="TCP/IP 模型"></a>TCP/IP 模型</h2><table><thead><tr><th>层次</th><th>名称</th><th>功能作用</th><th>代表性协议</th></tr></thead><tbody><tr><td>第四层(应用层)</td><td>应用层 (Application)</td><td>提供网络服务和用户接口,实现特定网络应用的通信</td><td>HTTP, FTP, SMTP, DNS, Telnet, SNMP</td></tr><tr><td>第三层(传输层)</td><td>传输层 (Transport)</td><td>提供端到端的通信</td><td>TCP, UDP, SCTP</td></tr><tr><td>第二层(网络层)</td><td>网络层 (Internet)</td><td>处理数据包的逻辑传输,实现不同网络之间的路由</td><td>IP, ICMP, OSPF, BGP</td></tr><tr><td>第一层(网络接口层)</td><td>网络接口层 (Link)</td><td>负责物理寻址和介质访问控制</td><td>Ethernet, PPP, HDLC, ARP</td></tr></tbody></table><blockquote><p>计算机启动或连接到网络时涉及的协议、其功能作用以及执行阶段和层次的信息</p></blockquote><table><thead><tr><th>阶段</th><th>协议</th><th>功能作用</th><th>执行阶段</th><th>层次</th></tr></thead><tbody><tr><td>启动阶段</td><td>无协议</td><td>无</td><td>计算机电源启动</td><td>无</td></tr><tr><td>网络适配器初始化阶段</td><td>无协议</td><td>无</td><td>初始化网络适配器,加载适当的驱动程序</td><td>无</td></tr><tr><td>DHCP 获取网络配置阶段</td><td>DHCP</td><td>获取动态分配的网络配置,包括 IP 地址、子网掩码、默认网关、DNS 服务器等</td><td>计算机启动或连接到网络时</td><td>网络层(第三层)</td></tr><tr><td>ARP 地址解析阶段</td><td>ARP</td><td>将目标设备的 IP 地址解析为对应的物理硬件地址(MAC 地址)</td><td>在需要进行局域网通信时</td><td>数据链路层(第二层)</td></tr><tr><td>DNS 解析域名阶段</td><td>DNS</td><td>将域名解析为对应的 IP 地址</td><td>计算机启动或进行网络通信前</td><td>网络层(第三层)</td></tr><tr><td>TCP 连接建立阶段</td><td>TCP</td><td>提供可靠的端到端通信</td><td>在建立连接和进行应用层通信时</td><td>传输层(第四层)</td></tr><tr><td>应用层通信阶段</td><td>HTTP、FTP、SMTP 等</td><td>实现特定网络应用的通信</td><td>计算机启动或进行网络通信时</td><td>应用层(第七层)</td></tr></tbody></table>]]></content>
<summary type="html"><p>把OSI模型以及TCP/IP模型做成表格</p></summary>
<category term="Other" scheme="http://chuchu-z.com/categories/other/"/>
</entry>
<entry>
<title>Python 使用 Django 框架</title>
<link href="http://chuchu-z.com/posts/python-use-Django/"/>
<id>http://chuchu-z.com/posts/python-use-Django/</id>
<published>2024-01-15T01:41:42.000Z</published>
<updated>2024-12-31T06:57:56.020Z</updated>
<content type="html"><![CDATA[<blockquote><p>有个项目需要用对接 ChatGpt 的API, 本来想拿老本行 PHP 写的, 但是 PHP 没有 Python 对接起来方便, 且我觉得语言只是工具, 每个语言都有它的优点和优势, 同时还能多多接触新东西, 利于学习。 </p></blockquote><span id="more"></span><h2 id="一-初始化"><a href="#一-初始化" class="headerlink" title="一. 初始化"></a>一. 初始化</h2><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token comment"># 安装</span>pip <span class="token function">install</span> Django<span class="token comment"># 创建项目名</span>django-admin startproject your_project_name<span class="token builtin class-name">cd</span> your_project_name<span class="token comment"># 创建应用名</span>python manage.py startapp your_app_name</code></pre><h2 id="二-修改settings-py配置"><a href="#二-修改settings-py配置" class="headerlink" title="二. 修改settings.py配置"></a>二. 修改settings.py配置</h2><h3 id="2-1-引入env"><a href="#2-1-引入env" class="headerlink" title="2.1 引入env"></a>2.1 引入env</h3><pre class="language-python" data-language="python"><code class="language-python"><span class="token keyword">import</span> os<span class="token keyword">from</span> pathlib <span class="token keyword">import</span> Path<span class="token keyword">from</span> dotenv <span class="token keyword">import</span> load_dotenv<span class="token comment"># 加载环境变量</span>load_dotenv<span class="token punctuation">(</span><span class="token punctuation">)</span></code></pre><h3 id="2-2-配置数据库"><a href="#2-2-配置数据库" class="headerlink" title="2.2 配置数据库"></a>2.2 配置数据库</h3><pre class="language-python" data-language="python"><code class="language-python"><span class="token comment"># Database</span><span class="token comment"># https://docs.djangoproject.com/en/5.0/ref/settings/#databases</span><span class="token comment"># mysql 版本使用5.7, 但Django要求8.0以上</span><span class="token comment"># 全局搜索 check_database_version_supported ,并注释, 就不会检查mysql版本</span><span class="token comment"># 位置大约在django/db/backends/base/base.py文件255行</span>DATABASES <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token comment"># 'default': {</span> <span class="token comment"># 'ENGINE': 'django.db.backends.sqlite3',</span> <span class="token comment"># 'NAME': BASE_DIR / 'db.sqlite3',</span> <span class="token comment"># }</span> <span class="token string">'default'</span><span class="token punctuation">:</span> <span class="token punctuation">{</span> <span class="token string">'ENGINE'</span><span class="token punctuation">:</span> <span class="token string">'django.db.backends.mysql'</span><span class="token punctuation">,</span> <span class="token string">'NAME'</span><span class="token punctuation">:</span> os<span class="token punctuation">.</span>getenv<span class="token punctuation">(</span><span class="token string">"DB_NAME"</span><span class="token punctuation">,</span> <span class="token string">''</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">'USER'</span><span class="token punctuation">:</span> os<span class="token punctuation">.</span>getenv<span class="token punctuation">(</span><span class="token string">"DB_USER"</span><span class="token punctuation">,</span> <span class="token string">''</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">'PASSWORD'</span><span class="token punctuation">:</span> os<span class="token punctuation">.</span>getenv<span class="token punctuation">(</span><span class="token string">"DB_PASSWORD"</span><span class="token punctuation">,</span> <span class="token string">''</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">'HOST'</span><span class="token punctuation">:</span> <span class="token string">'127.0.0.1'</span><span class="token punctuation">,</span> <span class="token comment"># 或者是数据库服务器的IP地址</span> <span class="token string">'PORT'</span><span class="token punctuation">:</span> <span class="token string">'3306'</span><span class="token punctuation">,</span> <span class="token comment"># MySQL默认端口</span> <span class="token string">'OPTIONS'</span><span class="token punctuation">:</span> <span class="token punctuation">{</span> <span class="token string">'charset'</span><span class="token punctuation">:</span> <span class="token string">'utf8mb4'</span><span class="token punctuation">,</span> <span class="token string">'collation'</span><span class="token punctuation">:</span> <span class="token string">'utf8mb4_general_ci'</span><span class="token punctuation">,</span> <span class="token comment"># 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></code></pre><h3 id="2-3-修改其他配置"><a href="#2-3-修改其他配置" class="headerlink" title="2.3 修改其他配置"></a>2.3 修改其他配置</h3><pre class="language-python" data-language="python"><code class="language-python"><span class="token comment"># 我的项目全是外部接口, 所以用不上表单和csrf, 注释csrf</span>MIDDLEWARE <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token comment"># 'django.middleware.csrf.CsrfViewMiddleware',</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">]</span></code></pre><h3 id="2-4-语言与时区"><a href="#2-4-语言与时区" class="headerlink" title="2.4 语言与时区"></a>2.4 语言与时区</h3><pre class="language-python" data-language="python"><code class="language-python">LANGUAGE_CODE <span class="token operator">=</span> <span class="token string">'zh-hans'</span>TIME_ZONE <span class="token operator">=</span> <span class="token string">'Asia/Shanghai'</span>DATE_FORMAT <span class="token operator">=</span> <span class="token string">'Y-m-d'</span>DATETIME_FORMAT <span class="token operator">=</span> <span class="token string">'Y-m-d H:i'</span>USE_I18N <span class="token operator">=</span> <span class="token boolean">True</span>USE_TZ <span class="token operator">=</span> <span class="token boolean">False</span></code></pre><h3 id="2-5-默认自增主键"><a href="#2-5-默认自增主键" class="headerlink" title="2.5 默认自增主键"></a>2.5 默认自增主键</h3><pre class="language-python" data-language="python"><code class="language-python">DEFAULT_AUTO_FIELD <span class="token operator">=</span> <span class="token string">'django.db.models.AutoField'</span></code></pre><h2 id="三-使用Django"><a href="#三-使用Django" class="headerlink" title="三. 使用Django"></a>三. 使用Django</h2><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token comment"># 数据迁移</span>python manage.py makemigrationspython manage.py migrate<span class="token comment"># 启动服务器, 可指定端口或指定ip+端口</span>python manage.py runserverpython manage.py runserver <span class="token number">8080</span>python manage.py runserver <span class="token number">0.0</span>.0.0:8000<span class="token comment"># 创建管理员</span>python manage.py createsuperuser<span class="token comment"># 搞定后登录管理</span>http://127.0.0.1:8000/admin/</code></pre><h2 id="四-model示例"><a href="#四-model示例" class="headerlink" title="四. model示例"></a>四. model示例</h2><blockquote><p>说实话, django的model和数据迁移做的真不好, 和laravel的migrate对比, 很多东西都不符合常理, 比如默认datetime(6), 还自带小数点</p></blockquote><pre class="language-python" data-language="python"><code class="language-python"><span class="token keyword">from</span> django<span class="token punctuation">.</span>db <span class="token keyword">import</span> models<span class="token comment"># 自定义 datetime 字段, 因为 django 默认datetime(6)</span><span class="token keyword">class</span> <span class="token class-name">MySQLDateTimeField</span><span class="token punctuation">(</span>models<span class="token punctuation">.</span>DateTimeField<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">def</span> <span class="token function">db_type</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span> connection<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">return</span> <span class="token string">'datetime'</span><span class="token keyword">class</span> <span class="token class-name">UploadedFile</span><span class="token punctuation">(</span>models<span class="token punctuation">.</span>Model<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token builtin">id</span> <span class="token operator">=</span> models<span class="token punctuation">.</span>AutoField<span class="token punctuation">(</span>primary_key<span class="token operator">=</span><span class="token boolean">True</span><span class="token punctuation">)</span> file_id <span class="token operator">=</span> models<span class="token punctuation">.</span>CharField<span class="token punctuation">(</span>max_length<span class="token operator">=</span><span class="token number">50</span><span class="token punctuation">,</span> null<span class="token operator">=</span><span class="token boolean">False</span><span class="token punctuation">,</span> blank<span class="token operator">=</span><span class="token boolean">True</span><span class="token punctuation">,</span> db_default<span class="token operator">=</span><span class="token string">""</span><span class="token punctuation">,</span> db_comment<span class="token operator">=</span><span class="token string">"文件ID"</span><span class="token punctuation">)</span> file_name <span class="token operator">=</span> models<span class="token punctuation">.</span>CharField<span class="token punctuation">(</span>max_length<span class="token operator">=</span><span class="token number">255</span><span class="token punctuation">,</span> null<span class="token operator">=</span><span class="token boolean">False</span><span class="token punctuation">,</span> blank<span class="token operator">=</span><span class="token boolean">True</span><span class="token punctuation">,</span> db_default<span class="token operator">=</span><span class="token string">""</span><span class="token punctuation">,</span> db_comment<span class="token operator">=</span><span class="token string">"文件名"</span><span class="token punctuation">)</span> file_size <span class="token operator">=</span> models<span class="token punctuation">.</span>IntegerField<span class="token punctuation">(</span>null<span class="token operator">=</span><span class="token boolean">False</span><span class="token punctuation">,</span> db_default<span class="token operator">=</span><span class="token number">0</span><span class="token punctuation">,</span> blank<span class="token operator">=</span><span class="token boolean">True</span><span class="token punctuation">,</span> db_comment<span class="token operator">=</span><span class="token string">"文件大小"</span><span class="token punctuation">)</span> file_status <span class="token operator">=</span> models<span class="token punctuation">.</span>CharField<span class="token punctuation">(</span>max_length<span class="token operator">=</span><span class="token number">50</span><span class="token punctuation">,</span> null<span class="token operator">=</span><span class="token boolean">False</span><span class="token punctuation">,</span> blank<span class="token operator">=</span><span class="token boolean">True</span><span class="token punctuation">,</span> db_default<span class="token operator">=</span><span class="token string">"uploaded"</span><span class="token punctuation">,</span> db_comment<span class="token operator">=</span><span class="token string">"文件状态"</span><span class="token punctuation">)</span> file_purpose <span class="token operator">=</span> models<span class="token punctuation">.</span>CharField<span class="token punctuation">(</span>max_length<span class="token operator">=</span><span class="token number">50</span><span class="token punctuation">,</span> null<span class="token operator">=</span><span class="token boolean">False</span><span class="token punctuation">,</span> blank<span class="token operator">=</span><span class="token boolean">True</span><span class="token punctuation">,</span> db_default<span class="token operator">=</span><span class="token string">"fine-tune"</span><span class="token punctuation">,</span> db_comment<span class="token operator">=</span><span class="token string">"文件用途"</span><span class="token punctuation">)</span> created_at <span class="token operator">=</span> MySQLDateTimeField<span class="token punctuation">(</span>auto_now_add<span class="token operator">=</span><span class="token boolean">True</span><span class="token punctuation">,</span> db_comment<span class="token operator">=</span><span class="token string">"创建时间"</span><span class="token punctuation">)</span> objects <span class="token operator">=</span> models<span class="token punctuation">.</span>Manager<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">class</span> <span class="token class-name">Meta</span><span class="token punctuation">:</span> db_table <span class="token operator">=</span> <span class="token string">"chatgpt_upload_files"</span> indexes <span class="token operator">=</span> <span class="token punctuation">[</span> models<span class="token punctuation">.</span>Index<span class="token punctuation">(</span>fields<span class="token operator">=</span><span class="token punctuation">[</span><span class="token string">"file_id"</span><span class="token punctuation">,</span> <span class="token string">"file_status"</span><span class="token punctuation">,</span> <span class="token string">"created_at"</span><span class="token punctuation">]</span><span class="token punctuation">,</span> name<span class="token operator">=</span><span class="token string">"idx_file_id_status_create"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token comment"># 联合索引</span> <span class="token punctuation">]</span> verbose_name <span class="token operator">=</span> <span class="token string">"上传文件表"</span> verbose_name_plural <span class="token operator">=</span> <span class="token string">"上传文件表"</span> <span class="token keyword">def</span> <span class="token function">__str__</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">return</span> self<span class="token punctuation">.</span>file_id</code></pre><h2 id="五-部署到服务器"><a href="#五-部署到服务器" class="headerlink" title="五. 部署到服务器"></a>五. 部署到服务器</h2><pre class="language-bash" data-language="bash"><code class="language-bash">python3 <span class="token parameter variable">-m</span> venv venv<span class="token builtin class-name">source</span> venv/bin/activatepip3 <span class="token function">install</span> <span class="token parameter variable">-r</span> requirements.txt</code></pre><blockquote><p>中途安装 mysqlclient 时报错<br>参考了该博主文章解决: <a href="https://blog.csdn.net/qq_42336581/article/details/132244022">https://blog.csdn.net/qq_42336581/article/details/132244022</a></p></blockquote><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/posts/python-use-Django/image-20240120155502627.png" alt title> </div> <div class="image-caption"></div> </figure>]]></content>
<summary type="html"><blockquote>
<p>有个项目需要用对接 ChatGpt 的API, 本来想拿老本行 PHP 写的, 但是 PHP 没有 Python 对接起来方便, 且我觉得语言只是工具, 每个语言都有它的优点和优势, 同时还能多多接触新东西, 利于学习。 </p>
</blockquote></summary>
<category term="Python" scheme="http://chuchu-z.com/categories/python/"/>
</entry>
<entry>
<title>Python Django 接入 ChatGPT 模型训练/助理</title>
<link href="http://chuchu-z.com/posts/exploring-ChatGPT-Integration-in-Python/"/>
<id>http://chuchu-z.com/posts/exploring-ChatGPT-Integration-in-Python/</id>
<published>2024-01-06T02:19:17.000Z</published>
<updated>2024-12-31T06:57:56.015Z</updated>
<content type="html"><![CDATA[<p>ChatGPT 和 AI 的话题近两年都很火热, 自从 OpenAI 诞生出 ChatGPT 以来, 各互联网大厂公司纷纷加入并研发自家的AI大模型, 也有不少人趁着这个风口, 利用 ChatGPT 实现变现, 赚的盆满钵满, 瓜分这块AI蛋糕。</p><span id="more"></span><h2 id="如何训练专属AI"><a href="#如何训练专属AI" class="headerlink" title="如何训练专属AI"></a>如何训练专属AI</h2><p>一是使用开源的大模型, 如 <a href="https://github.com/facebookresearch/llama">llama</a> 和 <a href="https://github.com/THUDM/ChatGLM-6B">ChatGLM-6B</a> , 其中 <strong>ChatGLM-6B</strong> 我个人也比较喜欢, 优点是中文支持的比较好, 而且在自己的电脑上都能训练, 这部分还没有去研究, 下次有机会试试, 然后再发布 <strong>ChatGLM-6B</strong> 的训练方式</p><table><thead><tr><th>模型</th><th>训练数据</th><th>训练数据量</th><th>模型参数量</th><th>词表大小</th></tr></thead><tbody><tr><td>LLaMA</td><td>以英语为主的拉丁语系,不包含中日韩文</td><td>1T/1.4T tokens</td><td>7B、13B、33B、65B</td><td>32000</td></tr><tr><td>ChatGLM-6B</td><td>中英双语,中英文比例为1:1</td><td>1T tokens</td><td>6B</td><td>130528</td></tr><tr><td>Bloom</td><td>46种自然语言和13种编程语言,包含中文</td><td>350B tokens</td><td>560M、1.1B、1.7B、3B、7.1B、176B</td><td>250880</td></tr></tbody></table><table><thead><tr><th>模型</th><th>模型结构</th><th>位置编码</th><th>激活函数</th><th>layer norm</th></tr></thead><tbody><tr><td>LLaMA</td><td>Casual decoder</td><td>RoPE</td><td>SwiGLU</td><td>Pre RMS Norm</td></tr><tr><td>ChatGLM-6B</td><td>Prefix decoder</td><td>RoPE</td><td>GeGLU</td><td>Post Deep Norm</td></tr><tr><td>Bloom</td><td>Casual decoder</td><td>ALiBi</td><td>GeLU</td><td>Pre Layer Norm</td></tr></tbody></table><p>二是接入<strong>ChatGpt</strong>, 也是本文的主角</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/posts/exploring-ChatGPT-Integration-in-Python/image-20240106102539178.png" alt title> </div> <div class="image-caption"></div> </figure><p>通过上文得知, 训练 ChatGPT 的方式通常有两种办法, 一种是<strong>微调(fine-tuning)</strong>, 一种是<strong>嵌入(embedding)</strong>。</p><p>大概流程就是由我们提供训练数据, 通过OpenAI官方文件上传接口给官方, 然后创建训练模型, 指定使用该文件给到该模型做训练</p><p>等训练完了之后, 我们就可以使用这个被训练过的模型与我们对话看看训练效果如何了</p><p>不想通过接口上传文件和创建训练模型的也可以登录OpenAI官方网站后, 在 <a href="https://platform.openai.com/files">https://platform.openai.com/files</a> 和 <a href="https://platform.openai.com/finetune">https://platform.openai.com/finetune</a> 操作也可以的</p><p>既然简单省事, 当然人家也不提供免费的午餐, 这是要收费的, 为啥收费的我还要用, 因为它训练参数更多更强, 不需要占用自己的服务器GPU, 更重要的是这是公司要求的接入 ChatGpt</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/posts/exploring-ChatGPT-Integration-in-Python/image-20240106112856778.png" alt title> </div> <div class="image-caption"></div> </figure><h2 id="使用Python接入OpenAI"><a href="#使用Python接入OpenAI" class="headerlink" title="使用Python接入OpenAI"></a>使用Python接入OpenAI</h2><p><a href="https://platform.openai.com/docs/api-reference">官方API文档</a></p><p><del>本次我是基于 <strong>gpt-3.5-turbo-1106</strong> 模型, 做微调(fine-tuning)训练, 接入微调训练不难, 难得是获取训练数据源以及数据的清洗和整合</del></p><p>由于微调缺乏大量训练数据, 转向了使用 <a href="https://platform.openai.com/docs/assistants"><strong>助理 Assistants API</strong></a> 的方式实现, 成本更低, 也能能满足大部分的需求, 但本项目仍然支持微调(fine-tuning)训练</p><h3 id="1-获取并设置秘钥"><a href="#1-获取并设置秘钥" class="headerlink" title="1.获取并设置秘钥"></a>1.获取并设置秘钥</h3><p>创建一个<a href="https://platform.openai.com/signup">OpenAI账号</a>或<a href="https://platform.openai.com/login">登录</a>。接下来,导航到<a href="https://platform.openai.com/account/api-keys">API 密钥页面</a>并“创建新密钥”, 拿到秘钥后, 添加到电脑环境变量里</p><h4 id="1-1-Windows-添加秘钥"><a href="#1-1-Windows-添加秘钥" class="headerlink" title="1.1 Windows 添加秘钥"></a>1.1 Windows 添加秘钥</h4><blockquote><p>我的电脑-属性-高级系统设置-环境变量-系统变量-新建</p></blockquote><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/posts/exploring-ChatGPT-Integration-in-Python/image-20240106170858694.png" alt title> </div> <div class="image-caption"></div> </figure><p>保存后, win + R, 输入 <strong>cmd</strong> 回车, 并执行下面的命令, 输出秘钥则成功</p><pre class="language-none"><code class="language-none">echo %OPENAI_API_KEY%</code></pre><h4 id="1-2-Linux-添加秘钥"><a href="#1-2-Linux-添加秘钥" class="headerlink" title="1.2 Linux 添加秘钥"></a>1.2 Linux 添加秘钥</h4><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token function">vim</span> ~/.bash_profile<span class="token comment"># 在文件的末尾添加以下行:</span><span class="token builtin class-name">export</span> <span class="token assign-left variable">OPENAI_API_KEY</span><span class="token operator">=</span><span class="token string">'your-api-key'</span><span class="token comment"># 执行以下命令刷新配置生效</span><span class="token builtin class-name">source</span> ~/.bash_profile</code></pre><h3 id="2-部署"><a href="#2-部署" class="headerlink" title="2.部署"></a>2.部署</h3><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token comment"># clone 代码</span><span class="token function">git</span> clone [email protected]:chuchu-z/fine-tuning.git OpenAI<span class="token comment"># 切换到OpenAI目录</span><span class="token builtin class-name">cd</span> OpenAI<span class="token comment"># 为该项目创建独立的 Python 虚拟环境</span>python <span class="token parameter variable">-m</span> venv venv<span class="token comment"># 激活虚拟环境, 在 Unix/Linux 系统中</span><span class="token builtin class-name">source</span> venv/bin/activate<span class="token comment"># 激活虚拟环境, 在 Windows 系统中</span>.<span class="token punctuation">\</span>venv<span class="token punctuation">\</span>Scripts<span class="token punctuation">\</span>activate或<span class="token builtin class-name">source</span> ./venv/Scripts/activate<span class="token comment"># 查看 sys.prefix, 是否在虚拟环境中</span>python <span class="token parameter variable">-c</span> <span class="token string">"import sys; print(sys.prefix)"</span><span class="token comment"># 安装依赖</span>pip <span class="token function">install</span> <span class="token parameter variable">-r</span> requirements.txt<span class="token comment"># 启动, 指定ip和端口(仅开发环境填写0.0.0.0, 线上环境请根据实际情况修改)</span>python manage.py runserver <span class="token number">0.0</span>.0.0:9527<span class="token comment"># 补充一个退出虚拟环境命令, 用不上的话就不用执行</span>deactivate</code></pre><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/posts/exploring-ChatGPT-Integration-in-Python/image-20240130155859396.png" alt title> </div> <div class="image-caption"></div> </figure><h3 id="3-访问接口"><a href="#3-访问接口" class="headerlink" title="3.访问接口"></a>3.访问接口</h3><p>以chatgpt下的目录划分模块, 其中 <strong>common</strong> 是公共的一些操作, <strong>migrations</strong> 是数据迁移的模块, 其余的都是OpenAI的相关模块, 具体路由配置在 <strong>chatgpt/urls.py</strong></p><pre class="language-none"><code class="language-none">chatgpt|-- assistants # 助理API相关|-- common # 公共内容|-- file # 文件上传API相关|-- fine_tuning # 微调API相关|-- messages # 助理消息API相关|-- migrations # 数据迁移|-- runs # 运行线程API相关`-- threads # 线程API相关</code></pre><h4 id="举例-访问-common-status"><a href="#举例-访问-common-status" class="headerlink" title="举例: 访问 /common/status"></a>举例: 访问 /common/status</h4><p>请求URL: <a href="http://127.0.0.1:9527/common/status">http://127.0.0.1:9527/common/status</a></p><p>说明: 查看状态, 能访问则说明应用启动成功</p><p>请求方式: GET</p><p>请求参数: 无</p><p> 返回值:</p><pre class="language-json" data-language="json"><code class="language-json"><span class="token punctuation">{</span> <span class="token property">"info"</span><span class="token operator">:</span> <span class="token string">"ok"</span><span class="token punctuation">,</span> <span class="token property">"response"</span><span class="token operator">:</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">}</span></code></pre><h3 id="4-训练数据"><a href="#4-训练数据" class="headerlink" title="4. 训练数据"></a>4. 训练数据</h3><h4 id="4-1微调训练数据格式"><a href="#4-1微调训练数据格式" class="headerlink" title="4.1微调训练数据格式"></a>4.1微调训练数据格式</h4><p>微调(fine-tuning)训练要用到的数据格式为JSONL, 而不是标准的JSON, 不要搞混了</p><blockquote><p>JSONL,全称为JSON Lines(或 JSONLines、JSON-L), 用于表示JSON对象的文本序列, 它与标准JSON格式略有不同,每行包含一个独立的JSON对象,而不是将它们包含在一个大的JSON数组中。每行都是有效的JSON,但整个文件可能不是一个有效的JSON数组。</p></blockquote><h4 id="4-2-jsonl示例数据"><a href="#4-2-jsonl示例数据" class="headerlink" title="4.2 jsonl示例数据"></a>4.2 jsonl示例数据</h4><pre class="language-json" data-language="json"><div class="caption"><span>lines</span></div><code class="language-json"><span class="token punctuation">{</span><span class="token property">"messages"</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">{</span><span class="token property">"role"</span><span class="token operator">:</span> <span class="token string">"system"</span><span class="token punctuation">,</span> <span class="token property">"content"</span><span class="token operator">:</span> <span class="token string">"Marv is a factual chatbot that is also sarcastic."</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token property">"role"</span><span class="token operator">:</span> <span class="token string">"user"</span><span class="token punctuation">,</span> <span class="token property">"content"</span><span class="token operator">:</span> <span class="token string">"What's the capital of France?"</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token property">"role"</span><span class="token operator">:</span> <span class="token string">"assistant"</span><span class="token punctuation">,</span> <span class="token property">"content"</span><span class="token operator">:</span> <span class="token string">"Paris, as if everyone doesn't know that already."</span><span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">}</span><span class="token punctuation">{</span><span class="token property">"messages"</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">{</span><span class="token property">"role"</span><span class="token operator">:</span> <span class="token string">"system"</span><span class="token punctuation">,</span> <span class="token property">"content"</span><span class="token operator">:</span> <span class="token string">"Marv is a factual chatbot that is also sarcastic."</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token property">"role"</span><span class="token operator">:</span> <span class="token string">"user"</span><span class="token punctuation">,</span> <span class="token property">"content"</span><span class="token operator">:</span> <span class="token string">"Who wrote 'Romeo and Juliet'?"</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token property">"role"</span><span class="token operator">:</span> <span class="token string">"assistant"</span><span class="token punctuation">,</span> <span class="token property">"content"</span><span class="token operator">:</span> <span class="token string">"Oh, just some guy named William Shakespeare. Ever heard of him?"</span><span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">}</span><span class="token punctuation">{</span><span class="token property">"messages"</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">{</span><span class="token property">"role"</span><span class="token operator">:</span> <span class="token string">"system"</span><span class="token punctuation">,</span> <span class="token property">"content"</span><span class="token operator">:</span> <span class="token string">"Marv is a factual chatbot that is also sarcastic."</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token property">"role"</span><span class="token operator">:</span> <span class="token string">"user"</span><span class="token punctuation">,</span> <span class="token property">"content"</span><span class="token operator">:</span> <span class="token string">"How far is the Moon from Earth?"</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token property">"role"</span><span class="token operator">:</span> <span class="token string">"assistant"</span><span class="token punctuation">,</span> <span class="token property">"content"</span><span class="token operator">:</span> <span class="token string">"Around 384,400 kilometers. Give or take a few, like that really matters."</span><span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">}</span><span class="token punctuation">{</span><span class="token property">"messages"</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">{</span><span class="token property">"role"</span><span class="token operator">:</span> <span class="token string">"system"</span><span class="token punctuation">,</span> <span class="token property">"content"</span><span class="token operator">:</span> <span class="token string">"Marv 是一个既真实又讽刺的聊天机器人。"</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token property">"role"</span><span class="token operator">:</span> <span class="token string">"user"</span><span class="token punctuation">,</span> <span class="token property">"content"</span><span class="token operator">:</span> <span class="token string">"法国的首都是什么?"</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token property">"role"</span><span class="token operator">:</span> <span class="token string">"assistant"</span><span class="token punctuation">,</span> <span class="token property">"content"</span><span class="token operator">:</span> <span class="token string">"巴黎,好像每个人都不知道这一点。"</span><span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">}</span><span class="token punctuation">{</span><span class="token property">"messages"</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">{</span><span class="token property">"role"</span><span class="token operator">:</span> <span class="token string">"system"</span><span class="token punctuation">,</span> <span class="token property">"content"</span><span class="token operator">:</span> <span class="token string">"Marv 是一个既真实又讽刺的聊天机器人。"</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token property">"role"</span><span class="token operator">:</span> <span class="token string">"user"</span><span class="token punctuation">,</span> <span class="token property">"content"</span><span class="token operator">:</span> <span class="token string">"谁写了'罗密欧与朱丽叶'?"</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token property">"role"</span><span class="token operator">:</span> <span class="token string">"assistant"</span><span class="token punctuation">,</span> <span class="token property">"content"</span><span class="token operator">:</span> <span class="token string">"哦,只是一个叫威廉·莎士比亚的人。听说过他吗?"</span><span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">}</span><span class="token punctuation">{</span><span class="token property">"messages"</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">{</span><span class="token property">"role"</span><span class="token operator">:</span> <span class="token string">"system"</span><span class="token punctuation">,</span> <span class="token property">"content"</span><span class="token operator">:</span> <span class="token string">"Marv 是一个既真实又讽刺的聊天机器人。"</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token property">"role"</span><span class="token operator">:</span> <span class="token string">"user"</span><span class="token punctuation">,</span> <span class="token property">"content"</span><span class="token operator">:</span> <span class="token string">"从地球到月球距离有多远?"</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token property">"role"</span><span class="token operator">:</span> <span class="token string">"assistant"</span><span class="token punctuation">,</span> <span class="token property">"content"</span><span class="token operator">:</span> <span class="token string">"大约384,400公里。再加减一点,好像也不是很重要。"</span><span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">}</span></code></pre><h4 id="4-3-助理数据"><a href="#4-3-助理数据" class="headerlink" title="4.3 助理数据"></a>4.3 助理数据</h4><blockquote><p>检索可以利用模型外部的知识来增强助手,例如专有产品信息或用户提供的文档。文件上传并传递给助手后,OpenAI 将自动对文档进行分块、索引和存储嵌入,并实施矢量搜索以检索相关内容来回答用户查询。</p></blockquote><p>简单来说就是, 我们只需要把文件上传上去给到助理, 它就会自动读取识别内容并学习模仿相关的内容来回复。</p><p>常见的支持文件格式有:</p><table><thead><tr><th align="center">文件格式</th><th align="center">MIME类型</th></tr></thead><tbody><tr><td align="center">.csv</td><td align="center">application/csv</td></tr><tr><td align="center">.docx</td><td align="center">application/vnd.openxmlformats-officedocument.wordprocessingml.document</td></tr><tr><td align="center">.html</td><td align="center">text/html</td></tr><tr><td align="center">.json</td><td align="center">application/json</td></tr><tr><td align="center">.md</td><td align="center">text/markdown</td></tr><tr><td align="center">.pdf</td><td align="center">application/pdf</td></tr><tr><td align="center">.txt</td><td align="center">text/plain</td></tr><tr><td align="center">.xlsx</td><td align="center">application/vnd.openxmlformats-officedocument.spreadsheetml.sheet</td></tr></tbody></table><p>更多支持的文件可查看官方: <a href="https://platform.openai.com/docs/assistants/tools/supported-files">支持的文件</a></p><h2 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h2><p><a href="https://gofly.v1kf.com/article/74">https://gofly.v1kf.com/article/74</a></p><p><a href="https://platform.openai.com/docs/guides/fine-tuning">https://platform.openai.com/docs/guides/fine-tuning</a></p><p><a href="https://platform.openai.com/docs/api-reference/chat">https://platform.openai.com/docs/api-reference/chat</a></p><p><a href="https://platform.openai.com/docs/api-reference/fine-tuning">https://platform.openai.com/docs/api-reference/fine-tuning</a></p><p><a href="https://platform.openai.com/docs/api-reference/files/create">https://platform.openai.com/docs/api-reference/files/create</a></p><p><a href="https://cookbook.openai.com/examples/chat_finetuning_data_prep">https://cookbook.openai.com/examples/chat_finetuning_data_prep</a></p><p><a href="https://greatdk.com/1908.html">https://greatdk.com/1908.html</a></p><p><a href="https://github.com/wdkwdkwdk/CLONE_DK">https://github.com/wdkwdkwdk/CLONE_DK</a></p><p><a href="https://cn.v2ex.com/t/930423">https://cn.v2ex.com/t/930423</a></p><p><a href="https://udify.app/chat/RkCYZlpzZyhAsumL">https://udify.app/chat/RkCYZlpzZyhAsumL</a></p><p><a href="https://github.com/LC044/WeChatMsg/">https://github.com/LC044/WeChatMsg/</a></p><p><a href="https://blog.lc044.love/post/5">https://blog.lc044.love/post/5</a></p><p><a href="https://github.com/saturn-opposition/wechat_analysis">https://github.com/saturn-opposition/wechat_analysis</a></p>]]></content>
<summary type="html"><p>ChatGPT 和 AI 的话题近两年都很火热, 自从 OpenAI 诞生出 ChatGPT 以来, 各互联网大厂公司纷纷加入并研发自家的AI大模型, 也有不少人趁着这个风口, 利用 ChatGPT 实现变现, 赚的盆满钵满, 瓜分这块AI蛋糕。</p></summary>
<category term="Python" scheme="http://chuchu-z.com/categories/python/"/>
<category term="ChatGPT" scheme="http://chuchu-z.com/categories/python/chatgpt/"/>
</entry>
<entry>
<title>谷歌翻译扩展失效 配置hosts解决</title>
<link href="http://chuchu-z.com/posts/translate-google-hosts/"/>
<id>http://chuchu-z.com/posts/translate-google-hosts/</id>
<published>2024-01-03T06:27:19.000Z</published>
<updated>2024-12-31T06:57:56.021Z</updated>
<content type="html"><![CDATA[<p>因为谷歌关闭了中国大陆的谷歌翻译服务, 谷歌翻译扩展也停用了, 尽管我也想少用翻译软件, 多尝试自己阅读原文文档, 但不等于直接用不了一点啊啊啊</p><span id="more"></span><h2 id="解决方案"><a href="#解决方案" class="headerlink" title="解决方案"></a>解决方案</h2><h3 id="1-修改hosts文件"><a href="#1-修改hosts文件" class="headerlink" title="1. 修改hosts文件"></a>1. 修改hosts文件</h3><p>Win + E, 地址栏直接输入 <strong>C:\Windows\System32\drivers\etc</strong> 回车</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/posts/translate-google-hosts/image-20240103143527333.png" alt title> </div> <div class="image-caption"></div> </figure><p>编辑hosts文件, 从下面现用和备用中选一个加到文件最后</p><pre class="language-latex" data-language="latex"><code class="language-latex"># 现用203.208.40.66 translate.google.com203.208.40.66 translate.googleapis.com# 如果上面的失效了, 可试试这个备用的120.253.253.34 translate.googleapis.com142.250.0.90 translate.googleapis.com</code></pre><h3 id="2-刷新DNS"><a href="#2-刷新DNS" class="headerlink" title="2. 刷新DNS"></a>2. 刷新DNS</h3><p>然后 Win + R, 输入 <strong>cmd</strong> 回车, 执行下面的命令, 刷新DNS, 搞定!</p><pre class="language-bash" data-language="bash"><code class="language-bash">ipconfig /flushdns</code></pre>]]></content>
<summary type="html"><p>因为谷歌关闭了中国大陆的谷歌翻译服务, 谷歌翻译扩展也停用了, 尽管我也想少用翻译软件, 多尝试自己阅读原文文档, 但不等于直接用不了一点啊啊啊</p></summary>
<category term="Other" scheme="http://chuchu-z.com/categories/other/"/>
</entry>
<entry>
<title>HELLO-2024</title>
<link href="http://chuchu-z.com/posts/hello-2024/"/>
<id>http://chuchu-z.com/posts/hello-2024/</id>
<published>2024-01-02T01:43:42.000Z</published>
<updated>2024-12-31T06:57:56.016Z</updated>
<content type="html"><![CDATA[<p>新的一年, 希望今年有更好的成长</p><span id="more"></span><h2 id="2024小目标"><a href="#2024小目标" class="headerlink" title="2024小目标"></a>2024小目标</h2><h3 id="工作"><a href="#工作" class="headerlink" title="工作"></a>工作</h3><pre class="language-none"><code class="language-none">1. 掌握hyperf、swoole2. 系统深入学习MySQL, 搞懂底层锁, 事务, Buffer Pool等知识点3. 系统学习计算机网络知识、通信协议4. 继续在多邻国学习英语5. 了解其他开发知识(Go,Oralce, 微服务)</code></pre><h3 id="生活-爱好"><a href="#生活-爱好" class="headerlink" title="生活/爱好"></a>生活/爱好</h3><pre class="language-none"><code class="language-none">1. 了解电脑硬件/系统装机等知识2. 组装一台新电脑(耕升4070踏雪)3. 沙盘战争红军/长征/抗美援朝部分4. 多做饭5. 《黑神话悟空》</code></pre>]]></content>
<summary type="html"><p>新的一年, 希望今年有更好的成长</p></summary>
<category term="岁月杂感" scheme="http://chuchu-z.com/categories/%E5%B2%81%E6%9C%88%E6%9D%82%E6%84%9F/"/>
</entry>
<entry>
<title>无聊的年终总结</title>
<link href="http://chuchu-z.com/posts/goodbye-2023/"/>
<id>http://chuchu-z.com/posts/goodbye-2023/</id>
<published>2023-12-29T10:31:33.000Z</published>
<updated>2024-12-31T06:57:56.016Z</updated>
<content type="html"><![CDATA[<blockquote><p>2023年就这么结束了, 今天是今年最后一天工作, 回想这一年, 也接触和了解到了很多新的东西, 即使成长的点滴虽小, 但<strong>不积跬步, 无以至千里</strong> 。</p></blockquote><span id="more"></span><h2 id="今年做了什么"><a href="#今年做了什么" class="headerlink" title="今年做了什么"></a>今年做了什么</h2><ol><li><strong>chatGpt</strong> 贯穿了我今年一整年的开发过程, 学习了如何跟它交流, 提取关键词提问, 获取信息</li><li>长达半年多的时间里, 从无到有, 学习了 <strong>Android studio</strong> 以及 <strong>webview</strong> App开发, 掌握 <strong>GooglePlay</strong> 商店 <strong>App 应用上架</strong>完整流程</li><li>学习众多有关于<strong>跨境电商知识</strong>, 接触较为有用的平台 <a href="https://sms-activate.org/cn">sms-activate</a> 、<a href="https://amzkeys.com/">amzkeys</a>、<a href="https://www.cloudflare.com/">cloudflare</a> 等</li><li>相比在<strong>安银</strong>的时候, 更加了解了 <strong>数字货币和钱包的交易关系</strong></li><li>深入了解 <strong>websocket</strong> 、<strong>Nginx 代理、 反向代理</strong>、 <strong>PHP-FPM 与 Nginx 、PHP-CGI</strong> 等关系</li><li>五月二十三号, 正式开始踏入<strong>多邻国</strong> 并学习英语, 195天连胜打卡(准确来说, 应该只有150多天是每天都在学习的)</li><li>同五月份, 开始慢慢重视博客文章的编写, 十月份国庆开始接触学习<strong>计算机硬件知识</strong></li></ol><blockquote><p>按年度来总结, 做的事情太多, 若不是提前规划好的事情, 最后能记住的事情太少, 能写下来的更少, 看来以后需要提前规划, 按月为单位来总结。</p><p> 一个刚开始只会<strong>水溅跃</strong>💦的<strong>鲤鱼王</strong>, 最后是怎么进化成<strong>暴鲤龙</strong>的。</p></blockquote>]]></content>
<summary type="html"><blockquote>
<p>2023年就这么结束了, 今天是今年最后一天工作, 回想这一年, 也接触和了解到了很多新的东西, 即使成长的点滴虽小, 但<strong>不积跬步, 无以至千里</strong> 。</p>
</blockquote></summary>
<category term="岁月杂感" scheme="http://chuchu-z.com/categories/%E5%B2%81%E6%9C%88%E6%9D%82%E6%84%9F/"/>
</entry>
<entry>
<title> 个人docker-compose 配置</title>
<link href="http://chuchu-z.com/posts/my-docker-zsh-config/"/>
<id>http://chuchu-z.com/posts/my-docker-zsh-config/</id>
<published>2023-12-26T09:15:00.000Z</published>
<updated>2024-12-31T06:57:56.018Z</updated>
<content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><blockquote><p>由于在 Windows 下开发 但是又想使用 zsh shell, 只好自己使用 docker 部署一套, 环境是搞好了, 但是还有个问题困扰着我</p><span id="more"></span><p>就是从 git-bash 里执行 docker exce 进入容器内部, 输入栏的光标位置与我实际输入的地方始终对不准 总是有一个空格的差距, 而在 docker desktop 里面的终端打开是正常的, 如下图, 仔细看就能发现</p><p>同样都是只输入了 <code>vim</code> , 在git-bash终端里面, 光标对准的位置却发生了偏差, 光标跑到了 <code>vim a</code> 那里去了</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/posts/my-docker-zsh-config/image-20231226170047096-17035824143912.png" alt title> </div> <div class="image-caption"></div> </figure><p>这个问题十分头疼 折腾许久找不到解决办法, 猜测是使用 agnoster.zsh-theme 主题的自带的特殊符号导致的, 因为尝试过删除特殊符号后就恢复了</p><p>但我仍无法解决如何在保留特殊符号的情况下不会出现那一个空格的偏差, 真是急死强迫症😓</p><p>这个难题就交给未来的我来解决吧</p></blockquote><h2 id="pull-Code"><a href="#pull-Code" class="headerlink" title="pull Code"></a>pull Code</h2><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token function">git</span> clone [email protected]:chuchu-z/docker-zsh.git</code></pre><h2 id="构建环境"><a href="#构建环境" class="headerlink" title="构建环境"></a>构建环境</h2><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token comment"># 根据 docker-compose 配置构造镜像容器</span><span class="token function">docker-compose</span> build --no-cache <span class="token operator">&&</span> <span class="token function">docker-compose</span> up <span class="token parameter variable">-d</span><span class="token comment"># 启动 Zsh shell, 也可以把 zsh 改成 bash, sh, /bin/sh 等</span>winpty <span class="token function">docker</span> <span class="token builtin class-name">exec</span> <span class="token parameter variable">-it</span> 11b3a0847350 <span class="token function">zsh</span></code></pre><h2 id="补充"><a href="#补充" class="headerlink" title="补充"></a>补充</h2><ol><li>由于 <strong>.gitignore</strong> 忽略了 <strong>.ssh</strong> , pull 代码时记得加上该目录</li></ol><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token function">cp</span> ~/.ssh <span class="token builtin class-name">.</span></code></pre><ol start="2"><li>太久没用的话记得先去看看 <strong>docker-compose.yml</strong></li><li>希望下次你能解决光标对齐问题 <strong>good luck~</strong> 👍</li></ol>]]></content>
<summary type="html"><h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><blockquote>
<p>由于在 Windows 下开发 但是又想使用 zsh shell, 只好自己使用 docker 部署一套, 环境是搞好了, 但是还有个问题困扰着我</p></blockquote></summary>
<category term="Docker" scheme="http://chuchu-z.com/categories/docker/"/>
</entry>
<entry>
<title>Windows10 激活产品密钥</title>
<link href="http://chuchu-z.com/posts/windows-activation/"/>
<id>http://chuchu-z.com/posts/windows-activation/</id>
<published>2023-12-26T01:37:20.000Z</published>
<updated>2024-12-31T06:57:56.022Z</updated>
<content type="html"><![CDATA[<blockquote><p>帮同事电脑重装系统 需要激活产品密钥 网上有很多 但是很大部分都不可用 找了挺久 找到一个挺多人反馈可用的 记录下来看后面用不用的上</p></blockquote><span id="more"></span><h2 id="激活方法"><a href="#激活方法" class="headerlink" title="激活方法"></a>激活方法</h2><p>win+Q, 搜索cmd, 以管理员身份打开cmd工具, 按顺序执行下面4条命令, 也有人说把第三个命令行输入后去掉 <code>http://</code> 只保留域名部分才可以成功</p><p>实在不行就去 <strong>设置-更新和安全-激活</strong> 里面激活, 产品密钥 <strong>W269N-WFGWX-YVC9B-4J6C9-T83GX</strong></p><pre class="language-bash" data-language="bash"><code class="language-bash">slmgr /ckmsslmgr /ipk W269N-WFGWX-YVC9B-4J6C9-T83GXslmgr /skms http://kms.03k.orgslmgr /ato</code></pre><h2 id="结语"><a href="#结语" class="headerlink" title="结语"></a>结语</h2><p>上面这个密钥不知道什么时候会失效, 以前也用过一些软件激活的, 现在想想这个东西, 其实就是写个循环 用枚举暴力破解, 假如我把网络上的产品密钥都收集起来放到一个文本文件里, 一个密钥一行, 脚本再一行一行的去读取该文本文件, 脚本循环执行上面的几行激活代码, 替换掉固定的密钥, 是不是也是一个自动激活工具呢</p>]]></content>
<summary type="html"><blockquote>
<p>帮同事电脑重装系统 需要激活产品密钥 网上有很多 但是很大部分都不可用 找了挺久 找到一个挺多人反馈可用的 记录下来看后面用不用的上</p>
</blockquote></summary>
<category term="Other" scheme="http://chuchu-z.com/categories/other/"/>
</entry>
<entry>
<title>Python youtube-dl与you-get工具爬取视频</title>
<link href="http://chuchu-z.com/posts/python-youtube-dl-and-you-get/"/>
<id>http://chuchu-z.com/posts/python-youtube-dl-and-you-get/</id>
<published>2023-12-25T03:23:21.000Z</published>
<updated>2024-12-31T06:57:56.021Z</updated>
<content type="html"><![CDATA[<p><strong>youtube-dl</strong> 和 <strong>you-get</strong> 都是用于从互联网上下载视频的命令行工具,它们支持多种网站和服务</p><ul><li><strong>youtube-dl</strong> 功能更加全面,支持的网站更多,但也可能更复杂一些。</li><li><strong>you-get</strong> 相对来说更简单,更容易上手,适用于一般用户。</li></ul><span id="more"></span><h2 id="查看Python版本"><a href="#查看Python版本" class="headerlink" title="查看Python版本"></a>查看Python版本</h2><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token comment"># 安装Python后 查看Python版本</span>python <span class="token parameter variable">--version</span></code></pre><h2 id="youtube-dl"><a href="#youtube-dl" class="headerlink" title="youtube-dl"></a>youtube-dl</h2><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token comment"># 下载youtube-dl工具</span>pip <span class="token function">install</span> youtube-dl<span class="token comment"># 使用工具</span>youtube-dl --list-formats <span class="token punctuation">[</span>url<span class="token punctuation">]</span> <span class="token comment"># 列出可用的视频格式和质量</span>youtube-dl <span class="token parameter variable">-oif</span> <span class="token punctuation">[</span> <span class="token parameter variable">-o</span> 指定输出文件名或目录<span class="token punctuation">]</span> <span class="token punctuation">[</span>-i 忽略下载过程中的错误<span class="token punctuation">]</span> <span class="token punctuation">[</span>-f 指定下载的视频格式/质量, 如mp4<span class="token punctuation">]</span> <span class="token punctuation">[</span>url<span class="token punctuation">]</span></code></pre><h2 id="you-get"><a href="#you-get" class="headerlink" title="you-get"></a>you-get</h2><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token comment"># 下载you-get工具</span>pip <span class="token function">install</span> you-get<span class="token comment"># 使用工具</span>you-get <span class="token parameter variable">-F</span> <span class="token punctuation">[</span>url<span class="token punctuation">]</span> <span class="token comment"># 列出可用的格式</span>you-get <span class="token parameter variable">-i</span> <span class="token punctuation">[</span>url<span class="token punctuation">]</span> <span class="token comment"># 显示视频信息</span>you-get <span class="token parameter variable">-o</span> <span class="token operator"><</span>输出目录<span class="token operator">></span> <span class="token operator"><</span>视频链接<span class="token operator">></span></code></pre>]]></content>
<summary type="html"><p><strong>youtube-dl</strong> 和 <strong>you-get</strong> 都是用于从互联网上下载视频的命令行工具,它们支持多种网站和服务</p>
<ul>
<li><strong>youtube-dl</strong> 功能更加全面,支持的网站更多,但也可能更复杂一些。</li>
<li><strong>you-get</strong> 相对来说更简单,更容易上手,适用于一般用户。</li>
</ul></summary>
<category term="Python" scheme="http://chuchu-z.com/categories/python/"/>
</entry>
<entry>
<title>Docker 私有化部署 wiki-MrDoc</title>
<link href="http://chuchu-z.com/posts/docker-deploy-wiki-MrDoc/"/>
<id>http://chuchu-z.com/posts/docker-deploy-wiki-MrDoc/</id>
<published>2023-12-19T03:52:09.000Z</published>
<updated>2024-12-31T06:57:56.013Z</updated>
<content type="html"><![CDATA[<p>为完善公司内部技术人员沟通以及共享信息文档, 使用wiki工具是很有必要的, 私有化部署可以避免信息外泄, <strong>MrDoc</strong> 是一款很不错的wiki工具, 有开源版以及功能更全的专业版</p><p>👉<a href="https://gitee.com/zmister/MrDoc">Gitee 地址</a></p><p>👉<a href="https://doc.mrdoc.pro/doc/3958/">MrDoc 官方文档</a></p><span id="more"></span><h2 id="部署"><a href="#部署" class="headerlink" title="部署"></a>部署</h2><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token builtin class-name">cd</span> /www/wwwroot<span class="token comment"># close下来时顺便定义项目名称为wiki-Mrdoc</span><span class="token function">git</span> clone https://gitee.com/zmister/MrDoc.git wiki-Mrdoc<span class="token comment"># pull镜像</span><span class="token function">docker</span> pull zmister/mrdoc:v7<span class="token comment"># 注意修改挂载的项目目录为/www/wwwroot/wiki-Mrdoc</span><span class="token function">docker</span> run <span class="token parameter variable">-d</span> <span class="token parameter variable">--name</span> mrdoc <span class="token parameter variable">-p</span> <span class="token number">10086</span>:10086 <span class="token parameter variable">-v</span> /www/wwwroot/wiki-Mrdoc:/app/MrDoc zmister/mrdoc:v7<span class="token comment"># 创建用户</span><span class="token function">docker</span> <span class="token builtin class-name">exec</span> <span class="token parameter variable">-it</span> mrdoc python manage.py createsuperuser</code></pre><pre class="language-nginx" data-language="nginx"><code class="language-nginx"><span class="token comment"># 配置反向代理</span><span class="token directive"><span class="token keyword">server</span></span> <span class="token punctuation">{</span> <span class="token directive"><span class="token keyword">listen</span> <span class="token number">80</span></span><span class="token punctuation">;</span> <span class="token directive"><span class="token keyword">server_name</span> wiki.chuchu-z.com</span><span class="token punctuation">;</span> <span class="token comment"># 托管静态文件资源</span> <span class="token directive"><span class="token keyword">location</span> ^~ /static/</span> <span class="token punctuation">{</span> <span class="token directive"><span class="token keyword">alias</span> /www/wwwroot/wiki-Mrdoc/static/</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment"># 配置反向代理</span> <span class="token directive"><span class="token keyword">location</span> /</span> <span class="token punctuation">{</span> <span class="token directive"><span class="token keyword">proxy_pass</span> http://127.0.0.1:10086</span><span class="token punctuation">;</span> <span class="token directive"><span class="token keyword">proxy_set_header</span> Host <span class="token variable">$host</span></span><span class="token punctuation">;</span> <span class="token directive"><span class="token keyword">proxy_set_header</span> X-Real-IP <span class="token variable">$remote_addr</span></span><span class="token punctuation">;</span> <span class="token directive"><span class="token keyword">proxy_set_header</span> X-Forwarded-For <span class="token variable">$proxy_add_x_forwarded_for</span></span><span class="token punctuation">;</span> <span class="token directive"><span class="token keyword">proxy_set_header</span> REMOTE-HOST <span class="token variable">$remote_addr</span></span><span class="token punctuation">;</span> <span class="token directive"><span class="token keyword">proxy_set_header</span> X-Forwarded-Proto <span class="token variable">$scheme</span></span><span class="token punctuation">;</span> <span class="token comment">#Set Nginx Cache</span> <span class="token directive"><span class="token keyword">add_header</span> Cache-Control no-cache</span><span class="token punctuation">;</span> <span class="token directive"><span class="token keyword">add_header</span> X-Cache <span class="token variable">$upstream_cache_status</span></span><span class="token punctuation">;</span> <span class="token directive"><span class="token keyword">proxy_ignore_headers</span> Set-Cookie Cache-Control expires</span><span class="token punctuation">;</span> <span class="token directive"><span class="token keyword">proxy_read_timeout</span> <span class="token number">300</span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></code></pre><h2 id="迁移到其他服务器部署"><a href="#迁移到其他服务器部署" class="headerlink" title="迁移到其他服务器部署"></a>迁移到其他服务器部署</h2><p>如果使用一段时间后, 需要将其部署到其他服务器</p><p>项目源代码在 <strong>/www/wwwroot/wiki-Mrdoc</strong> 目录下, 并且使用docker部署的</p><p>只需要将整个 <strong>wiki-Mrdoc</strong> 项目打包成压缩包文件, 并上传到其他服务器, 然后在新的服务器上执行部署命令</p><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token builtin class-name">cd</span> /www/wwwroot<span class="token comment"># 压缩</span><span class="token function">tar</span> <span class="token parameter variable">-czvf</span> wiki-Mrdoc.tar.gz wiki-Mrdoc<span class="token comment"># 传输到新服务器</span><span class="token function">scp</span> /www/wwwroot/wiki-Mrdoc.tar.gz root@<span class="token punctuation">{</span>ip<span class="token punctuation">}</span>:/www/wwwroot/</code></pre><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token builtin class-name">cd</span> /www/wwwroot<span class="token comment"># 解压 .tar.gz 文件</span><span class="token function">tar</span> <span class="token parameter variable">-xzvf</span> wiki-Mrdoc.tar.gz<span class="token builtin class-name">cd</span> wiki-Mrdoc<span class="token comment"># pull镜像(先安装docker)</span><span class="token function">docker</span> pull zmister/mrdoc:v7<span class="token comment"># 修改挂载的项目目录为/www/wwwroot/wiki-Mrdoc</span><span class="token function">docker</span> run <span class="token parameter variable">-d</span> <span class="token parameter variable">--name</span> mrdoc <span class="token parameter variable">-p</span> <span class="token number">10086</span>:10086 <span class="token parameter variable">-v</span> /www/wwwroot/wiki-Mrdoc:/app/MrDoc zmister/mrdoc:v7</code></pre><p>然后正常配置网站站点, 配置反向代理即可</p>]]></content>
<summary type="html"><p>为完善公司内部技术人员沟通以及共享信息文档, 使用wiki工具是很有必要的, 私有化部署可以避免信息外泄, <strong>MrDoc</strong> 是一款很不错的wiki工具, 有开源版以及功能更全的专业版</p>
<p>👉<a href="https://gitee.com/zmister/MrDoc">Gitee 地址</a></p>
<p>👉<a href="https://doc.mrdoc.pro/doc/3958/">MrDoc 官方文档</a></p></summary>
<category term="Docker" scheme="http://chuchu-z.com/categories/docker/"/>
<category term="wiki" scheme="http://chuchu-z.com/categories/docker/wiki/"/>
</entry>
<entry>
<title>使用Docker安装hyperf-admin</title>
<link href="http://chuchu-z.com/posts/use-Docker-install-hyperf/"/>
<id>http://chuchu-z.com/posts/use-Docker-install-hyperf/</id>
<published>2023-11-29T05:41:37.000Z</published>
<updated>2024-12-31T06:57:56.021Z</updated>
<content type="html"><![CDATA[<p>近期有项目用到 <a href="https://github.com/hyperf-admin/hyperf-admin"><strong>hyperf-admin</strong></a>, 顺便学习记录一下基于官方的镜像开始构建到部署过程 </p><p>👉 <a href="https://hyperf.wiki/2.0/#/zh-cn/quick-start/install">hyperf官方地址</a></p><span id="more"></span><h2 id="安装-amp-配置"><a href="#安装-amp-配置" class="headerlink" title="安装&配置"></a>安装&配置</h2><p>由于官方默认是在Linux执行的, 但实际我是在Win10下的 git-bash 终端执行, 所以命令稍微有点不一样, 比如指定项目路径的方式和不需要指定终端为 <strong>/bin/sh</strong></p><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token comment"># 官方镜像</span>winpty <span class="token function">docker</span> run <span class="token parameter variable">-v</span> <span class="token string">"D:\phpstudy\WWW\online-chat:/hyperf"</span> <span class="token parameter variable">-p</span> <span class="token number">9501</span>:9501 <span class="token parameter variable">-it</span> hyperf/hyperf:7.4-alpine-v3.11-swoole<span class="token comment"># 官方镜像重制后的镜像</span>winpty <span class="token function">docker</span> run <span class="token parameter variable">-v</span> <span class="token string">"D:\phpstudy\WWW\online-chat:/hyperf"</span> <span class="token parameter variable">-p</span> <span class="token number">9501</span>:9501 <span class="token parameter variable">-it</span> chuchuzz426/hyperf:1.0 <span class="token function">bash</span></code></pre><p>执行完后进入容器内执行</p><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token comment">#安装应用</span>apk <span class="token function">add</span> <span class="token function">vim</span> <span class="token function">wget</span> tzdata<span class="token comment">#修改时区为上海东八区</span><span class="token function">ln</span> <span class="token parameter variable">-sf</span> /usr/share/zoneinfo/Asia/Shanghai /etc/localtime<span class="token builtin class-name">echo</span> <span class="token string">"Asia/Shanghai"</span> <span class="token operator">></span> /etc/timezone<span class="token comment">#输出时间查看</span><span class="token function">date</span><span class="token comment">#修改配置文件</span><span class="token function">vim</span> ~/.bashrc<span class="token comment">#修改PS1</span><span class="token builtin class-name">export</span> <span class="token assign-left variable"><span class="token environment constant">PS1</span></span><span class="token operator">=</span><span class="token string">'\[\033]0;Bash\007\]\n\[\033[32;1m\] ➜ \[\033[33;1m\]\W\[\033[34;1m\] [\t] \[\033[36m\]'</span><span class="token comment">#添加alias</span><span class="token builtin class-name">alias</span> <span class="token assign-left variable">e</span><span class="token operator">=</span><span class="token string">'exit'</span><span class="token builtin class-name">alias</span> <span class="token assign-left variable">www</span><span class="token operator">=</span><span class="token string">'cd /hyperf'</span><span class="token builtin class-name">alias</span> <span class="token assign-left variable">ll</span><span class="token operator">=</span><span class="token string">'ls -al'</span><span class="token builtin class-name">alias</span> <span class="token assign-left variable">vp</span><span class="token operator">=</span><span class="token string">'vim ~/.bashrc'</span><span class="token builtin class-name">alias</span> <span class="token assign-left variable">sp</span><span class="token operator">=</span><span class="token string">'source ~/.bashrc'</span><span class="token comment">#保存后执行</span><span class="token builtin class-name">source</span> ~/.bashrc</code></pre><p>由于 Docker 容器默认是以非交互式且不登录的情况进入容器的, 我们需要以交互式的情况进入</p><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token comment"># 以 sh 方式启动 则需要在后面添加 -il 参数, 表示以交互式并且模拟登录的情况进入容器, 只有模拟登陆才会初始化执行 ~/.bashrc</span>winpty <span class="token function">docker</span> <span class="token builtin class-name">exec</span> <span class="token parameter variable">-it</span> e61fb6c63c38 <span class="token function">sh</span> <span class="token parameter variable">-il</span><span class="token comment"># 以 bash 方式启动, 会默认初始化执行 ~/.bashrc文件</span>winpty <span class="token function">docker</span> <span class="token builtin class-name">exec</span> <span class="token parameter variable">-it</span> e61fb6c63c38 <span class="token function">bash</span></code></pre><h2 id="启动hyperf"><a href="#启动hyperf" class="headerlink" title="启动hyperf"></a>启动hyperf</h2><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token comment"># 进入hyperf目录</span><span class="token builtin class-name">cd</span> /hyperf<span class="token comment"># 将 Composer 镜像设置为阿里云镜像,加速国内下载速度</span><span class="token function">composer</span> config <span class="token parameter variable">-g</span> repo.packagist <span class="token function">composer</span> https://mirrors.aliyun.com/composer<span class="token comment"># 由于项目已经从github拉取下来 所以无需执行安装hyperf命令, 只需要执行composer update 获取依赖</span><span class="token function">composer</span> update<span class="token comment"># 启动 Hyperf</span>php bin/hyperf.php start<span class="token comment"># 浏览器输入http://127.0.0.1:9501访问</span>http://127.0.0.1:9501</code></pre><h2 id="Linux-shell-配置文件关系表"><a href="#Linux-shell-配置文件关系表" class="headerlink" title="Linux shell 配置文件关系表"></a>Linux shell 配置文件关系表</h2><p>附带上文为什么修改 <code>~/.bashrc</code> 原因, 因为想要在容器内定义一些alias命令, 而容器默认是非登录进入的, 所以说明一下初始化时读取的是哪个配置文件</p><table><thead><tr><th>文件</th><th>位置</th><th>作用和描述</th></tr></thead><tbody><tr><td><code>~/.profile</code></td><td>用户主目录 (<code>$HOME</code>)</td><td>用户登录时执行的个人配置文件。通常在登录时执行一次,用于设置用户环境变量和执行用户的个人配置。</td></tr><tr><td><code>~/.bashrc</code></td><td>用户主目录 (<code>$HOME</code>)</td><td>非登录的 Bash shell 启动时执行的个人配置文件。用于设置 Bash shell 的特定配置,如别名、自定义函数等。</td></tr><tr><td><code>~/.bash_profile</code></td><td>用户主目录 (<code>$HOME</code>)</td><td>用户登录时执行的个人配置文件。如果存在该文件,则通常会覆盖 <code>~/.profile</code>。用于设置用户环境变量和执行用户的个人配置。</td></tr><tr><td><code>/etc/profile</code></td><td><code>/etc/</code> 目录</td><td>系统级别的 Bash shell 配置文件。在系统启动时,用于设置全局环境变量和执行系统范围的配置。用户登录时也会执行一次。</td></tr></tbody></table><h2 id="把容器制作为镜像并导出为tar"><a href="#把容器制作为镜像并导出为tar" class="headerlink" title="把容器制作为镜像并导出为tar"></a>把容器制作为镜像并导出为tar</h2><p>为了把修改过的容器方便在其他机器上使用, 打包制作成镜像</p><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token comment">#容器制作为镜像</span><span class="token function">docker</span> commit e61fb6c63c38 chuchuzz426/hyperf:1.0<span class="token comment">#镜像导出为tar文件</span><span class="token function">docker</span> save <span class="token parameter variable">-o</span> my-hyperf-image.tar chuchuzz426/hyperf:1.0</code></pre><h2 id="制作docker-compose-yml启动"><a href="#制作docker-compose-yml启动" class="headerlink" title="制作docker-compose.yml启动"></a>制作docker-compose.yml启动</h2><p>为了省去配置命令的麻烦和方便后续扩展, 添加docker-compose.yml文件</p><pre class="language-yaml" data-language="yaml"><code class="language-yaml"><span class="token key atrule">version</span><span class="token punctuation">:</span> <span class="token string">'3'</span><span class="token key atrule">x-project-settings</span><span class="token punctuation">:</span> <span class="token important">&project-settings</span> <span class="token key atrule">project_name</span><span class="token punctuation">:</span> hyperf<span class="token punctuation">-</span>app<span class="token key atrule">services</span><span class="token punctuation">:</span> <span class="token key atrule">hyperf-app</span><span class="token punctuation">:</span> <span class="token key atrule">image</span><span class="token punctuation">:</span> chuchuzz426/hyperf<span class="token punctuation">:</span><span class="token number">1.0</span> <span class="token key atrule">container_name</span><span class="token punctuation">:</span> hyperf <span class="token key atrule">ports</span><span class="token punctuation">:</span> <span class="token punctuation">-</span> <span class="token string">"9501:9501"</span> <span class="token punctuation">-</span> <span class="token string">"9502:9502"</span> <span class="token punctuation">-</span> <span class="token string">"9503:9503"</span> <span class="token key atrule">volumes</span><span class="token punctuation">:</span> <span class="token punctuation">-</span> D<span class="token punctuation">:</span>\phpstudy\WWW\online<span class="token punctuation">-</span>chat<span class="token punctuation">:</span>/hyperf <span class="token key atrule">working_dir</span><span class="token punctuation">:</span> /hyperf/hyperf <span class="token comment"># command: ["php", "bin/hyperf.php", "start"]</span> <span class="token comment"># 先执行一遍composer install</span> <span class="token key atrule">command</span><span class="token punctuation">:</span> <span class="token punctuation">-</span> /bin/sh <span class="token punctuation">-</span> <span class="token punctuation">-</span>c <span class="token punctuation">-</span> <span class="token string">"composer install && php bin/hyperf.php start"</span></code></pre><p>接下来就是 <del>原神⭕🗽</del> hyperf, 启动!</p><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token function">docker-compose</span> up <span class="token parameter variable">-d</span><span class="token comment"># 如果不是首次执行的话, 避免缓存问题最好执行这条</span><span class="token function">docker-compose</span> build --no-cache <span class="token operator">&&</span> <span class="token function">docker-compose</span> up <span class="token parameter variable">-d</span></code></pre><h2 id="DB与redis连接配置"><a href="#DB与redis连接配置" class="headerlink" title="DB与redis连接配置"></a>DB与redis连接配置</h2><ol><li>修改.env配置, 连接宿主机mysql, 先在宿主机执行 <strong>ipconfig</strong> 查看 <strong>WSL</strong> 的IPv4地址, 比如我的是172.21.240.1, 则 env配置文件的<strong>DB_HOST</strong>填写的就是<strong>172.21.240.1</strong></li></ol><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/posts/use-Docker-install-hyperf/image-20231129091510911.png" alt title> </div> <div class="image-caption"></div> </figure><ol start="2"><li>如果mysql拒绝连接, 则修改一下mysql的用户授权</li></ol><pre class="language-sql" data-language="sql"><code class="language-sql"><span class="token comment">#用户授权,记得换成对应的库名和用户名及密码</span><span class="token keyword">GRANT</span> <span class="token keyword">ALL</span> <span class="token keyword">PRIVILEGES</span> <span class="token keyword">ON</span> your_database<span class="token punctuation">.</span><span class="token operator">*</span> <span class="token keyword">TO</span> <span class="token string">'your_username'</span><span class="token variable">@'%'</span> IDENTIFIED <span class="token keyword">BY</span> <span class="token string">'your_password'</span><span class="token punctuation">;</span><span class="token comment">#刷新权限</span>FLUSH <span class="token keyword">PRIVILEGES</span><span class="token punctuation">;</span></code></pre><ol start="2"><li>redis连接宿主机同上, 记得确保 Redis 服务器的配置允许远程连接, 修改 <strong>redis.conf</strong></li></ol><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token comment">#只允许本地和 172.21.240.1 连接</span><span class="token builtin class-name">bind</span> <span class="token number">127.0</span>.0.1 <span class="token number">172.21</span>.240.1<span class="token comment">#允许任何ip连接, 不推荐,特别是在生产服务器上或者没设置密码的</span><span class="token builtin class-name">bind</span> <span class="token number">0.0</span>.0.0</code></pre><h2 id="server配置"><a href="#server配置" class="headerlink" title="server配置"></a>server配置</h2><p>在config/autoload/server.php的 <strong>server</strong> 配置如下, 端口具体根据实际情况修改</p><pre class="language-php" data-language="php"><code class="language-php"><span class="token string single-quoted-string">'servers'</span> <span class="token operator">=></span> <span class="token punctuation">[</span> <span class="token punctuation">[</span> <span class="token string single-quoted-string">'name'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'http'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'type'</span> <span class="token operator">=></span> <span class="token class-name static-context">Server</span><span class="token operator">::</span><span class="token constant">SERVER_HTTP</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'host'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'0.0.0.0'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'port'</span> <span class="token operator">=></span> <span class="token number">9502</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'sock_type'</span> <span class="token operator">=></span> <span class="token constant">SWOOLE_SOCK_TCP</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'callbacks'</span> <span class="token operator">=></span> <span class="token punctuation">[</span> <span class="token class-name static-context">Event</span><span class="token operator">::</span><span class="token constant">ON_REQUEST</span> <span class="token operator">=></span> <span class="token punctuation">[</span><span class="token class-name class-name-fully-qualified static-context">Hyperf<span class="token punctuation">\</span>HttpServer<span class="token punctuation">\</span>Server</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'onRequest'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span> <span class="token string single-quoted-string">'name'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'ws'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'type'</span> <span class="token operator">=></span> <span class="token class-name static-context">Server</span><span class="token operator">::</span><span class="token constant">SERVER_WEBSOCKET</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'host'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'0.0.0.0'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'port'</span> <span class="token operator">=></span> <span class="token number">9503</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'sock_type'</span> <span class="token operator">=></span> <span class="token constant">SWOOLE_SOCK_TCP</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'callbacks'</span> <span class="token operator">=></span> <span class="token punctuation">[</span> <span class="token class-name static-context">Event</span><span class="token operator">::</span><span class="token constant">ON_HAND_SHAKE</span> <span class="token operator">=></span> <span class="token punctuation">[</span><span class="token class-name class-name-fully-qualified static-context">Hyperf<span class="token punctuation">\</span>WebSocketServer<span class="token punctuation">\</span>Server</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'onHandShake'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token class-name static-context">Event</span><span class="token operator">::</span><span class="token constant">ON_MESSAGE</span> <span class="token operator">=></span> <span class="token punctuation">[</span><span class="token class-name class-name-fully-qualified static-context">Hyperf<span class="token punctuation">\</span>WebSocketServer<span class="token punctuation">\</span>Server</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'onMessage'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token class-name static-context">Event</span><span class="token operator">::</span><span class="token constant">ON_CLOSE</span> <span class="token operator">=></span> <span class="token punctuation">[</span><span class="token class-name class-name-fully-qualified static-context">Hyperf<span class="token punctuation">\</span>WebSocketServer<span class="token punctuation">\</span>Server</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'onClose'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">,</span><span class="token punctuation">]</span><span class="token punctuation">,</span></code></pre><h2 id="VUE"><a href="#VUE" class="headerlink" title="VUE"></a>VUE</h2><h3 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h3><pre class="language-none"><code class="language-none"># 环境依赖# 1. node ^v11.2.0 https://nodejs.org/zh-cn/download/# 2. npm ^6.4.1git clone https://github.com/hyperf-admin/hyperf-admin-frontend.git vue-admincd vue-adminnpm inpm run dev</code></pre><pre class="language-none"><code class="language-none"># 打包npm run build:prodnpm run build:test</code></pre><h3 id="vue-config-js配置"><a href="#vue-config-js配置" class="headerlink" title="vue.config.js配置"></a>vue.config.js配置</h3><p>主要留意 <strong>module.exports</strong> 模块里的 <strong>devServer</strong> 和 <strong>proxy</strong> 配置要和hyperf对应上</p><pre class="language-vue" data-language="vue"><code class="language-vue">module.exports = { /** * You will need to set publicPath if you plan to deploy your site under a sub path, * for example GitHub Pages. If you plan to deploy your site to https://foo.github.io/bar/, * then publicPath should be set to "/bar/". * In most cases please use '/' !!! * Detail: https://cli.vuejs.org/config/#publicpath */ publicPath: '/', outputDir: 'dist', assetsDir: 'static', lintOnSave: process.env.NODE_ENV === 'development', productionSourceMap: false, devServer: { port: port, open: true, overlay: { warnings: false, errors: true }, proxy: { '/api': { target: 'http://127.0.0.1:9502', // 后台接口地址 ws: 'ws://127.0.0.1:9503', //如果要代理 websockets,配置这个参数 secure: false, // 如果是https接口,需要配置这个参数 changeOrigin: true, //是否跨域 pathRewrite:{// 重写路径 '^/api':'' } } }, // before: require('./mock/mock-server.js') }, ...</code></pre><h3 id="生产环境"><a href="#生产环境" class="headerlink" title="生产环境"></a>生产环境</h3><p>留意 <strong>.env.production</strong>文件配置的 <strong>VUE_APP_BASE_API</strong> 域名改为线上域名</p>]]></content>
<summary type="html"><p>近期有项目用到 <a href="https://github.com/hyperf-admin/hyperf-admin"><strong>hyperf-admin</strong></a>, 顺便学习记录一下基于官方的镜像开始构建到部署过程 </p>
<p>👉 <a href="https://hyperf.wiki/2.0/#/zh-cn/quick-start/install">hyperf官方地址</a></p></summary>
<category term="Docker" scheme="http://chuchu-z.com/categories/docker/"/>
<category term="hyperf" scheme="http://chuchu-z.com/categories/docker/hyperf/"/>
</entry>
<entry>
<title>RabbitMQ简介(待补充)</title>
<link href="http://chuchu-z.com/posts/lntroduction-to-RabbitMQ/"/>
<id>http://chuchu-z.com/posts/lntroduction-to-RabbitMQ/</id>
<published>2023-10-20T03:34:11.000Z</published>
<updated>2024-12-31T06:57:56.018Z</updated>
<content type="html"><![CDATA[<p>近期学习了MQ, 打算记录一下个人的理解, 具体内容待补充</p><span id="more"></span><h2 id="交换机类型"><a href="#交换机类型" class="headerlink" title="交换机类型"></a>交换机类型</h2><h2 id="死信交换机"><a href="#死信交换机" class="headerlink" title="死信交换机"></a>死信交换机</h2><h2 id="延迟交换机"><a href="#延迟交换机" class="headerlink" title="延迟交换机"></a>延迟交换机</h2><h2 id="发布者的确认模式-交换机可靠性"><a href="#发布者的确认模式-交换机可靠性" class="headerlink" title="发布者的确认模式(交换机可靠性)"></a>发布者的确认模式(交换机可靠性)</h2><ul><li><p>保证生产者消息能正确到达交换机</p></li><li><p>备用交换机</p></li><li><p>设置交换机持久化</p></li></ul><h2 id="发布者的返回模式-队列可靠性"><a href="#发布者的返回模式-队列可靠性" class="headerlink" title="发布者的返回模式(队列可靠性)"></a>发布者的返回模式(队列可靠性)</h2><ul><li>保证消息能从交换机正确到达队列</li><li>备用队列</li><li>设置队列持久化</li></ul><h2 id="交换机的属性"><a href="#交换机的属性" class="headerlink" title="交换机的属性"></a>交换机的属性</h2><h2 id="队列的属性"><a href="#队列的属性" class="headerlink" title="队列的属性"></a>队列的属性</h2><ul><li>消息在队列中不丢失, 设置消息持久化</li><li>消费者监听队列, 自动确认改为手动确认</li></ul>]]></content>
<summary type="html"><p>近期学习了MQ, 打算记录一下个人的理解, 具体内容待补充</p></summary>
<category term="RabbitMQ" scheme="http://chuchu-z.com/categories/rabbitmq/"/>
</entry>
<entry>
<title>Android studio 缺少lombok 导致使用EvalEx错误</title>
<link href="http://chuchu-z.com/posts/android-studio-use-lombok-and-evalex/"/>
<id>http://chuchu-z.com/posts/android-studio-use-lombok-and-evalex/</id>
<published>2023-09-20T03:34:11.000Z</published>
<updated>2024-12-31T06:57:55.964Z</updated>
<content type="html"><![CDATA[<p>另一篇中说了使用了代码混淆导致<strong>EvalEx</strong>扩展包失效, 其实在此之前, 还有一个问题, 那就是缺少了 <strong>lombok</strong> 库</p><p>不过该问题也比较有趣, 在debug的情况下打包生成app, 是不会触发错误提示缺少 <strong>lombok</strong> 库的, 一切都正常运行</p><p>在进行<code>release</code>打包的时候才会触发错误提示,但是在我写这篇文章时, 该问题已被解决, 具体错误描述没法放上来了</p><span id="more"></span><p>先看看ChatGPT是怎么介绍 <strong>lombok</strong> 的</p><blockquote><p>Lombok是一个Java库,它可以通过注解来简化Java类的开发,并减少样板代码(boilerplate code)的编写。Lombok的目标是让Java开发者能够更加高效地编写简洁的代码,同时减少冗长的getter和setter方法、构造函数以及其他常见的样板代码。</p><p>使用Lombok,你可以在Java类中添加一些注解,以自动生成常见的代码块,例如:</p><ol><li><code>@Getter</code>和<code>@Setter</code>:自动生成字段的getter和setter方法。</li><li><code>@ToString</code>:自动生成<code>toString()</code>方法。</li><li><code>@EqualsAndHashCode</code>:自动生成<code>equals()</code>和<code>hashCode()</code>方法。</li><li><code>@NoArgsConstructor</code>:自动生成无参构造函数。</li><li><code>@RequiredArgsConstructor</code>:自动生成包含必填字段的构造函数。</li><li><code>@AllArgsConstructor</code>:自动生成包含所有字段的构造函数。</li><li><code>@Data</code>:生成所有常见方法,如getter、setter、equals、hashCode等。</li><li><code>@Builder</code>:用于构建器模式,自动生成建造对象的方法。</li></ol><p>通过使用Lombok,开发者可以更专注于业务逻辑而不是编写重复的模板代码,从而提高代码的可读性和维护性。</p><p>要使用Lombok,你需要在项目中添加Lombok的依赖,并在你的Java类中引入Lombok的注解。然后,编译器会在编译时自动生成相关的代码。请注意,虽然Lombok可以提高开发效率,但它也可能会导致一些潜在的问题,因此在使用之前需要仔细了解其工作原理和限制。</p></blockquote><p>经过上面的解释可以得知<strong>lombok</strong>是什么之后, 就要为<strong>EvalEx</strong>补上这个库了, 在翻找了一圈之后</p><p>找到了该库的</p><p><strong>github</strong>地址: <a href="https://github.com/projectlombok/lombok">https://github.com/projectlombok/lombok</a></p><p>官方地址: <a href="https://projectlombok.org/all-versions">https://projectlombok.org/all-versions</a></p><p>顺便补上<strong>EvalEx的github</strong>地址 : <a href="https://github.com/ezylang/EvalEx">https://github.com/ezylang/EvalEx</a></p><p>因为我的Android studio 版本在<strong>Plugins</strong>里面搜是没有这个扩展可安装的, 只能手动安装</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/posts/android-studio-use-lombok-and-evalex/image-20230927162308870.png" alt title> </div> <div class="image-caption"></div> </figure><img src="/posts/android-studio-use-lombok-and-evalex/image-20230927162533916.png" alt="image-20230927162533916" style="zoom:80%;"><p>所以另外找到了两个如何安装<strong>lombok</strong>的方法</p><p>方法一: <a href="https://www.xjx100.cn/news/193686.html?action=onClick">https://www.xjx100.cn/news/193686.html?action=onClick</a></p><p>方法二: <a href="https://zhuanlan.zhihu.com/p/597777983?utm_id=0">https://zhuanlan.zhihu.com/p/597777983?utm_id=0</a></p><p>Lombok插件网站(jetbrains.com) : <a href="https://plugins.jetbrains.com/plugin/6317-lombok/versions">https://plugins.jetbrains.com/plugin/6317-lombok/versions</a></p><p>但是这上面2个方法呢, 因为版本的关系 比较麻烦, 要把压缩包改来改去, 没有直接能使用的</p><p>我就去<strong>stackoverflow</strong>上找了找 确实找到了一个有用的回答</p><p><a href="https://stackoverflow.com/questions/72658652/plugin-lombok-is-not-compatible-with-current-version-of-ide-because-it-requires">https://stackoverflow.com/questions/72658652/plugin-lombok-is-not-compatible-with-current-version-of-ide-because-it-requires</a></p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/posts/android-studio-use-lombok-and-evalex/image-20230927163141841.png" alt="image-20230927163141841" title> </div> <div class="image-caption">image-20230927163141841</div> </figure><p>给出了一个链接, 里面有 <strong>Lombok插件网站(jetbrains.com)</strong> 所没有的版本</p><p>Goto- <a href="https://github.com/mplushnikov/lombok-intellij-plugin/issues/1111">lombok-compatible-versions</a></p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/posts/android-studio-use-lombok-and-evalex/image-20230927163400379.png" alt="image-20230927163400379" title> </div> <div class="image-caption">image-20230927163400379</div> </figure><p>找到对应版本, 直接下载好压缩包之后, 在 Android studio 的 Plugins 里面 点击从磁盘里找到刚刚下载好的压缩包, 选择安装即可</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/posts/android-studio-use-lombok-and-evalex/image-20230927163810244.png" alt="image-20230927163810244" title> </div> <div class="image-caption">image-20230927163810244</div> </figure><p>完成安装</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/posts/android-studio-use-lombok-and-evalex/image-20230927164022059.png" alt="image-20230927164022059" title> </div> <div class="image-caption">image-20230927164022059</div> </figure><p>另外ChatGPT给我的建议是, 在项目目录下新建一个<strong>lombok.config</strong>文件, 并加入如下代码</p><p>以此来用来控制是否在 Lombok 生成的代码中添加 <code>@javax.annotation.Generated</code> 注解</p><pre class="language-none"><code class="language-none">lombok.addLombokGeneratedAnnotation = true</code></pre>]]></content>
<summary type="html"><p>另一篇中说了使用了代码混淆导致<strong>EvalEx</strong>扩展包失效, 其实在此之前, 还有一个问题, 那就是缺少了 <strong>lombok</strong> 库</p>
<p>不过该问题也比较有趣, 在debug的情况下打包生成app, 是不会触发错误提示缺少 <strong>lombok</strong> 库的, 一切都正常运行</p>
<p>在进行<code>release</code>打包的时候才会触发错误提示,但是在我写这篇文章时, 该问题已被解决, 具体错误描述没法放上来了</p></summary>
<category term="Android" scheme="http://chuchu-z.com/categories/android/"/>
</entry>
<entry>
<title>Android studio 使用R8 代码混淆 错误性缩减代码</title>
<link href="http://chuchu-z.com/posts/android-studio-use-r8-shrink-code/"/>
<id>http://chuchu-z.com/posts/android-studio-use-r8-shrink-code/</id>
<published>2023-09-20T02:44:11.000Z</published>
<updated>2024-12-31T06:57:55.966Z</updated>
<content type="html"><![CDATA[<p>最近开发了一个支持简单四则运算的计算器, 其中使用到了 <code>com.ezylang:EvalEx</code> 扩展包, </p><p>用于支持基本数学运算符的数学表达式, 开发阶段正常使用没有问题</p><p>然而当我开发完成打包签名时, 进行计算时就会出现错误</p><span id="more"></span><blockquote><p>Operatorannotation for com.ezylang.evalex.operators.arithmetic PrefixPlusOperator’not found</p></blockquote><img src="/posts/android-studio-use-r8-shrink-code/WeChat Image_20230920093908.jpg" style="zoom:30%;"><p>大概就是说找不到<code>com.ezylang.evalex</code>里面的某个类, 然而, 我很确定的是在我开发阶段是没有任何问题的</p><p>经过对比, 确认是在<code>release</code> 配置中启用了代码混淆的问题, 先来看看官方对代码混淆的解释 👉 <a href="https://developer.android.google.cn/studio/build/shrink-code?hl=zh-cn#enable">官方地址</a></p><img src="/posts/android-studio-use-r8-shrink-code/image-20230920095227577.png" alt="image-20230920095227577" style="zoom:100%;float:left;"><p>可以看出, R8只做了3件事</p><ul><li>代码/资源缩减</li><li>混淆</li><li>优化</li></ul><p>其中, 我们重点关注<strong>代码缩减</strong>这个步骤</p><img src="/posts/android-studio-use-r8-shrink-code/image-20230920101003148.png" alt="image-20230920101003148" style="zoom:100%;float:left;"><img src="/posts/android-studio-use-r8-shrink-code/tree-shaking.png" alt="img" style="zoom:60%;"><p>有意思的是, 后面还有一段说明, 表示: <strong>在某些情况下,R8 很难做出正确判断,因而可能会移除应用实际上需要的代码</strong></p><img src="/posts/android-studio-use-r8-shrink-code/image-20230920101319712.png" alt="image-20230920101319712" style="zoom:100%;float:left;"><p>那么问题就很清晰了, 大概率是R8在做代码缩减时, 把 <code>com.ezylang:EvalEx</code>扩展包里我需要用到的东西当成无用代码给删掉了</p><p>so 👇 我们此时只需要在 <code>proguard-rules.pro</code> 文件, 加上一行, 表示保留<code>com.ezylang.evalex</code>包下的全部代码</p><blockquote><p>-keep class com.ezylang.evalex.** { *; }</p></blockquote><p>再次编译代码后, 四则运算计算器顺利执行</p><p>其实问题并不难, 但是若一开始被报错的内容所迷惑, 无从得知是R8的代码混淆造成的问题, 排查方向错了, </p><p>错误地把矛头指向<code>com.ezylang.evalex</code>, 可能在debug的路上越走越远, 最终放弃使用<code>com.ezylang.evalex</code>。 人生亦是如此🍺</p><p>PS: 补上 <code>build.gradle.kts</code>文件, 在<code>buildTypes</code> 中开启代码混淆配置, 完美收官💻</p><pre class="language-none"><code class="language-none"> buildTypes { release { isMinifyEnabled = true // 启用代码混淆// isShrinkResources = true // 启用资源缩减 proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" ) signingConfig = signingConfigs.getByName("release") } debug { isMinifyEnabled = false // 不启用代码混淆// isShrinkResources = true // 启用资源缩减 proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" ) signingConfig = signingConfigs.getByName("debug") } } signingConfigs { create("release") { keyAlias = "key0" keyPassword = "pwd" storeFile = file("D:\\Android\\Projects\\pwd.jks") storePassword = "pwd" } } </code></pre>]]></content>
<summary type="html"><p>最近开发了一个支持简单四则运算的计算器, 其中使用到了 <code>com.ezylang:EvalEx</code> 扩展包, </p>
<p>用于支持基本数学运算符的数学表达式, 开发阶段正常使用没有问题</p>
<p>然而当我开发完成打包签名时, 进行计算时就会出现错误</p></summary>
<category term="Android" scheme="http://chuchu-z.com/categories/android/"/>
</entry>
<entry>
<title>Install Python3 and OpenSSL</title>
<link href="http://chuchu-z.com/posts/install-python3/"/>
<id>http://chuchu-z.com/posts/install-python3/</id>
<published>2023-07-18T08:31:05.000Z</published>
<updated>2024-12-31T06:57:56.018Z</updated>
<content type="html"><![CDATA[<p>因为有个项目要用到 Python 爬取直播间主播和弹幕数据, 所以记录一下安装过程以及途中遇到的问题</p><span id="more"></span><p>先查看当前 Python 版本是2.7的, 后面要重新安装 Python3, 如果还没有安装过后面就更省事了</p><blockquote><p>python –version</p><p>#输出为 Python 2.7.16</p></blockquote><h2 id="OpenSSL-Install"><a href="#OpenSSL-Install" class="headerlink" title="OpenSSL Install"></a>OpenSSL Install</h2><p>#安装py3新版本之前先安装openssl, 否则后面缺少ssl又需要重装, 如果 /usr/local 目录下已经有 openssl 文件夹,先把openssl 改名为 opensslbak 备份, 防止后面出现问题能恢复</p><blockquote><p>cd /usr/local</p><p>mv openssl opensslbak</p><p>wget <a href="https://www.openssl.org/source/openssl-3.0.2.tar.gz">https://www.openssl.org/source/openssl-3.0.2.tar.gz</a> –no-check-certificate</p><p>tar -zxvf openssl-3.0.2.tar.gz</p><p>cd openssl-3.0.2/</p><p> ./Configure –prefix=/usr/local/openssl</p><p>#一般上面命令都会失败报错:Can‘t locate IPC/Cmd.pm in xxx</p><p>yum install -y perl-CPAN</p><p>perl -MCPAN -e shell</p><p>#进入后第一步选yes,第二步选manual,第三步选yes,出现 cpan[1]> 就可以了</p><p>install IPC/Cmd.pm</p><p>#按Ctrl+D退出cpan,重新执行./Configure –prefix=/usr/local/openssl</p><p>./Configure –prefix=/usr/local/openssl</p><p>make && make install</p><p>cd /usr/local/openssl</p><p>cp -rf /usr/local/openssl/lib64 /usr/local/openssl/lib</p></blockquote><h2 id="Python3-install"><a href="#Python3-install" class="headerlink" title="Python3 install"></a>Python3 install</h2><blockquote><p>cd ~</p><p>wget <a href="https://www.python.org/ftp/python/3.12.1/Python-3.12.1.tar.xz">https://www.python.org/ftp/python/3.12.1/Python-3.12.1.tar.xz</a></p><p>tar -xvf Python-3.12.1.tar.xz</p><p>yum update -y</p><p>yum install -y zlib-devel bzip2-devel libffi-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc make gcc gcc-c++</p><p>cd Python-3.12.1/</p><p>./configure –prefix=/usr/local/python3 –with-openssl=/usr/local/openssl –with-openssl-rpath=auto</p><p>#3个并发任务</p><p>make -j3 && make install</p><p>cd /usr/local/bin/</p><p>#把原有的python2改成python.bak</p><p>mv /usr/bin/python /usr/bin/python.bak</p><p>建立软链接</p><p>ln -s /usr/local/bin/python3 /usr/bin/python</p><p>python –version</p><p>#升级python版本之后将由默认的python指向了python3,yum不能正常使用,需要更改2个配置文件</p><p>vim /usr/bin/yum</p><p>vim /usr/libexec/urlgrabber-ext-down</p><p>2个文件都是把开头第一行的 #!/usr/bin/python => #!/usr/bin/python2.7</p></blockquote><p>注: 如果遇到了 php 程序正在使用openssl, 新安装的openssl缺少文件导致php那边报错<br>看具体缺少哪个文件, 去原来的 opensslbak 文件夹里复制过来到现有的openssl对应的目录下<br>然后重启一下Nginx和php就行了</p><h2 id="pip-Install"><a href="#pip-Install" class="headerlink" title="pip Install"></a>pip Install</h2><blockquote><p>pip install requests urllib3 pymysql websocket websocket-client mysql-connector-python pytz python-dotenv</p></blockquote><h2 id="USE"><a href="#USE" class="headerlink" title="USE"></a>USE</h2><blockquote><p>python LiveChatCrawler.py</p></blockquote><h2 id="Error"><a href="#Error" class="headerlink" title="Error"></a>Error</h2><blockquote><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token number">1</span>. pip is configured with locations that require TLS/SSL<span class="token function">mkdir</span> <span class="token parameter variable">-p</span> ~/.pip<span class="token function">vim</span> ~/.pip/pip.conf<span class="token comment"># 修改镜像源为阿里云</span><span class="token punctuation">[</span>global<span class="token punctuation">]</span>index-url <span class="token operator">=</span> http://mirrors.aliyun.com/pypi/simple/<span class="token punctuation">[</span>install<span class="token punctuation">]</span>trusted-host <span class="token operator">=</span> mirrors.aliyun.com</code></pre></blockquote><p>本文参考 <a href="https://blog.csdn.net/Yaphets_dan/article/details/129421953"> CSDN 文章 => Caused by SSLError(“Can‘t connect to HTTPS URL because the SSL module is not available.“</a></p><p>且在原基础上根据实际情况有所改动</p>]]></content>
<summary type="html"><p>因为有个项目要用到 Python 爬取直播间主播和弹幕数据, 所以记录一下安装过程以及途中遇到的问题</p></summary>
<category term="Python" scheme="http://chuchu-z.com/categories/python/"/>
</entry>
<entry>
<title>利用 AutoHotKey 实现 win10 多显示器(扩展模式)快速切换</title>
<link href="http://chuchu-z.com/posts/autohotkey-windows/"/>
<id>http://chuchu-z.com/posts/autohotkey-windows/</id>
<published>2023-05-25T09:15:04.000Z</published>
<updated>2024-12-31T06:57:56.013Z</updated>
<content type="html"><![CDATA[<blockquote><p>在日常办公中我们经常会使用到外接显示屏来辅佐我们 提高办公效率</p><p>然而多显示屏每次切换屏幕都要用鼠标来移动切换, 对鼠标的依赖非常重且非常麻烦😡</p><p>尤其是我左边显示屏是 <strong>IDE</strong> 或者 <strong>shell</strong> 终端, 右边是浏览器</p><p>于是乎在知乎上看到一篇这样的文章👇</p></blockquote><span id="more"></span><h2 id="MoveMouseToMonitor"><a href="#MoveMouseToMonitor" class="headerlink" title="MoveMouseToMonitor"></a>MoveMouseToMonitor</h2><p><a href="https://www.zhihu.com/question/50002939/answer/2482798775">请问win10接双显示器(扩展模式)怎么把鼠标游标切换到第二台显示器上?</a></p><p>看完这篇文章瞬间就觉得它能够完美解决我的问题, 于是乎我安装了答主分享的 <strong>MoveMouseToMonitor.exe</strong> 工具</p><p>然而使用过后似乎仍不能满足我的需求, 因为它仅仅实现了鼠标的光标由 <strong>A显示屏</strong> 👉 <strong>B显示屏</strong> 的移动</p><p>而实际的聚焦效果仍然保留在原来的 <strong>A显示屏</strong> 上</p><p>通俗易懂来讲就是 <strong>鼠标的聚焦</strong> 和 <strong>键盘的聚焦</strong> 是两码事</p><p>这样就导致我的鼠标光标从 <strong>shell</strong> 终端 或者 <strong>IDE</strong> 切换到浏览器后</p><p><strong>输入</strong>键盘时, 实际的<strong>输出</strong>仍然会停留在 <strong>shell</strong> 终端 或者 <strong>IDE</strong> 的上</p><h2 id="MoveMouseToMonitor-V2-0"><a href="#MoveMouseToMonitor-V2-0" class="headerlink" title="MoveMouseToMonitor V2.0"></a>MoveMouseToMonitor V2.0</h2><p>这。。。实现了但没完全实现我想要的效果😂</p><p>于是我就花了亿点点时间研究了下 <strong>AutoHotKey</strong> 的语法和这个<strong>MoveMouseToMonitor.exe</strong> 程序的源代码</p><p>然后再此基础上做了一点点改动, 具体改动为当执行完 <strong>PerformMove</strong> 函数成功移动鼠标后</p><p>创建一个 <strong>ActivateWindowByMousePosition</strong> 函数, 获取当前鼠标位置的窗口 <strong>title</strong></p><p><strong>WinActivate</strong> 会根据鼠标窗口的 <strong>title</strong> 来激活目标窗口, 把键盘的聚焦也切换到该窗口, 从而真正实现切换并激活窗口👍</p><pre class="language-autohotkey" data-language="autohotkey"><code class="language-autohotkey"><span class="token function">PerformMove</span><span class="token punctuation">(</span>MoveMonNum<span class="token punctuation">,</span> OffX<span class="token punctuation">,</span> OffY<span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">global</span> MoveX<span class="token punctuation">,</span> MoveY <span class="token command selector">Gosub</span><span class="token punctuation">,</span> CheckNumMonsChanged RestoreDPI <span class="token operator">:=</span> <span class="token builtin">DllCall</span><span class="token punctuation">(</span><span class="token string">"SetThreadDpiAwarenessContext"</span><span class="token punctuation">,</span> <span class="token string">"ptr"</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token string">"ptr"</span><span class="token punctuation">)</span> <span class="token command selector">SysGet</span><span class="token punctuation">,</span> Coordinates<span class="token variable">%MoveMonNum%</span><span class="token punctuation">,</span> Monitor<span class="token punctuation">,</span> <span class="token variable">%MoveMonNum%</span> <span class="token symbol">Left</span> <span class="token operator">:=</span> Coordinates<span class="token variable">%MoveMonNum%</span><span class="token symbol">Left</span> <span class="token symbol">Right</span> <span class="token operator">:=</span> Coordinates<span class="token variable">%MoveMonNum%</span><span class="token symbol">Right</span> <span class="token keyword">Top</span> <span class="token operator">:=</span> Coordinates<span class="token variable">%MoveMonNum%</span><span class="token keyword">Top</span> Bottom <span class="token operator">:=</span> Coordinates<span class="token variable">%MoveMonNum%</span>Bottom <span class="token keyword">If</span> <span class="token punctuation">(</span>OffX <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span> MoveX <span class="token operator">:=</span> <span class="token symbol">Left</span> <span class="token operator">+</span> <span class="token punctuation">(</span><span class="token builtin">Floor</span><span class="token punctuation">(</span><span class="token number">0.5</span> <span class="token operator">*</span> <span class="token punctuation">(</span><span class="token symbol">Right</span> <span class="token operator">-</span> <span class="token symbol">Left</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">Else</span> MoveX <span class="token operator">:=</span> <span class="token symbol">Left</span> <span class="token operator">+</span> OffX <span class="token keyword">If</span> <span class="token punctuation">(</span>OffY <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span> MoveY <span class="token operator">:=</span> <span class="token keyword">Top</span> <span class="token operator">+</span> <span class="token punctuation">(</span><span class="token builtin">Floor</span><span class="token punctuation">(</span><span class="token number">0.5</span> <span class="token operator">*</span> <span class="token punctuation">(</span>Bottom <span class="token operator">-</span> <span class="token keyword">Top</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">Else</span> MoveY <span class="token operator">:=</span> <span class="token keyword">Top</span> <span class="token operator">+</span> OffY <span class="token builtin">DllCall</span><span class="token punctuation">(</span><span class="token string">"SetCursorPos"</span><span class="token punctuation">,</span> <span class="token string">"int"</span><span class="token punctuation">,</span> MoveX<span class="token punctuation">,</span> <span class="token string">"int"</span><span class="token punctuation">,</span> MoveY<span class="token punctuation">)</span> <span class="token command selector">Sleep</span><span class="token punctuation">,</span> <span class="token number">10</span> <span class="token builtin">DllCall</span><span class="token punctuation">(</span><span class="token string">"SetCursorPos"</span><span class="token punctuation">,</span> <span class="token string">"int"</span><span class="token punctuation">,</span> MoveX<span class="token punctuation">,</span> <span class="token string">"int"</span><span class="token punctuation">,</span> MoveY<span class="token punctuation">)</span> <span class="token builtin">DllCall</span><span class="token punctuation">(</span><span class="token string">"SetThreadDpiAwarenessContext"</span><span class="token punctuation">,</span> <span class="token string">"ptr"</span><span class="token punctuation">,</span> RestoreDPI<span class="token punctuation">,</span> <span class="token string">"ptr"</span><span class="token punctuation">)</span> <span class="token command selector">Gosub</span><span class="token punctuation">,</span> ActivateWindowByMousePosition <span class="token command selector">Return</span><span class="token punctuation">}</span><span class="token tag">ActivateWindowByMousePosition</span><span class="token punctuation">:</span> <span class="token command selector">MouseGetPos</span><span class="token punctuation">,</span> <span class="token punctuation">,</span> <span class="token punctuation">,</span> <span class="token keyword">id</span><span class="token punctuation">,</span> <span class="token command selector">control</span> <span class="token command selector">WinGetTitle</span><span class="token punctuation">,</span> title<span class="token punctuation">,</span> <span class="token keyword">ahk_id</span> <span class="token variable">%id%</span> <span class="token command selector">WinActivate</span><span class="token punctuation">,</span> <span class="token variable">%title%</span> <span class="token command selector">Return</span></code></pre><h3 id="Github传送门👇"><a href="#Github传送门👇" class="headerlink" title="Github传送门👇"></a>Github传送门👇</h3><h3 id="https-github-com-chuchu-z-MoveMouseToMonitorV6"><a href="#https-github-com-chuchu-z-MoveMouseToMonitorV6" class="headerlink" title="https://github.com/chuchu-z/MoveMouseToMonitorV6"></a><a href="https://github.com/chuchu-z/MoveMouseToMonitorV6">https://github.com/chuchu-z/MoveMouseToMonitorV6</a></h3>]]></content>
<summary type="html"><blockquote>
<p>在日常办公中我们经常会使用到外接显示屏来辅佐我们 提高办公效率</p>
<p>然而多显示屏每次切换屏幕都要用鼠标来移动切换, 对鼠标的依赖非常重且非常麻烦😡</p>
<p>尤其是我左边显示屏是 <strong>IDE</strong> 或者 <strong>shell</strong> 终端, 右边是浏览器</p>
<p>于是乎在知乎上看到一篇这样的文章👇</p>
</blockquote></summary>
<category term="Other" scheme="http://chuchu-z.com/categories/other/"/>
</entry>
<entry>
<title>Hexo-Blog Docker搭建本地环境与持续集成</title>
<link href="http://chuchu-z.com/posts/hexo-blog-build/"/>
<id>http://chuchu-z.com/posts/hexo-blog-build/</id>
<published>2023-05-22T09:59:58.000Z</published>
<updated>2024-12-31T06:57:56.016Z</updated>
<content type="html"><![CDATA[<h1 id="Hexo-Blog-indigo-hexo6"><a href="#Hexo-Blog-indigo-hexo6" class="headerlink" title="Hexo-Blog (indigo-hexo6)"></a>Hexo-Blog (indigo-hexo6)</h1><p> 该博客使用了 <a href="https://docs.github.com/zh/pages/quickstart">GitHub Pages</a> + <a href="https://hexo.io/zh-cn/">Hexo</a> + <a href="https://github.com/chuchu-z/hexo-theme-indigo">indigo-hexo6 主题</a> 搭建</p><p><code>GitHub Pages</code> 允许我们 创建以自己用户名开头的<code>username.github.io</code>仓库用来搭建自己的静态页面网站或者博客</p><p>而 <code>Hexo</code> 本身就是一款支持 Markdown 静态化博客框架 有多种主题可供选择 并且上手简单 刚好契合我的需求</p><span id="more"></span><p>另外为了解决平时在写好文章想先本地预览</p><p>但是又不在自己电脑旁边或者使用公司电脑的时候要重新安装部署一遍 <code>nodejs </code> 和 <code>hexo</code> 这些东西</p><p>所以增加了<code>docker</code>来解决环境的问题</p><p>使用 <code>Dockerfile</code> + <code>docker-compose</code> 文件</p><h3 id="Dockerfile"><a href="#Dockerfile" class="headerlink" title="Dockerfile"></a>Dockerfile</h3><pre class="language-docker" data-language="docker"><code class="language-docker"><span class="token instruction"><span class="token keyword">FROM</span> node:14 <span class="token keyword">AS</span> builder</span><span class="token instruction"><span class="token keyword">WORKDIR</span> /app</span><span class="token instruction"><span class="token keyword">COPY</span> . .</span><span class="token instruction"><span class="token keyword">RUN</span> npm install --no-fund && npx hexo clean && npx hexo generate</span><span class="token instruction"><span class="token keyword">FROM</span> nginx:alpine</span><span class="token instruction"><span class="token keyword">WORKDIR</span> /usr/share/nginx/html</span><span class="token instruction"><span class="token keyword">COPY</span> <span class="token options"><span class="token property">--from</span><span class="token punctuation">=</span><span class="token string">builder</span></span> /app/public /usr/share/nginx/html</span><span class="token instruction"><span class="token keyword">EXPOSE</span> 8080</span></code></pre><blockquote><p>提醒</p><p>在中国大陆由于某些众所周知的网络原因, <code>npm install</code> 命令有时候会失败, 可以多试几次, 也可以使用国内镜像或者科学上网安装</p></blockquote><h3 id="docker-compose"><a href="#docker-compose" class="headerlink" title="docker-compose"></a>docker-compose</h3><pre class="language-none"><code class="language-none">version: '3'services: hexo: build: context: . dockerfile: Dockerfile image: chuchuzz426/blog-hexo:1.0 ports: - "8080:80"</code></pre><p>如此 <code>git clone</code> 下来的时候 能立马部署出一套本地环境</p><p>使用简单, 开袋即食😋</p><pre class="language-none"><code class="language-none"># 拉取src分支源码git clone -b src [email protected]:chuchu-z/chuchu-z.github.io.git# 在项目目录执行docker-compose build --no-cache && docker-compose up</code></pre><h3 id="然后就可以打开-http-127-0-0-1-8080-预览啦✨"><a href="#然后就可以打开-http-127-0-0-1-8080-预览啦✨" class="headerlink" title="然后就可以打开 http://127.0.0.1:8080/ 预览啦✨"></a>然后就可以打开 <a href="http://127.0.0.1:8080/">http://127.0.0.1:8080/</a> 预览啦✨</h3><h1 id="持续集成自动部署"><a href="#持续集成自动部署" class="headerlink" title="持续集成自动部署"></a>持续集成自动部署</h1><p>为了发布文章<code>push</code> 到 <code>src</code> 分支后能自动更新到博客, 使用了 <code>GitHub Actions</code> 来实现自动部署</p><p>通过使用 <code>GitHub Actions</code>,我们可以实现自动化的软件开发流程,提高开发效率和代码质量</p><p>它还可以帮助团队协同工作,确保代码的集成和部署过程更加可靠和一致</p><pre class="language-yaml" data-language="yaml"><code class="language-yaml"><span class="token comment"># Action 的名字</span><span class="token key atrule">name</span><span class="token punctuation">:</span> Hexo Auto Deploy<span class="token key atrule">on</span><span class="token punctuation">:</span> <span class="token comment"># 触发条件1:src 分支收到 push 后执行任务。</span> <span class="token key atrule">push</span><span class="token punctuation">:</span> <span class="token key atrule">branches</span><span class="token punctuation">:</span> <span class="token punctuation">-</span> src <span class="token comment"># 触发条件2:手动按钮</span> <span class="token key atrule">workflow_dispatch</span><span class="token punctuation">:</span><span class="token comment"># 这里放环境变量,需要替换成你自己的</span><span class="token key atrule">env</span><span class="token punctuation">:</span> <span class="token comment"># Hexo 编译后使用此 git 用户部署到 github 仓库</span> <span class="token key atrule">GIT_USER</span><span class="token punctuation">:</span> chuchu<span class="token punctuation">-</span>z <span class="token comment"># Hexo 编译后使用此 git 邮箱部署到 github 仓库</span> <span class="token key atrule">GIT_EMAIL</span><span class="token punctuation">:</span> [email protected] <span class="token comment"># Hexo 编译后要部署的 github 仓库</span> <span class="token key atrule">GIT_DEPLOY_REPO</span><span class="token punctuation">:</span> chuchu<span class="token punctuation">-</span>z/chuchu<span class="token punctuation">-</span>z.github.io <span class="token comment"># Hexo 编译后要部署到的分支</span> <span class="token key atrule">GIT_DEPLOY_BRANCH</span><span class="token punctuation">:</span> master<span class="token key atrule">jobs</span><span class="token punctuation">:</span> <span class="token key atrule">build</span><span class="token punctuation">:</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> Build on node $<span class="token punctuation">{</span><span class="token punctuation">{</span> matrix.node_version <span class="token punctuation">}</span><span class="token punctuation">}</span> and $<span class="token punctuation">{</span><span class="token punctuation">{</span> matrix.os <span class="token punctuation">}</span><span class="token punctuation">}</span> <span class="token key atrule">runs-on</span><span class="token punctuation">:</span> ubuntu<span class="token punctuation">-</span>latest <span class="token key atrule">if</span><span class="token punctuation">:</span> github.event.repository.owner.id == github.event.sender.id <span class="token key atrule">strategy</span><span class="token punctuation">:</span> <span class="token key atrule">matrix</span><span class="token punctuation">:</span> <span class="token key atrule">os</span><span class="token punctuation">:</span> <span class="token punctuation">[</span>ubuntu<span class="token punctuation">-</span>latest<span class="token punctuation">]</span> <span class="token key atrule">node_version</span><span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token number">14</span><span class="token punctuation">]</span> <span class="token key atrule">steps</span><span class="token punctuation">:</span> <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> Checkout <span class="token key atrule">uses</span><span class="token punctuation">:</span> actions/checkout@v2 <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> Checkout deploy repo <span class="token key atrule">uses</span><span class="token punctuation">:</span> actions/checkout@v2 <span class="token key atrule">with</span><span class="token punctuation">:</span> <span class="token key atrule">repository</span><span class="token punctuation">:</span> $<span class="token punctuation">{</span><span class="token punctuation">{</span> env.GIT_DEPLOY_REPO <span class="token punctuation">}</span><span class="token punctuation">}</span> <span class="token key atrule">ref</span><span class="token punctuation">:</span> $<span class="token punctuation">{</span><span class="token punctuation">{</span> env.GIT_DEPLOY_BRANCH <span class="token punctuation">}</span><span class="token punctuation">}</span> <span class="token key atrule">path</span><span class="token punctuation">:</span> .deploy_git <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> Use Node.js $<span class="token punctuation">{</span><span class="token punctuation">{</span> matrix.node_version <span class="token punctuation">}</span><span class="token punctuation">}</span> <span class="token key atrule">uses</span><span class="token punctuation">:</span> actions/setup<span class="token punctuation">-</span>node@v1 <span class="token key atrule">with</span><span class="token punctuation">:</span> <span class="token key atrule">node-version</span><span class="token punctuation">:</span> $<span class="token punctuation">{</span><span class="token punctuation">{</span> matrix.node_version <span class="token punctuation">}</span><span class="token punctuation">}</span> <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> Configuration environment <span class="token key atrule">env</span><span class="token punctuation">:</span> <span class="token key atrule">HEXO_DEPLOY_PRI</span><span class="token punctuation">:</span> $<span class="token punctuation">{</span><span class="token punctuation">{</span>secrets.HEXO_DEPLOY_PRI<span class="token punctuation">}</span><span class="token punctuation">}</span> <span class="token key atrule">run</span><span class="token punctuation">:</span> <span class="token punctuation">|</span><span class="token scalar string"> sudo timedatectl set-timezone "Asia/Shanghai" mkdir -p ~/.ssh/ echo "$HEXO_DEPLOY_PRI" > ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts # coding 已取消同步 ssh-keyscan -t rsa e.coding.net >> ~/.ssh/known_hosts ssh-keyscan -t rsa gitee.com >> ~/.ssh/known_hosts git config --global user.name $GIT_USER git config --global user.email $GIT_EMAIL</span> <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> Install dependencies <span class="token key atrule">run</span><span class="token punctuation">:</span> npm install <span class="token punctuation">-</span><span class="token punctuation">-</span>no<span class="token punctuation">-</span>fund <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> Deploy hexo <span class="token key atrule">run</span><span class="token punctuation">:</span> <span class="token punctuation">|</span><span class="token scalar string"> npm run deploy</span></code></pre><p>触发条件为每当有<code>push</code> 代码的时候将自动按照<code>.github/workflows/deploy.yml</code>下的配置文件构造部署环境</p><p>相当于帮我们执行了 <code>hexo generate</code> 和 <code>hexo deploy</code> 然后<code>hexo deploy</code>会根据项目根目录下的<code>_config.yml</code>配置文件</p><p>把编译好的静态文件更新到以自己用户名开头的<code>username.github.io</code>仓库的 <code>master</code> 分支上</p><p>这样就完成了自动化部署啦</p><pre class="language-yaml" data-language="yaml"><code class="language-yaml"><span class="token key atrule">deploy</span><span class="token punctuation">:</span> <span class="token key atrule">type</span><span class="token punctuation">:</span> git <span class="token comment"># repo: [email protected]:chuchu-z/chuchu-z.github.io.git #构建机器上没有配置 ssh 免密,所以使用https</span> <span class="token key atrule">repo</span><span class="token punctuation">:</span> https<span class="token punctuation">:</span>//[email protected]/chuchu<span class="token punctuation">-</span>z/chuchu<span class="token punctuation">-</span>z.github.io.git <span class="token key atrule">branch</span><span class="token punctuation">:</span> master <span class="token key atrule">message</span><span class="token punctuation">:</span> GitHub Actions 自动部署<span class="token punctuation">:</span><span class="token punctuation">{</span><span class="token punctuation">{</span> now('YYYY<span class="token punctuation">-</span>MM<span class="token punctuation">-</span>DD HH<span class="token punctuation">:</span>mm<span class="token punctuation">:</span>ss') <span class="token punctuation">}</span><span class="token punctuation">}</span></code></pre><h2 id="👉-博客地址-http-chuchu-z-com"><a href="#👉-博客地址-http-chuchu-z-com" class="headerlink" title="👉 博客地址: http://chuchu-z.com"></a>👉 博客地址: <a href="http://chuchu-z.com/">http://chuchu-z.com</a></h2><h2 id="👉-GitHub地址-https-github-com-chuchu-z-chuchu-z-github-io"><a href="#👉-GitHub地址-https-github-com-chuchu-z-chuchu-z-github-io" class="headerlink" title="👉 GitHub地址: https://github.com/chuchu-z/chuchu-z.github.io"></a>👉 GitHub地址: <a href="https://github.com/chuchu-z/chuchu-z.github.io">https://github.com/chuchu-z/chuchu-z.github.io</a></h2>]]></content>
<summary type="html"><h1 id="Hexo-Blog-indigo-hexo6"><a href="#Hexo-Blog-indigo-hexo6" class="headerlink" title="Hexo-Blog (indigo-hexo6)"></a>Hexo-Blog (indigo-hexo6)</h1><p> 该博客使用了 <a href="https://docs.github.com/zh/pages/quickstart">GitHub Pages</a> + <a href="https://hexo.io/zh-cn/">Hexo</a> + <a href="https://github.com/chuchu-z/hexo-theme-indigo">indigo-hexo6 主题</a> 搭建</p>
<p><code>GitHub Pages</code> 允许我们 创建以自己用户名开头的<code>username.github.io</code>仓库用来搭建自己的静态页面网站或者博客</p>
<p>而 <code>Hexo</code> 本身就是一款支持 Markdown 静态化博客框架 有多种主题可供选择 并且上手简单 刚好契合我的需求</p></summary>
<category term="Docker" scheme="http://chuchu-z.com/categories/docker/"/>
</entry>
<entry>
<title>[教程] Android Webview 开发(App内嵌web)</title>
<link href="http://chuchu-z.com/posts/android-webview-develop/"/>
<id>http://chuchu-z.com/posts/android-webview-develop/</id>
<published>2023-05-16T11:31:05.000Z</published>
<updated>2024-12-31T06:57:55.970Z</updated>
<content type="html"><![CDATA[<blockquote><p>自己花了2周的时间慢慢摸索出来的一点点经验, 网上教程很多, 但更多的是搬运或者年份比较久远的了, 借着着ChatGPT和网上的方法总算把项目搞定了, 打算把从开发到上架Google Play的全流程记录下来方便回顾总结, 同时希望对大家有一点点帮助。</p><span id="more"></span><p>另外安装 Android studio 教程就不出了, 实在是不想卸载了重新安装一遍, 需要安装教程的伙伴们可以参考知乎这位大佬写的教程 <a href="https://zhuanlan.zhihu.com/p/528196912">全网最全最细Android Studio 安装和使用教程</a> , 不过这个教程的第三步, <SDK的安装> 建议跳过, 直接看第四步 <Android模拟器的下载> , 因为现在新版本 Android studio 里面已经集成SDK安装了, 不需要去单独下载, 可能是这位大佬当时是旧版本还没有集成到。</p></blockquote><h2 id="一-创建项目"><a href="#一-创建项目" class="headerlink" title="一. 创建项目"></a>一. 创建项目</h2><p>选择 <code>Empty Activity</code></p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/posts/android-webview-develop/image-20230513175557001.png" alt title> </div> <div class="image-caption"></div> </figure><h3 id="1-Package-name"><a href="#1-Package-name" class="headerlink" title="1. Package name"></a>1. Package name</h3><p>Package name 尽量不要使用默认的 <code>com.example</code> 开头, 起个正经点的名字, 特别是如果后续想要打包发布到 <code>google paly</code> 上面的, <code>com.example</code> 开头是不会通过的, 到时候还得代码里各种改一遍包名, 然后还可能会有莫名其妙的缓存问题因为包名改了导致各种报错, 算是一个小小的坑, 尽量一开始定好就不要改动。</p><h3 id="2-Minimum-SDK"><a href="#2-Minimum-SDK" class="headerlink" title="2. Minimum SDK"></a>2. Minimum SDK</h3><p>关于SDK的选择, 尽量选择稍微低版本的SDK, 这样能支持的设备就更多一些, 如果是个人项目练习的可以随意, 如果公司项目的话尽量选择能支持多设备的, 一般能支持95%以上差不多可以了, 具体看公司要求, 本人这里选择的是API 28。</p><h3 id="3-Build-language"><a href="#3-Build-language" class="headerlink" title="3. Build language"></a>3. Build language</h3><p>构建语言选择, Kotlin 是 Android 开发的推荐语言,它提供了现代化的语言特性、更好的性能和良好的工具支持。而 Groovy 在 Android 开发中的使用相对较少,主要适用于特定场景或个人喜好。选择哪种语言取决于个人偏好、项目需求和团队情况 。本人推荐选择<code>Kotlin</code>, 选择完点击 <code>Finish</code> ,会自动进行项目初始化,耐心等待一会就好了 。</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/posts/android-webview-develop/image-20230515114344763.png" alt title> </div> <div class="image-caption"></div> </figure><h2 id="二-目录结构及重要文件"><a href="#二-目录结构及重要文件" class="headerlink" title="二. 目录结构及重要文件"></a>二. 目录结构及重要文件</h2><p>初始化好后, 可以点击左上角切换项目以什么形式展开, <code>Project</code>形式能更详细看到每个文件和目录, <code>Android</code>形式会简化很多不必要的文件夹,看起来更加简洁舒适 。目录结构介绍较长, 着急下一步安装的可以直接跳到第三步 <a href="#sdk">SDK安装</a> , 后续再回来看结构介绍。</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/posts/android-webview-develop/project.gif" alt title> </div> <div class="image-caption"></div> </figure><p>WebView 项目通常遵循以下目录结构:</p><pre class="language-prel" data-language="prel"><code class="language-prel">- app/ |- src/ | |- main/ | |- java/ | | |- com.example.app/ # 应用的代码 | | | |- MainActivity.java # 主Activity文件 | | | |- res/ | | |- layout/ # 布局文件 | | | |- activity_main.xml | | | | | |- values/ # 值资源文件 | | | |- strings.xml # 字符串资源文件 | | | |- AndroidManifest.xml # 应用程序清单文件 | | |- assets/ # WebView使用的本地资源 | | |- index.html # WebView入口HTML文件 | | |- css/ # CSS样式文件 | | |- js/ # JavaScript脚本文件 | | |- images/ # 图片文件 | |- ... |- build.gradle.kts # 项目的Gradle构建配置文件 |- ...</code></pre><h3 id="1-com-example-app"><a href="#1-com-example-app" class="headerlink" title="1. com.example.app"></a>1. com.example.app</h3><p>我们一般情况主要开发都是在<code>com.example.app</code>下面进行的, 主要代码基本都在这里, 这里说明一下, 如果是新版本的<code>Android studio</code>初始化的时候, 默认是使用<code>Kotlin</code> 语言进行开发的, 所以主Activity文件会是 <code>MainActivity.kt</code>而不是 <code>MainActivity.java</code>, 不管是<code>Kotlin</code>还是<code>Java</code>, 选择哪个作为应用的开发语言都可以的, 而且这两个语言是可以相互转换的, 用<code>Java</code>的话可以删掉<code>MainActivity.kt</code>, 自己新建 <code>MainActivity.java</code>。</p><blockquote><p>Kotlin 是一种现代的、静态类型的编程语言,与 Java 语言可以在 Android 开发中无缝集成。它提供了更简洁、安全、表达力强的语法,并具有许多特性和功能,可帮助开发者更高效地编写 Android 应用程序。</p></blockquote><h3 id="2-AndroidManifest-xml"><a href="#2-AndroidManifest-xml" class="headerlink" title="2. AndroidManifest.xml"></a>2. AndroidManifest.xml</h3><p><span style="color: #bf1d2c;"><strong>重要: <code>AndroidManifest.xml</code> 是 Android 应用程序的 核心配置文件,它描述了应用程序的基本信息、组件、权限和行为等。在开发 Android 应用程序时,清单文件的正确配置和使用非常重要,它直接影响应用程序的功能和行为。</strong></span></p><pre class="language-markup" data-language="markup"><code class="language-markup"><span class="token prolog"><?xml version="1.0" encoding="utf-8"?></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>manifest</span> <span class="token attr-name"><span class="token namespace">xmlns:</span>android</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://schemas.android.com/apk/res/android<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">xmlns:</span>tools</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>http://schemas.android.com/tools<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token comment"><!-- 权限声明:通过 <uses-permission> 元素,你可以声明应用程序需要的权限。Android 操作系统会在安装应用程序时向用户展示所请求的权限,并在用户同意后授予应用程序相应的权限。 --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>uses-permission</span> <span class="token attr-name"><span class="token namespace">android:</span>name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>android.permission.INTERNET<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>uses-permission</span> <span class="token attr-name"><span class="token namespace">android:</span>name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>android.permission.ACCESS_NETWORK_STATE<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>uses-permission</span> <span class="token attr-name"><span class="token namespace">android:</span>name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>android.permission.ACCESS_WIFI_STATE<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token comment"><!-- <application> 元素用于定义应用程序的全局配置和属性 --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>application</span> <span class="token attr-name"><span class="token namespace">android:</span>allowBackup</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>true<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">android:</span>dataExtractionRules</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>@xml/data_extraction_rules<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">android:</span>fullBackupContent</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>@xml/backup_rules<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">android:</span>icon</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>@mipmap/ic_launcher<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">android:</span>label</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>@string/app_name<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">android:</span>roundIcon</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>@mipmap/ic_launcher_round<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">android:</span>supportsRtl</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>true<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">android:</span>theme</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>@style/Theme.MyWebview<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">tools:</span>targetApi</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>31<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token comment"><!-- <activity> 元素用于声明应用程序的活动(Activity)。每个活动都需要在清单文件中进行声明,以便在应用程序中使用android:name: 指定活动的类名(默认MainActivity.java)android:theme:指定活动的主题样式--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>activity</span> <span class="token attr-name"><span class="token namespace">android:</span>name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>.MainActivity<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">android:</span>exported</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>true<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">android:</span>label</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>@string/app_name<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">android:</span>theme</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>@style/Theme.MyWebview<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token comment"><!-- 用于指定一个活动(Activity)作为应用程序打开时的主要入口点, 不可有多个, 多个的话安装app时桌面会出现多个应用图标 --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>intent-filter</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>action</span> <span class="token attr-name"><span class="token namespace">android:</span>name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>android.intent.action.MAIN<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>category</span> <span class="token attr-name"><span class="token namespace">android:</span>name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>android.intent.category.LAUNCHER<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>intent-filter</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>activity</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>application</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>manifest</span><span class="token punctuation">></span></span></code></pre><h3 id="3-res-目录"><a href="#3-res-目录" class="headerlink" title="3. res/ 目录"></a>3. res/ 目录</h3><p>在 Android 项目中的 <code>res/</code> 目录是用于存放资源文件的目录,其中包含了应用程序所需的各种资源,如布局文件、字符串、图像、颜色、样式等。这个目录是在 Android 项目创建时自动生成的,用于组织和管理应用程序的静态资源,在这些目录中,我们可以根据资源的类型和用途将相应的文件放置在相应的目录中,以便在代码中引用和使用这些资源。</p><p><code>res/</code> 目录通常包含以下子目录:</p><pre class="language-none"><code class="language-none">- res/ |- layout/# 用于存放布局文件,定义了应用程序的用户界面的组件和布局结构。 |- drawable/# 用于存放图像资源文件,如位图文件(.png、.jpg、.gif 等)或矢量图形文件(.xml)。 |- mipmap/# 用于存放应用程序图标的不同分辨率版本。通常包括 `mdpi`、`hdpi`、`xhdpi`、`xxhdpi`、`xxxhdpi` 等不同密度的图标文件。 |- values/# 用于存放资源值文件,如字符串、颜色、尺寸、样式等。包括 `strings.xml`、`colors.xml`、`dimens.xml`、`styles.xml`。 |- raw/ # 用于存放原始资源文件,如音频文件、视频文件、字体文件等。这些文件可以直接通过资源 ID 访问。 |- menu/ # 用于存放菜单资源文件,定义应用程序的菜单结构。 |- xml/ # 用于存放其他 XML 文件,如自定义视图、插件配置文件等。</code></pre><h3 id="4-build-gradle"><a href="#4-build-gradle" class="headerlink" title="4. build.gradle"></a>4. build.gradle</h3><p><code>build.gradle.kts</code> 是使用 Kotlin 脚本语言编写的 Android 项目的构建脚本文件,用于配置和管理项目的构建过程。如果一开始创建项目时选的是Groovy, 那么生成的就是 <code>build.gradle</code> 文件,两者相比, <code>build.gradle.kts</code> 提供了使用 Kotlin 语言进行更灵活、类型安全和可编程的构建配置。</p><p>在 <code>build.gradle.kts</code> 文件中,我们可以定义项目的依赖关系、插件应用、构建类型、任务配置等。</p><p><code>build.gradle.kts</code> 文件的基本结构:</p><pre class="language-kotlin" data-language="kotlin"><code class="language-kotlin"><span class="token comment">// 构建脚本的基本信息和配置</span>plugins <span class="token punctuation">{</span> <span class="token function">id</span><span class="token punctuation">(</span><span class="token string-literal singleline"><span class="token string">"com.android.application"</span></span><span class="token punctuation">)</span> version <span class="token string-literal singleline"><span class="token string">"7.0.0"</span></span> <span class="token comment">// 其他插件的应用</span><span class="token punctuation">}</span>android <span class="token punctuation">{</span> <span class="token comment">// Android 构建的配置</span> compileSdk <span class="token operator">=</span> <span class="token number">33</span> <span class="token comment">//应用程序的编译目标版本</span> defaultConfig <span class="token punctuation">{</span> applicationId <span class="token operator">=</span> <span class="token string-literal singleline"><span class="token string">"com.example.myapp"</span></span> minSdk <span class="token operator">=</span> <span class="token number">28</span> <span class="token comment">//最低支持的 Android 版本</span> targetSdk <span class="token operator">=</span> <span class="token number">33</span> <span class="token comment">//目标设备的 Android 版本</span> versionCode <span class="token operator">=</span> <span class="token number">1</span> versionName <span class="token operator">=</span> <span class="token string-literal singleline"><span class="token string">"1.0"</span></span> <span class="token punctuation">}</span> <span class="token comment">// 其他 Android 构建配置</span><span class="token punctuation">}</span>dependencies <span class="token punctuation">{</span> <span class="token comment">// 依赖关系配置</span> <span class="token function">implementation</span><span class="token punctuation">(</span><span class="token string-literal singleline"><span class="token string">"com.android.support:appcompat-v7:28.0.0"</span></span><span class="token punctuation">)</span> <span class="token comment">// 其他依赖项</span><span class="token punctuation">}</span><span class="token comment">// 自定义任务配置</span>tasks <span class="token punctuation">{</span> <span class="token comment">// 自定义任务的配置</span> <span class="token keyword">val</span> myTask <span class="token keyword">by</span> registering <span class="token punctuation">{</span> <span class="token comment">// 任务的配置</span> <span class="token punctuation">}</span> <span class="token comment">// 其他任务配置</span><span class="token punctuation">}</span></code></pre><h2 id="三-SDK安装"><a href="#三-SDK安装" class="headerlink" title="三. SDK安装"></a><a name="sdk" style="color: inherit;">三. SDK安装</a></h2><h3 id="1-SDK目录"><a href="#1-SDK目录" class="headerlink" title="1. SDK目录"></a>1. SDK目录</h3><p>在 Android 开发中,SDK Platforms 是用于开发和构建 Android 应用程序所需的 Android 平台版本。安装 SDK Platforms 是为了能够编译和运行应用程序的目标 Android 版本。例如,如果你开发的应用程序目标版本是 Android 10(API 级别 29),你应该选择安装对应的 Android 10 SDK Platforms。</p><p> 建议目录结构如下, 管理起来方便一些:</p><pre class="language-none"><code class="language-none">- d/ |- Android/ |- Projects# 项目目录,所有开发的项目可以放到此目录下 |- SDK# SDK目录 |- Studio# Android Studio 安装目录</code></pre><h3 id="2-环境变量配置"><a href="#2-环境变量配置" class="headerlink" title="2. 环境变量配置"></a>2. 环境变量配置</h3><p>点击我的电脑 -> 属性 -> 高级系统设置 -> 环境变量 -> 新建系统变量</p><pre class="language-none"><code class="language-none">创建2个系统变量ANDROID_SDK_ROOT => D:\Android\SDKANDROID_ADB => D:\Android\SDK\platform-tools</code></pre><p><img src="/posts/android-webview-develop/image-20230515192521267.png"></p><pre class="language-none"><code class="language-none">把刚创建的系统变量添加到Path变量中%ANDROID_SDK_ROOT%%ANDROID_ADB%</code></pre><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/posts/android-webview-develop/image-20230515192620190.png" alt title> </div> <div class="image-caption"></div> </figure><h3 id="3-SDK安装"><a href="#3-SDK安装" class="headerlink" title="3. SDK安装"></a>3. SDK安装</h3><p>点击左上角的 File -> Settings -> System Settings -> Android SDK, 安装目录可以像我这样, 如果我们的应用要在Android 10 运行就找到 Android 10 勾选上, 如果你的应用还要在其他Android版本上运行, 也可以把其他版本安装一下, 选完后点击<code>Apply</code> 耐心等待安装完成即可。</p><blockquote><p>注意: 后面安装虚拟设备的时候也是在SDK的基础上安装的</p><p>举例: 如果你没有安装Android 13的SDK, 那也没有办法安装和使用Android 13的虚拟设备, 另外安装虚拟设备时有的可能还需要用到 Google APIs 镜像的, 可以点击右下角的 Show Package Details 查看, 根据虚拟设备所需要的Google APIs 来勾选安装。</p></blockquote><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/posts/android-webview-develop/image-20230515183023944.png" alt title> </div> <div class="image-caption"></div> </figure><h3 id="4-SDK-Tools-安装"><a href="#4-SDK-Tools-安装" class="headerlink" title="4. SDK Tools 安装"></a>4. SDK Tools 安装</h3><ol><li>Android SDK Build-Tools:构建和编译Android应用程序所必需的工具集,包括编译器、调试器和其他构建工具。</li><li>Android SDK Platform-Tools:这是与Android设备通信、调试和管理的一组工具,如adb(Android Debug Bridge)、fastboot等。</li><li>Android Emulator:模拟Android设备的工具,用于在开发计算机上运行和测试Android应用程序。</li><li>Android Emulator Hypervisor Driver 和 Intelx6 Emulator Accelerator(HAXM installer) 都是加速 Android 模拟器用于提高 Android 模拟器性能的组件。</li><li>其他的非必选 各位实际项目需求来, 另外可能Android Studio版本不同, 下图的工具名称可能也有所不同甚至没有这个工具换成其他的替代了。</li></ol><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/posts/android-webview-develop/image-20230516103348480.png" alt title> </div> <div class="image-caption"></div> </figure><h2 id="四-虚拟设备安装"><a href="#四-虚拟设备安装" class="headerlink" title="四. 虚拟设备安装"></a>四. 虚拟设备安装</h2><h3 id="1-选择安装镜像"><a href="#1-选择安装镜像" class="headerlink" title="1. 选择安装镜像"></a>1. 选择安装镜像</h3><p>点击右上角的 <code>Device Manager</code>(手机机器人图标) -> Create Device (创建设备) , 在 <code>phone</code> 这一栏选择一个符合你要求的, 然后点击 <code>NEXT</code> 进入到具体得镜像选择,</p><p>选择好后继续点<code>NEXT</code>后再点击<code>Finish</code>等待安装完成就可以了</p><p>前面安装SDK时说过, 创建虚拟设备跟我们安装的SDK还有镜像有关, 在这里选择镜像的时候有的选项就会置灰不可选择, 因为你没有安装该虚拟设备所需要的Android SDK版本或者 镜像 </p><p><img src="/posts/android-webview-develop/create_device.gif"></p><h3 id="2-启动虚拟设备"><a href="#2-启动虚拟设备" class="headerlink" title="2. 启动虚拟设备"></a>2. 启动虚拟设备</h3><p>安装好之后, 如下图, 点击 <code>Actions</code> 即可启动虚拟设备</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/posts/android-webview-develop/start_device.gif" alt title> </div> <div class="image-caption"></div> </figure><h2 id="五-启动项目"><a href="#五-启动项目" class="headerlink" title="五. 启动项目"></a>五. 启动项目</h2><p>经过前面的铺垫, 现在终于可以进入开发阶段了, 如果前面一切顺利的话, 现在只需要点击一下右上角的<code>Run app</code> , 项目就会运行起来, 然后就可以在虚拟设备的界面上看到<code>Hello Android!</code></p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/posts/android-webview-develop/run_app.gif" alt title> </div> <div class="image-caption"></div> </figure>]]></content>
<summary type="html"><blockquote>
<p>自己花了2周的时间慢慢摸索出来的一点点经验, 网上教程很多, 但更多的是搬运或者年份比较久远的了, 借着着ChatGPT和网上的方法总算把项目搞定了, 打算把从开发到上架Google Play的全流程记录下来方便回顾总结, 同时希望对大家有一点点帮助。</p></blockquote></summary>
<category term="Android" scheme="http://chuchu-z.com/categories/android/"/>
</entry>
<entry>
<title>浅记冒泡排序及斐波那契数列优化点</title>
<link href="http://chuchu-z.com/posts/bubble-sort-and-fibonacci/"/>
<id>http://chuchu-z.com/posts/bubble-sort-and-fibonacci/</id>
<published>2023-02-16T11:04:13.000Z</published>
<updated>2024-12-31T06:57:56.013Z</updated>
<content type="html"><![CDATA[<h1 id="冒泡排序"><a href="#冒泡排序" class="headerlink" title="冒泡排序"></a>冒泡排序</h1><blockquote><p>一般的冒泡排序只能满足最基本的要求, 如果不加以优化, 还会多做无用功, 出现重复循环的无效排序。</p></blockquote><span id="more"></span><h4 id="常规冒泡排序"><a href="#常规冒泡排序" class="headerlink" title="常规冒泡排序**"></a>常规冒泡排序**</h4><pre class="language-php" data-language="php"><code class="language-php"><span class="token php language-php"><span class="token delimiter important"><?php</span><span class="token variable">$arr</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token operator">-</span><span class="token number">3</span><span class="token punctuation">,</span><span class="token operator">-</span><span class="token number">10</span><span class="token punctuation">,</span><span class="token number">4</span><span class="token punctuation">,</span><span class="token operator">-</span><span class="token number">5</span><span class="token punctuation">,</span><span class="token number">6</span><span class="token punctuation">,</span><span class="token number">7</span><span class="token punctuation">,</span><span class="token number">8</span><span class="token punctuation">,</span><span class="token number">12</span><span class="token punctuation">,</span><span class="token number">9</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token operator">-</span><span class="token number">11</span><span class="token punctuation">,</span><span class="token number">100</span><span class="token punctuation">,</span><span class="token operator">-</span><span class="token number">200</span><span class="token punctuation">,</span><span class="token number">300</span><span class="token punctuation">,</span><span class="token number">400</span><span class="token punctuation">,</span><span class="token number">500</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token variable">$len</span> <span class="token operator">=</span> <span class="token function">count</span><span class="token punctuation">(</span><span class="token variable">$arr</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">for</span><span class="token punctuation">(</span><span class="token variable">$i</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token variable">$i</span> <span class="token operator"><</span> <span class="token variable">$len</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token variable">$i</span><span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">for</span><span class="token punctuation">(</span><span class="token variable">$j</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token variable">$j</span> <span class="token operator"><</span> <span class="token variable">$len</span> <span class="token operator">-</span> <span class="token variable">$i</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token variable">$j</span><span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$arr</span><span class="token punctuation">[</span><span class="token variable">$j</span><span class="token punctuation">]</span> <span class="token operator">></span> <span class="token variable">$arr</span><span class="token punctuation">[</span><span class="token variable">$j</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$item</span> <span class="token operator">=</span> <span class="token variable">$arr</span><span class="token punctuation">[</span><span class="token variable">$j</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token variable">$arr</span><span class="token punctuation">[</span><span class="token variable">$j</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$arr</span><span class="token punctuation">[</span><span class="token variable">$j</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token variable">$arr</span><span class="token punctuation">[</span><span class="token variable">$j</span><span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$item</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token function">var_dump</span><span class="token punctuation">(</span><span class="token variable">$arr</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span></code></pre><h4 id="优化点1"><a href="#优化点1" class="headerlink" title="优化点1"></a>优化点1</h4><blockquote><p>如 <strong>[1,2,3,5,4 ]</strong> , 只需要排序一遍的, 我们可以增加标识位表示当前是有序或无序,已经是有序的情况可直接退出循环。</p></blockquote><pre class="language-php" data-language="php"><code class="language-php"><span class="token php language-php"><span class="token delimiter important"><?php</span><span class="token variable">$arr</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token operator">-</span><span class="token number">3</span><span class="token punctuation">,</span><span class="token operator">-</span><span class="token number">10</span><span class="token punctuation">,</span><span class="token number">4</span><span class="token punctuation">,</span><span class="token operator">-</span><span class="token number">5</span><span class="token punctuation">,</span><span class="token number">6</span><span class="token punctuation">,</span><span class="token number">7</span><span class="token punctuation">,</span><span class="token number">8</span><span class="token punctuation">,</span><span class="token number">12</span><span class="token punctuation">,</span><span class="token number">9</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token operator">-</span><span class="token number">11</span><span class="token punctuation">,</span><span class="token number">100</span><span class="token punctuation">,</span><span class="token operator">-</span><span class="token number">200</span><span class="token punctuation">,</span><span class="token number">300</span><span class="token punctuation">,</span><span class="token number">400</span><span class="token punctuation">,</span><span class="token number">500</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token variable">$len</span> <span class="token operator">=</span> <span class="token function">count</span><span class="token punctuation">(</span><span class="token variable">$arr</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token variable">$index</span> <span class="token operator">=</span> <span class="token variable">$len</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span><span class="token comment">//排序下限</span><span class="token variable">$maxIndex</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">//排序上限</span><span class="token keyword">for</span><span class="token punctuation">(</span><span class="token variable">$i</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token variable">$i</span> <span class="token operator"><</span> <span class="token variable">$len</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token variable">$i</span><span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token comment">//定义标识位标记已经有序或无序</span> <span class="token variable">$flag</span> <span class="token operator">=</span> <span class="token constant boolean">true</span><span class="token punctuation">;</span> <span class="token keyword">for</span><span class="token punctuation">(</span><span class="token variable">$j</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token variable">$j</span> <span class="token operator"><</span> <span class="token variable">$len</span> <span class="token operator">-</span> <span class="token variable">$i</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token variable">$j</span><span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$arr</span><span class="token punctuation">[</span><span class="token variable">$j</span><span class="token punctuation">]</span> <span class="token operator">></span> <span class="token variable">$arr</span><span class="token punctuation">[</span><span class="token variable">$j</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$item</span> <span class="token operator">=</span> <span class="token variable">$arr</span><span class="token punctuation">[</span><span class="token variable">$j</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token variable">$arr</span><span class="token punctuation">[</span><span class="token variable">$j</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$arr</span><span class="token punctuation">[</span><span class="token variable">$j</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token variable">$arr</span><span class="token punctuation">[</span><span class="token variable">$j</span><span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$item</span><span class="token punctuation">;</span> <span class="token variable">$flag</span> <span class="token operator">=</span> <span class="token constant boolean">false</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// 优化1,无排序即完成,可退出</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$flag</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token function">var_dump</span><span class="token punctuation">(</span><span class="token variable">$arr</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span></code></pre><h4 id="优化点2"><a href="#优化点2" class="headerlink" title="优化点2"></a>优化点2</h4><blockquote><p>当一个数组接近有序的时候, 只需要在某一个小范围内排序即可, 如 <strong>[1, 7,5,3,9,11,12,13,14]</strong> ,</p><p>在11后面都已经是有序的情况, 11后面的无需再排序, 可以使用标记来表示这个范围的下限, 只排序到此下标位置即可。</p></blockquote><pre class="language-php" data-language="php"><code class="language-php"><span class="token php language-php"><span class="token delimiter important"><?php</span><span class="token variable">$arr</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token operator">-</span><span class="token number">3</span><span class="token punctuation">,</span><span class="token operator">-</span><span class="token number">10</span><span class="token punctuation">,</span><span class="token number">4</span><span class="token punctuation">,</span><span class="token operator">-</span><span class="token number">5</span><span class="token punctuation">,</span><span class="token number">6</span><span class="token punctuation">,</span><span class="token number">7</span><span class="token punctuation">,</span><span class="token number">8</span><span class="token punctuation">,</span><span class="token number">12</span><span class="token punctuation">,</span><span class="token number">9</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token operator">-</span><span class="token number">11</span><span class="token punctuation">,</span><span class="token number">100</span><span class="token punctuation">,</span><span class="token operator">-</span><span class="token number">200</span><span class="token punctuation">,</span><span class="token number">300</span><span class="token punctuation">,</span><span class="token number">400</span><span class="token punctuation">,</span><span class="token number">500</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token variable">$len</span> <span class="token operator">=</span> <span class="token function">count</span><span class="token punctuation">(</span><span class="token variable">$arr</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token variable">$index</span> <span class="token operator">=</span> <span class="token variable">$len</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span><span class="token comment">//排序下限</span><span class="token variable">$maxIndex</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">//排序上限</span><span class="token keyword">for</span><span class="token punctuation">(</span><span class="token variable">$i</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token variable">$i</span> <span class="token operator"><</span> <span class="token variable">$len</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token variable">$i</span><span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token comment">//定义标识位标记已经有序或无序</span> <span class="token variable">$flag</span> <span class="token operator">=</span> <span class="token constant boolean">true</span><span class="token punctuation">;</span> <span class="token keyword">for</span><span class="token punctuation">(</span><span class="token variable">$j</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token variable">$j</span> <span class="token operator"><</span> <span class="token variable">$index</span><span class="token punctuation">;</span> <span class="token variable">$j</span><span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$arr</span><span class="token punctuation">[</span><span class="token variable">$j</span><span class="token punctuation">]</span> <span class="token operator">></span> <span class="token variable">$arr</span><span class="token punctuation">[</span><span class="token variable">$j</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$item</span> <span class="token operator">=</span> <span class="token variable">$arr</span><span class="token punctuation">[</span><span class="token variable">$j</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token variable">$arr</span><span class="token punctuation">[</span><span class="token variable">$j</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$arr</span><span class="token punctuation">[</span><span class="token variable">$j</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token variable">$arr</span><span class="token punctuation">[</span><span class="token variable">$j</span><span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$item</span><span class="token punctuation">;</span> <span class="token variable">$flag</span> <span class="token operator">=</span> <span class="token constant boolean">false</span><span class="token punctuation">;</span> <span class="token variable">$maxIndex</span> <span class="token operator">=</span> <span class="token variable">$j</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// 优化1,无排序即完成,可退出</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$flag</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * 优化2 * 当一个数组接近有序的时候 * 只需要在某一个小范围内排序即可 * 使用标记来表示这个范围的下限 * 只排序到此下标位置即可 */</span> <span class="token variable">$index</span> <span class="token operator">=</span> <span class="token variable">$maxIndex</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token function">var_dump</span><span class="token punctuation">(</span><span class="token variable">$arr</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span></code></pre><h1 id="斐波那契数列"><a href="#斐波那契数列" class="headerlink" title="斐波那契数列"></a>斐波那契数列</h1><h4 id="斐波那契数列递归"><a href="#斐波那契数列递归" class="headerlink" title="斐波那契数列递归"></a>斐波那契数列递归</h4><pre class="language-php" data-language="php"><code class="language-php"><span class="token php language-php"><span class="token delimiter important"><?php</span><span class="token keyword">function</span> <span class="token function-definition function">fibonacci</span><span class="token punctuation">(</span><span class="token variable">$n</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token variable">$n</span> <span class="token operator"><=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token variable">$n</span> <span class="token operator">==</span> <span class="token number">1</span> <span class="token operator">||</span> <span class="token variable">$n</span> <span class="token operator">==</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token function">fibonacci</span><span class="token punctuation">(</span><span class="token variable">$n</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token function">fibonacci</span><span class="token punctuation">(</span><span class="token variable">$n</span> <span class="token operator">-</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token comment">// 经过测试, 使用该方法当计算数值达到30以上运算会肉眼可见的明显变慢</span><span class="token keyword">for</span><span class="token punctuation">(</span><span class="token variable">$i</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token variable">$i</span> <span class="token operator"><</span> <span class="token number">30</span><span class="token punctuation">;</span> <span class="token variable">$i</span><span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token function">var_dump</span><span class="token punctuation">(</span><span class="token function">fibonacci</span><span class="token punctuation">(</span><span class="token variable">$i</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span></span></code></pre><h4 id="递归优化"><a href="#递归优化" class="headerlink" title="递归优化"></a>递归优化</h4><blockquote><p>从上面的递归方法可以看到,进行了很多的重复计算,性能极差,N越大,计算的次数越多,既然因为重复计算影响了性能,那么优化就从减少重复计算入手,即把之前计算的存储起来,这样就避免了过多的重复计算,优化了递归算法(但仍然不推荐使用递归)。</p></blockquote><pre class="language-php" data-language="php"><code class="language-php"><span class="token php language-php"><span class="token delimiter important"><?php</span><span class="token keyword">function</span> <span class="token function-definition function">fibonacci_2</span><span class="token punctuation">(</span><span class="token variable">$n</span> <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token variable">$a</span> <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token variable">$b</span> <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$n</span> <span class="token operator"><=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$n</span> <span class="token operator">></span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// 存储前一位,优化递归计算</span> <span class="token keyword">return</span> <span class="token function">fibonacci_2</span><span class="token punctuation">(</span><span class="token variable">$n</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token variable">$a</span> <span class="token operator">+</span> <span class="token variable">$b</span><span class="token punctuation">,</span> <span class="token variable">$a</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token variable">$a</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token comment">// 优化后500内的计算0.2090780735s内可算出来</span><span class="token keyword">for</span><span class="token punctuation">(</span><span class="token variable">$i</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token variable">$i</span> <span class="token operator"><</span> <span class="token number">500</span><span class="token punctuation">;</span> <span class="token variable">$i</span><span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token function">var_dump</span><span class="token punctuation">(</span><span class="token function">fibonacci_2</span><span class="token punctuation">(</span><span class="token variable">$i</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span></span></code></pre><h4 id="非递归写法-记忆化自底向上"><a href="#非递归写法-记忆化自底向上" class="headerlink" title="非递归写法(记忆化自底向上)"></a>非递归写法(记忆化自底向上)</h4><blockquote><p>自底向上计算, 把结果存储到数组中, 避免重复计算。</p></blockquote><pre class="language-php" data-language="php"><code class="language-php"><span class="token php language-php"><span class="token delimiter important"><?php</span><span class="token keyword">function</span> <span class="token function-definition function">fibonacci_3</span><span class="token punctuation">(</span><span class="token variable">$n</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$n</span> <span class="token operator"><=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$n</span> <span class="token operator"><=</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token variable">$list</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token variable">$i</span> <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">;</span> <span class="token variable">$i</span> <span class="token operator"><=</span> <span class="token variable">$n</span><span class="token punctuation">;</span> <span class="token variable">$i</span><span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$list</span><span class="token punctuation">[</span><span class="token variable">$i</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$list</span><span class="token punctuation">[</span><span class="token variable">$i</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">+</span> <span class="token variable">$list</span><span class="token punctuation">[</span><span class="token variable">$i</span> <span class="token operator">-</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token variable">$list</span><span class="token punctuation">[</span><span class="token variable">$n</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token comment">// 返回最后一个数,即第N个数</span><span class="token punctuation">}</span><span class="token keyword">for</span><span class="token punctuation">(</span><span class="token variable">$i</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token variable">$i</span> <span class="token operator"><</span> <span class="token number">500</span><span class="token punctuation">;</span> <span class="token variable">$i</span><span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token function">var_dump</span><span class="token punctuation">(</span><span class="token function">fibonacci_3</span><span class="token punctuation">(</span><span class="token variable">$i</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span></span></code></pre><h4 id="动态规划"><a href="#动态规划" class="headerlink" title="动态规划"></a>动态规划</h4><blockquote><p>进一步优化, 没必要将结果存储到一个数组, 利用动态规划思想, 定义临时变量解决。</p><p>动态规划的思想是,记录中间计算结果,计算后面时,根据前面保存的结果直接计算,避免重复计算且减少存储空间占用。</p></blockquote><pre class="language-php" data-language="php"><code class="language-php"><span class="token php language-php"><span class="token delimiter important"><?php</span><span class="token keyword">function</span> <span class="token function-definition function">fibonacci_4</span><span class="token punctuation">(</span><span class="token variable">$n</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$n</span> <span class="token operator"><=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$n</span> <span class="token operator"><=</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token variable">$a</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token variable">$b</span> <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token variable">$i</span> <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token variable">$i</span> <span class="token operator"><</span> <span class="token variable">$n</span><span class="token punctuation">;</span> <span class="token variable">$i</span><span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$b</span> <span class="token operator">=</span> <span class="token variable">$a</span> <span class="token operator">+</span> <span class="token variable">$b</span><span class="token punctuation">;</span> <span class="token variable">$a</span> <span class="token operator">=</span> <span class="token variable">$b</span> <span class="token operator">-</span> <span class="token variable">$a</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token variable">$b</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">for</span><span class="token punctuation">(</span><span class="token variable">$i</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token variable">$i</span> <span class="token operator"><</span> <span class="token number">500</span><span class="token punctuation">;</span> <span class="token variable">$i</span><span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token function">var_dump</span><span class="token punctuation">(</span><span class="token function">fibonacci_4</span><span class="token punctuation">(</span><span class="token variable">$i</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span></span></code></pre>]]></content>
<summary type="html"><h1 id="冒泡排序"><a href="#冒泡排序" class="headerlink" title="冒泡排序"></a>冒泡排序</h1><blockquote>
<p>一般的冒泡排序只能满足最基本的要求, 如果不加以优化, 还会多做无用功, 出现重复循环的无效排序。</p>
</blockquote></summary>
<category term="Other" scheme="http://chuchu-z.com/categories/other/"/>
</entry>
<entry>
<title>GitHub Actions实现Hexo自动化部署</title>
<link href="http://chuchu-z.com/posts/hexo-blog-git-actions/"/>
<id>http://chuchu-z.com/posts/hexo-blog-git-actions/</id>
<published>2023-02-13T21:24:23.000Z</published>
<updated>2024-12-31T06:57:56.016Z</updated>
<content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><blockquote><p>由于半夜睡不着,突然想到博客很久没有更新了, 准备把很久之前写好的文章发布一下,但是发现原来使用的 <strong>travis-ci</strong> 没有触发, 去查了一下才知道 <a href="https://blog.travis-ci.com/2020-11-02-travis-ci-new-billing">Travis CI 在 2020年 11 月 2 日就改变了收费策略</a> ,原来我现在用的免费方案,系统会赠送 10000 积分(一次性)。</p><span id="more"></span><p>Linux 机器上每分钟消耗 10 积分,macOS 机器上每分钟消耗 50 积分,我的积分已经消耗完了。一开始我觉得比较诧异,因为我以前从来没关注有这个积分机制,以为公共仓库使用 Travis CI 服务都是免费的。被迫无奈,本来只是想发个文章,变成了连夜更换CI/CD,中途还发现域名快到期了顺便续了一年😥。</p></blockquote><h2 id="Hexo-持续集成"><a href="#Hexo-持续集成" class="headerlink" title="Hexo 持续集成"></a>Hexo 持续集成</h2><p>由于本人是通过<strong>GitHub Pages</strong>方式来实现博客托管的,好处是不需要自己购买服务器和域名, 只需要在github上创建一个repository,这个repository的名字还有要求必须是<strong>username.github.io</strong>,再随便写个静态html内容上传就可以直接访问了,具体方法这里不再多说。</p><p>先简单介绍一下项目仓库,源代码和hexo编译后的静态资源都在同一仓库(<strong>chuchu-z.github.io</strong>), 只是分支不同,src分支为源代码仓库, master分支为hexo编译后的静态资源, 也就是博客展示出来的内容。</p><h3 id="生成公钥私钥"><a href="#生成公钥私钥" class="headerlink" title="生成公钥私钥"></a>生成公钥私钥</h3><pre class="language-none"><code class="language-none">ssh-keygen -t rsa -C "$(git config user.name)" -f github-deploy-key</code></pre><h3 id="添加仓库环境变量"><a href="#添加仓库环境变量" class="headerlink" title="添加仓库环境变量"></a>添加仓库环境变量</h3><p>设置 HEXO_DEPLOY_PUB,value 是上步生成的 github-deploy-key.pub 文件内容。</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/posts/hexo-blog-git-actions/image-20230214054920822.png" alt title> </div> <div class="image-caption"></div> </figure><p>设置 HEXO_DEPLOY_PRI,value 是上步生成的 github-deploy-key 文件内容。</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/posts/hexo-blog-git-actions/image-20230214055043562.png" alt title> </div> <div class="image-caption"></div> </figure><h3 id="编写配置文件deploy-yml"><a href="#编写配置文件deploy-yml" class="headerlink" title="编写配置文件deploy.yml"></a>编写配置文件deploy.yml</h3><p>在 <code>myblog</code> 项目根目录下创建 <code>.github/workflows/deploy.yml</code> 文件。</p><pre class="language-yaml" data-language="yaml"><code class="language-yaml"><span class="token comment"># Action 的名字</span><span class="token key atrule">name</span><span class="token punctuation">:</span> Hexo Auto Deploy<span class="token key atrule">on</span><span class="token punctuation">:</span> <span class="token comment"># 触发条件1:src 分支收到 push 后执行任务。</span> <span class="token key atrule">push</span><span class="token punctuation">:</span> <span class="token key atrule">branches</span><span class="token punctuation">:</span> <span class="token punctuation">-</span> src <span class="token comment"># 触发条件2:手动按钮</span> <span class="token key atrule">workflow_dispatch</span><span class="token punctuation">:</span><span class="token comment"># 这里放环境变量,需要替换成你自己的</span><span class="token key atrule">env</span><span class="token punctuation">:</span> <span class="token comment"># Hexo 编译后使用此 git 用户部署到 github 仓库</span> <span class="token key atrule">GIT_USER</span><span class="token punctuation">:</span> chuchu<span class="token punctuation">-</span>z <span class="token comment"># Hexo 编译后使用此 git 邮箱部署到 github 仓库</span> <span class="token key atrule">GIT_EMAIL</span><span class="token punctuation">:</span> [email protected] <span class="token comment"># Hexo 编译后要部署的 github 仓库</span> <span class="token key atrule">GIT_DEPLOY_REPO</span><span class="token punctuation">:</span> chuchu<span class="token punctuation">-</span>z/chuchu<span class="token punctuation">-</span>z.github.io <span class="token comment"># Hexo 编译后要部署到的分支</span> <span class="token key atrule">GIT_DEPLOY_BRANCH</span><span class="token punctuation">:</span> master<span class="token key atrule">jobs</span><span class="token punctuation">:</span> <span class="token key atrule">build</span><span class="token punctuation">:</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> Build on node $<span class="token punctuation">{</span><span class="token punctuation">{</span> matrix.node_version <span class="token punctuation">}</span><span class="token punctuation">}</span> and $<span class="token punctuation">{</span><span class="token punctuation">{</span> matrix.os <span class="token punctuation">}</span><span class="token punctuation">}</span> <span class="token comment"># 配置运行的机器环境</span> <span class="token key atrule">runs-on</span><span class="token punctuation">:</span> ubuntu<span class="token punctuation">-</span>latest <span class="token key atrule">if</span><span class="token punctuation">:</span> github.event.repository.owner.id == github.event.sender.id <span class="token key atrule">strategy</span><span class="token punctuation">:</span> <span class="token key atrule">matrix</span><span class="token punctuation">:</span> <span class="token key atrule">os</span><span class="token punctuation">:</span> <span class="token punctuation">[</span>ubuntu<span class="token punctuation">-</span>latest<span class="token punctuation">]</span> <span class="token key atrule">node_version</span><span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token number">14</span><span class="token punctuation">]</span><span class="token comment"># 执行步骤</span> <span class="token key atrule">steps</span><span class="token punctuation">:</span> <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> Checkout <span class="token key atrule">uses</span><span class="token punctuation">:</span> actions/checkout@v2 <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> Checkout deploy repo <span class="token key atrule">uses</span><span class="token punctuation">:</span> actions/checkout@v2 <span class="token key atrule">with</span><span class="token punctuation">:</span> <span class="token key atrule">repository</span><span class="token punctuation">:</span> $<span class="token punctuation">{</span><span class="token punctuation">{</span> env.GIT_DEPLOY_REPO <span class="token punctuation">}</span><span class="token punctuation">}</span> <span class="token key atrule">ref</span><span class="token punctuation">:</span> $<span class="token punctuation">{</span><span class="token punctuation">{</span> env.GIT_DEPLOY_BRANCH <span class="token punctuation">}</span><span class="token punctuation">}</span> <span class="token key atrule">path</span><span class="token punctuation">:</span> .deploy_git <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> Use Node.js $<span class="token punctuation">{</span><span class="token punctuation">{</span> matrix.node_version <span class="token punctuation">}</span><span class="token punctuation">}</span> <span class="token key atrule">uses</span><span class="token punctuation">:</span> actions/setup<span class="token punctuation">-</span>node@v1 <span class="token key atrule">with</span><span class="token punctuation">:</span> <span class="token key atrule">node-version</span><span class="token punctuation">:</span> $<span class="token punctuation">{</span><span class="token punctuation">{</span> matrix.node_version <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token comment"># 授权密钥</span> <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> Configuration environment <span class="token key atrule">env</span><span class="token punctuation">:</span> <span class="token key atrule">HEXO_DEPLOY_PRI</span><span class="token punctuation">:</span> $<span class="token punctuation">{</span><span class="token punctuation">{</span>secrets.HEXO_DEPLOY_PRI<span class="token punctuation">}</span><span class="token punctuation">}</span> <span class="token key atrule">run</span><span class="token punctuation">:</span> <span class="token punctuation">|</span><span class="token scalar string"> sudo timedatectl set-timezone "Asia/Shanghai" mkdir -p ~/.ssh/ echo "$HEXO_DEPLOY_PRI" > ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts # coding 已取消同步 ssh-keyscan -t rsa e.coding.net >> ~/.ssh/known_hosts ssh-keyscan -t rsa gitee.com >> ~/.ssh/known_hosts git config --global user.name $GIT_USER git config --global user.email $GIT_EMAIL</span><span class="token comment"># 安装并执行hexo</span> <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> Install dependencies <span class="token key atrule">run</span><span class="token punctuation">:</span> <span class="token punctuation">|</span><span class="token scalar string"> npm install -g hexo-cli --no-fund npm install -g --no-fund hexo clean hexo generate</span> <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> Deploy hexo <span class="token key atrule">run</span><span class="token punctuation">:</span> <span class="token punctuation">|</span><span class="token scalar string"> npm run deploy</span></code></pre><p>把配置文件提交到github仓库之后, 只要src(源代码)分支触发push操作,就会自动触发部署,在Actions就可以看到具体部署情况。</p><h3 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h3><p>在学习了网上其他大佬们的方法后自己稍微做了些修改,也是总算成功完成了,感觉这次处理起来比上次使用<code>travis-ci</code>简单快的多,也可能是之前踩过不少坑了,这次比较顺利,早知道<code>GitHub Actions</code>这么方便就不用<code>travis-ci</code>了, 不过要不是<code>travis-ci</code>收费了我现在也还不知道<code>GitHub Actions</code>也挺好用,刚好天亮了睡觉😴。</p>]]></content>
<summary type="html"><h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><blockquote>
<p>由于半夜睡不着,突然想到博客很久没有更新了, 准备把很久之前写好的文章发布一下,但是发现原来使用的 <strong>travis-ci</strong> 没有触发, 去查了一下才知道 <a href="https://blog.travis-ci.com/2020-11-02-travis-ci-new-billing">Travis CI 在 2020年 11 月 2 日就改变了收费策略</a> ,原来我现在用的免费方案,系统会赠送 10000 积分(一次性)。</p></blockquote></summary>
<category term="Other" scheme="http://chuchu-z.com/categories/other/"/>
</entry>
<entry>
<title>gRPC的简介与Protobuf的使用</title>
<link href="http://chuchu-z.com/posts/gRPC-info-and-Protobuf-use/"/>
<id>http://chuchu-z.com/posts/gRPC-info-and-Protobuf-use/</id>
<published>2023-02-13T19:36:50.000Z</published>
<updated>2024-12-31T06:57:56.016Z</updated>
<content type="html"><![CDATA[<blockquote><p><a href="https://grpc.io/docs/"><strong>gRPC</strong></a>实现微服务,将大的项目拆分为多个小且独立的业务模块;即服务;各服务之间使用高效的<strong>Protobuf</strong>协议进行RPC调用。</p><p><a href="https://developers.google.com/protocol-buffers/docs/overview"><strong>Protobuf</strong></a> 实际是一套类似<strong>Json或者XML</strong>的数据传输格式和规范,用于不同应用或进程之间进行通信时使用。通信时所传递的信息是通过Protobuf定义的<strong>message数据结构</strong>进行打包,然后编译成<strong>二进制</strong>的码流再进行传输或者存储。</p><span id="more"></span><p>gRPC开发的核心文件是*<strong>.proto</strong>文件 ,它定义了gRPC服务和消息的约定。根据这个文件,gRPC框架可以通过<strong>protoc 工具</strong>生成服务基类,消息和完整的客户端代码, 支持 <strong>C++、Java、Go、Python、Ruby、C#、Node.js、Android Java、Objective-C、PHP</strong>等多种编程语言。</p><p><strong>protoc</strong> 是用于将<strong>proto文件</strong>编程成各种语言源码文件的工具。</p></blockquote><h2 id="PHP使用gRPC"><a href="#PHP使用gRPC" class="headerlink" title="PHP使用gRPC"></a>PHP使用gRPC</h2><h3 id="安装扩展"><a href="#安装扩展" class="headerlink" title="安装扩展"></a>安装扩展</h3><p>在<strong>PHP</strong>中使用<strong>gRPC</strong>需要先安装<a href="http://pecl.php.net/package/gRPC"><strong>gRPC扩展</strong></a>和<a href="http://pecl.php.net/package/protobuf"><strong>protobuf扩展</strong></a></p><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token comment"># 使用pecl安装</span><span class="token comment"># 查看pecl版本</span>pecl version <span class="token comment">#如果没有安装 pecl</span><span class="token comment"># php版本 > 7</span><span class="token function">wget</span> http://pear.php.net/go-pear.pharphp go-pear.phar<span class="token comment"># php版本 < 7</span>yum <span class="token function">install</span> php-pear<span class="token comment">#否则会报错PHP Parse error: syntax error, unexpected //'new' (T_NEW) in /usr/share/pear/PEAR/Frontend.php on //line 91</span><span class="token comment"># 查看版本</span>/usr/local/php/bin/pear version<span class="token comment"># 使用pecl安装grpc和protobuf</span>/usr/local/php/bin/pecl <span class="token function">install</span> grpc/usr/local/php/bin/pecl <span class="token function">install</span> protobuf<span class="token comment"># 写入到php.ini配置(重启php生效)</span><span class="token builtin class-name">echo</span> <span class="token string">"extension=grpc.so"</span> <span class="token operator">>></span> /usr/local/php/etc/php.ini<span class="token builtin class-name">echo</span> <span class="token string">"extension=protobuf.so"</span> <span class="token operator">>></span> /usr/local/php/etc/php.iniphp <span class="token parameter variable">-m</span> <span class="token operator">|</span> <span class="token function">grep</span> grpcphp <span class="token parameter variable">-m</span> <span class="token operator">|</span> <span class="token function">grep</span> protobuf</code></pre><h3 id="安装protoc工具"><a href="#安装protoc工具" class="headerlink" title="安装protoc工具"></a>安装protoc工具</h3><p>下载 <strong><a href="https://github.com/protocolbuffers/protobuf/releases">protoc源码</a></strong> 具体版本要选择与<strong>proto文件</strong>中定义一致, 否则报错无法解析<strong>proto文件</strong>, 目前我们使用的是<strong>proto3</strong>, 所以我当前使用的<strong>protoc</strong>工具是<a href="https://github.com/protocolbuffers/protobuf/releases/tag/v3.10.1">3.10.1版本</a></p><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token comment"># 先安装协议缓存编译器(否则解析proto文件生成对应代码时会乱码)</span>yum <span class="token function">install</span> protobuf-compiler libtool libsysfs<span class="token comment"># 解压</span><span class="token function">tar</span> <span class="token parameter variable">-xvf</span> protobuf-3.10.1.tar.gz<span class="token comment"># 编译安装</span><span class="token builtin class-name">cd</span> protobuf-3.10.1./autogen.sh./configure<span class="token comment"># 如果报错 configure: WARNING: no configuration information is in third_party/googletest</span><span class="token comment"># 需要下载googletest,下载地址:https://github.com/google/googletest/releases</span><span class="token comment"># 直接解压并重命名googletest,放在 protobuf-3.10.1/third_party/googletest,然后重新执行./autogen.sh之后的</span><span class="token function">make</span><span class="token function">make</span> <span class="token function">install</span><span class="token comment"># 查看protoc版本</span>protoc <span class="token parameter variable">--version</span></code></pre><h3 id="使用protoc工具"><a href="#使用protoc工具" class="headerlink" title="使用protoc工具"></a>使用protoc工具</h3><p>使用protoc工具, 生成PHP代码文件</p><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token comment"># 执行命令</span>protoc <span class="token parameter variable">--php_out</span><span class="token operator">=</span>out_dir file.proto<span class="token comment"># --php_out 表示生成PHP代码格式</span><span class="token comment"># out_dir 生成代码要存放的路径</span><span class="token comment"># file.proto 要编译的proto文件</span></code></pre><p>示例:</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/posts/gRPC-info-and-Protobuf-use/f91a56d9cea146efa2bd31cb3e807d8e.png" alt="protoc工具生成php代码1" title> </div> <div class="image-caption">protoc工具生成php代码1</div> </figure> <figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/posts/gRPC-info-and-Protobuf-use/257d88446cac4982a7338bb6978ce117.png" alt="protoc工具生成php代码2" title> </div> <div class="image-caption">protoc工具生成php代码2</div> </figure> <h3 id="aexlib(工作目录)中调用gRPC"><a href="#aexlib(工作目录)中调用gRPC" class="headerlink" title="aexlib(工作目录)中调用gRPC"></a>aexlib(工作目录)中调用gRPC</h3><p>生成的代码放到<strong>aexlib/Lib/Plugin/</strong> 目录下, 新建一个<strong>Api.php</strong>和<strong>Client.php</strong>, 编写具体的业务逻辑, 并在<strong>aexlib/Lib/Model/**下新建</strong>model**, <strong>model</strong>内调用<strong>Api.php</strong>具体方法</p>]]></content>
<summary type="html"><blockquote>
<p><a href="https://grpc.io/docs/"><strong>gRPC</strong></a>实现微服务,将大的项目拆分为多个小且独立的业务模块;即服务;各服务之间使用高效的<strong>Protobuf</strong>协议进行RPC调用。</p>
<p><a href="https://developers.google.com/protocol-buffers/docs/overview"><strong>Protobuf</strong></a> 实际是一套类似<strong>Json或者XML</strong>的数据传输格式和规范,用于不同应用或进程之间进行通信时使用。通信时所传递的信息是通过Protobuf定义的<strong>message数据结构</strong>进行打包,然后编译成<strong>二进制</strong>的码流再进行传输或者存储。</p></blockquote></summary>
<category term="Other" scheme="http://chuchu-z.com/categories/other/"/>
</entry>
<entry>
<title>Linux Shell 使用alias定义别名</title>
<link href="http://chuchu-z.com/posts/linux-shell-alias-config/"/>
<id>http://chuchu-z.com/posts/linux-shell-alias-config/</id>
<published>2022-03-31T01:57:18.000Z</published>
<updated>2024-12-31T06:57:56.018Z</updated>
<content type="html"><![CDATA[<p>在我们使用终端时, 为了提高平时工作效率和减少常用命令过长, 敲起来浪费时间, 可在<code>/etc/profile</code>文件中配置<code>alias</code>,自定指令的别名</p><span id="more"></span><p>打开<code>/etc/profile</code>配置文件</p><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token function">vim</span> /etc/profile</code></pre><p>在文件末尾增加以下配置</p><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token comment">#[alias]</span><span class="token comment">##cd dir##</span><span class="token builtin class-name">alias</span> -- -<span class="token operator">=</span><span class="token string">'cd -'</span> <span class="token comment"># 此处意思为输入 - 回车, 相当于执行 cd -, 快速切换回上一个目录(两个目录之间来回切换)</span><span class="token builtin class-name">alias</span> <span class="token punctuation">..</span><span class="token operator">=</span><span class="token string">'cd ..'</span><span class="token builtin class-name">alias</span> <span class="token assign-left variable">e</span><span class="token operator">=</span><span class="token string">'exit'</span><span class="token builtin class-name">alias</span> <span class="token string">'www'</span><span class="token operator">=</span><span class="token string">'cd $www'</span> <span class="token comment"># $www是个人配置的环境变量, $www指向的是工作目录</span><span class="token comment">##vim file##</span><span class="token builtin class-name">alias</span> <span class="token string">'vp'</span><span class="token operator">=</span><span class="token string">'vim /etc/profile'</span><span class="token builtin class-name">alias</span> <span class="token string">'vv'</span><span class="token operator">=</span><span class="token string">'vim /etc/vimrc'</span><span class="token builtin class-name">alias</span> <span class="token string">'sp'</span><span class="token operator">=</span><span class="token string">'source /etc/profile'</span><span class="token comment">##git##</span><span class="token builtin class-name">alias</span> <span class="token string">'gs'</span><span class="token operator">=</span><span class="token string">'git status'</span><span class="token builtin class-name">alias</span> <span class="token string">'gaa'</span><span class="token operator">=</span><span class="token string">'git add .'</span><span class="token builtin class-name">alias</span> <span class="token string">'gcm'</span><span class="token operator">=</span><span class="token string">'git commit -m'</span><span class="token builtin class-name">alias</span> <span class="token string">'gco'</span><span class="token operator">=</span><span class="token string">'git checkout'</span><span class="token builtin class-name">alias</span> <span class="token string">'gb'</span><span class="token operator">=</span><span class="token string">'git branch -vvv'</span><span class="token builtin class-name">alias</span> <span class="token string">'gd'</span><span class="token operator">=</span><span class="token string">'git diff'</span><span class="token builtin class-name">alias</span> <span class="token string">'cls'</span><span class="token operator">=</span><span class="token string">'clear'</span><span class="token builtin class-name">alias</span> -- --<span class="token operator">=</span><span class="token string">'git checkout -'</span> <span class="token comment">#此处意思为输入 -- 回车, 相当于执行 git checkout -, 快速切换回上一个分支(两个分支之间来回切换)</span><span class="token builtin class-name">alias</span> <span class="token string">'show'</span><span class="token operator">=</span><span class="token string">'git show'</span><span class="token builtin class-name">alias</span> <span class="token string">'push'</span><span class="token operator">=</span><span class="token string">'git push origin `git branch --show-current`'</span><span class="token builtin class-name">alias</span> <span class="token string">'fpush'</span><span class="token operator">=</span><span class="token string">'git push -f origin `git branch --show-current`'</span> <span class="token comment">#强推</span><span class="token builtin class-name">alias</span> <span class="token string">'pull'</span><span class="token operator">=</span><span class="token string">'git pull origin `git branch --show-current`'</span><span class="token builtin class-name">alias</span> <span class="token string">'rpull'</span><span class="token operator">=</span><span class="token string">'git pull origin `git branch --show-current` --rebase'</span> <span class="token comment">#pull时增加 --rebase参数</span><span class="token builtin class-name">alias</span> <span class="token string">'ml'</span><span class="token operator">=</span><span class="token string">'git log --author=`git config user.name`'</span> <span class="token comment">#查看本人提交的log</span><span class="token builtin class-name">alias</span> <span class="token string">'gl'</span><span class="token operator">=</span><span class="token string">'git log'</span><span class="token builtin class-name">alias</span> <span class="token string">'ggl'</span><span class="token operator">=</span><span class="token string">'git log --graph'</span><span class="token builtin class-name">alias</span> <span class="token string">'gglp'</span><span class="token operator">=</span><span class="token string">'git log --graph --pretty=oneline --abbrev-commit'</span><span class="token comment">#可视化查看分支线的情况</span><span class="token builtin class-name">alias</span> <span class="token string">'review'</span><span class="token operator">=</span><span class="token string">'review() { git status --short | egrep ^*.php | sed "s/^ *//" | egrep ^[^D] | tr -s " "| cut -d" " -f 2 | egrep -v database/migrations | xargs $1;};review'</span> <span class="token comment">#列出修改过未提交的php文件</span><span class="token builtin class-name">alias</span> <span class="token string">'qq'</span><span class="token operator">=</span><span class="token string">'review "git checkout"'</span><span class="token comment">#把列出修改过未提交的php文件当做参数 提供给git checkout, 全部撤销</span><span class="token comment">##ssh##</span><span class="token builtin class-name">alias</span> <span class="token string">'chuchu'</span><span class="token operator">=</span><span class="token string">'ssh root@ip'</span><span class="token comment">##Docker##</span><span class="token builtin class-name">alias</span> <span class="token string">'dkre'</span><span class="token operator">=</span><span class="token string">'docker-compose restart'</span><span class="token builtin class-name">alias</span> <span class="token string">'dkup'</span><span class="token operator">=</span><span class="token string">'docker-compose up'</span><span class="token builtin class-name">alias</span> <span class="token string">'dkop'</span><span class="token operator">=</span><span class="token string">'docker-compose stop'</span><span class="token builtin class-name">alias</span> <span class="token string">'dkphp'</span><span class="token operator">=</span><span class="token string">"winpty docker exec -it <span class="token variable"><span class="token variable">`</span><span class="token function">docker</span> <span class="token function">ps</span> <span class="token parameter variable">--filter</span><span class="token operator">=</span><span class="token string">'name=php7'</span> <span class="token parameter variable">-q</span><span class="token variable">`</span></span> bash"</span> <span class="token comment">#快速进入docker的php7容器</span><span class="token builtin class-name">alias</span> <span class="token string">'dkphp5'</span><span class="token operator">=</span><span class="token string">"winpty docker exec -it <span class="token variable"><span class="token variable">`</span><span class="token function">docker</span> <span class="token function">ps</span> <span class="token parameter variable">--filter</span><span class="token operator">=</span><span class="token string">'name=php5'</span> <span class="token parameter variable">-q</span><span class="token variable">`</span></span> bash"</span></code></pre><p>执行 <code>source /etc/profile</code> 重新加载刚修改配置生效</p><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token builtin class-name">source</span> /etc/profile</code></pre>]]></content>
<summary type="html"><p>在我们使用终端时, 为了提高平时工作效率和减少常用命令过长, 敲起来浪费时间, 可在<code>/etc/profile</code>文件中配置<code>alias</code>,自定指令的别名</p></summary>
<category term="Linux" scheme="http://chuchu-z.com/categories/linux/"/>
</entry>
<entry>
<title>Git 中的奇葩玩法</title>
<link href="http://chuchu-z.com/posts/git-ridiculous-behavior/"/>
<id>http://chuchu-z.com/posts/git-ridiculous-behavior/</id>
<published>2022-03-25T11:01:50.000Z</published>
<updated>2024-12-31T06:57:56.016Z</updated>
<content type="html"><![CDATA[<h2 id="随机的-git-commit-你敢提交吗"><a href="#随机的-git-commit-你敢提交吗" class="headerlink" title="随机的 git commit 你敢提交吗"></a>随机的 git commit 你敢提交吗</h2><blockquote><p>一个 Git 随机生成提交日志网站, 每次刷新的内容随机</p><p>太搞了, 不怕挨揍的壮士可以使用如下命令进行日常代码的提交😂</p></blockquote><span id="more"></span><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token function">git</span> commit <span class="token parameter variable">-m</span> <span class="token variable"><span class="token variable">$(</span><span class="token function">curl</span> <span class="token parameter variable">-s</span> http://whatthecommit.com/index.txt<span class="token variable">)</span></span></code></pre><p><a href="http://whatthecommit.com/">http://whatthecommit.com</a></p><h2 id="没有最坑,只有更坑!"><a href="#没有最坑,只有更坑!" class="headerlink" title="没有最坑,只有更坑!"></a>没有最坑,只有更坑!</h2><p>此仓库专门收集史上最坑爹的代码片段,专治低血压 😁</p><p><a href="https://gitee.com/oschina/bullshit-codes/tree/master">https://gitee.com/oschina/bullshit-codes/tree/master</a></p>]]></content>
<summary type="html"><h2 id="随机的-git-commit-你敢提交吗"><a href="#随机的-git-commit-你敢提交吗" class="headerlink" title="随机的 git commit 你敢提交吗"></a>随机的 git commit 你敢提交吗</h2><blockquote>
<p>一个 Git 随机生成提交日志网站, 每次刷新的内容随机</p>
<p>太搞了, 不怕挨揍的壮士可以使用如下命令进行日常代码的提交😂</p>
</blockquote></summary>
<category term="Git" scheme="http://chuchu-z.com/categories/git/"/>
</entry>
<entry>
<title>关于谷歌Chrome浏览器非安全端口限制问题</title>
<link href="http://chuchu-z.com/posts/chrome-proxy-limit/"/>
<id>http://chuchu-z.com/posts/chrome-proxy-limit/</id>
<published>2022-03-24T04:38:16.000Z</published>
<updated>2024-12-31T06:57:56.013Z</updated>
<content type="html"><![CDATA[<p>关于前段时间深圳疫情严重, 公司选择通过VPN居家远程办公</p><p>有个项目在App端测试由于无法通过VPN请求Api, 运维开放了外网地址并指定端口</p><span id="more"></span><p>但在<code>Chrome</code>浏览器上打开时无法正常得到正常的响应, 而使用<code>postman</code>等测试工具是可以正常响应的</p><p>这个问题以前有遇到过,是因为 <code>Chrome</code> 浏览器对非安全端口进行了限制, 具体端口可在这里查看</p><p><a href="https://chromium.googlesource.com/chromium/src.git/+/refs/heads/master/net/base/port_util.cc">https://chromium.googlesource.com/chromium/src.git/+/refs/heads/master/net/base/port_util.cc</a></p><h2 id="解决的办法"><a href="#解决的办法" class="headerlink" title="解决的办法"></a>解决的办法</h2><p>windows只需要右键<code>Chrome</code>浏览器快捷图标, 在<code>属性</code>设置里面的<code>目标</code>处增加以下参数, 然后关闭<code>Chrome</code>重新打开即可正常访问</p><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token comment"># 多个端口号以英文逗号隔开</span>--explicitly-allowed-ports<span class="token operator">=</span><span class="token number">10080,30300</span></code></pre><p><img src="https://aexphoto-1251755124.file.myqcloud.com/img/2022/03/69ffe943a57fbc38de7c4e6b52f30fec.png" alt="image-20220324140658057"></p><p>Mac</p><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token comment"># Chrome浏览器的解决方案</span><span class="token function">open</span> <span class="token parameter variable">-a</span> /Applications/Google Chrome.app/Contents/MacOS/Google Chrome --explicitly-allowed-ports<span class="token operator">=</span><span class="token number">6666,8888</span></code></pre><h2 id="Chrome-302重定向"><a href="#Chrome-302重定向" class="headerlink" title="Chrome 302重定向"></a>Chrome 302重定向</h2><p>本以为解决完端口问题后就可以快乐地编码, 然而当我正常打开页面登录后, 又遇到了另一个问题</p><p>登录成功后, 只要点击其他任意跳转, 页面会被重定向跳回到登录界面, 初步判断是因为<code>Cookies</code>的问题, 导致登录态没有了</p><blockquote><p> 遗留问题1. 无法确定是因为端口的问题导致<code>Cookies</code>丢失</p></blockquote><p>具体是事例在网上只找到了这个, 不确定是否同样的原因, 但因为我的<code>Chrome</code>浏览器版本目前是<code>99.0.4844.82</code>版本, 正如此博主所说</p><p>在<code>chrome91</code>及其以上版本,无法找到<code>SameSite by default cookies</code>和<code>Cookies without SameSite must be secure</code>两项配置</p><p>虽然没有解决我的问题, 但起码提供了参考</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="https://aexphoto-1251755124.file.myqcloud.com/img/2022/03/2067d66b7b939b94f21ae22acabc8668.png" alt title> </div> <div class="image-caption"></div> </figure><blockquote><p> 遗留问题2. 无法验证该方案是否可行</p></blockquote>]]></content>
<summary type="html"><p>关于前段时间深圳疫情严重, 公司选择通过VPN居家远程办公</p>
<p>有个项目在App端测试由于无法通过VPN请求Api, 运维开放了外网地址并指定端口</p></summary>
<category term="Other" scheme="http://chuchu-z.com/categories/other/"/>
</entry>
<entry>
<title>Win10 自定义 Git-Bash 终端界面 + 一言API与终端结合</title>
<link href="http://chuchu-z.com/posts/windows10-git-bash/"/>
<id>http://chuchu-z.com/posts/windows10-git-bash/</id>
<published>2022-02-25T02:39:27.000Z</published>
<updated>2024-12-31T06:57:56.022Z</updated>
<content type="html"><![CDATA[<p>由于Git默认的界面长的实在是不够美观, 平时用起来都无法赏心悦目, 参考网上的一些文章资料, 做了下改动</p><span id="more"></span><h3 id="修改Git-Bash-窗口左上角标题"><a href="#修改Git-Bash-窗口左上角标题" class="headerlink" title="修改Git Bash 窗口左上角标题"></a>修改Git Bash 窗口左上角标题</h3><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token comment">#该命令是一次性的,关闭后重新打开会恢复, 后面有完整的 </span><span class="token builtin class-name">echo</span> <span class="token parameter variable">-ne</span> <span class="token string">"<span class="token entity" title="\\">\\</span>e]0;title name<span class="token entity" title="\\">\\</span>a"</span></code></pre><h3 id="修改命令提示符"><a href="#修改命令提示符" class="headerlink" title="修改命令提示符"></a>修改命令提示符</h3><p>具体操作</p><p>打开 git-prompt.sh 文件</p><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token function">vim</span> /etc/profile.d/git-prompt.sh</code></pre><p>将其修改为如下内容:</p><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token keyword">if</span> <span class="token builtin class-name">test</span> <span class="token parameter variable">-f</span> /etc/profile.d/git-sdk.sh<span class="token keyword">then</span> <span class="token assign-left variable">TITLEPREFIX</span><span class="token operator">=</span>SDK-<span class="token variable">${MSYSTEM<span class="token operator">#</span>MINGW}</span><span class="token keyword">else</span> <span class="token assign-left variable">TITLEPREFIX</span><span class="token operator">=</span><span class="token variable">$MSYSTEM</span><span class="token keyword">fi</span><span class="token keyword">if</span> <span class="token builtin class-name">test</span> <span class="token parameter variable">-f</span> ~/.config/git/git-prompt.sh<span class="token keyword">then</span> <span class="token builtin class-name">.</span> ~/.config/git/git-prompt.sh<span class="token keyword">else</span> <span class="token assign-left variable"><span class="token environment constant">PS1</span></span><span class="token operator">=</span><span class="token string">'\[\033]0;Bash\007\]'</span> <span class="token comment"># 窗口标题</span> <span class="token assign-left variable"><span class="token environment constant">PS1</span></span><span class="token operator">=</span><span class="token string">"<span class="token environment constant">$PS1</span>"</span><span class="token string">'\n'</span> <span class="token comment"># 换行</span> <span class="token assign-left variable"><span class="token environment constant">PS1</span></span><span class="token operator">=</span><span class="token string">"<span class="token environment constant">$PS1</span>"</span><span class="token string">'\[\033[32;1m\]'</span> <span class="token comment"># 高亮绿色</span> <span class="token assign-left variable"><span class="token environment constant">PS1</span></span><span class="token operator">=</span><span class="token string">"<span class="token environment constant">$PS1</span>"</span><span class="token string">' ➜ '</span> <span class="token comment"># unicode 字符,右箭头, 如果显示不出来大概率是utf-8编码问题</span> <span class="token assign-left variable"><span class="token environment constant">PS1</span></span><span class="token operator">=</span><span class="token string">"<span class="token environment constant">$PS1</span>"</span><span class="token string">'\[\033[33;1m\]'</span> <span class="token comment"># 高亮黄色</span> <span class="token assign-left variable"><span class="token environment constant">PS1</span></span><span class="token operator">=</span><span class="token string">"<span class="token environment constant">$PS1</span>"</span><span class="token string">'\W'</span> <span class="token comment"># 当前目录</span> <span class="token assign-left variable"><span class="token environment constant">PS1</span></span><span class="token operator">=</span><span class="token string">"<span class="token environment constant">$PS1</span>"</span><span class="token string">'\[\033[34;1m\]'</span> <span class="token comment"># 高亮蓝色</span> <span class="token assign-left variable"><span class="token environment constant">PS1</span></span><span class="token operator">=</span><span class="token string">"<span class="token environment constant">$PS1</span>"</span><span class="token string">' [\t]'</span> <span class="token comment"># 当前时间</span> <span class="token keyword">if</span> <span class="token builtin class-name">test</span> <span class="token parameter variable">-z</span> <span class="token string">"<span class="token variable">$WINELOADERNOEXEC</span>"</span> <span class="token keyword">then</span> <span class="token assign-left variable">GIT_EXEC_PATH</span><span class="token operator">=</span><span class="token string">"<span class="token variable"><span class="token variable">$(</span><span class="token function">git</span> --exec-path <span class="token operator"><span class="token file-descriptor important">2</span>></span>/dev/null<span class="token variable">)</span></span>"</span> <span class="token assign-left variable">COMPLETION_PATH</span><span class="token operator">=</span><span class="token string">"<span class="token variable">${GIT_EXEC_PATH<span class="token operator">%</span><span class="token operator">/</span>libexec<span class="token operator">/</span>git-core}</span>"</span> <span class="token assign-left variable">COMPLETION_PATH</span><span class="token operator">=</span><span class="token string">"<span class="token variable">${COMPLETION_PATH<span class="token operator">%</span><span class="token operator">/</span>lib<span class="token operator">/</span>git-core}</span>"</span> <span class="token assign-left variable">COMPLETION_PATH</span><span class="token operator">=</span><span class="token string">"<span class="token variable">$COMPLETION_PATH</span>/share/git/completion"</span> <span class="token keyword">if</span> <span class="token builtin class-name">test</span> <span class="token parameter variable">-f</span> <span class="token string">"<span class="token variable">$COMPLETION_PATH</span>/git-prompt.sh"</span> <span class="token keyword">then</span> <span class="token builtin class-name">.</span> <span class="token string">"<span class="token variable">$COMPLETION_PATH</span>/git-completion.bash"</span> <span class="token builtin class-name">.</span> <span class="token string">"<span class="token variable">$COMPLETION_PATH</span>/git-prompt.sh"</span> <span class="token assign-left variable"><span class="token environment constant">PS1</span></span><span class="token operator">=</span><span class="token string">"<span class="token environment constant">$PS1</span>"</span><span class="token string">'\[\033[31m\]'</span> <span class="token comment"># 红色</span> <span class="token assign-left variable"><span class="token environment constant">PS1</span></span><span class="token operator">=</span><span class="token string">"<span class="token environment constant">$PS1</span>"</span><span class="token string">'`__git_ps1`'</span> <span class="token comment"># git 插件</span> <span class="token keyword">fi</span> <span class="token keyword">fi</span> <span class="token assign-left variable"><span class="token environment constant">PS1</span></span><span class="token operator">=</span><span class="token string">"<span class="token environment constant">$PS1</span>"</span><span class="token string">'\[\033[36m\] '</span> <span class="token comment"># 青色</span><span class="token keyword">fi</span><span class="token assign-left variable">MSYS2_PS1</span><span class="token operator">=</span><span class="token string">"<span class="token environment constant">$PS1</span>"</span></code></pre><p>这个非常像 oh-my-zsh 的风格, 其实一开始就是想用zsh终端的, 奈何windows不支持, 如果平时日常开发想装的话也可以在linux虚拟主机或者docker里面装一个, zsh在目前来说可以说是最强大的shell了, 谁用谁知道</p><h3 id="修改界面主题"><a href="#修改界面主题" class="headerlink" title="修改界面主题"></a>修改界面主题</h3><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token function">vim</span> ~/.minttyrc</code></pre><p>默认配置如下:</p><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token assign-left variable">Transparency</span><span class="token operator">=</span>low<span class="token assign-left variable">Language</span><span class="token operator">=</span><span class="token assign-left variable">ForegroundColour</span><span class="token operator">=</span><span class="token number">0,255</span>,64<span class="token assign-left variable">CursorColour</span><span class="token operator">=</span><span class="token number">0,255</span>,64<span class="token assign-left variable">CursorType</span><span class="token operator">=</span>block<span class="token assign-left variable">Scrollbar</span><span class="token operator">=</span>none<span class="token assign-left variable">FontHeight</span><span class="token operator">=</span><span class="token number">12</span></code></pre><p>把以下内容添加到配置文件里面:</p><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token assign-left variable">Font</span><span class="token operator">=</span>Fira Code Medium<span class="token assign-left variable">FontHeight</span><span class="token operator">=</span><span class="token number">14</span><span class="token assign-left variable">FontHeight</span><span class="token operator">=</span><span class="token number">14</span><span class="token assign-left variable">Transparency</span><span class="token operator">=</span>low<span class="token assign-left variable">FontSmoothing</span><span class="token operator">=</span>default<span class="token assign-left variable">Locale</span><span class="token operator">=</span>C<span class="token assign-left variable">Charset</span><span class="token operator">=</span>UTF-8<span class="token assign-left variable">Columns</span><span class="token operator">=</span><span class="token number">88</span><span class="token assign-left variable">Rows</span><span class="token operator">=</span><span class="token number">26</span><span class="token assign-left variable">OpaqueWhenFocused</span><span class="token operator">=</span>no<span class="token assign-left variable">Scrollbar</span><span class="token operator">=</span>none<span class="token assign-left variable">Language</span><span class="token operator">=</span>zh_CN<span class="token assign-left variable">ForegroundColour</span><span class="token operator">=</span><span class="token number">131,148</span>,150<span class="token assign-left variable">BackgroundColour</span><span class="token operator">=</span><span class="token number">0,43</span>,54<span class="token assign-left variable">CursorColour</span><span class="token operator">=</span><span class="token number">220,130</span>,71<span class="token assign-left variable">BoldBlack</span><span class="token operator">=</span><span class="token number">128,128</span>,128<span class="token assign-left variable">Red</span><span class="token operator">=</span><span class="token number">255,64</span>,40<span class="token assign-left variable">BoldRed</span><span class="token operator">=</span><span class="token number">255,128</span>,64<span class="token assign-left variable">Green</span><span class="token operator">=</span><span class="token number">64,200</span>,64<span class="token assign-left variable">BoldGreen</span><span class="token operator">=</span><span class="token number">64,255</span>,64<span class="token assign-left variable">Yellow</span><span class="token operator">=</span><span class="token number">190,190</span>,0<span class="token assign-left variable">BoldYellow</span><span class="token operator">=</span><span class="token number">255,255</span>,64<span class="token assign-left variable">Blue</span><span class="token operator">=</span><span class="token number">0,128</span>,255<span class="token assign-left variable">BoldBlue</span><span class="token operator">=</span><span class="token number">128,160</span>,255<span class="token assign-left variable">Magenta</span><span class="token operator">=</span><span class="token number">211,54</span>,130<span class="token assign-left variable">BoldMagenta</span><span class="token operator">=</span><span class="token number">255,128</span>,255<span class="token assign-left variable">Cyan</span><span class="token operator">=</span><span class="token number">64,190</span>,190<span class="token assign-left variable">BoldCyan</span><span class="token operator">=</span><span class="token number">128,255</span>,255<span class="token assign-left variable">White</span><span class="token operator">=</span><span class="token number">200,200</span>,200<span class="token assign-left variable">BoldWhite</span><span class="token operator">=</span><span class="token number">255,255</span>,255<span class="token assign-left variable">BellTaskbar</span><span class="token operator">=</span>no<span class="token assign-left variable">Term</span><span class="token operator">=</span>xterm<span class="token assign-left variable">FontWeight</span><span class="token operator">=</span><span class="token number">400</span><span class="token assign-left variable">FontIsBold</span><span class="token operator">=</span>no</code></pre><p>最后重启Git-Bash就可以看到配置好的界面了</p><p>效果图:</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="https://aexphoto-1251755124.file.myqcloud.com/img/2022/02/b59d6821407fde73b5f757df99c3b600.png" alt="image-20220225095728006" title> </div> <div class="image-caption">image-20220225095728006</div> </figure><p>另外说一下第一行是在 Options 中选择字体时设置的,我使用了 Fira Code, 14号字体, Fira Code就是一款为写程序而生的字体</p><p>以上内容参考网络文章 有兴趣的可以深入了解<a href="http://www.voidcn.com/article/p-wavhthxe-tr.html">这里</a>, 不过也有可能无法访问了</p><h3 id="Fira-Code"><a href="#Fira-Code" class="headerlink" title="Fira Code"></a>Fira Code</h3><p><a href="https://www.jianshu.com/p/266b4fa2c446?tdsourcetag=s_pctim_aiomsg">Fira</a> 是 Mozilla 公司(火狐浏览器她爹)主推的字体系列。Fira Code 是其中的一员,专为写程序而生。出来具有<code>等宽</code>等基本属性外,还加入了编程连字特性(ligatures)。</p><p>Fira Code 就是利用这个特性对编程中的常用符号进行优化,比如把输入的「!=」直接显示成「≠」或者把「>=」变成「≥ 」等等,以此来提高代码的可读性</p><p>本人的使用的IDE也是装的这一款字体, 咳咳跑题了..</p><h3 id="一言与终端结合"><a href="#一言与终端结合" class="headerlink" title="一言与终端结合"></a>一言与终端结合</h3><p>去年无意发现一个名叫 <a href="https://hitokoto.cn/">一言</a> 的网站, 这个网站只是单纯的提供一句话, 可以是动漫中的台词,也可以是网络上的各种小段子。 或是感动,或是开心,有或是单纯的回忆</p><p> 并且还官方还提供了 <a href="https://developer.hitokoto.cn/sentence/#%E7%AE%80%E4%BB%8B">API接口文档</a> 供我们免费调用, 于是并尝试了把该功能与终端做结合, 大概就是, 启动终端时请求API, 把随机返回的句子显示在终端上, 我认为是个有趣的想法, 具体实现思路, 写一个请求一言API的脚本, 终端启动时自动调用一次这个脚本</p><p>效果如下:</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="https://aexphoto-1251755124.file.myqcloud.com/img/2022/02/6000258bf5290f8a45b134500f78ed39.png" alt="图片" title> </div> <div class="image-caption">图片</div> </figure><p>编写一言脚本, 文件名和路径没有具体要求, 看个人</p><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token function">vim</span> yy</code></pre><p>具体代码<a href="https://github.com/chuchu-z/local-config/blob/master/yy">GitHub</a>上也有, 直接拿下面的也行:</p><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token comment"># 一言</span><span class="token comment"># 返回普通文本</span><span class="token comment">#`curl -ks https://v1.hitokoto.cn/?encode=text`</span><span class="token assign-left variable">url</span><span class="token operator">=</span><span class="token string">'https://v1.hitokoto.cn'</span><span class="token keyword">if</span> <span class="token punctuation">[</span> x<span class="token variable">$1</span> <span class="token operator">!=</span> x <span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">then</span> <span class="token assign-left variable">url</span><span class="token operator">=</span><span class="token string">'https://v1.hitokoto.cn?'</span><span class="token variable">$1</span><span class="token keyword">fi</span><span class="token comment"># 处理 json 数据(处理json数据需要安装jq)</span><span class="token assign-left variable">json</span><span class="token operator">=</span><span class="token variable"><span class="token variable">`</span><span class="token function">curl</span> <span class="token parameter variable">-ks</span> $url<span class="token variable">`</span></span><span class="token comment"># linux 安裝jq</span><span class="token comment"># yum install epel-release</span><span class="token comment"># yum list jq</span><span class="token comment"># yum install jq</span><span class="token comment"># windows 安裝jq</span><span class="token comment"># https://stedolan.github.io/jq/</span><span class="token assign-left variable">random</span><span class="token operator">=</span>$<span class="token punctuation">[</span><span class="token environment constant">RANDOM</span>%7+31<span class="token punctuation">]</span><span class="token builtin class-name">echo</span> <span class="token parameter variable">-e</span><span class="token assign-left variable">content</span><span class="token operator">=</span><span class="token variable"><span class="token variable">`</span><span class="token builtin class-name">echo</span> $<span class="token punctuation">{</span>json<span class="token punctuation">}</span> <span class="token operator">|</span> jq <span class="token string">'.hitokoto'</span> <span class="token operator">|</span> <span class="token function">sed</span> <span class="token string">'s/"//g'</span> <span class="token operator">|</span> <span class="token function">tr</span> <span class="token parameter variable">-d</span> <span class="token string">'\n'</span><span class="token variable">`</span></span><span class="token builtin class-name">printf</span> <span class="token string">"<span class="token entity" title="\033">\033</span>[1;<span class="token variable">${random}</span>m%s<span class="token entity" title="\033">\033</span>[0m"</span> <span class="token string">"『 "</span> <span class="token variable">$content</span> <span class="token string">" 』"</span><span class="token assign-left variable">from_who</span><span class="token operator">=</span><span class="token variable"><span class="token variable">`</span><span class="token builtin class-name">echo</span> $<span class="token punctuation">{</span>json<span class="token punctuation">}</span> <span class="token operator">|</span> jq <span class="token string">'.from_who'</span> <span class="token operator">|</span> <span class="token function">sed</span> <span class="token string">'s/"//g'</span> <span class="token operator">|</span> <span class="token function">tr</span> <span class="token parameter variable">-d</span> <span class="token string">'\n'</span><span class="token variable">`</span></span><span class="token builtin class-name">echo</span> <span class="token parameter variable">-e</span><span class="token keyword">if</span> <span class="token punctuation">[</span> <span class="token string">"<span class="token variable">$from_who</span>"</span> <span class="token operator">==</span> <span class="token string">'null'</span> <span class="token punctuation">]</span><span class="token keyword">then</span> <span class="token assign-left variable">from_who</span><span class="token operator">=</span><span class="token string">'匿名'</span><span class="token keyword">fi</span><span class="token assign-left variable">length</span><span class="token operator">=</span><span class="token variable"><span class="token variable">`</span><span class="token function">expr</span> $<span class="token punctuation">{</span>#content<span class="token punctuation">}</span> <span class="token punctuation">\</span>* <span class="token number">2</span><span class="token variable">`</span></span><span class="token builtin class-name">printf</span> <span class="token string">"<span class="token entity" title="\033">\033</span>[1;<span class="token variable">${random}</span>m%<span class="token variable">${length}</span>s<span class="token entity" title="\033">\033</span>[0m"</span> <span class="token string">"—— <span class="token variable">$from_who</span>"</span><span class="token assign-left variable">from</span><span class="token operator">=</span><span class="token variable"><span class="token variable">`</span><span class="token builtin class-name">echo</span> $<span class="token punctuation">{</span>json<span class="token punctuation">}</span> <span class="token operator">|</span> jq <span class="token string">'.from'</span> <span class="token operator">|</span> <span class="token function">sed</span> <span class="token string">'s/"//g'</span> <span class="token operator">|</span> <span class="token function">tr</span> <span class="token parameter variable">-d</span> <span class="token string">'\n'</span><span class="token variable">`</span></span><span class="token builtin class-name">printf</span> <span class="token string">"<span class="token entity" title="\033">\033</span>[1;<span class="token variable">${random}</span>m%s<span class="token entity" title="\033">\033</span>[0m"</span> <span class="token string">"「"</span> <span class="token variable">$from</span> <span class="token string">"」"</span><span class="token builtin class-name">echo</span> <span class="token parameter variable">-e</span><span class="token builtin class-name">exit</span> <span class="token number">0</span></code></pre><p>编写完后可以试着执行 yy脚本一下试试 (代码里有说明要安装jq处理json数据)</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="https://aexphoto-1251755124.file.myqcloud.com/img/2022/02/4bafe9395e8ebc8797efa3ffe93e244e.png" alt="具体效果" title> </div> <div class="image-caption">具体效果</div> </figure><p>最后编辑~/.bashrc文件, 因为Git-Bash启动时会加载此文件</p><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token function">vim</span> ~/.bashrc</code></pre><p>在文件内容里加上yy后保存退出重新启动Git-Bash就行, (我能直接执行yy是配置了环境变量的, 如果没有配置的话需要写绝对路径)</p><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token comment"># vim ~/.bashrc</span><span class="token comment"># Git-Bash 初始化加载此配置文件</span><span class="token comment"># shopt -s expand_aliases</span><span class="token comment"># 允许shell脚本中使用 alias 命令</span><span class="token comment"># 经测试, 在 #!/bin/sh 下, 该命令可有可无, 不影响 alias 的使用</span><span class="token comment"># 在 !/bin/bash 下,才有影响</span>yy</code></pre>]]></content>
<summary type="html"><p>由于Git默认的界面长的实在是不够美观, 平时用起来都无法赏心悦目, 参考网上的一些文章资料, 做了下改动</p></summary>
<category term="Git" scheme="http://chuchu-z.com/categories/git/"/>
</entry>
<entry>
<title>一言网(hitokoto.cn)API接入shell脚本</title>
<link href="http://chuchu-z.com/posts/hitokoto-api-shell/"/>
<id>http://chuchu-z.com/posts/hitokoto-api-shell/</id>
<published>2022-02-24T03:49:48.000Z</published>
<updated>2024-12-31T06:57:56.017Z</updated>
<content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>之前发现个很不错的网站 <a href="hitokoto.cn"> 一言网(hitokoto.cn)</a> 很喜欢该网站的提供的服务</p><img src="/posts/hitokoto-api-shell/image-20231225124236829.png" style="zoom:150%;"><p>并且他们还提供了免费的API接口, 只需要访问该接口, 就会返回一段话 <a href="https://v1.hitokoto.cn/?encode=text">https://v1.hitokoto.cn/?encode=text</a> </p><p>于是我就更想把它做进我的<strong>shell</strong>终端里</p><span id="more"></span><h2 id="接口文档"><a href="#接口文档" class="headerlink" title="接口文档"></a>接口文档</h2><blockquote><p>一言接口文档</p><p><a href="https://developer.hitokoto.cn/sentence/">https://developer.hitokoto.cn/sentence/</a></p></blockquote><h2 id="具体脚本代码"><a href="#具体脚本代码" class="headerlink" title="具体脚本代码"></a>具体脚本代码</h2><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token comment"># 返回普通文本</span><span class="token comment">#`curl -ks https://v1.hitokoto.cn/?encode=text`</span><span class="token assign-left variable">url</span><span class="token operator">=</span><span class="token string">'https://v1.hitokoto.cn'</span><span class="token keyword">if</span> <span class="token punctuation">[</span> x<span class="token variable">$1</span> <span class="token operator">!=</span> x <span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">then</span> <span class="token assign-left variable">url</span><span class="token operator">=</span><span class="token string">'https://v1.hitokoto.cn?'</span><span class="token variable">$1</span><span class="token keyword">fi</span><span class="token comment"># 处理 json 数据(处理json数据需要安装jq)</span><span class="token assign-left variable">json</span><span class="token operator">=</span><span class="token variable"><span class="token variable">`</span><span class="token function">curl</span> <span class="token parameter variable">-ks</span> $url<span class="token variable">`</span></span><span class="token comment"># linux 安裝jq</span><span class="token comment"># yum install epel-release</span><span class="token comment"># yum list jq</span><span class="token comment"># yum install jq</span><span class="token comment"># windows 安裝jq</span><span class="token comment"># https://stedolan.github.io/jq/</span><span class="token assign-left variable">random</span><span class="token operator">=</span>$<span class="token punctuation">[</span><span class="token environment constant">RANDOM</span>%7+31<span class="token punctuation">]</span><span class="token builtin class-name">echo</span> <span class="token parameter variable">-e</span><span class="token assign-left variable">content</span><span class="token operator">=</span><span class="token variable"><span class="token variable">`</span><span class="token builtin class-name">echo</span> $<span class="token punctuation">{</span>json<span class="token punctuation">}</span> <span class="token operator">|</span> jq <span class="token string">'.hitokoto'</span> <span class="token operator">|</span> <span class="token function">sed</span> <span class="token string">'s/"//g'</span> <span class="token operator">|</span> <span class="token function">tr</span> <span class="token parameter variable">-d</span> <span class="token string">'\n'</span><span class="token variable">`</span></span><span class="token builtin class-name">printf</span> <span class="token string">"<span class="token entity" title="\033">\033</span>[1;<span class="token variable">${random}</span>m%s<span class="token entity" title="\033">\033</span>[0m"</span> <span class="token string">"『 "</span> <span class="token variable">$content</span> <span class="token string">" 』"</span><span class="token assign-left variable">from_who</span><span class="token operator">=</span><span class="token variable"><span class="token variable">`</span><span class="token builtin class-name">echo</span> $<span class="token punctuation">{</span>json<span class="token punctuation">}</span> <span class="token operator">|</span> jq <span class="token string">'.from_who'</span> <span class="token operator">|</span> <span class="token function">sed</span> <span class="token string">'s/"//g'</span> <span class="token operator">|</span> <span class="token function">tr</span> <span class="token parameter variable">-d</span> <span class="token string">'\n'</span><span class="token variable">`</span></span><span class="token builtin class-name">echo</span> <span class="token parameter variable">-e</span><span class="token keyword">if</span> <span class="token punctuation">[</span> <span class="token string">"<span class="token variable">$from_who</span>"</span> <span class="token operator">==</span> <span class="token string">'null'</span> <span class="token punctuation">]</span><span class="token keyword">then</span> <span class="token assign-left variable">from_who</span><span class="token operator">=</span><span class="token string">'匿名'</span><span class="token keyword">fi</span><span class="token assign-left variable">length</span><span class="token operator">=</span><span class="token variable"><span class="token variable">`</span><span class="token function">expr</span> $<span class="token punctuation">{</span>#content<span class="token punctuation">}</span> <span class="token punctuation">\</span>* <span class="token number">2</span><span class="token variable">`</span></span><span class="token builtin class-name">printf</span> <span class="token string">"<span class="token entity" title="\033">\033</span>[1;<span class="token variable">${random}</span>m%<span class="token variable">${length}</span>s<span class="token entity" title="\033">\033</span>[0m"</span> <span class="token string">"—— <span class="token variable">$from_who</span>"</span><span class="token assign-left variable">from</span><span class="token operator">=</span><span class="token variable"><span class="token variable">`</span><span class="token builtin class-name">echo</span> $<span class="token punctuation">{</span>json<span class="token punctuation">}</span> <span class="token operator">|</span> jq <span class="token string">'.from'</span> <span class="token operator">|</span> <span class="token function">sed</span> <span class="token string">'s/"//g'</span> <span class="token operator">|</span> <span class="token function">tr</span> <span class="token parameter variable">-d</span> <span class="token string">'\n'</span><span class="token variable">`</span></span><span class="token builtin class-name">printf</span> <span class="token string">"<span class="token entity" title="\033">\033</span>[1;<span class="token variable">${random}</span>m%s<span class="token entity" title="\033">\033</span>[0m"</span> <span class="token string">"「"</span> <span class="token variable">$from</span> <span class="token string">"」"</span><span class="token builtin class-name">echo</span> <span class="token parameter variable">-e</span><span class="token builtin class-name">exit</span> <span class="token number">0</span></code></pre>]]></content>
<summary type="html"><h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>之前发现个很不错的网站 <a href="hitokoto.cn"> 一言网(hitokoto.cn)</a> 很喜欢该网站的提供的服务</p>
<img src="/posts/hitokoto-api-shell/image-20231225124236829.png" style="zoom:150%;">
<p>并且他们还提供了免费的API接口, 只需要访问该接口, 就会返回一段话 <a href="https://v1.hitokoto.cn/?encode=text">https://v1.hitokoto.cn/?encode=text</a> </p>
<p>于是我就更想把它做进我的<strong>shell</strong>终端里</p></summary>
<category term="Linux" scheme="http://chuchu-z.com/categories/linux/"/>
</entry>
<entry>
<title>Docker环境初始化及安装php扩展</title>
<link href="http://chuchu-z.com/posts/docker-init-php-extensions/"/>
<id>http://chuchu-z.com/posts/docker-init-php-extensions/</id>
<published>2021-12-30T06:53:42.000Z</published>
<updated>2024-12-31T06:57:56.013Z</updated>
<content type="html"><![CDATA[<blockquote><p>这只是一段操作命令的过程, 没有任何值得学习的地方…😁</p></blockquote><span id="more"></span><pre class="language-bash" data-language="bash"><code class="language-bash">yum <span class="token parameter variable">-y</span> <span class="token function">install</span> <span class="token function">vim</span><span class="token function">vim</span> /root/.bashrc<span class="token comment"># 设置alias</span><span class="token builtin class-name">alias</span> <span class="token assign-left variable">e</span><span class="token operator">=</span><span class="token string">'exit'</span><span class="token builtin class-name">alias</span> <span class="token assign-left variable">www</span><span class="token operator">=</span><span class="token string">'cd /home/www/task_server'</span><span class="token comment"># 写入设置utf8编码,否则乱码,设置好后先保存退出,并执行source /root/.bashrc生效,再设置PS1变量</span><span class="token builtin class-name">export</span> <span class="token assign-left variable"><span class="token environment constant">LANG</span></span><span class="token operator">=</span><span class="token string">"en_US.utf8"</span><span class="token comment"># 设置完编码后这里先退出保存一次,先让编码生效, 然后再打开编辑</span><span class="token builtin class-name">source</span> /root/.bashrc<span class="token comment"># 设置PS1变量</span><span class="token builtin class-name">export</span> <span class="token assign-left variable"><span class="token environment constant">PS1</span></span><span class="token operator">=</span><span class="token string">"\[<span class="token entity" title="\033">\033</span>]0;Docker<span class="token entity" title="\007">\007</span>\]<span class="token entity" title="\n">\n</span>\[<span class="token entity" title="\033">\033</span>[32;1m\] ➜ \[<span class="token entity" title="\033">\033</span>[33;1m\]\W\[<span class="token entity" title="\033">\033</span>[34;1m\] [<span class="token entity" title="\t">\t</span>]\[<span class="token entity" title="\033">\033</span>[31m\]\[<span class="token entity" title="\033">\033</span>[36m\] "</span><span class="token comment"># 保存退出</span><span class="token builtin class-name">source</span> /root/.bashrc<span class="token comment"># 新框架资产中心需要用到GRPC, Docker环境下安装GRPC</span><span class="token comment"># 查看版本</span>pecl version <span class="token comment">#如果没有安装 pecl</span><span class="token comment"># php版本 > 7</span><span class="token function">wget</span> http://pear.php.net/go-pear.pharphp go-pear.phar<span class="token comment"># php版本 < 7</span>yum <span class="token function">install</span> php-pear<span class="token comment">#否则会报错PHP Parse error: syntax error, unexpected //'new' (T_NEW) in /usr/share/pear/PEAR/Frontend.php on //line 91</span><span class="token comment"># 安装 grpc</span>pecl <span class="token function">install</span> grpc<span class="token comment"># 因为pecl没有加入PATH变量, 如果默认pecl PHP版本小于7.0 则可以使用一下路径方式或者把/usr/local/php/bin/加入PATH变量</span>/usr/local/php/bin/pecl <span class="token function">install</span> protobuf/usr/local/php/bin/pecl <span class="token function">install</span> grpc/usr/local/php/bin/pecl <span class="token function">install</span> apcu<span class="token comment"># GCC版本4.8编译报错, 升级版本到gcc 7.3</span>yum <span class="token parameter variable">-y</span> <span class="token function">install</span> centos-release-sclyum <span class="token parameter variable">-y</span> <span class="token function">install</span> devtoolset-7-gcc devtoolset-7-gcc-c++ devtoolset-7-binutilsscl <span class="token builtin class-name">enable</span> devtoolset-7 <span class="token function">bash</span><span class="token builtin class-name">echo</span> <span class="token string">"source /opt/rh/devtoolset-7/enable"</span> <span class="token operator">>></span>/etc/profile<span class="token comment"># ssh证书问题 如果没有openssl文件夹先创建</span><span class="token function">wget</span> http://curl.haxx.se/ca/cacert.pem <span class="token operator">&&</span> <span class="token function">mv</span> cacert.pem /usr/local/openssl/cert.pem<span class="token comment"># 写入配置</span><span class="token builtin class-name">echo</span> <span class="token string">"extension=grpc.so"</span> <span class="token operator">>></span> /usr/local/php/etc/php.ini<span class="token builtin class-name">echo</span> <span class="token string">"extension=protobuf.so"</span> <span class="token operator">>></span> /usr/local/php/etc/php.ini<span class="token builtin class-name">echo</span> <span class="token string">"extension=apcu.so"</span> <span class="token operator">>></span> /usr/local/php/etc/php.ini<span class="token comment">#重启Docker</span></code></pre><h3 id="Docker-启动报错"><a href="#Docker-启动报错" class="headerlink" title="Docker 启动报错"></a>Docker 启动报错</h3><pre class="language-bash" data-language="bash"><code class="language-bash">Docker.Core.Backend.BackendException:Error response from daemon: <span class="token function">open</span> <span class="token punctuation">\</span><span class="token punctuation">\</span>.<span class="token punctuation">\</span>pipe<span class="token punctuation">\</span>docker_engine_linux: The system cannot <span class="token function">find</span> the <span class="token function">file</span> specified.</code></pre><p><strong>在win10 管理员身份打开cmd命令行提示符执行:</strong></p><pre class="language-bash" data-language="bash"><code class="language-bash">Net stop com.docker.serviceNet start com.docker.service</code></pre><h3 id="以往安装时执行过的命令参考"><a href="#以往安装时执行过的命令参考" class="headerlink" title="以往安装时执行过的命令参考"></a>以往安装时执行过的命令参考</h3><pre class="language-bash" data-language="bash"><code class="language-bash"><span class="token number">1</span> vp<span class="token number">2</span> php <span class="token parameter variable">-m</span><span class="token number">3</span> e<span class="token number">4</span> <span class="token builtin class-name">logout</span><span class="token number">5</span> <span class="token builtin class-name">exit</span><span class="token number">6</span> <span class="token builtin class-name">exit</span><span class="token number">7</span> yum <span class="token parameter variable">-y</span> <span class="token function">install</span> <span class="token function">vim</span><span class="token number">8</span> <span class="token function">vim</span> /root/.bashrc<span class="token number">9</span> <span class="token builtin class-name">source</span> /root/.bashrc<span class="token number">10</span> <span class="token function">vim</span> /root/.bashrc<span class="token number">11</span> <span class="token builtin class-name">source</span> /root/.bashrc<span class="token number">12</span> pecl version <span class="token number">13</span> <span class="token function">wget</span> http://pear.php.net/go-pear.phar<span class="token number">14</span> php go-pear.phar<span class="token number">15</span> <span class="token function">wget</span> http://pear.php.net/go-pear.phar<span class="token number">16</span> php go-pear.phar<span class="token number">17</span> yum <span class="token function">install</span> php-pear<span class="token number">18</span> pecl <span class="token function">install</span> grpc<span class="token number">19</span> /usr/local/php/bin/pecl <span class="token function">install</span> protobuf<span class="token number">20</span> /usr/local/php/bin/pecl <span class="token function">install</span> protobuf<span class="token number">21</span> /usr/local/php/bin/pecl <span class="token function">install</span> grpc<span class="token number">22</span> yum <span class="token function">install</span> php70w-devel<span class="token number">23</span> /usr/bin/phpize<span class="token number">24</span> <span class="token function">which</span> phpize<span class="token number">25</span> /usr/bin/phpize<span class="token number">26</span> yum <span class="token function">install</span> php-devel <span class="token number">27</span> php <span class="token parameter variable">-v</span><span class="token number">28</span> yum <span class="token function">install</span> php70w-devel <span class="token number">29</span> /usr/bin/phpize<span class="token number">30</span> <span class="token function">which</span> php<span class="token number">31</span> <span class="token builtin class-name">cd</span> /usr/local/bin/php<span class="token number">32</span> <span class="token builtin class-name">pwd</span><span class="token number">33</span> ll<span class="token number">34</span> /usr/local/php/bin/pecl <span class="token function">install</span> protobuf<span class="token number">35</span> /usr/local/php/bin/pecl <span class="token function">install</span> grpc<span class="token number">36</span> gcc <span class="token parameter variable">--version</span><span class="token number">37</span> g++ <span class="token parameter variable">--version</span><span class="token number">38</span> yum <span class="token parameter variable">-y</span> <span class="token function">install</span> centos-release-scl<span class="token number">39</span> yum <span class="token parameter variable">-y</span> <span class="token function">install</span> devtoolset-6-gcc devtoolset-6-gcc-c++ devtoolset-6-binutils<span class="token number">40</span> scl <span class="token builtin class-name">enable</span> devtoolset-6 <span class="token function">bash</span><span class="token number">41</span> yum <span class="token function">install</span> centos-release-scl scl-utils-build<span class="token number">42</span> yum list all <span class="token parameter variable">--enablerepo</span><span class="token operator">=</span><span class="token string">'centos-sclo-rh'</span><span class="token number">43</span> yum <span class="token function">install</span> devtoolset-4-gcc.x86_64 devtoolset-4-gcc-c++.x86_64 devtoolset-4-gcc-gdb-plugin.x86_64 <span class="token number">44</span> scl <span class="token parameter variable">--list</span> 或 scl <span class="token parameter variable">-l</span><span class="token number">45</span> scl <span class="token parameter variable">--list</span><span class="token number">46</span> gcc <span class="token parameter variable">-v</span><span class="token number">47</span> php <span class="token parameter variable">-m</span><span class="token number">48</span> e<span class="token number">49</span> /usr/local/php/bin/pecl <span class="token function">install</span> protobuf<span class="token number">50</span> /usr/local/php/bin/pecl channel-update pecl.php.net<span class="token number">51</span> /usr/local/php/bin/pecl <span class="token function">install</span> protobuf<span class="token number">52</span> e<span class="token number">53</span> pecl version <span class="token number">54</span> <span class="token function">wget</span> http://pear.php.net/go-pear.phar<span class="token number">55</span> php go-pear.phar<span class="token number">56</span> <span class="token function">vim</span> /etc/profile<span class="token number">57</span> <span class="token function">vim</span> ~/.bashrc <span class="token number">58</span> <span class="token function">vim</span> ~/.bashrc <span class="token number">59</span> <span class="token builtin class-name">source</span> ~/.bashrc<span class="token number">60</span> gcc <span class="token parameter variable">--version</span><span class="token number">61</span> g++ <span class="token parameter variable">--version</span><span class="token number">62</span> /usr/local/php/bin/pecl <span class="token function">install</span> protobuf<span class="token number">63</span> <span class="token function">wget</span> http://curl.haxx.se/ca/cacert.pem <span class="token operator">&&</span> <span class="token function">mv</span> cacert.pem /usr/local/openssl/cert.pem<span class="token number">64</span> ll<span class="token number">65</span> /usr/local/php/bin/pecl <span class="token function">install</span> protobuf<span class="token number">66</span> /usr/local/php/bin/pecl <span class="token function">install</span> grpc<span class="token number">67</span> /usr/local/php/bin/pecl <span class="token function">install</span> grpc<span class="token number">68</span> /usr/local/php/bin/pecl <span class="token function">install</span> apcu<span class="token number">69</span> /usr/local/php/bin/pecl <span class="token function">install</span> apcu<span class="token number">70</span> <span class="token function">wget</span> http://curl.haxx.se/ca/cacert.pem <span class="token operator">&&</span> <span class="token function">mv</span> cacert.pem /usr/local/openssl/cert.pem<span class="token number">71</span> ll<span class="token number">72</span> <span class="token builtin class-name">cd</span> /usr/local/openssl<span class="token number">73</span> <span class="token builtin class-name">cd</span> /usr/local/<span class="token number">74</span> <span class="token function">mkdir</span> openssl<span class="token number">75</span> <span class="token builtin class-name">cd</span> -<span class="token number">76</span> <span class="token function">mv</span> cacert.pem /usr/local/openssl/cert.pem<span class="token number">77</span> /usr/local/php/bin/pecl <span class="token function">install</span> apcu<span class="token number">78</span> <span class="token function">vim</span> /usr/local/php/etc/php.ini<span class="token number">79</span> e<span class="token number">80</span> pecl <span class="token function">install</span> grpc<span class="token number">81</span> pecl channel-update pecl.php.net<span class="token number">82</span> pecl <span class="token function">install</span> grpc<span class="token number">83</span> yum <span class="token parameter variable">-y</span> <span class="token function">install</span> centos-release-scl<span class="token number">84</span> yum <span class="token parameter variable">-y</span> <span class="token function">install</span> devtoolset-7-gcc devtoolset-7-gcc-c++ devtoolset-7-binutils<span class="token number">85</span> scl <span class="token builtin class-name">enable</span> devtoolset-7 <span class="token function">bash</span><span class="token number">86</span> e<span class="token number">87</span> www<span class="token number">88</span> php tinyBell.php<span class="token number">89</span> php tinyBell.php start<span class="token number">90</span> php tinyBell.php start<span class="token number">91</span> <span class="token builtin class-name">pwd</span><span class="token number">92</span> e</code></pre>]]></content>
<summary type="html"><blockquote>
<p>这只是一段操作命令的过程, 没有任何值得学习的地方…😁</p>
</blockquote></summary>
<category term="Docker" scheme="http://chuchu-z.com/categories/docker/"/>
</entry>
</feed>