vault backup: 2025-12-04 09:12:56

This commit is contained in:
杜鹏飞
2025-12-04 09:12:56 +08:00
commit 71e83861de
300 changed files with 339584 additions and 0 deletions

154
技术探究/2021-10-23.md Normal file
View File

@@ -0,0 +1,154 @@
---
date created: 2022-01-01 21:22
---
# mysql 字段编码的问题
mysql 编码有 数据库编码 表编码 字段编码
[mysql 中查看表、字段的编码格式_what you want!-CSDN博客](https://blog.csdn.net/zf472422160/article/details/84604124)
```sql
-- 查看表的字段编码
show full columns from dacp_dataex_cdr;
-- 查看表的编码格式:
show create table dacp_dataex_cdr;
-- 修改数据库的编码格式:
mysql>alter database databasename character set utf8
-- 修改表的编码格式 (不会修改列)
mysql>alter table tablename character set utf8
## alter table t2 default character set utf8mb4; -- (不会修改列)
alter table t2 convert to character set utf8mb4;
-- 修改字段的编码格式 这句会修改所有列
alter table tablename modify fieldname varchar(50) character set utf8
```
原来的表中之前定义的列字段的编码类型不会因为表的编码格式而变化还是latin1(拉丁文格式) 但新建列的类型为是UTF8格式的。由此可见MYSQL中的数据编码格式已经粒子化到 单位“列”。 在建 数据库的时候可以指定数据库编码格式,在这之后所建的表和列的编码格式都会以此格式为默认格式。若之后想改数据库的编码格式的话,想要把之前的表和列的编码格式都改过来的话就要一一改过来了。
**批量改字符 的字段,其他好像没有方便的方法**
```sql
-- **把表默认的字符集和所有字符列CHAR,VARCHAR,TEXT改为新的字符集**
ALTER TABLE dacp_dataex_cdr CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;
ALTER TABLE dacp_dataex_cdr CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
```
[更改表的字符集utf8 to utf8mb4_多维217的博客-CSDN博客_修改表的字符集](https://blog.csdn.net/wl21787/article/details/107090351/)
[mysql 字符编码的查看与修改 - tresser - 博客园](https://www.cnblogs.com/tresser/p/9308045.html)
# mysqldump 数据导出详解
[MySQL mysqldump数据导出详解 - pursuer.chen - 博客园](https://www.cnblogs.com/chenmh/p/5300370.html)
```shell
mysqldump \
--host=127.0.0.1 --user=root -p --port=5623 \
--default-character-set=utf8mb4 \
--master-data=2 --single-transaction test t2 >/data/mysql/tmp/t2.sql
```
## ignore-table 排除表
```shell
mysqldump -u root -p DB_NAME --ignore-table=DB_NAME.table1 --ignore-table=DB_NAME.table3 > database.sql
docker run --rm mysql:5.7 mysqldump -h172.22.4.41 -uroot -pqa@123 --ignore-table=ci_jszf_dev.dacp_trace_log --ignore-table=ci_jszf_dev.dacp_trace_log_bak -B ci_jszf_dev > /data01/dataos_mysql_backup/${today}/ci_jszf_dev.sql
```
# 查看mysql数据库容量大小
[查看mysql数据库容量大小 - --smile - 博客园](https://www.cnblogs.com/--smile/p/11451238.html)
## 查看所有数据库各容量大小
```sql
select
table_schema as '数据库',
sum(table_rows) as '记录数',
sum(truncate(data_length/1024/1024, 2)) as '数据容量(MB)',
sum(truncate(index_length/1024/1024, 2)) as '索引容量(MB)'
from information_schema.tables
group by table_schema
order by sum(data_length) desc, sum(index_length) desc;
```
# Mysql 复制数据库及数据
[Mysql 复制数据库及数据 - ㄓㄤㄑㄧㄤ - 博客园](https://www.cnblogs.com/azhqiang/p/13177683.html)
```sql
create database ci_jszf_dev_new default character set utf8mb4 collate utf8mb4_general_ci;
create database ci_jszf_dev_new default character set utf8 collate utf8_general_ci;
./mysqldump ci_jszf_dev -uroot -pqa@123 --add-drop-table | ./mysql ci_jszf_dev_new -uroot -pqa@123
mysqldump data -u root -p123456 --add-drop-table | mysql -h 192.168.1.22 newdata -u root -p123456
docker exec -it mysql57_185 /bin/bash
mysql -uroot -pCq185@mDxKpa
mysqldump jfzx_manage_dev -u root -pCq185@mDxKpa --add-drop-table | mysql jfzx_manage_0825_back -uroot -pCq185@mDxKpa
mysqldump jfzx_system_dev -u root -pCq185@mDxKpa --add-drop-table | mysql jfzx_system_0825_back -uroot -pCq185@mDxKpa
```
# mysql 数据库 改名
[MySQL数据库改名的三种方法 - yayun - 博客园](https://www.cnblogs.com/gomysql/p/3584881.html)
> shell 脚本改表名
```shell
docker exec -i mysql57 mysql -uroot -pMy1014@Do -e 'create database if not exists bak_ci_jszf_pro'
list_table=$(docker exec -i mysql57 mysql -uroot -pMy1014@Do -Nse "select table_name from information_schema.TABLES where TABLE_SCHEMA='ci_jszf_pro'")
for table in $list_table
do
docker exec -i mysql57 mysql -uroot -pMy1014@Do -e "rename table ci_jszf_pro.$table to bak_ci_jszf_pro.$table"
done
create database ci_jszf_dev_new default character set utf8 collate utf8_general_ci;
```
[为什么现在MySQL无法重命名数据库 - 知乎](https://www.zhihu.com/question/63551632)
> 数据量小 -- mysqldump
> 数据量大 -- 改表名
实际上 使用数据库复制的方法也可行
```shell
./mysqldump ci_jszf_dev -uroot -pqa@123 --add-drop-table | ./mysql ci_jszf_dev_new -uroot -pqa@123
docker exec -i mysql57 mysqldump ci_jszf_pro -uroot -pMy1014@Do --add-drop-table | docker exec -i mysql57 mysql bak_ci_jszf_pro -uroot -pMy1014@Do
docker exec -i mysql57 mysqldump ci_jszf_dev -uroot -pMy1014@Do --add-drop-table | docker exec -i mysql57 mysql bak_ci_jszf_dev -uroot -pMy1014@Do
```

View File

@@ -0,0 +1 @@
coze 智能体 tt8b19fda41412cbc501

View File

@@ -0,0 +1 @@
概念: 提示词、智能体

View File

@@ -0,0 +1,2 @@
postman 访问 es
![[Pasted image 20220322100217.png]]

28
技术探究/GO/CGO.md Normal file
View File

@@ -0,0 +1,28 @@
portaudio 音频处理库
使用 chocolaty
安装 pkg-config
**vcpkg**
```
git clone https://github.com/Microsoft/vcpkg.git .\vcpkg\bootstrap-vcpkg.bat
vcpkg install portaudio
vcpkg integrate install
choco install pkgconfiglite
set PKG_CONFIG_PATH=%PKG_CONFIG_PATH%;C:\path\to\vcpkg\installed\x64-windows\lib\pkgconfig
```
#### 1. 找到 PortAudio DLL 文件
- **如果你使用 vcpkg**:
- DLL 通常位于 `D:\projects\rpa_team\vcpkg\installed\x64-windows\bin\`
- 查找名为 `portaudio_x64.dll` 或 `libportaudio64.dll` 的文件。

View File

@@ -0,0 +1,29 @@
- 查看文件大小
```text
du -ah .git/objects
```
- 占用空间最多的五个文件
```text
git rev-list --objects --all | grep "$(git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -5 | awk '{print$1}')"
```
从 git 历史中移除
```text
git filter-branch --force --index-filter 'git rm -rf --cached --ignore-unmatch 你的大文件名' --prune-empty --tag-name-filter cat -- --all
```
真正删除
```text
rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --prune=now
git gc --aggressive --prune=now
git push origin master --force
```

View File

@@ -0,0 +1,25 @@
>
刘银 11-23 09:37:15
弄下dump日志有dump日志就好分析了
杜鹏飞 11-23 09:37:28
dump日志是程序输出日志么
杜鹏飞 11-23 09:39:55
我去操作下。。
刘银 11-23 09:41:12
![](file:///E:/Documents/WXWork/1688855439456504/Cache/Image/2023-11/企业微信截图_d118f4d1-c13d-4399-ac47-c581b303a019.png)
刘银 11-23 09:41:23
启动参数加上这个,
刘银 11-23 09:41:42
挂掉后会生成dump文件。
刘银 11-23 09:42:33
dump文件直接拖到idea里面结合代码就可以看到内存占用可以分析到哪行代码。
java 进程查看
```shell
top -o %MEM -b -n 1 | grep java | awk '{print "PID: "$1" \t 虚拟内存: "$5" \t 物理内存: "$6" \t 共享内存: "$7" \t CPU使用率: "$9"% \t 内存使用率: "$10"%"}'
```
线程查看
```shell
ps p {pid} -L -o pcpu,pmem,pid,tid,time,tname,cmd
```

View File

@@ -0,0 +1,32 @@
### mybatis xxx join 做连接查询
引入以下依赖
```xml
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-boot-starter</artifactId>
<version>1.4.9</version>
</dependency>
```
``` JAVA
import com.baomidou.mybatisplus.extension.service.IService;
to
import com.github.yulichang.base.MPJBaseService;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
to
import com.github.yulichang.base.MPJBaseMapper;
LambdaQueryWrapper
to
MPJLambdaWrapper
```
### 批量 性能 优化
> https://developer.aliyun.com/article/1055592
```
rewriteBatchedStatements=true
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

@@ -0,0 +1,18 @@
## feign 调用不成功
![[企业微信截图_16705110327149.png]]
![[企业微信截图_16705110828214.png]]
网卡不通,导致调用失败 设置 微服务 网卡
spring:
application:
# 应用名称
name: country-assets
profiles:
# 环境配置
active: @profiles.active@
cloud:
inetutils:
preferred-networks: 10.4.42
### scg spring cloud gateway 服务异常
http://www.manongjc.com/detail/27-iazhohptlxsunmg.html

View File

@@ -0,0 +1,49 @@
>https://www.cnblogs.com/liujunqiao/p/10719942.html
* yum -y install epel-release
```#epel库里就有fail2ban 直接安装epel库就可以使用```
* yum -y install fail2ban
```#安装fail2ban```
* systemctl enable fail2ban
* cd /etc/fail2ban
* cp jail.conf jail.local
> 可以删除所有配置,配置以下内容
```
[sshd-iptables]
enabled = true
port = 22922
filter = sshd
# 过滤参数对应filter.d 目录下的动作
action = iptables[name=SSH, port=22922, protocol=tcp]
# 动作参数 对应actioin.d目录下的动作当前使用iptables
logpath = %(sshd_log)s
backend = %(sshd_backend)s
maxretry = 3
findtime = 10m
# 10分钟内输错3次
bantime = 60m
# 60分钟内禁止链接实际为iptables增加了reject规则
```
* systemctl start fail2ban
* systemctl status fail2ban
* fail2ban-client status
查看fail2ban已经操作的ip
> iptables -nL
```
Chain f2b-SSH (1 references)
target prot opt source destination
RETURN all -- 0.0.0.0/0 0.0.0.0/0
```
* 解封ip
```
fail2ban-client set sshd-iptables unbanip xxx.xxx.xxx.xxx
set 后面的参数 为 jail.local 里面 [xxxx] 对应的节点 sshd-iptables
```

View File

@@ -0,0 +1,58 @@
### 所有环境均为security用户
```
#### 设置用户 工作 目录
mkdir /data/security
useradd -d /data/security -m security
#### 设置用户密码
passwd security
asiainfo_4321
chown -R security:security /data/security
chmod 760 /data/security
usermod -d /data/security security
cp /etc/skel/.bashrc /root/
cp /etc/skel/.bash_profile /root/
yum install -y java-devel
#### 设置主机名称
hostnamectl set-hostname xxxxx
```
修改文件格式内容换行符号
``` sed -i s/\r// **.sh```
### **chmod u+x**
chmod是权限管理命令change the permissions mode of a file的缩写。。
u代表所有者
x代表执行权限。
 + 表示增加权限。
chmod u+x *.sh 就表示对当前目录下的*.sh文件的所有者增加可执行权限
### 切换系统用户
> sudo -i
### 自定义 命令
```
vi ~/.bashrc
alias mysql5.7='/data/cnds/mysql/link_mysql-5.7.37.sh'
```
### 图形化 ui 界面
https://blog.csdn.net/u011811066/article/details/131155350
### 免密 互信
> https://blog.csdn.net/m0_71751187/article/details/138846235
>

View File

@@ -0,0 +1,54 @@
nohup command > /dev/null 2>&1 &
> \> 和 >> 区别,> 会先清空,>> 做追加
### 查看 MAC 地址
ifconfig 这是最常用的方式
ip link show
cat /sys/class/net/eth0/address 查看eth0的mac地址
dmesg | [grep](https://so.csdn.net/so/search?q=grep&spm=1001.2101.3001.7020) eth0
### 开放端口
一个
iptables -I INPUT -s 172.22.0.0/16 -p tcp --dport 5432 -j ACCEPT
iptables -I INPUT -s 125.81.157.249 -p tcp --dport 8848 -j ACCEPT
-m comment --comment "allow SSH to this host from anywhere"
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
service iptables save
所有
iptables -I INPUT -s  172.3.2.0/24 -p tcp --dport 1:65535 -j ACCEPT
> iptables 语法
>https://blog.csdn.net/niuch1029291561/article/details/130935708
### 获取运行脚本 位置
> $(dirname $(readlink -f "$0")
### 获取运行进程
> ll /proc/进程号
### 统计当前目录 文件个数 文件 计数
> ls -hl|grep ^d|wc -l
### 查看文件 大小
> du -h -d 1
### 整体替换 文字
```shell
find /data/zhsq/countryside/juyuan/ -type f|grep yml$|xargs sed -i 's/qinghai-country/juyuan-country/g'
```
### 查找文件 内容 文件名
```shell
grep -rl "pattern" /path/to/directory
file1.txt
file2.txt
file3.txt
```
### 图形化界面
>https://blog.csdn.net/u011811066/article/details/131155350

View File

@@ -0,0 +1,22 @@
简易版
ls -l /dev/vd*
fdisk -l /dev/vdb
fdisk /dev/vdb
n p 1 回车两下 t 8e w
pvcreate /dev/vdb1
vgcreate datavg /dev/vdb1
lvcreate -l 100%VG -n datalv datavg
mkfs -t ext4 /dev/datavg/datalv
mkdir /data
mount /dev/datavg/datalv /data
vi /etc/fstab
/dev/datavg/datalv /data ext4 defaults 0 0

View File

@@ -0,0 +1,12 @@
### 由于windows格式直接复制过来导致无法在linux上运行
set ff 查看
set ff=xxx
```
unix
dos
```
ff -> fileformat
>
:help ff

View File

@@ -0,0 +1,39 @@
```
根据进程号查看运行路径 例子13129
[root@ict-dmp2-2859 puaiuc]# ll /proc/13129
dr-xr-xr-x. 2 root root 0 1月 25 17:35 attr
-rw-r--r--. 1 root root 0 1月 25 17:38 autogroup
-r--------. 1 root root 0 1月 25 17:38 auxv
-r--r--r--. 1 root root 0 1月 25 17:38 cgroup
--w-------. 1 root root 0 1月 25 17:38 clear_refs
-r--r--r--. 1 root root 0 11月 15 14:11 cmdline
-rw-r--r--. 1 root root 0 1月 25 17:38 comm
-rw-r--r--. 1 root root 0 1月 25 17:38 coredump_filter
-r--r--r--. 1 root root 0 1月 25 17:38 cpuset
lrwxrwxrwx. 1 root root 0 1月 25 17:38 cwd -> /usr/local/nginx
-r--------. 1 root root 0 11月 15 14:11 environ
lrwxrwxrwx. 1 root root 0 11月 15 14:11 exe -> /usr/local/nginx/sbin/nginx
```
容器查看
```
docker exec -it bash
docker ps -a
```
shell 启动脚本 启停
```
pid=`ps -ef|grep xxxxxxxxx|grep -v grep|awk '{print $2}'`
echo $pid
kill -9 $pid
./xxxx >> log.mock 2>&1&
echo '-------'
pid=`ps -ef|grep xxxxxxxxx|grep -v grep|awk '{print $2}'`
echo $pid
```
## 问题排查 进程 cpu 内存 占用
```
ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%mem | head
```

View File

@@ -0,0 +1,8 @@
# NPM 包
* 登录仓库
* npm login --registry=http://cqaivm.860001.xyz:12245/repository/idi-private/
* 提示输入 用户名密码 admin/4KwKq4wd@A2Bjrjt
* 上传资源包
* npm publish --registry=http://cqaivm.860001.xyz:12245/repository/idi-private/
* 新项目 install
* npm install {static-file@1.0.0} --registry=http://cqaivm.860001.xyz:12245/repository/idi-private/

Binary file not shown.

After

Width:  |  Height:  |  Size: 349 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -0,0 +1,84 @@
<html><head></head><body><div id="content_views" class="htmledit_views">
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> <span style="text-indent:0px">作者:一帅</span></p>
<h2 style="margin:0px 0px 0.5em; font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; line-height:1.6em; color:rgb(51,51,51); font-size:18px; text-indent:1em; background-color:rgb(254,254,254)"><a name="t0"></a> 简介</h2>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> SQL任务是ODPS中使用最频繁的一类作业,大部分用户开始使用ODPS时要做的第一件事情就是学习怎么写ODPS的SQL。ODPS SQL是一种非常灵活的语言,兼容大部分的SQL92规范,也对大规模计算场景做了一些特别的定制。有些用户写出的SQL让人看了之后茅塞顿开的感觉,也有一些神级用户经常写一些1000多行的SQL,让人看的只想撞墙。本文会介绍一下SQL是如何分析解析,并拆解成分布式飞天任务的一些实现原理。</p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> <em>ps.由于一些历史包袱和工程实现的原因,ODPS某些内部实现细节可能与本文提到的不一致</em></p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> 语法分析的作用是将一个输入的‘字符串’变换为一个描述这个字符串的‘结构体’,让计算机可以更容易的理解用户输入的字符串是什么意义。这个阶段包含三个过程,分别是词法分析、语法分析、输出抽象语法树。</p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> 词法分析器是一个确定有限自动机&nbsp;<a target="_blank" href="http://zh.wikipedia.org/wiki/%E7%A1%AE%E5%AE%9A%E6%9C%89%E9%99%90%E7%8A%B6%E6%80%81%E8%87%AA%E5%8A%A8%E6%9C%BA" style="color:rgb(148,148,148); text-decoration:none; outline:none 0px; border-bottom-width:1px; border-bottom-style:dashed; border-bottom-color:rgb(148,148,148); font-style:italic; font-weight:bold" rel="noopener noreferrer">(DFA)</a>&nbsp;,可以按照我们定义好的词法,将输入的字符集转换为‘单词’。如下:</p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> <img alt="1" src="http://img0.tuicool.com/e2qeuu.png!web" style="max-width:96%; height:auto; vertical-align:middle; border:0px none; margin:0px auto; text-align:center; display:block"></p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> 在词法分析之后,接下来的过程就是语法分析了,词法分析的结果会作为语法分析的输入,语法分析在词法分析的基础上,来判断用户输入的单词是否符合语法逻辑,*SELECT FOO+100 FROM POKES*就是一个符合语法的句子,而*SELECT FOO+100 FROM*,是个不合法的语句,因为在FROM之后,一定要跟着一个表名。此时语法分析器会报错:</p>
<pre class="prettyprint undefined" style="padding:0.3em; font-family:Monaco,Menlo,Consolas,&quot;Courier New&quot;,monospace; color:rgb(51,51,51); margin-top:0px; margin-bottom:1.5em; line-height:1.5em; word-break:break-all; word-wrap:break-word; white-space:pre-wrap; overflow-y:auto; background-color:rgb(246,246,246)" name="code"><code style="padding:0.3em; font-family:Monaco,Menlo,Consolas,&quot;Courier New&quot;,monospace; border:0px; display:block; overflow-y:auto" class="hljs"><a target="_blank" href="http://blog.aliyun.com/wp-content/uploads/2014/06/2.png" style="color:rgb(148,148,148); text-decoration:none; outline:none 0px; border-bottom-width:1px; border-bottom-style:dashed; border-bottom-color:rgb(148,148,148); font-style:italic; font-weight:bold" rel="noopener noreferrer"><img class="alignnone size-medium wp-image-736" alt="2" src="http://img1.tuicool.com/n2iMJn.png!web" width="600" height="37" style="max-width:96%; height:34.0106px; vertical-align:middle; border:0px none; margin:0px auto; text-align:center; width:550px; display:block"></a>
</code><div class="hljs-button {2}" data-title="复制" data-report-click="{&quot;spm&quot;:&quot;1001.2101.3001.4259&quot;}" onclick="hljs.copyCode(event)"></div></pre>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> <code class="prettyprint" style="padding:2px 4px; font-family:Monaco,Menlo,Consolas,&quot;Courier New&quot;,monospace; border:none; background-color:rgb(247,247,249)">抽象语法树</code>&nbsp;<a target="_blank" href="http://baike.baidu.com/view/1874022.htm?fr=aladdin" style="color:rgb(148,148,148); text-decoration:none; outline:none 0px; border-bottom-width:1px; border-bottom-style:dashed; border-bottom-color:rgb(148,148,148); font-style:italic; font-weight:bold" rel="noopener noreferrer">(AST)</a>&nbsp;的英文全拼是:*&nbsp;<code class="prettyprint" style="padding:2px 4px; font-family:Monaco,Menlo,Consolas,&quot;Courier New&quot;,monospace; border:none; background-color:rgb(247,247,249)">abstract syntax tree</code>&nbsp;*,这是用户输入语句的树形结构的表现形式,树上的每一个节点都是一个&nbsp;<code class="prettyprint" style="padding:2px 4px; font-family:Monaco,Menlo,Consolas,&quot;Courier New&quot;,monospace; border:none; background-color:rgb(247,247,249)">单词</code>&nbsp;,树的结构体现了&nbsp;<code class="prettyprint" style="padding:2px 4px; font-family:Monaco,Menlo,Consolas,&quot;Courier New&quot;,monospace; border:none; background-color:rgb(247,247,249)">语法</code>&nbsp;。抽象&nbsp;语法&nbsp;树是随着语法分析的过程构造的,当语法分析正常结束后,语法分析器就会输出一个抽象语法树,用户的输入和抽象语法树的结构内容是一一对应的,至此,用户输入的‘字符串’完完全全的变成了一个‘结构体’,&nbsp;&nbsp;<em>SELECT FOO+100 FROM POKES</em>&nbsp;转换为抽象语法树后如下所示:&nbsp;<br> <img alt="3" src="http://img1.tuicool.com/qaAFjy.gif" style="max-width:96%; height:auto; vertical-align:middle; border:0px none; margin:0px auto; text-align:center; display:block"><br> <em>ps.在ODPS中,真实的抽象语法树会复杂许多,为了方便大家理解,我将输出的抽象语法树做了一些简化。</em></p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> 编译的过程在过去曾经是最为复杂繁琐的,涉及到很多编译原理的理论,但是现在,开源的编译器工具已经足够的多,我们可以定义好语法,让编译器工具来帮我们完成这个转换。目前我们使用编译工具:&nbsp;<a target="_blank" href="http://www.antlr.org/" style="color:rgb(148,148,148); text-decoration:none; outline:none 0px; border-bottom-width:1px; border-bottom-style:dashed; border-bottom-color:rgb(148,148,148); font-style:italic; font-weight:bold" rel="noopener noreferrer">Antlr</a>&nbsp;来完成我们的编译。</p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> 语义分析阶段是SQL解析过程中最为复杂最有难度的一环,涉及到SQL标准,SQL优化,和MapReduce的相关理论和概念。在这里,接着上面环输出的抽象语法树,语意分析后会输出一个&nbsp;<code class="prettyprint" style="padding:2px 4px; font-family:Monaco,Menlo,Consolas,&quot;Courier New&quot;,monospace; border:none; background-color:rgb(247,247,249)">查询计划</code>&nbsp;,这个&nbsp;<code class="prettyprint" style="padding:2px 4px; font-family:Monaco,Menlo,Consolas,&quot;Courier New&quot;,monospace; border:none; background-color:rgb(247,247,249)">查询计划</code>&nbsp;会指导着物理执行算子一步步的运行在我们的分布式系统之上,去读取表的内容,根据SQL的语意做运算,最后输入用户的内容。接下来我们会逐步分解语义分析的过程,揭开庐山真面目</p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> 语义分析阶段包含两大块,先&nbsp;<code class="prettyprint" style="padding:2px 4px; font-family:Monaco,Menlo,Consolas,&quot;Courier New&quot;,monospace; border:none; background-color:rgb(247,247,249)">逻辑分析</code>&nbsp;&nbsp;<code class="prettyprint" style="padding:2px 4px; font-family:Monaco,Menlo,Consolas,&quot;Courier New&quot;,monospace; border:none; background-color:rgb(247,247,249)">物理分析</code>&nbsp;,逻辑分析基本上是纯代数的分析过程,与底层的分布式环境无关,而物理分析则是将逻辑分析后的结果做变换,与底层的执行环境密切相关。如我们使用飞天的分布式环境,物理分析时就需要确定在MapReduce时如何将数据分区、排序、读取数据量的大小、启动多少个进程来执行任务,等等。</p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> 顾名思义,逻辑分析过程就是要分析一下输入的SQL语句到底是干什么的,都有哪些操作。一般来讲,一个SQL语句总有一个输入,一个输出,输入数据经过SQL加工后得到输出数据,</p>
<h4 style="margin:0px 0px 0.5em; font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; line-height:27.2px; color:rgb(51,51,51); font-size:16px; text-indent:1em; background-color:rgb(254,254,254)"> 2.1.1语句的执行顺序</h4>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> SQL语句基本可以分解成下面7大块</p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> </p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> (5)SELECT (6)DISTINCT &lt; select list &gt;&nbsp;<br> (1)FROM &lt; table source &gt;&nbsp;<br> (2)WHERE &lt; condition &gt;&nbsp;<br> (3)GROUP BY &lt; group by list &gt;&nbsp;<br> (4)HAVING &lt; having condition &gt;&nbsp;<br> (7) ORDER BY &lt; order by list &gt;</p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> </p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> 在执行时,按照1-7的标号顺序执行,有些子句是可选的,比如where子句。当没有出现的时候就跳过这步。我们发现,写在最前面的select子句其实并不是最先执行的,这是因为SQL语句设计时为了让用SQL的人更容易与自己的思维相衔接。</p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> 根据上述的几个SQL基本操作,我们抽象出了一些&nbsp;<code class="prettyprint" style="padding:2px 4px; font-family:Monaco,Menlo,Consolas,&quot;Courier New&quot;,monospace; border:none; background-color:rgb(247,247,249)">逻辑算子(Operator)</code>&nbsp;,这些算子的功能是单一的不可再拆分的单位。分别是:</p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> <img alt="4" src="http://img1.tuicool.com/zAFZ73.png" style="max-width:96%; height:auto; vertical-align:middle; border:0px none; margin:0px auto; text-align:center; display:block"></p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> 这些奇怪的算子是干什么用的呢?说白了,一个逻辑查询计划就是由这些算子组成的一个&nbsp;<code class="prettyprint" style="padding:2px 4px; font-family:Monaco,Menlo,Consolas,&quot;Courier New&quot;,monospace; border:none; background-color:rgb(247,247,249)">有向无环图(DAG)</code>&nbsp;,每一个算子都描述了SQL操作里的不同动作,由算子组成的&nbsp;有向无环图(DAG)&nbsp;描述了数据流的方向.</p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> 对于大部分算子而言,都有一个输入数据集,和一个输出数据集。JoinOperator和UnionAllOperator比较特殊,拥有两个或者两个以上的输入数据集,因为这两个算子的操作就是要将多个数据集做关联。我们将算子的&nbsp;<code class="prettyprint" style="padding:2px 4px; font-family:Monaco,Menlo,Consolas,&quot;Courier New&quot;,monospace; border:none; background-color:rgb(247,247,249)">输入数据集</code>&nbsp;&nbsp;<code class="prettyprint" style="padding:2px 4px; font-family:Monaco,Menlo,Consolas,&quot;Courier New&quot;,monospace; border:none; background-color:rgb(247,247,249)">输出数据集</code>&nbsp;称之为&nbsp;<code class="prettyprint" style="padding:2px 4px; font-family:Monaco,Menlo,Consolas,&quot;Courier New&quot;,monospace; border:none; background-color:rgb(247,247,249)">虚表(vtable)</code></p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> 用户是看不到虚表(vtable)的,它只用来做内部分析,是算子和算子之间的桥梁,如下图所示:</p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> <img alt="5" src="http://img2.tuicool.com/6Vny63.jpg!web" style="max-width:96%; height:auto; vertical-align:middle; border:0px none; margin:0px auto; text-align:center; display:block"></p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> 在SQL里,有很多子句都可以带有表达式,比如</p>
<pre class="prettyprint undefined" style="padding:0.3em; font-family:Monaco,Menlo,Consolas,&quot;Courier New&quot;,monospace; color:rgb(51,51,51); margin-top:0px; margin-bottom:1.5em; line-height:1.5em; word-break:break-all; word-wrap:break-word; white-space:pre-wrap; overflow-y:auto; background-color:rgb(246,246,246)" name="code"><code style="padding:0.3em; font-family:Monaco,Menlo,Consolas,&quot;Courier New&quot;,monospace; border:0px; display:block; overflow-y:auto" class="hljs"><a target="_blank" href="http://blog.aliyun.com/wp-content/uploads/2014/06/61.png" style="color:rgb(148,148,148); text-decoration:none; outline:none 0px; border-bottom-width:1px; border-bottom-style:dashed; border-bottom-color:rgb(148,148,148); font-style:italic; font-weight:bold" rel="noopener noreferrer"><img class="alignnone size-medium wp-image-740" alt="6" src="http://img0.tuicool.com/yAZ3Ib.png!web" width="600" height="71" style="max-width:96%; height:65.106px; vertical-align:middle; border:0px none; margin:0px auto; text-align:center; width:550px; display:block"></a>
</code><div class="hljs-button {2}" data-title="复制" data-report-click="{&quot;spm&quot;:&quot;1001.2101.3001.4259&quot;}" onclick="hljs.copyCode(event)"></div></pre>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> 其中SELECT子句中,GROUP BY子句中, WHERE子句中都带有表达式。表达式的解析和计算贯穿着整个SQL解析的过程,所以这里单独讲讲表达式。</p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> 1.类型推导</p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> 在分析表达式时,会遇到用户输入的常量,我们需要通过类型推导给输入的每一个常量做标记,识别SQL中常量的类型,规则较为简单,如:</p>
<pre class="prettyprint undefined" style="padding:0.3em; font-family:Monaco,Menlo,Consolas,&quot;Courier New&quot;,monospace; color:rgb(51,51,51); margin-top:0px; margin-bottom:1.5em; line-height:1.5em; word-break:break-all; word-wrap:break-word; white-space:pre-wrap; overflow-y:auto; background-color:rgb(246,246,246)" name="code"><code style="padding:0.3em; font-family:Monaco,Menlo,Consolas,&quot;Courier New&quot;,monospace; border:0px; display:block; overflow-y:auto" class="hljs"><a target="_blank" href="http://blog.aliyun.com/wp-content/uploads/2014/06/71.png" style="color:rgb(148,148,148); text-decoration:none; outline:none 0px; border-bottom-width:1px; border-bottom-style:dashed; border-bottom-color:rgb(148,148,148); font-style:italic; font-weight:bold" rel="noopener noreferrer"><img class="alignnone size-medium wp-image-741" alt="7" src="http://img0.tuicool.com/qMFjai.png!web" width="600" height="88" style="max-width:96%; height:80.6537px; vertical-align:middle; border:0px none; margin:0px auto; text-align:center; width:550px; display:block"></a>
</code><div class="hljs-button {2}" data-title="复制" data-report-click="{&quot;spm&quot;:&quot;1001.2101.3001.4259&quot;}" onclick="hljs.copyCode(event)"></div></pre>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> 2.隐式类型转换</p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> 所有的编程语言都会遇到隐式类型转换的问题,即当调用一个函数时,如果输入参数类型不符合函数签名时,就要尝试对输入的参数做隐式类型转换。当然,并不一定每次隐式类型转换都是成功的,如果发现无法无论如何转换都无法满足函数的签名,就会有异常抛出,终止分析过程。</p>
<pre class="prettyprint undefined" style="padding:0.3em; font-family:Monaco,Menlo,Consolas,&quot;Courier New&quot;,monospace; color:rgb(51,51,51); margin-top:0px; margin-bottom:1.5em; line-height:1.5em; word-break:break-all; word-wrap:break-word; white-space:pre-wrap; overflow-y:auto; background-color:rgb(246,246,246)" name="code"><code style="padding:0.3em; font-family:Monaco,Menlo,Consolas,&quot;Courier New&quot;,monospace; border:0px; display:block; overflow-y:auto" class="hljs"> <a target="_blank" href="http://blog.aliyun.com/wp-content/uploads/2014/06/82.png" style="color:rgb(148,148,148); text-decoration:none; outline:none 0px; border-bottom-width:1px; border-bottom-style:dashed; border-bottom-color:rgb(148,148,148); font-style:italic; font-weight:bold" rel="noopener noreferrer"><img class="alignnone size-medium wp-image-743" alt="8" src="http://img1.tuicool.com/QFJNNr.png!web" width="600" height="66" style="max-width:96%; height:60.1411px; vertical-align:middle; border:0px none; margin:0px auto; text-align:center; width:550px; display:block"></a>
</code><div class="hljs-button {2}" data-title="复制" data-report-click="{&quot;spm&quot;:&quot;1001.2101.3001.4259&quot;}" onclick="hljs.copyCode(event)"></div></pre>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> 3.布尔表达式分析</p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> 布尔表达式的分析主要作用是可以让之后的SQL优化更容易的进行下去,如Join时的条件下推优化,分区裁剪优化,都需要使用布尔表达式分析后的结果来进行。这步分析会用到很多布尔代数的知识,目的只有一个,那就是将用户输入的冗长的布尔表达式变换为<code class="prettyprint" style="padding:2px 4px; font-family:Monaco,Menlo,Consolas,&quot;Courier New&quot;,monospace; border:none; background-color:rgb(247,247,249)">最简合取范式</code>&nbsp;,简而言之,就是将用户输入的一大推and or组成的布尔表达式变换成由and连接的最简形式,如:</p>
<pre class="prettyprint undefined" style="padding:0.3em; font-family:Monaco,Menlo,Consolas,&quot;Courier New&quot;,monospace; color:rgb(51,51,51); margin-top:0px; margin-bottom:1.5em; line-height:1.5em; word-break:break-all; word-wrap:break-word; white-space:pre-wrap; overflow-y:auto; background-color:rgb(246,246,246)" name="code"><code style="padding:0.3em; font-family:Monaco,Menlo,Consolas,&quot;Courier New&quot;,monospace; border:0px; display:block; overflow-y:auto" class="hljs"><a target="_blank" href="http://blog.aliyun.com/wp-content/uploads/2014/06/91.png" style="color:rgb(148,148,148); text-decoration:none; outline:none 0px; border-bottom-width:1px; border-bottom-style:dashed; border-bottom-color:rgb(148,148,148); font-style:italic; font-weight:bold" rel="noopener noreferrer"><img class="alignnone size-medium wp-image-744" alt="9" src="http://img0.tuicool.com/buiAFv.png!web" width="600" height="57" style="max-width:96%; height:51.5018px; vertical-align:middle; border:0px none; margin:0px auto; text-align:center; width:550px; display:block"></a>
</code><div class="hljs-button {2}" data-title="复制" data-report-click="{&quot;spm&quot;:&quot;1001.2101.3001.4259&quot;}" onclick="hljs.copyCode(event)"></div></pre>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> 看起来这是一个很神奇的变换,实际上已经有很现成的算法来解决这个问题了。总共需要2步</p>
<ol style="padding:0px; margin:0px 0px 0.75em 25px; font-size:16px; line-height:27.2px; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"><li style="line-height:1.7em">利用Quine McCluskey 算法对输入的布尔表达式生成合取范式(CNF)</li><li style="line-height:1.7em">利用Petricks method&nbsp;算法对第一步生成的CNF计算最简合取范式(Minimal CNF)</li></ol>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> 4.CASE WHEN表达式的分析</p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> CASE WHEN表达式是一个略显奇葩的表达式,它本身上是一个&nbsp;<code class="prettyprint" style="padding:2px 4px; font-family:Monaco,Menlo,Consolas,&quot;Courier New&quot;,monospace; border:none; background-color:rgb(247,247,249)">值函数ScalarFunction</code>&nbsp;,但又有逻辑判断,返回值又不固定,并且还可以嵌套使用,而且在语法上还有两种形式(简单CASE函数和CASE搜索函数) -! 想在计算机里优雅的记录表达这个CASE WHEN真的很不容易。</p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> <img alt="10" src="http://img2.tuicool.com/IFVvii.png!web" style="max-width:96%; height:auto; vertical-align:middle; border:0px none; margin:0px auto; text-align:center; display:block"></p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> condition参数是casewhen子句的条件,returnvalue1代表这THEN后的返回值,returnvalue2代表ELSE后的返回值。&nbsp;<br> 这样,我们就可以很好的在计算机中结构化的表达,如:</p>
<h4 style="margin:0px 0px 0.5em; font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; line-height:27.2px; color:rgb(51,51,51); font-size:16px; text-indent:1em; background-color:rgb(254,254,254)"> 2.1.4逻辑查询计划生成</h4>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> 有了以上的基础,我们就可以开始生成我们的查询计划了。严格按照SQL语句的执行顺序来遍历编译阶段生成的AST树,遇到什么操作就生成什么样的算子,遇到表达式就调用之前的表达式分析,真是兵来将挡水来土掩。&nbsp;<br> 举个例子:</p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> <img alt="12" src="http://img1.tuicool.com/BRneEjz.png!web" style="max-width:96%; height:auto; vertical-align:middle; border:0px none; margin:0px auto; text-align:center; display:block"><br> 需要注意的是,在聚合函数里的值函数、Group by列表中的值函数,需要在聚合操作以前就计算完成,否则无法进行聚合操作,于是乎,出现了一个叫&nbsp;<code class="prettyprint" style="padding:2px 4px; font-family:Monaco,Menlo,Consolas,&quot;Courier New&quot;,monospace; border:none; background-color:rgb(247,247,249)">初始投影</code>&nbsp;的东西,本质上这是一个SelectOperator,只是用来计算一下聚合需要用到的表达式。</p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> <em>题外话,在很久以前,group by 列表中和聚合函数里都是不允许使用表达式的,只能使用单一的值或者列,所以那时也不需要初始投影。用户想使用类似功能时只能通过子查询来实现。后来SQL语法扩展了,支持了group by、聚合函数中调用值函数,于是,在SQL解析时要先判断一下是否需要初始投影</em></p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> 还有很多结构的SQL没有讲到,比如JOIN, UNION ALL, WINDOWN FUNCTION,由于篇幅原因,这里先不提了,感兴趣的同学可以来找我们私下交流。</p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> SQL语法本身就是一个递归的结构,支持在FROM之后写一个子查询,如:</p>
<pre class="prettyprint undefined" style="padding:0.3em; font-family:Monaco,Menlo,Consolas,&quot;Courier New&quot;,monospace; color:rgb(51,51,51); margin-top:0px; margin-bottom:1.5em; line-height:1.5em; word-break:break-all; word-wrap:break-word; white-space:pre-wrap; overflow-y:auto; background-color:rgb(246,246,246)" name="code"><code style="padding:0.3em; font-family:Monaco,Menlo,Consolas,&quot;Courier New&quot;,monospace; border:0px; display:block; overflow-y:auto" class="hljs"><a target="_blank" href="http://blog.aliyun.com/wp-content/uploads/2014/06/13.png" style="color:rgb(148,148,148); text-decoration:none; outline:none 0px; border-bottom-width:1px; border-bottom-style:dashed; border-bottom-color:rgb(148,148,148); font-style:italic; font-weight:bold" rel="noopener noreferrer"><img class="alignnone size-medium wp-image-748" alt="13" src="http://img2.tuicool.com/eyaYbif.png!web" width="600" height="60" style="max-width:96%; height:54.417px; vertical-align:middle; border:0px none; margin:0px auto; text-align:center; width:550px; display:block"></a>
</code><div class="hljs-button {2}" data-title="复制" data-report-click="{&quot;spm&quot;:&quot;1001.2101.3001.4259&quot;}" onclick="hljs.copyCode(event)"></div></pre>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> 面对这样的语句,我们只要先去生成子查询的逻辑查询计划,将子查询的的结果虚表作为父查询的输入即可,在逻辑上很方便去应对。上面这个示例的查询计划如下图所示:&nbsp;<br> <img alt="14" src="http://img2.tuicool.com/6jABza.gif" style="max-width:96%; height:auto; vertical-align:middle; border:0px none; margin:0px auto; text-align:center"></p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> 生成逻辑查询计划后,需要先对查询计划做一次优化,将一些显而易见的点优化掉,避免冗余的计算。主要包含三个优化:</p>
<ul style="padding:0px; margin:0px 0px 0.75em 25px; list-style-type:none; font-size:16px; line-height:27.2px; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"><li style="line-height:1.7em; list-style-type:disc">常量表达式的计算举个例子: <p style="margin-top:0px; margin-bottom:0.75em; line-height:1.7em">SELECT 1+2 FROM POKES&nbsp;<br>&nbsp;<code class="prettyprint" style="padding:2px 4px; font-family:Monaco,Menlo,Consolas,&quot;Courier New&quot;,monospace; border:none; background-color:rgb(247,247,249)">1+2</code>&nbsp;“就是一个常量表达式,此时,我们可以将1+2的结果先计算出来,然后将结果放入查询计划,避免在执行时,对每一行数据都去计算这个固定结果的表达式。</p> </li><li style="line-height:1.7em; list-style-type:disc">列裁剪在生成查询计划时,默认会把全表中没一列的数据都读取出来,但现实的情况是用户可能只需要其中的某几列做计算,其他的列就变成了冗余数据,读取出来耗时耗力,但没有被用到。此时,我们就使用列裁剪这个优化去把不必要的列裁剪掉。</li><li style="line-height:1.7em; list-style-type:disc">Predict Push Down在遇有JOIN运算时,用户很有可能还要在JOIN之后做WHERE运算,此时就要从代数逻辑上分析,WHERE中计算的条件是否可以被提前到JOIN之前运算,以此来减少JOIN运算的数据量,提升效率,千言万语不胜一张图,(又称no pic you say a bird): <p style="margin-top:0px; margin-bottom:0.75em; line-height:1.7em">SELECT * FROM A JOIN B ON A.ID=B.ID WHERE A.AGE&gt;10 AND B.AGE&gt;5</p> <p style="margin-top:0px; margin-bottom:0.75em; line-height:1.7em"><img alt="15" src="http://img1.tuicool.com/uay2ue.jpg!web" style="max-width:96%; height:auto; vertical-align:middle; border:0px none; margin:0px auto; text-align:center; display:block"></p> <p style="margin-top:0px; margin-bottom:0.75em; line-height:1.7em">左面的是未优化前的查询计划,在FIL_4中计算了A.AGE&gt;10 AND B.AGE&gt;5这个表达式,右面的是优化后的查询计划,将A.AGE&gt;10放入了FIL_7计算并且提前,将B.AGE&gt;5放入了FIL_8中计算并且提前,最后将原有的FIL_4删除,以此来达到减少JOIN输入数据量的目的。</p> </li></ul>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> 至此,逻辑查询与逻辑优化就结束了,逻辑查询计划和逻辑优化在所有的SQL系统中都是差不多的,下面来讲讲与我们分布式系统MapReduce相关的物理查询计划。</p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> 物理查询计划是通过之前产生的逻辑查询计划生成的,在转换的过程中,要与飞天的MapReduce编程框架做适配,生成飞天系统可以识别的&nbsp;<a target="_blank" href="http://wiki.aliyun-inc.com/projects/apsara/wiki/FuxiJobProgrammingManual" style="color:rgb(148,148,148); text-decoration:none; outline:none 0px; border-bottom-width:1px; border-bottom-style:dashed; border-bottom-color:rgb(148,148,148); font-style:italic; font-weight:bold" rel="noopener noreferrer">DAG</a></p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> 飞天的DAG是一个类似MapReduce的编程框架,想把刚刚一个SQL跑在分布式的飞天系统上,就需要按照分布式系统编程框架来抽象出一些新的物理运算符。</p>
<ul style="padding:0px; margin:0px 0px 0.75em 25px; list-style-type:none; font-size:16px; line-height:27.2px; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"><li style="line-height:1.7em; list-style-type:disc">Shuffle-Sort算子(在ODPS中,这个算子叫ReduceSink)在飞天系统上,我们如果想做Group by或者Join操作,那么必须把相同key的数据放到同一个进程节点上来执行,而在这直线,这些相同key的数据也许是被打散在各个进程里的,这时我们就需要一个专门的算子来做数据的重新分区、排序的操作</li><li style="line-height:1.7em; list-style-type:disc">GroupBy的不同阶段在飞天系统上,我们想实现一个GroupBy需要有4步:
<ol style="padding:0px; margin:0px 0px 0px 25px; line-height:1.7em"><li style="line-height:1.7em; list-style-type:disc">准备阶段(AggregationPrepare), 在做一些非线性的聚合函数操作时,比如AVG求平均值,需要将AVG()拆解成SUM(),COUNT()两个线性的聚合函数,最后再使用SUM()/COUNT()来算出AVG()的值。在这步,只做拆解。</li><li style="line-height:1.7em; list-style-type:disc">本地聚合(SemiHashAggregation), 对于Group by来说,需要将所有Group by 列表的字段数据放倒一个机器上才可以进行完全聚合,但是出于优化考虑,我们可以在数据片不全的时候先做一次聚合,虽然这次聚合操作不完全,但是可以减少输出的数据量,并且可以保证数据的正确性</li><li style="line-height:1.7em; list-style-type:disc">流式聚合(StremAggregation), 这个聚合有个前提,一定是要求前趋的虚表Group by 列表中的数据都会在这一个进程里,并且排好序。一般而言,在本地聚合之后,数据会通过Shuffle-Sort运算数据重新分区和排序,再输入到流式聚合算子中</li><li style="line-height:1.7em; list-style-type:disc">合并(FinalAggregation),这里输入的其实是已经聚合好的结果了,但是由于第一步提到的原因,有些非线性聚合函数被分解成了线性聚合函数,这里要将他们合并。如:AVG()=SUM()/COUNT()</li></ol> <p style="margin-top:0px; margin-bottom:0.75em; line-height:1.7em">在只有线性聚合函数时,上面的1,4步可以省略。</p> </li><li style="line-height:1.7em; list-style-type:disc">MapJoin 算子和MergeJoin算子</li></ul>
<ol style="padding:0px; margin:0px 0px 0.75em 25px; font-size:16px; line-height:27.2px; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"><li style="line-height:1.7em">MergeJoinMergeJoin是最常见的一种Join算子,一般而言,MergeJoin是要求输入数据的虚表按照Join的Key分区并且排序的,所以MergeJoin一般出现在Shuffle-Sort算子之后。</li><li style="line-height:1.7em">MapJoin使用过的人应该都知道有一种Join的优化叫MapJoin,这个名字的本意是Map-side JOIN,就是JOIN运算在MapReduce的Map阶段完成。如果用户在做Join时,知道有一个数据表的数据量很小,可以选择使用MapJoin,MapJoin算子会在每一个进程里都把小表中的数据加载到内存,与打表一一做Join。这样可以减少一次Shuffle-Sort,提升执行效率。</li></ol>
<h4 style="margin:0px 0px 0.5em; font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; line-height:27.2px; color:rgb(51,51,51); font-size:16px; text-indent:1em; background-color:rgb(254,254,254)"> 2.2.2生成物理查询计划</h4>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> 逻辑查询计划是物理查询计划的输入,我们按照拓扑序去遍历逻辑查询计划上的每一个逻辑算子,生成物理算子,当我们认为虚表需要重新分区排序才能满足下一个阶段的运算时,我们就在中间加入一个Shuffle-Sort运算符.&nbsp;<br> 还是使用逻辑查询计划生成的那个例子来描述一下物理查询计划是什么样子:</p>
<pre class="prettyprint undefined" style="padding:0.3em; font-family:Monaco,Menlo,Consolas,&quot;Courier New&quot;,monospace; color:rgb(51,51,51); margin-top:0px; margin-bottom:1.5em; line-height:1.5em; word-break:break-all; word-wrap:break-word; white-space:pre-wrap; overflow-y:auto; background-color:rgb(246,246,246)" name="code"><code style="padding:0.3em; font-family:Monaco,Menlo,Consolas,&quot;Courier New&quot;,monospace; border:0px; display:block; overflow-y:auto" class="hljs"> <a target="_blank" href="http://blog.aliyun.com/wp-content/uploads/2014/06/16.png" style="color:rgb(148,148,148); text-decoration:none; outline:none 0px; border-bottom-width:1px; border-bottom-style:dashed; border-bottom-color:rgb(148,148,148); font-style:italic; font-weight:bold" rel="noopener noreferrer"><img class="alignnone size-medium wp-image-751" alt="16" src="http://img2.tuicool.com/7RJJba.png!web" width="600" height="39" style="max-width:96%; height:35.8907px; vertical-align:middle; border:0px none; margin:0px auto; text-align:center; width:550px; display:block"></a>
</code><div class="hljs-button {2}" data-title="复制" data-report-click="{&quot;spm&quot;:&quot;1001.2101.3001.4259&quot;}" onclick="hljs.copyCode(event)"></div></pre>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> <img alt="17" src="http://img2.tuicool.com/6r6z2q.gif" style="max-width:96%; height:auto; vertical-align:middle; border:0px none; margin:0px auto; text-align:center"></p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> 现在,又进入了一个优化的环节。此时的优化与底层的分布式系统更相关,主要目标就是减少读取的数据量,减少整个SQL执行的过程中,数据分区排序落地的过程。以此来提高执行效率。</p>
<ul style="padding:0px; margin:0px 0px 0.75em 25px; list-style-type:none; font-size:16px; line-height:27.2px; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"><li style="line-height:1.7em; list-style-type:disc">分区裁剪大家知道,我们的业务表一般都是有分区的,而且一般都是按照时间来分区。大部分情况下不需要全表扫描,只需读出几个分区的数据就可以完成我们的业务逻辑。于是,分区裁剪优化诞了。&nbsp;<br> 我们会分析用户写在WHERE子句中的分区字段,将分区字段的条件拿出来,再去metastore中读取所有的分区信息,用WHERE子句中的条件做过滤,最后,我们就知道哪些分区是需要读取的了,我们把要读取的分区信息放入对应的TableScanOperator,在执行是时,就不用读取不必要的数据了。 <p style="margin-top:0px; margin-bottom:0.75em; line-height:1.7em">需要注意的是,并不是所有的WHERE条件中的分区条件都可以做裁剪,当用户写了LEFT JOIN,RIGHT JOIN, FULL OUTER JOIN时,如果在JOIN条件中涉及到了分区字段,那么很有可能就无法完成分区裁剪的优化,因为裁剪后SQL的结果就不对了。</p> </li><li style="line-height:1.7em; list-style-type:disc">减少不必要的Shuffle-Sort有时我们会写出这样的语句 <pre class="prettyprint undefined" style="padding:0.3em; font-family:Monaco,Menlo,Consolas,&quot;Courier New&quot;,monospace; margin-top:0px; margin-bottom:1.5em; font-size:12px; line-height:1.5em; word-break:break-all; word-wrap:break-word; white-space:pre-wrap; overflow-y:auto; background-color:rgb(246,246,246)" name="code"><code style="padding:0.3em; font-family:Monaco,Menlo,Consolas,&quot;Courier New&quot;,monospace; border:0px; display:block; overflow-y:auto" class="hljs"><a target="_blank" href="http://blog.aliyun.com/wp-content/uploads/2014/06/18.png" style="color:rgb(148,148,148); text-decoration:none; outline:none 0px; border-bottom-width:1px; border-bottom-style:dashed; border-bottom-color:rgb(148,148,148); font-style:italic; font-weight:bold" rel="noopener noreferrer"><img class="alignnone size-medium wp-image-753" alt="18" src="http://img0.tuicool.com/y6fmUj.png!web" width="600" height="62" style="max-width:96%; height:auto; vertical-align:middle; border:0px none; margin:0px auto; text-align:center; display:block"></a>
</code><div class="hljs-button {2}" data-title="复制" data-report-click="{&quot;spm&quot;:&quot;1001.2101.3001.4259&quot;}" onclick="hljs.copyCode(event)"></div></pre> <p style="margin-top:0px; margin-bottom:0.75em; line-height:1.7em">在上面这个例子中,Join 后做Group by ,应该在Join和Group by之间加入一个Shuffle-Sort算子,以保证Group by 算子的输入虚表按照固定的A.ID来排序,但是我们发现,JOIN之后A.ID这个字段本来就是有序的,所以,我们可以将中间这个Shuffle-Sort算子删除,减少数据的网络传输和落地。</p> </li></ul>
<h4 style="margin:0px 0px 0.5em; font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; line-height:27.2px; color:rgb(51,51,51); font-size:16px; text-indent:1em; background-color:rgb(254,254,254)"> 2.2.4生成飞天的DAG</h4>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> 物理查询计划已经生成好了,下一步就是按照飞天的DAG编程模型把物理查询计划的算子适配进去。飞天DAG的单位是Stage,由多个Stage组成了DAG,Stage和Stage之间可以进行对数据的分区和排序,有点想Map和Reduce的关系。</p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> 生成飞天DAG的规则也很简单</p>
<ul style="padding:0px; margin:0px 0px 0.75em 25px; list-style-type:none; font-size:16px; line-height:27.2px; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"><li style="line-height:1.7em; list-style-type:disc">按照拓扑序遍历物理查询计划上的每一个算子,每一个算子都在一个独立的集和里。如果两个算子相连接,则将这两个集和合并。当遇到Shuffle-Sort算子时终止,并开始新一轮的合并集和过程。 <pre class="prettyprint undefined" style="padding:0.3em; font-family:Monaco,Menlo,Consolas,&quot;Courier New&quot;,monospace; margin-top:0px; margin-bottom:1.5em; font-size:12px; line-height:1.5em; word-break:break-all; word-wrap:break-word; white-space:pre-wrap; overflow-y:auto; background-color:rgb(246,246,246)" name="code"><code style="padding:0.3em; font-family:Monaco,Menlo,Consolas,&quot;Courier New&quot;,monospace; border:0px; display:block; overflow-y:auto" class="hljs"><a target="_blank" href="http://blog.aliyun.com/wp-content/uploads/2014/06/19.png" style="color:rgb(148,148,148); text-decoration:none; outline:none 0px; border-bottom-width:1px; border-bottom-style:dashed; border-bottom-color:rgb(148,148,148); font-style:italic; font-weight:bold" rel="noopener noreferrer"><img class="alignnone size-medium wp-image-754" alt="19" src="http://img2.tuicool.com/y6jUVj.png!web" width="600" height="62" style="max-width:96%; height:auto; vertical-align:middle; border:0px none; margin:0px auto; text-align:center; display:block"></a>
</code><div class="hljs-button {2}" data-title="复制" data-report-click="{&quot;spm&quot;:&quot;1001.2101.3001.4259&quot;}" onclick="hljs.copyCode(event)"></div></pre> </li></ul>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> 对于上面这个语句,按照规则生成DAG后的样子如下:&nbsp;<br> <img alt="20" src="http://img0.tuicool.com/bEVbau.jpg!web" style="max-width:96%; height:auto; vertical-align:middle; border:0px none; margin:0px auto; text-align:center"></p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> 其中每一个灰色的方块代表Fuxi的一个Stage。TS_1在STAGE1中读取表A,RS_3进按A.ID进行分区排序,TS_2在STAGE2中读取表B,RS_4按照B.ID进行分区排序。JOIN_5在STAGTE3中,按照A.ID=B.ID做MergeJoin, SEMIHASH_7为Group by A.AGE做半聚合,通过RS_8将数据按照A.AGE重新分区排序。 STAGE3的第一算子是STREAMEDAGG_9,接收按照A.AGE排序后的数据做流式聚合,最后SEL_10将数据做投影,FS_11将数据写出到磁盘。</p>
<p style="margin-top:0px; margin-bottom:0.75em; font-size:16px; line-height:27.2px; text-indent:1em; color:rgb(51,51,51); font-family:&quot;Helvetica Neue&quot;,Helvetica,Tahoma,Arial,STXihei,&quot;Microsoft YaHei&quot;,微软雅黑,sans-serif; background-color:rgb(254,254,254)"> 洋洋洒洒写了这么多,SQL解析的逻辑基本就结束了,SQL解析是一个逻辑非常复杂繁琐的过程,有很多细节和恶心的坑本文中还没有提到,稍有不慎就可能引起SQL正确性的错误。</p>
</div></body></html>

View File

@@ -0,0 +1,266 @@
# centos 虚拟机 安装 nginx
pcre 注意需要这个
yum -y install gcc-c++
## 依赖问题
没有gcc的话参考
gcc-4.8.5 含依赖完整RPM安装包centos7
貌似不需要perl
参考`pyenv`安装系统开发环境
wiki中:
```shell
yum install gcc zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel tk-devel libffi-devel
```
Common build problems 中:
```shell
sudo yum install zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel xz xz-devel libffi-devel findutils
```
## 关于 openssl
包安装需要两个
yum install openssl openssl-devel
源码安装只需一个压缩包 openssl-1.0.2h.tar.gz 就行了
```bash
./config shared zlib
make depend
make
make install
mv /usr/bin/openssl /usr/bin/openssl.bak
mv /usr/include/openssl /usr/include/openssl.bak
ln -s /usr/local/ssl/bin/openssl /usr/bin/openssl
ln -s /usr/local/ssl/include/openssl /usr/include/openssl
echo “/usr/local/ssl/lib” >> /etc/ld.so.conf
ldconfig -v
```
## 上传文件
```shell
-rw-r--r--. 1 xxw xxw 1032347 4月 30 11:57 nginx-1.15.12.tar.gz
-rw-r--r--. 1 xxw xxw 5375802 4月 30 17:31 openssl-1.0.2n.tar.gz
-rw-r--r--. 1 xxw xxw 2065161 4月 30 11:57 pcre-8.40.tar.gz
-rw-r--r--. 1 xxw xxw 607698 4月 30 15:44 zlib-1.2.11.tar.gz
[xxw@centos7]~/download%
```
## 解压编译
```shell
cd /home/xxw/download
tar zxvf nginx-1.15.12.tar.gz
tar zxvf openssl-1.0.2n.tar.gz
tar zxvf pcre-8.40.tar.gz
tar zxvf zlib-1.2.11.tar.gz
```
```shell
cd /home/xxw/download/pcre-8.40
./configure --prefix=/home/xxw/download/install/pcre
make
make install
cd /home/xxw/download/zlib-1.2.11
./configure --prefix=/home/xxw/download/install/zlib
make
make install
cd /home/xxw/download/openssl-1.0.2n
./config --prefix=/home/xxw/download/install/openssl
make
make install
cd /home/xxw/download/nginx-1.15.12
# 注意configure的时候 pcre zlib openssl 都是源码目录
./configure --with-http_stub_status_module --prefix=/home/xxw/nginx --with-pcre=/home/xxw/download/pcre-8.40 --user=zp --with-zlib=/home/xxw/download/zlib-1.2.11 --with-http_ssl_module --with-openssl=/home/xxw/download/openssl-1.0.2n
make
make install
```
最后 注意 防火墙
```shell
firewall-cmd --zone=public --list-all
firewall-cmd --get-active-zones
firewall-cmd --zone=public --add-port=8088/tcp --permanent
firewall-cmd --reload
```
# 2020-04-24 长安安装 1.17.10
```shell
cd /root/Downloads/ng17
tar zxvf nginx-1.17.10.tar.gz
tar zxvf openssl-1.1.1g.tar.gz
tar zxvf pcre-8.44.tar.gz
tar zxvf zlib-1.2.11.tar.gz
```
```shell
cd /root/Downloads/ng17/pcre-8.44
./configure --prefix=/root/Downloads/ng17/install/pcre
make
make install
cd /root/Downloads/ng17/zlib-1.2.11
./configure --prefix=/root/Downloads/ng17/install/zlib
make
make install
cd /root/Downloads/ng17/openssl-1.1.1g
./config --prefix=/root/Downloads/ng17/install/openssl
make
make install
cd /root/Downloads/ng17/nginx-1.17.10/
# 注意configure的时候 pcre zlib openssl 都是源码目录而不是安装目录
./configure --with-http_stub_status_module --prefix=/root/nginx --with-pcre=/root/Downloads/ng17/pcre-8.44 --user=root --with-zlib=/root/Downloads/ng17/zlib-1.2.11 --with-http_ssl_module --with-openssl=/root/Downloads/ng17/openssl-1.1.1g
make
make install
```
restart.sh
```shell
cd /data01/nginx/bin/nginx
before=`ps -ef|grep nginx|grep -v grep|grep userapp|grep -v xiewei|awk '{print $2}'`
ps -ef|grep nginx|grep -v grep|grep userapp|grep -v xiewei|awk '{print $2}'|xargs -i kill -9 {}
/data01/nginx/bin/nginx/sbin/nginx
echo "restart!"
echo $before
after=`ps -ef|grep nginx|grep -v grep|grep userapp|grep -v xiewei|awk '{print $2}'`
echo $after
```
## 2020-07-23 180 安装
```bash
configure: error: C preprocessor "/lib/cpp" fails sanity check
yum install kernel-headers
yum install gcc zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel tk-devel libffi-devel
yum -y install gcc-c++
cd /data01/ng17
tar zxvf nginx-1.17.10.tar.gz
tar zxvf openssl-1.1.1g.tar.gz
tar zxvf pcre-8.44.tar.gz
tar zxvf zlib-1.2.11.tar.gz
cd /data01/ng17/pcre-8.44
./configure --prefix=/data01/ng17/install/pcre
make
make install
cd /data01/ng17/zlib-1.2.11
./configure --prefix=/data01/ng17/install/zlib
make
make install
cd /data01/ng17/openssl-1.1.1g
./config --prefix=/data01/ng17/install/openssl
make
make install
cd /data01/ng17/nginx-1.17.10/
# 注意configure的时候 pcre zlib openssl 都是源码目录而不是安装目录
./configure --with-http_stub_status_module --prefix=/data01/nginx --with-pcre=/data01/ng17/pcre-8.44 --user=userapp --with-zlib=/data01/ng17/zlib-1.2.11 --with-http_ssl_module --with-openssl=/data01/ng17/openssl-1.1.1g
make
make install
```
# 2021-10-24 亚信云 安装
```shell
mkdir -p /home/dacp/src/nginx_install
cd /home/dacp/src
tar zxvf zlib-1.2.11.tar.gz
tar zxvf pcre-8.45.tar.gz
tar zxvf openssl-1.1.1l.tar.gz
tar zxvf nginx-1.20.1.tar.gz
cd /home/dacp/src/pcre-8.45
./configure --prefix=/home/dacp/src/nginx_install/pcre
make
make install
cd /home/dacp/src/zlib-1.2.11
./configure --prefix=/home/dacp/src/nginx_install/zlib
make
make install
cd /home/dacp/src/openssl-1.1.1l
./config --prefix=/home/dacp/src/nginx_install/openssl
make
make install
cd /home/dacp/src/nginx-1.20.1/
# 注意configure的时候 pcre zlib openssl 都是源码目录而不是安装目录
./configure --with-http_stub_status_module --prefix=/home/dacp/nginx --with-pcre=/home/dacp/src/pcre-8.45 --user=dacp --with-zlib=/home/dacp/src/zlib-1.2.11 --with-http_ssl_module --with-openssl=/home/dacp/src/openssl-1.1.1l
make
make install
```
# 安装包下载
2021-10
zlib-1.2.11.tar.gz
pcre-8.45.tar.gz
openssl-1.1.1l.tar.gz
nginx-1.20.1.tar.gz
[[2022-02-20]]
zlib-1.2.11.tar.gz
pcre-8.45.tar.gz
openssl-1.1.1m.tar.gz
nginx-1.20.2.tar.gz
## nginx
nginx-1.17.10.tar.gz
Stable version
http://nginx.org/en/download.html
http://nginx.org/download/nginx-1.20.1.tar.gz
## openssl
openssl-1.1.1g.tar.gz
> The latest stable version is the 3.0 series. Also available is the 1.1.1 series which is our Long Term Support (LTS) version
https://www.openssl.org/source/
https://www.openssl.org/source/openssl-1.1.1l.tar.gz
https://www.openssl.org/source/openssl-1.1.1m.tar.gz
## pcre
http://www.pcre.org/
https://sourceforge.net/projects/pcre/files/pcre/8.45/
pcre-8.44.tar.gz
## zlib
http://www.zlib.net/
http://www.zlib.net/zlib-1.2.11.tar.gz
zlib-1.2.11.tar.gz

3
技术探究/chrome.md Normal file
View File

@@ -0,0 +1,3 @@
# chrome https
> chrome://net-internals/#hsts

View File

@@ -0,0 +1,809 @@
# 1、离线安装docker
因为有部分服务器在全内网环境,不能联网安装 `Docker`。这时要在服务器上安装 `Docker` 就只能下载对应安装包,离线安装 `Docker` 需要 `docker-engine``docker-engine-selinux``libtool-ltdl`这三个软件包。
下面以安装 `Docker 1.12.6` 为例讲讲如何在离线环境中安装 `Docker`,首先我们要下载对应的 `Docker` 软件包,下面的地址是官方提供的软件仓库地址,里面有各个版本的 `Docker` 软件包。
```
# CentOS
https://download.docker.com/linux/centos/7/x86_64/stable/Packages/
http://mirror.centos.org/centos/7/extras/x86_64/Packages/
```
`Docker` 安装需要依赖 `libtool-ltdl` 软件包,`libtool-ltdl`可在`pkgs.org`这个网站搜索下载。
- 在 CentOS 7 下安装
```
$ mkdir docker_install
$ cd docker_install
$ wget https://download.docker.com/linux/centos/7/x86_64/stable/Packages/docker-ce-20.10.6-3.el7.x86_64.rpm
$ wget https://download.docker.com/linux/centos/7/x86_64/stable/Packages/containerd.io-1.4.4-3.1.el7.x86_64.rpm
$ wget https://download.docker.com/linux/centos/7/x86_64/stable/Packages/docker-ce-cli-20.10.6-3.el7.x86_64.rpm
$ wget https://download.docker.com/linux/centos/7/x86_64/stable/Packages/docker-ce-rootless-extras-20.10.6-3.el7.x86_64.rpm
$ wget https://download.docker.com/linux/centos/7/x86_64/stable/Packages/docker-ce-selinux-17.03.3.ce-1.el7.noarch.rpm
$ wget https://download.docker.com/linux/centos/7/x86_64/stable/Packages/docker-scan-plugin-0.7.0-3.el7.x86_64.rpm
$ wget http://mirror.centos.org/centos/7/extras/x86_64/Packages/container-selinux-2.119.1-1.c57a6f9.el7.noarch.rpm
$ rpm -ivh container-selinux-2.21-1.el7.noarch.rpm
$ rpm -ivh docker-ce-17.06.2.ce-1.el7.centos.x86_64.rpm
$ rpm -ivh *.rpm
```
## 1.1.CentOS7修改Docker镜像默认存储位置
##### 1.1.1停止docker服务
```bash
# systemctl stop docker
```
##### 1.1.2修改docker服务启动文件
```bash
# vim /etc/sysconfig/docker
OPTIONS='--selinux-enabled --log-driver=journald --graph=/docker --signature-verification=false --insecure-registry 192.168.1.1'
#--insecure-registry 192.168.1.1这是仓库地址可以忽略
# /docker这个目录就是我用于替代默认/var/lib/docker的目录目录创建好之后记得“mv /var/lib/docker/* /docker/”,把所有原先目录下所有的文件和目录拷贝到新目录下。
```
##### 1.1.3重新加载配置并启动
```bash
# systemctl daemon-reload
# systemctl start docker
# systemctl enable docker
```
##### 1.1.4检查docker信息
```bash
# docker info
# docker version
```
## 1.2Docker 过程中经常会被使用到的一些命令
## 容器生命周期管理
### 创建容器
```
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
```
因为创建命令涉及了容器运行时几乎所有的设置,所有 `run` 命令具有比其他任何 `docker` 命令更多的选项,接下来主要看一下具体的 `[OPTIONS]` 有哪些
- `-a stdin` : 指定标准输入输出内容类型,可选 `STDIN`/`STDOUT`/`STDERR` 三项
- `-d` : 后台运行容器并返回容器ID
- `-i` : 以交互模式运行容器,通常与 -t 同时使用
- `-P` : 随机端口映射,容器内部端口随机映射到主机的高端口
- `-p` : 指定端口映射,格式为:主机(宿主)端口:容器端口
- `-t` : 为容器重新分配一个伪输入终端,通常与 -i 同时使用
- `--name string` : 为容器指定一个名称
- `--dns 8.8.8.8` : 指定容器使用的DNS服务器默认和宿主一致
- `--dns-search example.com` : 指定容器DNS搜索域名默认和宿主一致
- `-h "mars"` : 指定容器的hostname
- `-e username="ritchie"` : 设置环境变量
- `--env-file=[]` : 从指定文件读入环境变量
- `--cpuset-cpus string` : 绑定容器到指定 CPU 运行("0-2"/"0,1,2")
- `-m` : 设置容器使用内存最大值
- `--net="bridge"` : 指定容器的网络连接类型,支持 bridge/host/none/container: 四种类型
- `--link=[]` : 添加链接到另一个容器
- `--expose=[]` : 开放一个端口或一组端口
- `--volume , -v` : 绑定一个卷
命令有点多,一般情况,启动一个服务,常用的几个参数
- `-d`: 后台运行
- `-v`:绑定卷 例如 `-v /opt/server/logs:/opt/logs` 简单点说,就是将容器里的 `/opt/logs` 地址和宿主机 `/opt/server/logs` 的地址绑定,类似于挂载,用户就可以通过宿主机 `/opt/server/logs` 路径直接查看容器里生成的文件
- `--name string` 声明容器的名称,建议启动的时候自己指定,便于后期启动停止可以通过容器名称直接控制
- `-p 8100:8000` 端口映射,宿主机 `8100`,容器 `8000`, 这样发送到宿主机 `8100` 端口的消息,就会由 `docker` 转发到容器 `8000` 端口, 供容器里的服务监听
- `-e ENV_LOGLEVALE=info` 声明一个可以让容器里识别到的环境变量,服务需要用户设置的一些信息,都可以通过定义成环境变量的形式在创建的时候传入容器
### 启动/停止/重启
```
docker start [OPTIONS] CONTAINER [CONTAINER...]
docker stop [OPTIONS] CONTAINER [CONTAINER...]
docker restart [OPTIONS] CONTAINER [CONTAINER...]
```
日常使用过程中这3个命令里的 `[OPTIONS]` 都没有使用到,一般都是直接后接容器名,例如
```
docker start redis-server
```
### 暂停/恢复
- `docker pause` : 暂停容器中所有的进程。
- `docker unpause` : 恢复容器中所有的进程。
```
docker pause CONTAINER [CONTAINER...]
docker unpause CONTAINER [CONTAINER...]
```
### 删除容器
删除一个或多少容器。
```
docker rm [OPTIONS] CONTAINER [CONTAINER...]
```
`OPTIONS` 说明:
- `-f` : 强制删除一个运行中的容器
- `-l` : 移除容器间的网络连接,而非容器本身
- `-v` : 删除与容器关联的卷
```
docker rm -f mysql
```
### 在运行的容器中执行命令
```
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
```
`OPTIONS` 说明:
- `-d` : 分离模式: 在后台运行
- `-i` : 即使没有附加也保持 `STDIN` 打开
- `-t` : 分配一个伪终端
简单点说,**可以进入容器里**,在容器的环境下,输入一些命令,就类似于 `ssh` 到别人的机器上
其中 `OPTIONS` 的中 `-d` 的作用不详,但是输入命令需要 `-t`, 看到命令执行结果需要 `-i`, 所以在实际使用过程中,一般都是 `-it` 一起使用,也就是下面这样的
```
docker exec -it redis-server /bin/sh
```
## 容器操作
### 列出容器
```
docker ps [OPTIONS]
```
`OPTIONS` 说明:
- `-a` : 显示所有的容器,包括未运行的
- `-f` : 根据条件过滤显示的内容
- `--format` : 指定返回值的模板文件
- `-l` : 显示最近创建的容器
- `-n` : 列出最近创建的n个容器
- `--no-trunc` : 不截断输出容器ID完整显示
- `-q` : 只显示容器编号
- `-s` : 额外显示容器大小
列出所有在运行的容器信息。
```
docker ps
```
输出详情介绍:
- `CONTAINER ID` : 容器 ID
- `IMAGE` : 使用的镜像
- `COMMAND` : 启动容器时运行的命令
- `CREATED` : 容器的创建时间
- `STATUS` : 容器状态。状态有 7 种
- - `created`(已创建)
- `restarting`(重启中)
- `running`(运行中)
- `removing`(迁移中)
- `paused`(暂停)
- `exited`(停止)
- `dead`(死亡)
- `PORTS` : 容器的端口信息和使用的连接类型tcp\udp
- `NAMES` : 自动分配的容器名称
### 查看容器详情
获取容器/镜像的元数据,元数据包括容器的 id、创建时间、运行状态、启动参数、目录挂载、网路配置等等。注意该命令也可以用来查看镜像的信息。
```
docker inspect [OPTIONS] NAME|ID [NAME|ID...]
```
`OPTIONS` 说明:
- `-f (--format)` : 指定返回值的 go 模板文件
- `-s` : 显示总的文件大小。
- `--type` : 指定类型,用于指定 `docker` 对象类型,如:`container``image`。在容器与镜像同名时可以使用。默认返回容器信息
直接 `docker inspect 容器名` 会返回特别多的信息,这时候就需要使用 `-f` 来做一步筛选
格式如下, 这里的key 指的是 `docker inspect 容器名` 返回结果里的 `key`
```
docker inspect -f "{{json .key}}" 容器名
# 方便看json, 使用 jq
docker inspect -f "{{json .key}}" 容器名 | jq
```
举个例子
```
# 查看容器 redis-server 的容器ID
docker inspect -f "{{json .ID}}" redis-server
# 查看容器 redis-server 的挂载信息
docker inspect -f "{{json .Mounts}}" redis-server | jq
# 查看容器 redis-server 的网络设置中网络信息
docker inspect -f "{{json .NetworkSettings.Networks}}" redis-server | jq
```
### 获取日志
```
docker logs [OPTIONS] CONTAINER
```
`OPTIONS` 说明:
- `-f` : 跟踪日志输出,实时显示
- `--since` : 显示某个开始时间的所有日志
- `-t` : 显示时间戳
- `--tail N` : 仅列出最新 N 条容器日志
查看容器 `redis-server` 从 2020 年 12 月 30 日后的最新 10 条日志, 并且实时显示最新的日志输出。
```
docker logs -f --since="2020-12-30" --tail 10 redis-server
```
### 数据拷贝
用于容器与主机之间的数据拷贝。
```
# 从容器中拷贝出来
docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
# 拷贝到容器中
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
```
`OPTIONS` 说明:
- `-L` : 保持源目标中的链接
## 镜像管理
一般情况下很少涉及到对镜像管理,但是这里简单介绍一些
### 列出本地镜像
```
docker images [OPTIONS] [REPOSITORY[:TAG]]
```
OPTIONS 说明:
- `-a` : 列出本地所有的镜像(含中间映像层,默认情况下,过滤掉中间映像层)
- `--digests` : 显示镜像的摘要信息
- `-f` : 显示满足条件的镜像
- `--format` : 指定返回值的模板文件
- `--no-trunc` : 显示完整的镜像信息
- `-q`: 只显示镜像ID
列出本地镜像中 REPOSITORY 为 ubuntu 的镜像列表。
```
docker images ubuntu
```
### 删除镜像
删除本地一个或多少镜像。
```
docker rmi [OPTIONS] IMAGE [IMAGE...]
```
`OPTIONS` 说明:
- `-f`: 强制删除
- `--no-prune` : 不移除该镜像的过程镜像,默认移除
强制删除本地镜像 runoob/ubuntu:v4。
```
docker rmi -f runoob/ubuntu:v4
```
### 标记本地镜像/重命名
标记本地镜像,将其归入某一仓库。
```
docker tag [OPTIONS] IMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG]
```
将镜像 `ubuntu:15.10` 标记为 `runoob/ubuntu:v3` 镜像。
```
docker tag ubuntu:15.10 runoob/ubuntu:v3
```
### 导出镜像
将指定镜像保存成 tar 归档文件。
```
docker save [OPTIONS] IMAGE [IMAGE...]
```
`OPTIONS` 说明:
- `-o` : 输出到的文件
将镜像 `runoob/ubuntu:v3` 生成 `my_ubuntu_v3.tar` 文档。
```
docker save -o my_ubuntu_v3.tar runoob/ubuntu:v3
docker save runoob/ubuntu:v3 > my_ubuntu_v3.tar
```
### 导入镜像
导入使用 `docker save` 命令导出的镜像。
```
docker load [OPTIONS]
```
`OPTIONS` 说明:
- `--input, -i` : 指定导入的文件,代替 STDIN
- `--quiet, -q` : 精简输出信息
`busybox.tar.gz` 导入镜像。
```
docker load < busybox.tar.gz
```
指定导入文件 `busybox.tar` 导入镜像。
```
docker load -i busybox.tar
```
## 小技巧
```
# 删除所有容器
docker rm -f $(docker ps -aq)
# 筛选出所有含有 k8s 字段的容器
docker ps -a | grep k8s
# 同理,删除满足条件 (含有 k8s 字段) 的容器
docker rm -f $(docker ps -a | grep k8s | awk -F ' ' '{print $1}')
```
Linux 下管道还是很强大的,前一个命令的输出作为后一个命令的输入,因此 `grep` `awk` 等等都是可以配合使用的
同时也可以将命令的输出结果作为变量,供另一个命令使用
## 1.3、常用docker命令
### 1.3.1、查看docker信息
###### 1、查看docker版本
```
docker version
```
###### 2、显示docker系统的信息
```
docker info
```
### 1.3.2、对image的操作
###### 1、检索image
```
docker search image_name
```
###### 2、下载image
```
docker pull image_name
```
###### 3、列出镜像列表
```
docker images
```
###### 4、删除一个或者多个镜像
```
docker rmi image_name
```
###### 5、显示一个镜像的历史
```
docker history image_name
```
### 1.3.3、启动容器
###### 1、在容器中运行”echo”命令输出”hello word”
```
docker run image_name echo "hello word"
```
###### 2、交互式进入容器中
```
docker run -i -t image_name /bin/bash
```
###### 3、在容器中安装新的程序
```
docker run image_name apt-get install -y app_name
```
### 1.3.4、查看容器
###### 1、列出当前所有正在运行的container
```
docker ps
```
###### 2、列出所有的container
```
docker ps -a
```
###### 3、列出最近一次启动的container
```
docker ps -l
```
### 1.3.5、保存对容器的修改
###### 1、保存对容器的修改
```
docker commit ID new_image_name
```
### 1.3.6、对容器的操作
###### 1、删除所有容器
```
docker rm `docker ps -a -q`
```
###### 2、删除单个容器
```
docker rm Name/ID
```
###### 3、 停止、启动、杀死一个容器
```
$docker stop Name/ID
$docker start Name/ID
$docker kill Name/ID
```
###### 4、从一个容器中取日志
```
docker logs Name/ID
```
###### 5、列出一个容器里面被改变的文件或者目录
```
docker diff Name/ID
```
###### 6、显示一个运行的容器里面的进程信息
```
docker top Name/ID
```
###### 7、从容器里面拷贝文件/目录到本地一个路径
```
docker cp Name:/container_path to_path
docker cp ID:/container_path to_path
```
###### 8、重启一个正在运行的容器
```
docker restart Name/ID
```
###### 9、附加到一个运行的容器上面
```
docker attach ID
```
### 1.3.7、 保存和加载镜像
###### 1、保存镜像到一个tar包
```
docker save image_name -o file_path
```
###### 2、加载一个tar包格式的镜像
```
docker load -i file_path
```
### 1.3.8、 登录registry server
###### 1、登陆registry server
```
docker login
```
### 1.3.9、发布image
###### 1、发布docker镜像
```
docker push new_image_name
```
**Docker镜像拉取**
```
root@linuxcool:~# docker pull mysql:5.6
5.6: Pulling from library/mysql
e62d08fa1eb1: Pull complete
Digest: sha256:60c27b50ca72d81d92a743a965a82f124a4e123c7d374a021887286408878d60
Status: Downloaded newer image for mysql:5.6
docker.io/library/mysql:5.6
```
**Docker容器备份**
```
root@linuxcool:~# docker image save mysql:5.6 -o mysql:5.6.tar.gz
mysql:5.6
mysql:5.6.tar.gz
```
**Docker容器导出**
```
root@linuxcool:~# docker save mysql:5.6 > mysql:5.6.tar.gz
mysql:5.6
mysql:5.6.tar.gz
```
**Docker容器恢复**
```
root@linuxcool:~# docker image load -i mysql:5.6.tar.gz
mysql:5.6.tar.gz
```
**Docker容器导入**
```
root@linuxcool:~# docker image load < mysql:5.6.tar.gz
Loaded image: mysql:5.6
mysql:5.6.tar.gz
```
# 1.4、搭建需要镜像
## 已有镜像列表
jenkins/jenkins latest 3d2f88dfa0ea 16 hours ago 572MB
gitlab/gitlab-ce latest e5894d9173ec 7 days ago 2.21GB
portainer/portainer latest 580c0e4e98b0 4 weeks ago 79.1MB
sonatype/nexus3 latest f07af611e0df 6 weeks ago 662MB
idoop/zentao latest 2d8b2ca2e0d7 2 months ago 188MB
mysql 5.7 a70d36bc331a 3 months ago 449MB
rabbitmq 3.8.9 7471fb821b97 3 months ago 167MB
redis 6.0.9 6060df96cef3 3 months ago 104MB
nginx 1.19.4 daee903b4e43 5 months ago 133MB
registry 2.4.1 8ff6a4aae657 4 years ago 172MB
java 8 d23bdf5b1b1b 4 years ago 643MB
## 导出需要的镜像
docker save java -o /opt/images/java.tar.gz
docker save gitlab/gitlab-ce -o /opt/images/gitlab-ce.tar.gz
docker save portainer/portainer -o /opt/images/portainer.tar.gz
docker save sonatype/nexus3 -o /opt/images/nexus3.tar.gz
docker save idoop/zentao -o /opt/images/zentao.tar.gz
docker save mysql -o /opt/images/mysql.tar.gz
docker save rabbitmq -o /opt/images/rabbitmq.tar.gz
docker save redis -o /opt/images/redis.tar.gz
docker save nginx -o /opt/images/nginx.tar.gz
docker save registry -o /opt/images/registry.tar.gz
docker save jenkins/jenkins -o /opt/images/jenkins.tar.gz
docker commit ca0037d8a147 jenkins/jenkins
docker save jenkins/jenkins -o /opt/data/jenkins.tar.gz
## 加载需要的镜像
docker load -i /opt/images/java.tar.gz
docker load -i /opt/images/gitlab-ce.tar.gz
docker load -i /opt/images/portainer.tar.gz
docker load -i /opt/images/nexus3.tar.gz
docker load -i /opt/images/zentao.tar.gz
docker load -i /opt/images/mysql.tar.gz
docker load -i /opt/images/rabbitmq.tar.gz
docker load -i /opt/images/redis.tar.gz
docker load -i /opt/images/nginx.tar.gz
docker load -i /opt/images/registry.tar.gz
docker load -i /opt/images/jenkins.tar.gz
tar -zcvf jekins.tar.gz jenkins/
tar -zxvf jekins.tar.gz -C /opt/data/
tar -zcvf data.tar.gz data/
# 2、修改yum源
**概要**
刚装完的CentOs系统里使用的是国外的CentOs更新源这就造成了我们使用默认更新源安装或者更新软件时速度很慢的问题。
为了使用yum工具能快速的安装更新软件我们需要将默认的yum更新源配置为国内的更新源。
### **开启网络连接**
对于新装的CentOS默认是没有开启网络连接的所以你看不到IP地址。
```text
#查看有线网设备
ip address
```
可以看到几个设备:
```text
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue
2: enp4s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500
...
```
那么有线网就是叫enp4s0虚拟机一般为 ens33
```text
#打开有线网配置
vi /etc/sysconfig/network-scripts/ifcfg-enp4s0
#最后一行修改为YES
ONBOOT=YES
#重启网络服务
systemctl restart network.service
```
### **更换yum官方源**
```text
#下载wget工具,一般默认有
yum install -y wget
#进入yum源配置文件所在文件夹
cd /etc/yum.repos.d/
#备份本地yum源(修改或删除文件都建议备份下)
mv CentOS-Base.repo CentOS-Base.repo_bak
```
获取国内yum源进行覆盖阿里云、163等等
```text
#以CentOs7为例若为CentOs5/6只需要改下方数字
wget -O CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
#wget -O CentOS-Base.repo http://mirrors.163.com/.help/CentOS7-Base-163.repo
```
通常yum 把下载的header和软件包都存储在/var/cache/yum目录中而不会自动删除。如果你觉得它们占用了大量磁盘空间可以使用yum clean指令进行清除
```text
#清理yum缓存
yum clean all
#清理后重建缓存
yum makecache
#升级Linux系统
yum -y update
```
### **增加EPEL源**
(Extra Packages for Enterprise Linux)为“红帽系”的操作系统提供额外的软件包适用于RHEL、CentOS等里面有1万多个软件**强烈建议安装。**
```text
#安装epel源
yum install epel-release
#修改为阿里的epel源
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
```
**yum priorities** 插件可以用来强制保护源。它通过给各个源设定不同的优先级,使得系统管理员可以将某些源(比如 Linux 发行版的官方源)设定为最高优先级,从而保证系统的稳定性(同时也可能无法更新到其它源上提供的软件最新版本)。
```text
#安装yum源优先级管理工具
yum install -y yum-priorities
#添加优先级(数字越小优先级越高)
vim /etc/yum.repo.d/epel.repo
priority=88
#添加优先级这个数要小于epel里的88即可
vim /etc/yum.repo.d/Centos-Base.repo
priority=6
#开启yum源优先级功能
vim /etc/yum/pluginconf.d/priorities.conf
#确保文件内容包含如下:
[main]
enabled=1
```

View File

@@ -0,0 +1,133 @@
# docker cmd
## bash
`docker exec -it <container> bash`
[Docker image的导入导出 - 简书](https://www.jianshu.com/p/69b6c4c556ad)
## 导出image 导出镜像
[docker load | Docker Documentation](https://docs.docker.com/engine/reference/commandline/load/)
```bash
docker save -o /home/user/images/ubuntu_14.04.tar ubuntu:14.04
```
## 导入image 导入镜像
```bash
docker load --input ubuntu_14.04.tar
```
## 导入导出压缩
```bash
docker save mp_info | gzip > /home/userapp/xiewei/mp_info/mp_info.tar.gz
# gunzip -c /home/userapp/xiewei/mp_info/mp_info.tar.gz | docker load
docker save gcr.io/cadvisor/cadvisor:latest | gzip > cadvisor.tar.gz
docker load -i cadvisor.tar.gz
# Load an image or repository from a tar archive (even if compressed with gzip, bzip2, or xz) from a file or STDIN. It restores both images and tags.
# 直接读取,不解压也可以
docker load -i /home/userapp/xiewei/mp_info/mp_info.tar.gz
```
## docker run
最后面的 `server /data` 是指定需要在容器内执行的命令。
```sh
docker run -p 9000:9000 --name myminio \
-e "MINIO_ACCESS_KEY=AKIAIOSFODNN7EXAMPLE" \
-e "MINIO_SECRET_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" \
-v /mnt/data:/data \
-v /mnt/config:/root/.minio \
minio/minio server /data
```
```yml
version: '3'
services:
minio:
image: minio/minio:latest
container_name: myminio
ports:
- 9000:9000
volumes:
- /var/minio/data:/data
- /var/minio/config:/root/.minio
environment:
MINIO_ACCESS_KEY: "root"
MINIO_SECRET_KEY: "password"
command: server /data
restart: always
```
## docker stack
单机模式下,我们可以使用 Docker Compose 来编排多个服务,而 Docker Swarm 只能实现对单个服务的简单部署。本文的主角 Docker Stack ,通过 Docker Stack 我们只需对已有的 docker-compose.yml 配置文件稍加改造就可以完成 Docker 集群环境下的多服务编排
## docker cp
```bash
# Docker容器向宿主机传送文件
docker cp container_id:<docker容器内的路径> <本地保存文件的路径>
# ---
# 宿主机向Docker容器传送文件
docker cp 本地文件的路径 container_id:<docker容器内的路径>
```
## docker stats
资源监控
```shell
docker top xxx
docker stats
```
## docker 进入未启动的容器 `How To Run Commands In Stopped Docker Containers`
[How To Run Commands In Stopped Docker Containers · Thorsten Hans](https://www.thorsten-hans.com/how-to-run-commands-in-stopped-docker-containers/)
```bash
# Commit the stopped image
docker commit 0dfd54557799 xxx
# now we have a new image
docker images list
REPOSITORY TAG IMAGE ID CREATED SIZE
debug/ubuntu <none> cc9db32dcc2d 2 seconds ago 64.3MB
# create a new container from the "broken" image
docker run -it --rm --entrypoint sh xxxx
# inside of the container we can inspect - for example, the file system
$ ls /app
App.dll
App.pdb
App.deps.json
# CTRL+D to exit the container
# delete the container and the image
docker image rm xxx
```
>端口映射 实际上就是  SNAT+DNAT
都是NAT
SNAT源地址转换和DNAT目的地址转换
这个是 容器不能访问其他容器的情况
```bash
iptables -I INPUT -i docker0 -j ACCEPT
iptables -t nat -L -n -v
```

View File

@@ -0,0 +1,420 @@
# docker tips
#docker #tips
官方教程
[Samples | Docker Documentation](https://docs.docker.com/samples/)
## docker 验证
docker_auth
[GitHub - cesanta/docker_auth: Authentication server for Docker Registry 2](https://github.com/cesanta/docker_auth)
harbor
[GitHub - goharbor/harbor: An open source trusted cloud native registry project that stores, signs, and scans content.](https://github.com/goharbor/harbor)
nexus
## docker 安装源
[Debian Docker 安装 | 菜鸟教程](https://www.runoob.com/docker/debian-docker-install.html)
```bash
curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/debian/gpg | sudo apt-key add -
add-apt-repository \
"deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/debian \
$(lsb_release -cs) \
stable"
apt-get update
apt-get install docker-ce docker-ce-cli containerd.io
```
## docker 容器镜像源
[阿里云容器镜像服务](https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors)
镜像库可能只包含流行的公有镜像,而私有镜像仍需要从美国镜像库中拉取。
但是portianer 要先在images中pull 可以找到80x86/filebrowser
Registry
```
https://upm3cnhv.mirror.aliyuncs.com
```
[汇总最近更新的一些docker镜像群晖威联通等通用_网摘资源部落_社区_115一生相伴](https://q.115.com/22495040/T31798.html)
[oldiy's Profile - Docker Hub](https://hub.docker.com/u/oldiy/)
[30多个N1可用docker镜像-百度云同步、1898种dos游戏、花生壳、可道云、蚂蚁笔记... - 斐讯无线路由器以及其它斐迅网络设备 - 恩山无线论坛 - Powered by Discuz!](https://www.right.com.cn/forum/thread-911375-1-1.html)
[DaoCloud | Docker 极速下载](http://get.daocloud.io/)
### docker国内镜像源Azure 中国(最快镜像源)
`vim /etc/docker/daemon.json`
```json
{
"registry-mirrors": ["https://dockerhub.azk8s.cn","http://hub-mirror.c.163.com"]
}
```
## docker 容器启动后立马退出的解决方法
Docker容器后台运行,就必须有一个前台进程
```
tail -f /dev/null
docker run -d --name mycentos-zp5 -d centos:7.4.1708 /bin/sh -c "while true;do echo hello;sleep 5;done"
sudo docker run -d ubuntu:14.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
docker run -d --name mycentos-zp4 -d centos:7.4.1708 ping 8.8.8.8
docker run -dit --name ubuntu2 ubuntu
docker run -d --name ubuntu ubuntu /bin/bash -c "tail -f /dev/null"
#####
# docker-nginx-amplify/entrypoint.sh
有这种写法
nginx -g "daemon off;" &
nginx_pid=$!
wait ${nginx_pid}
```
## 查看docker container内进程信息及与宿主机上进程的映射关系
1、docker ps 找到对应的容器
2、根据container id 找到容器在宿主机上映射后的进程信息
`docker top id`
就会得到类似下面的信息其中PID是容器内进程在宿主机上的pidppid是容器内进程在宿主机上的父进程pid
[查看docker container内进程信息及与宿主机上进程的映射关系 - 衣舞晨风 - CSDN博客](https://blog.csdn.net/jiankunking/article/details/85853187)
## 映射的host目录 好像会自己建立
在portainer上试验是这样的
## PUID=1000 and PGID=1000
id应该是按主机上的用户id来定义
建立文件和文件夹的权限是该账户的
-e TZ="Asia/Shanghai" -e HOST_OS="Unraid" -e 'PUID'='99' -e 'PGID'='100'
[Understanding PUID and PGID - LinuxServer.io](https://docs.linuxserver.io/general/understanding-puid-and-pgid)
`id $user`
## 查看一个正在运行的Docker容器的启动命令
`docker ps -a --no-trunc`
apt-get install python-pip
pip install setuptools
pip install runlike
runlike Docker_container_name
runlike -p Docker_container_name
## docker开启远程tcp监听端口
[Docker TCP远程连接_慕课手记](https://www.imooc.com/article/details/id/28426)
https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-configuration-file
> You cannot set options in daemon.json that have already been set on daemon startup as a flag. On systems that use systemd to start the Docker daemon, -H is already set, so you cannot use the hosts key in daemon.json to add listening addresses. See https://docs.docker.com/engine/admin/systemd/#custom-docker-daemon-options for how to accomplish this task with a systemd drop-in file.
>
configure-docker-to-start-on-boot
[Post-installation steps for Linux | Docker Documentation](https://docs.docker.com/engine/install/linux-postinstall/#configure-docker-to-start-on-boot)
Configure where the Docker daemon listens for connections
[Post-installation steps for Linux | Docker Documentation](https://docs.docker.com/engine/install/linux-postinstall/#configure-where-the-docker-daemon-listens-for-connections)
按官方文档的说法好像在centos里面用不了 daemon.json 来配置 host
/etc/docker/daemon.json
```json
{
"registry-mirrors": ["https://upm3cnhv.mirror.aliyuncs.com"],
"hosts": ["tcp://192.168.66.254:2375", "unix:///var/run/docker.sock"]
"hosts": ["tcp://0.0.0.0:22375", "unix:///var/run/docker.sock"]
}
```
所以使用下面的方法
systemctl edit docker.service
```
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:22375
```
重启docker网络
```
systemctl daemon-reload
```
重启docker服务 重启 docker
```bash
systemctl restart docker
systemctl status docker.service
```
curl -l http://localhost:22375/info
## Non-Root
[Work With Non-Root Containers for Bitnami Applications](https://docs.bitnami.com/containers/how-to/work-with-non-root-containers/)
## docker 普通用户 将docker权限添加给普通用户
[将docker权限添加给普通用户 - 简书](https://www.jianshu.com/p/b0245f0360ca)
[使用普通用户执行 docker - klvchen - 博客园](https://www.cnblogs.com/klvchen/p/9098745.html)
```shell
cat /etc/group
sudo gpasswd -a userapp docker
# 最好不要用这个命令,这个命令可以添加一个用户到指定的组,但是以前添加的组就会清空掉
# 所以想要添加一个用户到一个组,同时保留以前添加的组时,请使用 gpasswd 这个命令来添加操作用户
# usermod -G docker userapp
#####
groupadd docker
gpasswd -a ${USER} docker
```
## 网络
### drone 有时候会导致整个服务器网络异常
```shell
docker network ls
docker network rm drone-ysqYZHndoYiYX2ndglk8
```
### docker 中访问宿主
宿主执行 ip a
看docker0 网卡的ip
一般是
`172.17.0.1`
### host 模式
[docker 网络-host - 简书](https://www.jianshu.com/p/1dd65ab5b997)
容器与主机在相同的网络命名空间下面,使用相同的网络协议栈,容器可以直接使用主机的所有网络接口
host 模式 不能使用端口映射和自定义路由规则,这些都与主机一致,-p 与-icc 参数是无效的
host 模式下面的网络模型是最简单和最低延迟的模式,容器进程直接与主机网络接口通信,与物理机性能一致
```bash
docker run -itd --net host --name C1 hub.c.163.com/library/alpine:latest
```
## 判断系统是否运行在Docker环境中
[判断系统是否运行在Docker环境中_白帽子技术/思路_i春秋社区-分享你的技术,为安全加点温度.](https://bbs.ichunqiu.com/thread-47469-1-1.html)
`cat /proc/1/cgroup|grep docker`
```bash
# docker
root@55ff7ae5bdae:~# cat /proc/1/sched | head -n 1
startWebLogic.s (8212, #threads: 1)
root@55ff7ae5bdae:~#
# real
root@kali:~# cat /proc/1/sched | head -n 1
systemd (1, #threads: 1)
root@kali:~#
# real
root@kali:~# ps -q1
PID TTY TIME CMD
1 ? 00:00:02 systemd
root@kali:~#
# docker
root@55ff7ae5bdae:~# ps -p 1
PID TTY TIME CMD
1 ? 00:00:00 startWebLogic.s
root@55ff7ae5bdae:~#
```
## 容器内查看运行时间
[uptime command gives weird results in a docker image - Server Fault](https://serverfault.com/questions/830643/uptime-command-gives-weird-results-in-a-docker-image)
`stat /proc/1/cmdline`
## unraid 的docker命令
```bash
root@localhost:# /usr/local/emhttp/plugins/dynamix.docker.manager/scripts/docker create --name='nginx' --net='bridge' --log-opt max-size='50m' --log-opt max-file='1' -e TZ="Asia/Shanghai" -e HOST_OS="Unraid" -e 'PUID'='99' -e 'PGID'='100' -p '2280:80/tcp' -p '22443:443/tcp' -v '/mnt/user/appdata/nginx':'/config':'rw' 'linuxserver/nginx'
1c20c14ca61487a84313eac231c46fdaa0818eb1e5a872246abd6147c97f8945
```
## docker restart policy
[Docker容器的重启策略及docker run的--restart选项详解_运维_成长的足迹-CSDN博客](https://blog.csdn.net/taiyangdao/article/details/73076019)
no不自动重新启动容器。默认默认策略在容器退出时不重启容器
on-failure 由于一个错误退出它表现为退出状态不等于0自动启动容器
on-failure:3在容器非正常退出时重启容器最多重启3次
unless-stopped :除非被显式停止 stop、kill 否则docker服务停止或自动重启自动启动容器
在容器退出时总是重启容器但是不考虑在Docker守护进程启动时就已经停止了的容器
always如果容器停止总是重新启动容器。这是官方解释如果手动kill容器 无法自动重启,应该也属于正常 如果手动都不能让他停止 也许我们会更烦恼怎么停止它~~~~)在容器退出时总是重启容器
使用重新启动策略时请记住以下几点:
1. 重新启动策略仅在容器启动成功后才生效。在这种情况下启动成功意味着容器已启动至少10秒并且Docker已开始监视它。这可以防止根本不启动的容器进入重启循环。
2. 如果手动停止容器则会忽略其重新启动策略直到Docker守护程序重新启动或手动重新启动容器。这是另一个防止重启循环的尝试。
3. 重新启动策略仅适用于容器。群集服务的重新启动策略配置不同。
https://docs.docker.com/engine/reference/commandline/service_create/
## Configure Docker to use a proxy server 容器内代理
两种方式
一个是配置文件
一个是容器的环境变量
| Variable | Dockerfile example | `docker run` Example |
| ------------- | ------------------------------------------------- | --------------------------------------------------- |
| `HTTP_PROXY` | `ENV HTTP_PROXY "http://127.0.0.1:3001"` | `--env HTTP_PROXY="http://127.0.0.1:3001"` |
| `HTTPS_PROXY` | `ENV HTTPS_PROXY "https://127.0.0.1:3001"` | `--env HTTPS_PROXY="https://127.0.0.1:3001"` |
| `FTP_PROXY` | `ENV FTP_PROXY "ftp://127.0.0.1:3001"` | `--env FTP_PROXY="ftp://127.0.0.1:3001"` |
| `NO_PROXY` | `ENV NO_PROXY "*.test.example.com,.example2.com"` | `--env NO_PROXY="*.test.example.com,.example2.com"` |
## 宿主机进程的问题
[在Linux宿主机审计docker进程和网络连接 - 血梦博客 - 专注于网络安全|渗透测试|代码审计|国内最专业的黑客技术博客](http://www.hacksec.cn/Penetration-test/965.html)
有docker字样的是docker进程
```bash
root@unRaid:~# cat /proc/23437/cgroup
10:pids:/docker/069de498d1d22d31565ea8816981cb4d546e5437bb0e84ff0d6bdc2655475b5f
9:perf_event:/docker/069de498d1d22d31565ea8816981cb4d546e5437bb0e84ff0d6bdc2655475b5f
8:net_cls:/docker/069de498d1d22d31565ea8816981cb4d546e5437bb0e84ff0d6bdc2655475b5f
7:freezer:/docker/069de498d1d22d31565ea8816981cb4d546e5437bb0e84ff0d6bdc2655475b5f
6:devices:/docker/069de498d1d22d31565ea8816981cb4d546e5437bb0e84ff0d6bdc2655475b5f
5:memory:/docker/069de498d1d22d31565ea8816981cb4d546e5437bb0e84ff0d6bdc2655475b5f
4:blkio:/docker/069de498d1d22d31565ea8816981cb4d546e5437bb0e84ff0d6bdc2655475b5f
3:cpuacct:/docker/069de498d1d22d31565ea8816981cb4d546e5437bb0e84ff0d6bdc2655475b5f
2:cpu:/docker/069de498d1d22d31565ea8816981cb4d546e5437bb0e84ff0d6bdc2655475b5f
1:cpuset:/docker/069de498d1d22d31565ea8816981cb4d546e5437bb0e84ff0d6bdc2655475b5f
```
## 保存修改后的容器
[保存对容器的修改 - Docker入门教程 - docker中文社区](http://www.docker.org.cn/book/docker/docer-save-changes-10.html)
commit 之前最好停止容器
查看被修改的容器docker ps -l
提交指定容器保存为新的镜像: `docker commit <container id> <new image name>`
查看本地所有镜像docker images
[Docker保存修改后的镜像 - 知乎](https://zhuanlan.zhihu.com/p/86524042)
```text
docker run -it ubuntu:16.04 /bin/bash
docker run -it openjdk:8-jdk /bin/bash
docker commit d3742a06f8ae openjdk-tesseract
```
## Docker 配置 HTTP 代理
[Docker配置HTTP代理 - Hazx小屋](https://hazx.hmacg.cn/server/docker-http-proxy.html)
配置的 HTTP 代理主要用于 Docker 拉取 (pull) 和推送 (push) 镜像使用。不会影响 Docker 容器的联网状态。
Docker 代理仅支持 HTTP 协议。
若有特殊需求,请自备梯子。
代理地址配置为自己的本地服务器地址,必须是 HTTP 代理协议。
NO_PROXY 配置跳过代理的地址,需要填入所以用到的本地地址,支持 *,多个地址用逗号隔开。
```bash
mkdir -p /etc/systemd/system/docker.service.d
vim /etc/systemd/system/docker.service.d/http-proxy.conf
[Service]
Environment="HTTP_PROXY=http://192.168.100.100:8080/"
Environment="HTTPS_PROXY=http://192.168.100.100:8080/"
Environment="NO_PROXY=localhost,127.0.0.1,10.96.0.1,192.168.*"
systemctl daemon-reload
systemctl restart docker
```
## docker 运行 代理
[Configure Docker to use a proxy server | Docker Documentation](https://docs.docker.com/network/proxy/)
| Variable | Dockerfile example | `docker run` Example |
| ------------- | ------------------------------------------------- | --------------------------------------------------- |
| `HTTP_PROXY` | `ENV HTTP_PROXY="http://127.0.0.1:3001"` | `--env HTTP_PROXY="http://127.0.0.1:3001"` |
| `HTTPS_PROXY` | `ENV HTTPS_PROXY="https://127.0.0.1:3001"` | `--env HTTPS_PROXY="https://127.0.0.1:3001"` |
| `FTP_PROXY` | `ENV FTP_PROXY="ftp://127.0.0.1:3001"` | `--env FTP_PROXY="ftp://127.0.0.1:3001"` |
| `NO_PROXY` | `ENV NO_PROXY="*.test.example.com,.example2.com"` | `--env NO_PROXY="*.test.example.com,.example2.com"` |
## ERROR: Failed to Setup IP tables: Unable to enable SKIP DNAT rule
原因是防火墙关闭之后需要重启docker服务
`service docker restart`
## tools
ctop 监控
[ctop](https://ctop.sh/)
[CTOP一款管理Docker容器的TOP命令 | 佰阅部落](https://baiyue.one/archives/1135.html)
## links
[Docker 与 Vagrant 的区别? - V2EX](https://www.v2ex.com/t/296100#reply17)
[docker 部署方式 - V2EX](https://www.v2ex.com/t/401144#reply9)
[有什么好玩的自建服务没? 最近在玩 docker搭上瘾了。。。。。 - V2EX](https://www.v2ex.com/t/226691#reply7)
[实在没理解 docker 或 vagrant 是怎么统一 开发 环境的 - V2EX](https://www.v2ex.com/t/388777#reply34)
[Dockerize PostgreSQL | Docker Documentation](https://docs.docker.com/engine/examples/postgresql_service/)
[docker 使用 mysql 时选择新建 mysql 容器还是单一容器内新开 mysql 进程? - V2EX](https://www.v2ex.com/t/357237#reply32)
> docker 建议是单一进程的,也就是这一个容器里只跑一个进程
> 别在 docker 上跑数据库,会被坑死的
>
[京东MySQL数据库Docker化最佳实践附PPT - MySQL - dbaplus社群围绕Data、Blockchain、AiOps的企业级专业社群。技术大咖、原创干货每天精品原创文章推送每周线上技术分享每月线下技术沙龙。](https://dbaplus.cn/news-11-1118-1.html)
[容器监控实践—cAdvisor - 简书](https://www.jianshu.com/p/91f9d9ec374f)
[Samples | Docker Documentation](https://docs.docker.com/samples/)
### 资料
[WORKDIR 指定工作目录-Docker — 从入门到实践](https://www.cntofu.com/book/139/image/dockerfile/workdir.md)
### books
[Docker — 从入门到实践](https://www.cntofu.com/book/139/index.html)

View File

@@ -0,0 +1,34 @@
docker compose up -d
docker compose down
### docker 执行命令
```
docker run -it -u 1000:1000 --rm -v "$PWD":/usr/src/app -w /usr/src/app node:14.21 bash a.sh
docker run -it -u 1000:1000 --rm -v "$PWD":/usr/src/app -w /usr/src/app node:14.21 bash
```
```
docker run -it -u 1000:1000 --rm -v "$PWD":/usr/src/mymaven -v "$HOME/.m2":/root/.m2 -v "$PWD/target":/usr/src/mymaven/target -w /usr/src/mymaven maven mvn clean package
```
## docker java 环境变量
```
docker run -itd -p 28080:28080 -e "SPRING_PROFILES_ACTIVE=prod" -e "SWAGGER_ENABLED=true" -e "KNIFE4J_PRODUCTION=false" -v /data/jfzx/docker_data/nginx/cache:/nginx/cache --name idigital-admin-server idigital-admin-server:latest
```
* -e SPRING_PROFILES_ACTIVE=prod 指定 yml
* 其他 跟jar 启动 一样
## docker 代理
```
[root@master ~]# systemctl show --property=Environment docker
Environment=HTTP_PROXY=http://192.168.186.1:10809/ HTTPS_PROXY=http://192.168.186.1:10809/
[root@master ~]# mkdir -p /etc/systemd/system/docker.service.d
systemctl daemon-reload
systemctl restart docker
[root@master ~]# cd /etc/systemd/system/docker.service.d/
[root@master docker.service.d]# cat http-proxy.conf
[Service]
Environment="HTTP_PROXY=http://192.168.186.1:10809/"
Environment="HTTPS_PROXY=http://192.168.186.1:10809/"
```

View File

@@ -0,0 +1,120 @@
## 阿里云 ECS 安装 docker
> https://developer.aliyun.com/article/1662498
## 普通用户入组
```
sudo usermod -aG docker userapp
```
## nginx-proxy
```
docker run -d -p 9024:80 -p 9025:81 -p 9026:443 -v /data/letsencrypt:/etc/letsencrypt -v /data/nginx-proxy-manager/data:/data --name nginx-proxy-manager docker.io/jc21/nginx-proxy-manager:latest
```
## portainer
```shell
docker run -d -p 9000:9000 --name porainer -v /var/run/docker.sock:/var/run/docker.sock -v /data/portainer:/data --restart=always portainer/portainer-ce:2.19.4
```
## mysql
/data/mysql/conf
```shell
touch my.cnf
```
```text
[client]
default_character_set=utf8mb4
[mysql]
default_character_set=utf8mb4
[mysqld]
collation_server = utf8mb4_unicode_ci
character_set_server = utf8mb4
```
```shell
docker run -p 9090:3306 --name mysql \
-v /data/mysql/log:/var/log/mysql \
-v /data/mysql/data:/var/lib/mysql \
-v /data/mysql/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7
```
## nginx
1. 生成容器
1. 将容器nginx.conf文件复制到宿主机
1. 将容器conf.d文件夹下内容复制到宿主机
1. 将容器中的html文件夹复制到宿主机
```
docker run --name nginx -p 9001:80 -d nginx
docker cp nginx:/etc/nginx/nginx.conf /home/nginx/conf/nginx.conf
docker cp nginx:/etc/nginx/conf.d /home/nginx/conf/conf.d
# 删除正在运行的nginx容器
docker rm -f nginx
docker run \
-p 9002:80 \
--name nginx \
-v /home/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
-v /home/nginx/conf/conf.d:/etc/nginx/conf.d \
-v /home/nginx/log:/var/log/nginx \
-v /home/nginx/html:/usr/share/nginx/html \
-d nginx:latest
```
## redis
配置文件
![[redis.conf]]
```
docker run -p 6379:6379 --name redis -v /data/redis/data:/data -v /data/redis/conf/redis.conf:/etc/redis/redis.conf -d redis redis-server /etc/redis/redis.conf
```
## docker Jenkins
https://blog.csdn.net/weixin_44000133/article/details/132189696
## filebrowser
### 注意!!!! 需要先创建文件,不是文件夹
```
docker run \
-v /path/to/root:/srv \
-v /path/to/filebrowser.db:/database/filebrowser.db \
-v /path/to/settings.json:/config/settings.json \
-e PUID=$(id -u) \
-e PGID=$(id -g) \
-p 8080:80 \
-d \
--name filebrowser \
filebrowser/filebrowser:v2.25.0-s6
```
```json
settings.json
{
"port": 80,
"baseURL": "",
"address": "",
"log": "stdout",
"database": "/database/filebrowser.db",
"root": "/srv"
}
```
## ssh web niruix/sshwifty
```
ssl 凭据
openssl req -newkey rsa:4096 -nodes -keyout domain.key -x509 -days 90 -out domain.crt
mkdir -p /data/sshwifty
docker run --detach \
--restart always \
--publish 8182:8182 \
--env SSHWIFTY_DOCKER_TLSCERT="$(cat domain.crt)" \
--env SSHWIFTY_DOCKER_TLSCERTKEY="$(cat domain.key)" \
--name sshwifty \
niruix/sshwifty:latest
```

View File

@@ -0,0 +1,37 @@
docker 环境
```
1.pom/jenkinsfile/dockerfille
2.基础镜像 open jdk 公网下载
a.没有hub仓库的时候镜像上传jenkins所在主机的load  imges
b.如果存在 harbor 仓库,需要上传权限,构建后上传到 harbor里面
3.修改jenkinsfile
```
在目标主机拉取构建后的镜像 并运行
```
a、导出 images 传到目标主机目标主机load 镜像,并运行
b、在目标主机上 拉取 构建后镜像 并运行
```
二、基础镜像
```
保证能读取 openjdk 基础镜像(无论是 jenkins 主机 还是harbor 仓库
然后进行构建;对于构建的结果
1、如果不存在 harbor 仓库那么结果在jenkins 主机上,在(三)进行导出;
2、如果存在 harbor 仓库,需要上传权限,构建后上传到 harbor里面
```
三    修改 Jenkisfile
```
1、导出 images 传到目标主机目标主机load 镜像,并运行
2、在目标主机上 拉取 harbor 构建后镜像 并运行
```

View File

@@ -0,0 +1,92 @@
## 节点容器化自动构建流程
#### 设置GitLab服务器钩子
运用GitLab的webhook勾选push Event当每次有push操作的时候会触发webhook向Jenkins发送事件。
#### Jenkins配置主要步骤
##### 新建Job项目
新建项目,并添加项目描述。
![image-20211117230728593](/Users/tiangui/Desktop/yaxin/zhenjianhui_830/12、容器化相关/节点容器化自动构建流程.assets/image-20211117230728593.png)
##### Git项目源配置
![image-20211117230305803](/Users/tiangui/Desktop/yaxin/zhenjianhui_830/12、容器化相关/节点容器化自动构建流程.assets/image-20211117230305803-7161408.png)
##### Maven构建配置
![image-20211117230900667](/Users/tiangui/Desktop/yaxin/zhenjianhui_830/12、容器化相关/节点容器化自动构建流程.assets/image-20211117230900667.png)
##### 清理镜像构建服务器的Jar包并重新上传
* 采用远程执行脚本清理镜像构建服务器的旧Jar包
* 复制新构建成功的Jar至镜像构建服务器上
##### 清理旧的容器实例
```
container=`docker container ls -a | grep $container_name | awk '{print $1}'`
echo 'stop container ' $container
[[ -n $container ]] && docker stop $container
echo 'rm container ' $container
[[ -n $container ]] && docker rm $container
```
##### 清理旧的镜像实例
```
image=`docker images | grep $image_name | awk '{print $3}'`
echo 'rm image ' $image
[[ -n $image ]] && docker rmi $image
```
##### 构建镜像文件
dockerfile如下
```
# 基础镜像
FROM openjdk:8-jre
# author
MAINTAINER ruoyi
# 挂载目录
VOLUME /home/ruoyi
# 创建目录
RUN mkdir -p /home/ruoyi
# 指定路径
WORKDIR /home/ruoyi
# 复制jar文件到路径
COPY ./jar/ruoyi-modules-system.jar /home/ruoyi/ruoyi-modules-system.jar
# 启动系统服务
ENTRYPOINT ["java","-jar","ruoyi-modules-system.jar"]
```
构建镜像:
```
docker build -t ruoyi-modules-system:0.0.1 .
```
##### 运行容器实例
```
new_image=`docker images |grep $image_name |awk '{print $3}'`
[[ -n $new_image ]] && docker run -d -p 19201:9201 --name $container_name $new_image
```

View File

@@ -0,0 +1,28 @@
给鹏飞的镜像下载教程
https://hub.docker.com/ 上查看镜像的 pull 命令
比如原来是 docker pull postgres:14也就是没有用户名的 docker 的官方镜像
改成
docker pull docker.wanpeng.top/library/postgres:14
docker tag docker.wanpeng.top/library/postgres:14 postgres:14
docker rmi docker.wanpeng.top/library/postgres:14
原来是 docker pull bitnami/mediawiki:1.40.0 也就是用户名是 bitnami 属于 bitnami 组织或者公司的镜像
改成
docker pull docker.wanpeng.top/bitnami/mediawiki:1.40.0
docker tag docker.wanpeng.top/bitnami/mediawiki:1.40.0 bitnami/mediawiki:1.40.0
docker rmi docker.wanpeng.top/bitnami/mediawiki:1.40.
2025-01-15 目前可用的代理加速地址  
docker.wanpeng.top  
hub.211678.top  
cjie.eu.org
dhub.kubesre.xyz
下载不行,或者报错,有时候是不能用了,有时候是抽风了,多试几次
dockerpull.cn
新增一个这个

255
技术探究/gitea.md Normal file
View File

@@ -0,0 +1,255 @@
# gitea
### 安装
下载
[Releases · go-gitea/gitea](https://github.com/go-gitea/gitea/releases)
安装的前提必须要 `PATH` 里面有 git
> Check that Git is installed on the server. If it is not, install it first.
#### 二进制安装
```bash
cd /data01/devops/gitea
wget -O gitea https://dl.gitea.io/gitea/1.12.2/gitea-1.12.2-linux-amd64
https://github.com/go-gitea/gitea/releases/download/v1.12.2/gitea-1.12.2-linux-amd64.xz
xz -d gitea-1.12.2-linux-amd64.xz
mv gitea-1.12.2-linux-amd64 gitea
./gitea web
nohup ./gitea web > log.file 2>&1&
第一次打开页面的时候会配置数据库登信息
第一个注册的用户为管理员
管理员账户为rootadmin被系统保留无法使用
点击【立即安装】后会开始在数据库建表时间有点长一共74张表
```
**官网还有更正规的安装方式**,英文的详细一些
[从二进制安装 - Docs](https://docs.gitea.io/zh-cn/install-from-binary/)
[Installation from binary - Docs](https://docs.gitea.io/en-us/install-from-binary/)
### docker 安装
[使用 Docker 安装 - Docs](https://docs.gitea.io/zh-cn/install-with-docker/)
[Installation with Docker - Docs](https://docs.gitea.io/en-us/install-with-docker/)
简单命令 docker安装
```bash
gitea gitea@123
root gitea@123
flyaway Xxw!123
docker pull gitea/gitea:1.14.2
docker pull gitea/gitea:1.14.3
# DB_HOST 等参数好像实际没什么用,还是得安装页面配置 SSH_PORT 也没用
# 还是在运行起来后修改配置文件
docker run --name gitea -p 3010:3010 -v /mnt/user/appdata/gitea:/data \
-e "RUN_MODE=prod" \
-e "DOMAIN=192.168.66.254" \
-e "HTTP_PORT=3010" \
-e "ROOT_URL=http://192.168.66.254:3010" \
-e "DB_TYPE=mysql" \
-e "DB_HOST=192.168.66.254" \
-e "DB_NAME=gitea" \
-e "DB_USER=gitea" \
-e "DB_PASSWD=gitea@123" \
-e "USER_UID=1000" \
-e "USER_GID=100" \
--env=TZ=Asia/Shanghai \
-d gitea/gitea:1.14.2
```
### 组织和团队有啥区别 #1912
[组织和团队有啥区别 · Issue #1912 · gogs/gogs](https://github.com/gogs/gogs/issues/1912)
> organization => company
> team => department or small unit
[Organization / teams structure - Support - Gitea](https://discourse.gitea.io/t/organization-teams-structure/2766)
### Gitea is running slow
The most common culprit for this is loading federated avatars.
This can be turned off by setting `ENABLE_FEDERATED_AVATAR `to `false` in your app.ini
Another option that may need to be changed is setting `DISABLE_GRAVATAR `to true in your `app.ini`
```ini
[picture]
DISABLE_GRAVATAR = true
ENABLE_FEDERATED_AVATAR = false
```
### Gitea avatar 修改 cdn
```ini
GRAVATAR_SOURCE=https://gravatar.cat.net/avatar/ # 感觉不靠谱
```
```shell
# 升级后 好像这个文件会丢失
/data01/devops/gitea/data/avatars
上传 asia_ico_20210610201425-25.jpg
改名
asia_ico_20210610201425
mv asia_ico_20210610201425-25.jpg asia_ico_20210610201425
```
### gitea webhook i/o timeout
webhook 超时报错问题
[Re: Webhook i/o timeout failure - Shopify Community](https://community.shopify.com/c/Shopify-APIs-SDKs/Webhook-i-o-timeout-failure/m-p/825409)
<br />
[Webhooks randomly fail with 408 timeout · Issue #5470 · go-gitea/gitea](https://github.com/go-gitea/gitea/issues/5470)
[Internal server Error · Issue #10246 · go-gitea/gitea](https://github.com/go-gitea/gitea/issues/10246)
很可能是`.drone.yml `文件名错了
> ok. I have solved this problem.
> my gitea repository's webhook is Drone URL. and the point is that CI `repository - setting - Main - Configuration` specified yaml file named `.drone.yml`, and my git repository's file named `drone.yml`!!
> that's worker after modified file name... :)
>
或者是版本库有问题
> Update: I deleted the repository and pushed again and that worked fine.
>
### Gitea webhook push 消息不对的问题,是因为配置文件中`html_url` 是 `localhost` ,导致 push的消息不对
导致 `jenkins` 无法正常自动触发
日志 `/data01/docker_appdata/jenkins/logs/jenkins.branch.MultiBranchProject.log` 中就会出现 `Matched 0 错误` 的问题,正常应该是 `Matched 1` 或其他。
```ini
SSH_DOMAIN = cqaivm.860001.xyz
DOMAIN = cqaivm.860001.xyz
ROOT_URL = http://cqaivm.860001.xyz:12239/
```
### gitea 关闭用户注册
注意是 service 不是 server
https://docs.gitea.io/en-us/config-cheat-sheet/
`custom/conf/app.ini `
```ini
[service]
DISABLE_REGISTRATION = true
```
### gitea 登录才能浏览
```ini
[service]
REQUIRE_SIGNIN_VIEW = true
```
### Gitea  Jenkins 上返回的仓库数目不对的问题
gitea  api 限制
```ini
[api]
MAX_RESPONSE_ITEMS = 200
DEFAULT_PAGING_NUM = 100
# 注意好像可能有配置的顺序问题,或者大小限制
```
- 官方代码仓库里面 `custom/conf/app.example.ini` 有示例
- [[JENKINS-63048] gitea API added general pagination in 1.12.x (potentially affecting repo listings) - Jenkins Jira](https://issues.jenkins.io/browse/JENKINS-63048)
- [[JENKINS-64059] Scan Gitea Organization limited to 30 repositories - Jenkins Jira](https://issues.jenkins.io/browse/JENKINS-64059)
google `jenkins gitea Repository limit`
### Gitea API
[https://try.gitea.io/api/swagger](https://try.gitea.io/api/swagger)
### 其他工具 Awesome Gitea
[gitea/awesome-gitea: A curated list of awesome projects related to Gitea - README.md at master - awesome-gitea - Gitea: Git with a cup of tea](https://gitea.com/gitea/awesome-gitea/src/branch/master/README.md#user-content-devops)
[Awesome Gitea](https://gitea.com/gitea/awesome-gitea/src/branch/master/README.md)
# 更新 升级 gitea [[2022-02-16]]
注意升级后可能头像文件asiainfo丢失
gitea-1.15.6-linux-amd64.xz
改成
gitea-1.16.1-linux-amd64.xz
[[2022-03-10]]
gitea-1.16.3-linux-amd64.xz
[[2022-05-03]]
gitea-1.16.7-linux-amd64.xz
```shell
cd /data01/devops/gitea
vi custom/conf/app.ini
[service]
REQUIRE_SIGNIN_VIEW = true
# 注意停止旧的进程
# ps -ef|grep gitea
pid1=`ps -ef|grep gitea|grep -v grep|grep -v bash|awk '{print $2}'`
kill -9 ${pid1}
mv gitea bak_gitea_1.15.6
xz -d gitea-1.16.3-linux-amd64.xz
mv gitea-1.16.3-linux-amd64 gitea
chmod u+x gitea
nohup ./gitea web > log.file 2>&1&
```
## 1.16 Webhook
```shell
webhook can only call allowed HTTP servers (check your webhook.ALLOWED_HOST_LIST setting), deny 'cqaivm.860001.xyz(127.0.0.1:12250)'
```
新版要设置 webhook
`ALLOWED_HOST_LIST`: **external**: Since 1.15.7. Default to `*` for 1.15.x, `external` for 1.16 and later. Webhook can only call allowed hosts for security reasons. Comma separated list.
- Built-in networks:
- `loopback`: 127.0.0.0/8 for IPv4 and ::1/128 for IPv6, localhost is included.
- `private`: RFC 1918 (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) and RFC 4193 (FC00::/7). Also called LAN/Intranet.
- `external`: A valid non-private unicast IP, you can access all hosts on public internet.
- `*`: All hosts are allowed.
- CIDR list: `1.2.3.0/8` for IPv4 and `2001:db8::/32` for IPv6
- Wildcard hosts: `*.mydomain.com`, `192.168.100.*`
```ini
[webhook]
ALLOWED_HOST_LIST = *
```

2
技术探究/kafka.md Normal file
View File

@@ -0,0 +1,2 @@
# kafka 查看 工具
kafka-ui-lite-1.2.9.jar

97
技术探究/logstash.md Normal file
View File

@@ -0,0 +1,97 @@
### 本地文件
Sample Logstash configuration for creating a simple
```
Beats -> Logstash -> Elasticsearch pipeline.
input {
  tcp {
    port => 5000
  }
  file {
    path => "D:/projects/beijing/migu_music/migu-wiki/logs/server.log"
    start_position => beginning
    # sincedb_path => "D:\projects\beijing\migu_music\migu-wiki\logs"
    codec => multiline {
      pattern => "^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}"
      negate => true
      auto_flush_interval => 3
      what => previous
    }
  }
}
filter {
  mutate { replace => { type => "random_logs" } }
}
output {
  elasticsearch {
    hosts => "http://cqmg.860001.xyz:26017/"
    user => "elastic"
    password => "changeme"
    index=>"random_logs"
  }
  stdout { codec => rubydebug }
}
```
F:\Users\ASUS\Downloads\logstash-8.1.3-windows-x86_64\logstash-8.1.3
### 同步mysql
```
input{
stdin {
}
jdbc {
jdbc_driver_library => "/data/app/logstash-7.13.4/mysql-connector-java-5.1.47.jar"
jdbc_driver_class => "com.mysql.jdbc.Driver"
jdbc_connection_string => "jdbc:mysql://10.19.83.209:12306/dmp_dev?characterEncoding=utf8&useSSL=false"
jdbc_user => "root"
jdbc_password => "My%209admin"
jdbc_paging_enabled => "true"
jdbc_page_size => "50000"
# 设置监听间隔 各字段含义(由左至右)分、时、天、月、年,全部为*默认含>义为每分钟都更新
schedule => "* * * * * "
statement => "select * from res_terminal"
# tracking_column => "updatetime"
# 保存上一次运行>的信息(tracking_column)
# last_run_metadata_path => "./logstash_jdbc_last_run"
type => "res_terminal"
}
}
filter{
json{
source => "message"
remove_field => ["message"]
}
}
#output插件配置
output{
if[type] == "res_terminal" {
elasticsearch {
hosts => ["127.0.0.1:9200"]
index => "res_terminal"
document_type => "res_terminal"
document_id => "%{resource_id}"
}
}
#控制台打印json
stdout {
codec => json_lines
}
}
```
bin/logstash -f logstash.conf
bin/logstash -f logstash.conf -t 检测配置文件
### document_id 大小写敏感

View File

@@ -0,0 +1,5 @@
---
date created: 2022-01-01 21:22
---
https://www.cnblogs.com/yincg/p/16848816.html

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View File

@@ -0,0 +1,14 @@
### 1. http://0.0.0.0/ 错误
> ![[Pasted image 20220313122140.png]]
解决方案修改对应maven命令的mirror配置注释掉0.0.0.0
```
<mirror>
<id>aliyunmaven</id>
<mirrorOf>*</mirrorOf>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
```

67
技术探究/mysql.md Normal file
View File

@@ -0,0 +1,67 @@
# mysql 导出
mysqldump
https://blog.csdn.net/ichen820/article/details/124022855
# 连接
## 连接mysql3306端口命令
mysql -h58.64.217.120 -ushop -p123456
## 连接非3306端口(指定其他端口) 的命令
mysql -h58.64.217.120 -P3308-ushop -p123456
# 分组
## 分组合并查询字段
```sql
SELECT
GROUP_CONCAT(a.id) as ids,
GROUP_CONCAT(a.name) as names,
CASE
WHEN a.age<18 THEN '少年'
WHEN a.age>=18 AND a.age< 40 THEN '青年'
WHEN a.age>=40 AND a.age< 60 THEN '中年'
END as age,
count(a.id) as count
FROM
(SELECT id, name, birthday, TIMESTAMPDIFF(YEAR,student.birthday,CURDATE()) as age FROM `student`) as a
GROUP BY
CASE
WHEN a.age<18 THEN '少年'
WHEN a.age>=18 AND a.age< 40 THEN '青年'
WHEN a.age>=40 AND a.age< 60 THEN '中年'
END
```
![[Pasted image 20230110121247.png]]
![[SQL原理.html]]
##### 修改表字符集
alter  table t2 convert to character set utf8mb4;
##### 查看所有表大小
```sql
select
table_schema as '数据库',
table_name as '表名',
table_rows as '记录数',
truncate(data_length/1024/1024, 2) as '数据容量(MB)',
truncate(index_length/1024/1024, 2) as '索引容量(MB)'
from information_schema.tables
order by data_length desc, index_length desc;
```
##### 查看所有库大小
```sql
select
table_schema as '数据库',
sum(table_rows) as '记录数',
sum(truncate(data_length/1024/1024, 2)) as '数据容量(MB)',
sum(truncate(index_length/1024/1024, 2)) as '索引容量(MB)'
from information_schema.tables
group by table_schema
order by sum(data_length) desc, sum(index_length) desc;
```

105
技术探究/nginx.md Normal file
View File

@@ -0,0 +1,105 @@
1. 虚拟机用途API接入服务器虚拟机主机名datasecurity_nginx1
部署位置:/data/security/soft/
安装版本nginx-1.18.0.tar.gz
部署步骤:
解压安装包tar -zxvf nginx1.18.0.tar.gz
进入解压成功的目录cd nginx
进行自定义配置
./configure \
--prefix=/data/security/soft/nginx \
--conf-path=/data/security/soft/nginx/conf/nginx.conf \
--pid-path=/data/security/soft/nginx/conf/nginx.pid \
--lock-path=/data/security/soft/nginx/lock/nginx.lock
yum -y install zlib zlib-devel openssl openssl-devel pcre pcre-devel
编译make
编译安装make install
### 重定向
location / {
rewrite '' /opt/manage permanent;
}
websocket 长连接 转发
```
location 中加入 以下配置
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
```
### SSL 证书申请
![[nginx ssl 自签名证书配置.pdf]]
### ng 部署环境静态文件加载失败 MIME type
https://blog.csdn.net/yanglangdan/article/details/107833650
由于最近在部署 CI 的项目,静态的 css 一直没有生效,导致部分格式错误
具体错误提示为:
Error: The stylesheet http://example.com/style.css was not loaded
because its MIME type, "text/html", is not "text/css".
错误原因: http Header Content-Type没有指定文件类型
解决方式:
1. 查看 nginx.conf 文件中http{ } 内是否有
include mime.types;
default_type application/octet-stream;
没有就添加。 但 一般都有这个,只是确认下而已,所以不用做什么修改;
2. 手动添加Header Content-Type文件类型
location ~ \.css {
access_log logs/css.access.log;
error_log logs/css.error.log;
root /data/**/**/;
index index.htm index.html index.php;
add_header Content-Type text/css;
}
## 记住如果有指定默认root 路径,一定要添加,不然就找不到静态文件,报 404
## 静态 资源 目录
location /WW_verify_HChUdHAFH0uRShMS.txt {
root /data01/temp/verify;
}
location ~ \.js {
root ****;
add_header Content-Type application/x-javascript;
}
### vhost 解决
>与 server 平级
>include /data01/nginx/conf/vhost/*.conf;
### nginx 413 request too large
http 下 `client_max_body_size 500m;`
### 验证 防爬虫 扫描
[Nginx - 配置 Nginx auth\_basic 身份验证\_努力的一行的博客-CSDN博客\_nginx 身份验证](https://blog.csdn.net/qq_44633541/article/details/124370705)
```
Nginx 配置 http basic 验证
```
### 可视化界面项目
https://github.com/NginxProxyManager/nginx-proxy-manager
https://github.com/cym1102/nginxWebUI
https://github.com/jvns/nginx-playground
###

View File

@@ -0,0 +1,78 @@
# JAVA 混淆
目前能够打出目标混淆文件,需要替换回去
### 参考资料
>http://t.zoukankan.com/eggTwo-p-13685557.html
### 失败的参考资料
>https://www.cnblogs.com/codhome/p/13621169.html
```xml
<plugin>
<groupId>com.github.wvengen</groupId>
<artifactId>proguard-maven-plugin</artifactId>
<version>2.0.14</version>
<executions> <execution> <!--混淆时刻,这里是打包的时候混淆-->
<phase>package</phase>
<goals> <!--使用插件的什么功能,当然是混淆-->
<goal>proguard</goal>
</goals> </execution> </executions> <configuration> <proguardVersion>6.3.0beta1</proguardVersion>
<obfuscate>true</obfuscate>
<!--是否将生成的PG文件安装部署-->
<attach>true</attach>
<!--是否混淆-->
<obfuscate>true</obfuscate>
<!--指定生成文件分类-->
<attachArtifactClassifier>pg</attachArtifactClassifier>
<options> <!--JDK目标版本1.8-->
<option>-target 1.8</option>
<!--不做收缩(删除注释、未被引用代码)-->
<!--<option>-dontshrink</option>--> <!--不做优化(变更代码实现逻辑)-->
<!--<option>-dontoptimize</option>--> <!--不路过非公用类文件及成员-->
<option>-dontskipnonpubliclibraryclasses</option>
<option>-dontskipnonpubliclibraryclassmembers</option>
<!--优化时允许访问并修改有修饰符的类和类的成员-->
<option>-allowaccessmodification</option>
<!--确定统一的混淆类的成员名称来增加混淆,防止冲突-->
<option>-useuniqueclassmembernames</option>
<!--不混淆所有包名Spring配置中有大量固定写法的包名-->
<option>-keeppackagenames</option>
<!--不混淆所有特殊的类-->
<option>
-keepattributes
Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod
</option>
<!--不混淆所有的set/get方法毕竟项目中使用的部分第三方框架例如Shiro会用到大量的set/get映射-->
<option>-keepclassmembers public class *{void set*(***);*** get*();}
</option>
<option>-keep public class * {
public protected *;
}
</option>
<!--不显示警告信息如果显示则会出现Error无法完成混淆-->
<option>-dontwarn **</option>
</options> <outjar>${project.build.finalName}-pg.jar</outjar>
<!--添加依赖这里你可以按你的需要修改这里测试只需要一个JRE的Runtime包就行了-->
<libs>
<lib>${java.home}/lib/rt.jar</lib>
<lib>${java.home}/lib/jce.jar</lib>
</libs>
<!--加载文件的过滤器,就是你的工程目录了-->
<inFilter>com/ai/**</inFilter>
<!--对什么东西进行加载这里仅有classes成功毕竟你也不可能对配置文件及JSP混淆吧-->
<injar>classes</injar>
<!--输出目录-->
<outputDirectory>${project.build.directory}</outputDirectory>
</configuration>
<dependencies> <!--使用6.3.0beta1版本来混淆-->
<dependency>
<groupId>net.sf.proguard</groupId>
<artifactId>proguard-base</artifactId>
<version>6.3.0beta1</version>
<scope>runtime</scope>
</dependency>
</dependencies>
</plugin>
```

11
技术探究/redis.md Normal file
View File

@@ -0,0 +1,11 @@
### 查看所有key
>keys *;
### 进入 docker 的redis
>redis-cli
>auth <password/>
### 清空数据
>- flushdb删除当前选择数据库中的所有key
>- flushall删除所有数据库中的所有key

15
技术探究/secureCRT.md Normal file
View File

@@ -0,0 +1,15 @@
sz 下载文件
1.快捷键alt+p打开sftp窗口输入想要下载的文件所在的目录回车
```java
lcd E:/download
```
2.输入要下载的文件
```java
get /usr/hello.jar
```
回车之后,就能将服务器中指定的文件下载到本地指定的目录下。

View File

@@ -0,0 +1,218 @@
sonarqube 安装 2020-11-01
最好安装 7版本否则因为太新了pdf插件不支持
https://hub.docker.com/_/sonarqube
https://www.sonarqube.org/downloads/
官网
docker pull sonarqube:8.4.2-community
dockerhub 最新是 8.5.1
https://docs.sonarqube.org/latest/setup/install-server/
## Docker Host Requirements
https://hub.docker.com/_/sonarqube/
```
sysctl -w vm.max_map_count=262144
sysctl -w fs.file-max=65536
ulimit -n 65536
ulimit -u 4096
```
## postgresql
新版的sonar不再支持mysql,所以我们需要使用postgresql作为替代
```
If you want to use a custom schema and not the default "public" one, the PostgreSQL search_path property must be set:
ALTER USER mySonarUser SET search_path to mySonarQubeSchema
```
最新的是13
```sh
docker pull postgres:13
$ docker run -d \
--name some-postgres \
-e POSTGRES_PASSWORD=Ai#pg%2011 \
-e PGDATA=/var/lib/postgresql/data/pgdata \
-v /custom/mount:/var/lib/postgresql/data \
postgres
docker run -d \
--name postgres13 \
-e POSTGRES_PASSWORD=Ai#pg%2011 \
-e PGDATA=/var/lib/postgresql/data/pgdata \
-p 12235:5432 \
-e TZ="Asia/Shanghai" \
-v /data01/docker_appdata/postgresql/data:/var/lib/postgresql/data \
postgres:13
/data01/docker_appdata/postgresql/data /var/lib/postgresql/data
12235 5432
-e TZ="Asia/Shanghai"
create user sonar with password 'Ai%ssn2011';
create database sonardb owner sonar;
grant all on database sonardb to sonar;
```
## sonarqube
```sh
$> docker run -d --name sonarqube \
-p 9000:9000 \
-e SONAR_JDBC_URL=... \
-e SONAR_JDBC_USERNAME=... \
-e SONAR_JDBC_PASSWORD=... \
-v sonarqube_data:/opt/sonarqube/data \
-v sonarqube_extensions:/opt/sonarqube/extensions \
-v sonarqube_logs:/opt/sonarqube/logs \
<image_name>
docker pull sonarqube:8.4.2-community
/data01/docker_appdata/sonarqube/data /opt/sonarqube/data
/data01/docker_appdata/sonarqube/extensions /opt/sonarqube/extensions
/data01/docker_appdata/sonarqube/logs /opt/sonarqube/logs
12236 9000
TZ Asia/Shanghai
SONAR_JDBC_URL jdbc:postgresql://172.17.0.1:12235/sonardb
SONAR_JDBC_USERNAME sonar
SONAR_JDBC_PASSWORD Ai%ssn2011
初始密码 admin admin
在 Marketplace 安装 Chinese Pack
```
### No quality profiles have been found, you probably don't have any language plugin installed.
```sh
mvn sonar:sonar \
-Dsonar.projectKey=test \
-Dsonar.host.url=http://cqaivm.860001.xyz:12236 \
-Dsonar.login=4d729d69f038eec469a1ff6e153b94fafdbdde8d
```
--2020-11-23 在平台上改标识为 trafficplat
```sh
mvn sonar:sonar \
-Dsonar.projectKey=trafficplat \
-Dsonar.host.url=http://cqaivm.860001.xyz:12236 \
-Dsonar.login=4d729d69f038eec469a1ff6e153b94fafdbdde8d
```
Java Code Quality and Security
Code Analyzer for Java
下载不下来的情况
https://github.com/SonarSource/sonar-java/releases
6.5.1.22586
https://github.com/SonarSource/sonar-java/archive/6.5.1.22586.zip
上传到
/data01/docker_appdata/sonarqube/extensions/plugins
上面的方法不行 因为下载的是源码 不是jar
从docker日志里面可以看到
https://binaries.sonarsource.com/Distribution/sonar-java-plugin/sonar-java-plugin-6.5.1.22586.jar
直接上传后重启
weishan-manage-be: b3252f418f321c133b59a94cdc9de598d0f5edfa
weishan-manage-be
mvn clean package -Dmaven.test.skip=true
mvn sonar:sonar
-Dsonar.projectKey=weishan-manage-be
-Dsonar.host.url=http://cqaivm.860001.xyz:12236
-Dsonar.login=b3252f418f321c133b59a94cdc9de598d0f5edfa
weishan: f9ab5cd3a6d97c4a216fbbf923595a8f9b10b488
weishan
mvn clean package -Dmaven.test.skip=true
mvn sonar:sonar
-Dsonar.projectKey=weishan
-Dsonar.host.url=http://cqaivm.860001.xyz:12236
-Dsonar.login=f9ab5cd3a6d97c4a216fbbf923595a8f9b10b488
## Your project contains .java files, please provide compiled classes with sonar.java.binaries property, or exclude them from the analysis with sonar.exclusions property
貌似是需要先编译一次才行
mvn clean package -Dmaven.test.skip=true
## SCM provider was set to "git" but no SCM
市场安装 git 插件
https://binaries.sonarsource.com/Distribution/sonar-scm-git-plugin/sonar-scm-git-plugin-1.12.1.2064.jar
https://binaries.sonarsource.com/Distribution/sonar-javascript-plugin/sonar-javascript-plugin-6.2.2.13315.jar
The plugin 'typescript' required by 'javascript' is missing
https://binaries.sonarsource.com/Distribution/sonar-javascript-plugin/sonar-javascript-plugin-6.2.2.13315.jar
sonar-python-plugin-2.13.0.7236.jar
https://binaries.sonarsource.com/Distribution/sonar-python-plugin/sonar-python-plugin-2.13.0.7236.jar
weishan-museum-front: 149d034aa220eeaac36b805b7021b0a12d5d5dff
sonar-scanner
-Dsonar.projectKey=weishan-museum-front
-Dsonar.sources=.
-Dsonar.host.url=http://cqaivm.860001.xyz:12236
-Dsonar.login=149d034aa220eeaac36b805b7021b0a12d5d5dff
http://plugins.drone.io/aosapps/drone-sonar-plugin/
docker 里面的 maven 项目不好用
但是js的项目好用
##
smart-sys-admin-biz: f362f8da8ee64ee3ed28d1329bcb040b09c4e5bc
mvn sonar:sonar
-Dsonar.projectKey=smart-sys-admin-biz
-Dsonar.host.url=http://cqaivm.860001.xyz:12236
-Dsonar.login=f362f8da8ee64ee3ed28d1329bcb040b09c4e5bc
##
smart-park-manage: 6e0f8f9d0b24d5c8a03c4350eb130ec7647e9feb
# sonarqube:7.9.5
[郑剑峰的个人博客 » 关于sonar这里有你需要的一切-安装篇](https://zhengjianfeng.cn/?p=266)
docker pull sonarqube:7.9.5-community
[sonar-pdf-plugin: sonarqube生成pdf报告插件支持 5.5--7.x](https://gitee.com/zzulj/sonar-pdf-plugin/)
create user sonar7 with password 'Ai%ssn2011';
create database sonardb7 owner sonar7;
grant all on database sonardb7 to sonar7;
chown -R 999:999 /data01/docker_appdata/sonarqube7
/data01/docker_appdata/sonarqube7/data /opt/sonarqube/data
/data01/docker_appdata/sonarqube7/extensions /opt/sonarqube/extensions
/data01/docker_appdata/sonarqube7/logs /opt/sonarqube/logs
/data01/docker_appdata/sonarqube7/conf /opt/sonarqube/conf
12237 9000
TZ Asia/Shanghai
SONAR_JDBC_URL jdbc:postgresql://172.17.0.1:12235/sonardb7
SONAR_JDBC_USERNAME sonar7
SONAR_JDBC_PASSWORD Ai%ssn2011
mvn sonar:sonar
-Dsonar.projectKey=trafficPlat
-Dsonar.host.url=http://cqaivm.860001.xyz:12237
-Dsonar.login=a0e08aaed03df9aaa7fa9ea45571c3f188e84e96
mvn sonar:sonar
-Dsonar.projectKey=weishan-manage-be
-Dsonar.host.url=http://cqaivm.860001.xyz:12237
-Dsonar.login=ab5b2080e96c5199b45cfc564323f7a647bf615d

View File

@@ -0,0 +1,5 @@
# Pannellum
https://blog.csdn.net/qq564280420/article/details/126997788
# photo-sphere-viewer
https://blog.csdn.net/weixin_42752574/article/details/121215430
https://blog.csdn.net/weixin_42752574/article/details/122243459

View File

@@ -0,0 +1,6 @@
>https://v2.cn.vuejs.org/v2/cookbook/dockerize-vuejs-app.html
> https://zhuanlan.zhihu.com/p/150568805
> https://www.nginx.com/blog/deploying-nginx-nginx-plus-docker/
>

View File

@@ -0,0 +1,4 @@
express 解决 单页面 history 模式 404
```javascript
http://zhenglinglu.cn/pages/ea5e6f/#%E5%AE%89%E8%A3%85%E4%BE%9D%E8%B5%96
```

View File

@@ -0,0 +1,19 @@
```javascript
// 全局模态框关闭事件
Element.Dialog.props.closeOnClickModal.default = false
// 全局 输入框 回车 刷新 阻止
const render = Element.Form.render;
const stopFormDefaultSubmit = e => {
if (e.keyCode === 13) {
e.preventDefault()
}
}
Element.Form.render = function() {
setTimeout(() => {
this.$el.removeEventListener('keydown', stopFormDefaultSubmit)
this.$el.addEventListener('keydown', stopFormDefaultSubmit)
}, 500)
return render.apply(this, arguments)
}
```

View File

@@ -0,0 +1,6 @@
# keep-live 失效问题
组件 name 有规范
> https://gitee.com/y_project/RuoYi-Vue/issues/I7PDIL
# 路由配置 404
* 排查组件之间 name 冲突

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

View File

@@ -0,0 +1,11 @@
es6 动态引入 报错
dynamic-import-node -> dynamic-import-webpack
![[企业微信截图_16850860511501.png]]
babel-plugin-dynamic-import-node -> babel-plugin-dynamic-import-webpack
![[企业微信截图_16850860633778.png]]
![[企业微信截图_16850860865162.png]]
webpack4的bug不支持es6的动态引入语法import()

View File

@@ -0,0 +1,8 @@
# 编辑器
## monaca
>https://cloud.tencent.com/developer/article/2316837
# 低代码
## brick-design
## ToolJet

View File

@@ -0,0 +1,122 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
<link rel="stylesheet" href="https://a.amap.com/jsapi_demos/static/demo-center/css/demo-center.css" type="text/css">
<style>
html,body,#container{
height: 100%
}
.input-item{
height: 2.2rem;
}
.btn{
width: 6rem;
margin: 0 1rem 0 2rem;
}
.input-text{
width: 4rem;
margin-right:1rem;
}
</style>
<title>鼠标工具绘制</title>
</head>
<body>
<div id='container'></div>
<div class='info'>操作说明:圆和矩形通过拖拽来绘制,其他覆盖物通过点击来绘制</div>
<div class="input-card" style='width: 24rem;'>
<div class="input-item">
<input type="radio" name='func' checked="" value='marker'><span class="input-text">画点</span>
<input type="radio" name='func' value='polyline'><span class="input-text">画折线</span>
<input type="radio" name='func' value='polygon'><span class="input-text" style='width:5rem;'>画多边形</span>
</div>
<div class="input-item">
<input type="radio" name='func' value='rectangle'><span class="input-text">画矩形</span>
<input type="radio" name='func' value='circle'><span class="input-text">画圆</span>
</div>
<div class="input-item">
<input id="clear" type="button" class="btn" value="清除" />
<input id="close" type="button" class="btn" value="关闭绘图" />
</div>
</div>
<script src="https://webapi.amap.com/maps?v=1.4.15&key=您申请的key值&plugin=AMap.MouseTool"></script>
<script type="text/javascript">
var map = new AMap.Map('container',{
zoom:14
});
var mouseTool = new AMap.MouseTool(map);
//监听draw事件可获取画好的覆盖物
var overlays = [];
mouseTool.on('draw',function(e){
overlays.push(e.obj);
})
AMap.event.addListener( mouseTool,'draw',function(e){
console.log(e.obj.getPath());//获取路径/范围
});
function draw(type){
switch(type){
case 'marker':{
mouseTool.marker({
//同Marker的Option设置
});
break;
}
case 'polyline':{
mouseTool.polyline({
strokeColor:'#80d8ff'
//同Polyline的Option设置
});
break;
}
case 'polygon':{
mouseTool.polygon({
fillColor:'#00b0ff',
strokeColor:'#80d8ff'
//同Polygon的Option设置
});
break;
}
case 'rectangle':{
mouseTool.rectangle({
fillColor:'#00b0ff',
strokeColor:'#80d8ff'
//同Polygon的Option设置
});
break;
}
case 'circle':{
mouseTool.circle({
fillColor:'#00b0ff',
strokeColor:'#80d8ff'
//同Circle的Option设置
});
break;
}
}
}
var radios = document.getElementsByName('func');
for(var i=0;i<radios.length;i+=1){
radios[i].onchange = function(e){
draw(e.target.value)
}
}
draw('marker')
document.getElementById('clear').onclick = function(){
map.remove(overlays)
overlays = [];
}
document.getElementById('close').onclick = function(){
mouseTool.close(true)//关闭,并清除覆盖物
for(var i=0;i<radios.length;i+=1){
radios[i].checked = false;
}
}
</script>
</body>
</html>

View File

@@ -0,0 +1,25 @@
```
百度
http://api.map.baidu.com/lbsapi/getpoint/index.html
高德
https://lbs.amap.com/tools/picker
```
## 小程序 腾讯 地图 插件 配额
```
https://lbs.qq.com/miniProgram/plugin/pluginGuide/pluginStart
```
## 地图 边界 代码
https://lbs.amap.com/demo/javascript-api/example/mouse-operate-map/mouse-draw-overlayers
![[运行代码.txt]]
## Geo JSON
#### 获取 geojson
>https://www.jianshu.com/p/e66fc55f5f6e
### 高德 电子 围栏
>https://blog.csdn.net/m0_46641774/article/details/129705773

View File

@@ -0,0 +1,6 @@
adb sdk
# 环境变量
## 模拟器
夜深 adb E:\Program Files\Nox\bin
##

View File

@@ -0,0 +1,79 @@
---
UUID: 20230504143144
title: 即时通讯 IM
date created: 2023-05-04 14:31
aliases: IM,即时通信
tags:
- IM
date updated: 2023-05-04 14:31
---
## 即时通讯 IM
52im
http://www.52im.net/
https://gitee.com/jackjiang/MobileIMSDK
野火IM
[野火IM | 即时通讯实时音视频专家](https://wildfirechat.cn/price/)
openim
https://github.com/OpenIMSDK/Open-IM-Server
https://doc.rentsoft.cn/#/introduce/production_introduce
Tailchat
Tailchat 是一款现代化开源的即时通讯聊天应用,基于 React + Typescript 开发
https://github.com/msgbyte/tailchat
Tailchat 视频会议
https://github.com/msgbyte/tailchat-meeting
基于 WebRTC meeting service using mediasoup.
https://tailchat.msgbyte.com/zh-Hans/
国外的
Rocket.Chat
https://github.com/RocketChat
网易云信
https://yunxin.163.com/
融云,环信,网易云信和腾讯 IM
[公司让我调研 IM SDK 哪个比较好 - V2EX](https://www.v2ex.com/t/954400#reply0)
融云
[融云-为用户提供IM即时通讯和实时音视频通信云服务](https://www.rongcloud.cn/)
唐僧叨叨
https://tangsengdaodao.com/
[做开源真难😭,某些模块收费,就说你是假开源。 - V2EX](https://www.v2ex.com/t/965335#reply19)
GGTalk
[有谁介绍一个即时通信软件,最好是开源的,能够自己部署服务器的那种? - 知乎](https://www.zhihu.com/question/270234898/answer/3177265453)
## 直播
https://cloud.tencent.com/product/css
https://www.upyun.com/products/live
https://www.aliyun.com/product/live
https://netease.im/interact
https://netease.im/price/live
价格计算器
https://www.aliyun.com/price/product?spm=5176.7991389.J_5253785160.5.687e47ea2XQibk#/live/detail/liveflowbag
[寻求成熟开源的 im 客户端方案的结果 - V2EX](https://www.v2ex.com/t/1006282#reply13)

View File

@@ -0,0 +1,30 @@
>https://gitee.com/rainsuper/RuoYi-Vue-Super/wikis/pages?sort_id=5953970&doc_id=2965484
>https://gitee.com/tony2y/RuoYi-flowable
# Docker 安装 达梦 8
> https://eco.dameng.com/document/dm/zh-cn/start/dm-install-docker.html
docker run -d -p 30236:5236 --restart=always --name dm8_test --privileged=true -e PAGE_SIZE=16 -e LD_LIBRARY_PATH=/opt/dmdbms/bin -e EXTENT_SIZE=32 -e BLANK_PAD_MODE=1 -e LOG_SIZE=1024 -e UNICODE_FLAG=1 -e LENGTH_IN_CHAR=1 -e INSTANCE_NAME=dm8_test -v /data/dm8_test:/opt/dmdbms/data dm8_single:dm8_20230808_rev197096_x86_rh6_64
### 驱动
> F:\JAVA_Hibernate_lib_dameng\DmJdbcDriver18.jar
### 修改字段
```
### 批量修改数据库表字段长度
select concat('alter table ',OWNER,'.',TABLE_NAME,' MODIFY ',COLUMN_NAME,' VARCHAR(1000)',';')
from SYS.DBA_TAB_COLUMNS
WHERE OWNER= '模式' and DATA_LENGTH = '字段大小,自行更改'
and COLUMN_NAME = '字段名,自行更改'
### 批量修改数据库表字段大小写
select CONCAT('alter table ',OWNER,'.',TABLE_NAME,' rename column ',CONCAT('"',COLUMN_NAME,'"'),' TO "',UPPER(COLUMN_NAME),'";')
from SYS.DBA_TAB_COLUMNS
where OWNER= '模式' and DATA_LENGTH = '字段大小,自行更改'
and COLUMN_NAME = '字段名,自行更改'
and COLUMN_NAME = UPPER(COLUMN_NAME)
```

View File

@@ -0,0 +1,2 @@
# ToolGood 框架
> https://gitee.com/toolgood/ToolGood.Words

View File

@@ -0,0 +1,3 @@
# swagger knife 关闭
> https://www.seasidecrab.com/Java/1193.html

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,17 @@
谢威 1-18 21:42:21
https://github.com/guangzhengli/k8s-tutorials
https://github.com/chaseSpace/k8s-tutorial-cn/tree/main
https://k8s.easydoc.net/docs/dRiQjyTY/28366845/6GiNOzyZ/9EX8Cp45
谢威 1-18 21:43:01
https://www.bilibili.com/video/BV1Tg411P7EB/
### 谢威 1-18 21:43:10
https://k8s.easydoc.net/docs/dRiQjyTY/28366845/6GiNOzyZ/9EX8Cp45
#### Master join
```
kubeadm join 192.168.186.100:6443 --token whgnp2.qemqt8xtod7onf6j --discovery-token-ca-cert-hash sha256:e4f53bd2268f097d79694f7dbc72a6990dfacad41154bd5c9ad2c52ac0e72576
```

View File

@@ -0,0 +1,28 @@
kubectl get namespace cattle-system -o yaml
kubectl get namespace cattle-system -o json >tmp.json
kubectl proxy
curl -k -H "Content-Type: application/json" -X PUT --data-binary @tmp.json http://127.0.0.1:8001/api/v1/namespaces/cattle-system/finalize
kubernetes-dashboard
kubectl get namespace kubernetes-dashboard -o yaml
kubectl get namespace kubernetes-dashboard -o json >tmp.json
curl -k -H "Content-Type: application/json" -X PUT --data-binary @tmp.json http://127.0.0.1:8001/api/v1/namespaces/kubernetes-dashboard/finalize
kubectl get pod -n cattle-system
kubectl get pods --all-namespaces -o wide
docker stats

View File

@@ -0,0 +1,12 @@
### 用户名密码
```
root/123
麒麟 root/kylin@123
```
### 网络
> 192.168.186.100 - 192.168.186.xxx
### portainer
admin administrator@123