rclone同步文件到Google云盘

安装unzip

rclone安装用的到unzip

apt install -y unzip

安装fuse3

apt install -y fuse3

安装socat (可选)

socat 用于后续配置的时候, 代理127.0.0.1上的端口.也可以用其他代理工具代理

apt install -y socat 

安装rclone

curl https://rclone.org/install.sh | sudo bash

创建本地文件夹,用于同步远程

mkdir -p /google_drive_local

配置

rclone config

注意是 google drive,不是 google cloud 或 google photos

socat代理端口

配置的过程中, 会等待回调http:127.0.0.1:xxxx这样的端口 由于Linux上没有安装桌面端,需要代理出来,在桌面端浏览器访问

如下,将服务器上的127.0.0.1的xxxx端口映射到Linux公网IP上的1234端口

#如 控制台这样提示的时候, 使用下面命令 2024/05/10 01:38:21 NOTICE: If your browser doesn't open automatically go to the following link: http://127.0.0.1:53682/auth?state=Czs9IR66wt5eLQYQtlogbQ
socat TCP-LISTEN:1234,fork,reuseaddr TCP:127.0.0.1:53682

代理成功后, 在桌面端浏览器访问, 访问完成,授权登录后,Linux终端会提示Success,即完成了配置

创建Service, 启动挂载

需要特别注意的是: rclone mount 每次挂载后,总是用云盘的数据覆盖本地的挂载文件夹, 所以云盘上不存在,但是存在于本地挂载文件夹/google_drive_local下的数据一定要先做备份,避免覆盖丢失

vim /etc/systemd/system/rclone-mount.service 文件内容如下

[Unit]
Description=RClone Mount Service
After=network-online.target

[Service]
User=root
Group=root
ExecStart=/usr/bin/rclone mount google_drive:/vps_backup/xjp /google_drive_local --allow-other --allow-non-empty --vfs-cache-mode writes
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

重新加载 systemd 并启动服务

sudo systemctl daemon-reload
sudo systemctl start rclone-mount.service
sudo systemctl enable rclone-mount.service

创建备份脚本

vim /usr/local/bin/vps_backup 内容如下

cd / && tar -zcvf app.tar.gz /app/ && mv app.tar.gz /google_drive_local/

赋予执行权限chmod +x /usr/local/bin/vps_backup

编写定时任务

执行crontab -e打开定时任务配置文件, 增加以下内容

#12小时同步一次
0  */12 * * *  /usr/local/bin/vps_backup
#30分钟执行一次
*/30 * * * *  /usr/local/bin/vps_backup

查看所有的rclone配置

rclone config show

docker-compose网络

docker-compose网络

网段隔离

在不同的文件下存放docker-compose.yml, 如mysql/docker-compose.yml, redis/docker-compose.yml, 当执行docker-compose up -d会自动创建一个新的网络. 通过docker network ls可以看到. 每一个网络相互隔离.

root@ec2-0804:# docker network ls
NETWORK ID     NAME                   DRIVER    SCOPE
8fbc5468dcab   bridge                 bridge    local
46e3affd9d7c   host                   host      local
e778a30f25d4   mysql_default          bridge    local
3b2337441be6   vaultwarden_default    bridge    local

网段打通

有时候, 并不想隔离, 比如zk和kafka共享一个网络. 比如应用微服务和mysql共享同一个网络

方法一

nginx和kafka存放在同一个nginx\docker-compose.yml中,启动后自然就是同一个网络. 如

version: '3.8'

services:
  nginx:
    image: zookeeper
    container_name: nginx

  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden 

启动后, 会创建一个新的网络nginx_default,前缀来自于当前docker-compose.yml所在的文件夹的名字

方法二

手动创建一个网络

docker network create --driver=bridge --subnet=172.16.238.0/24 --gateway=172.16.238.1 my_docker_network

在不同的docker-compose.yml中指定想要加入的网络

version: '3.8'

services:
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: always
    environment:
      # 
      - WEBSOCKET_ENABLED=true
      # 禁止邀请
      - INVITATIONS_ALLOWED=false
      # 禁止注册. 注意, 初始化搭建的时候.需要改成true,启动后注册用户.注册成功后,改成false,重新执行docker-compose up -d 
      - SIGNUPS_ALLOWED=false
      - ADMIN_TOKEN=AqaiTTm4LbMaTCyVFLTFzwmHPxxYa4Kg
    volumes:
      - /app/docker/vaultwarden/data:/data/
    #ports:
     # 由于vaultwarden和nginx部署在了同一个网络下,所以用服务名通信了.因此不需要暴漏80端口 
     #- "80:80"
    networks:
      - my_docker_network

networks:
  my_docker_network:
    external: true

docker常用操作记录

容器中执行apt update报错

解决办法

sed -i 's/stretch/buster/g' /etc/apt/sources.list

查看指定容器的近10条日志

docker logs --tail 10 -f mariadb1

docker指定常用参数

  • 指定网络
  • 指定ipv4地址
  • 绑定hosts
version: '3.8'

services:
  nginx:
    image: nginx:1.21.1
    container_name: nginx
    restart: always
    ports:
      - 80:80
      - 443:443
    volumes:
      - /app/docker/nginx/nginx:/etc/nginx
      - /root/.acme.sh/*.nguone.eu.org_ecc/fullchain.cer:/etc/nginx/ssl/vaultwarden.crt:ro
      - /root/.acme.sh/*.nguone.eu.org_ecc/*.nguone.eu.org.key:/etc/nginx/ssl/vaultwarden.key:ro
    extra_hosts:
      - "remotework.nguone.eu.org:172.31.5.162"     
    networks:
      my_docker_network:
        ipv4_address: 172.16.238.6

networks:
  my_docker_network:
    external: true

docker gitea搭建

配置Nginx

git.conf

server {
    listen 80; #侦听80端口,如果强制所有的访问都必须是HTTPs的,这行需要注销掉
    listen 443 ssl;
    server_name git.xxx.com;
    ssl_certificate /root/.acme.sh/*.xxx.com_ecc/fullchain.cer;
    ssl_certificate_key /root/.acme.sh/*.xxx.com_ecc/*.xxx.com.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
    ssl_prefer_server_ciphers on;

    client_max_body_size 1024m;
    # 开启HSTS后能够提升到A+. SSL评估 https://myssl.com/
    add_header Strict-Transport-Security "max-age=31536000";

    location / {
        proxy_set_header HOST $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://127.0.0.1:3000;
    }
}

Nginx配置重载

nginx -s reload

docker-compose.yml

version: '3.8'

services:
  gitea:
    image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/gitea/gitea:1.22.3 
    container_name: gitea
    environment:
      - USER_UID=1000
      - USER_GID=1000
      - DB_TYPE=sqlite3  
    restart: always
    volumes:
      - ./data:/data
    ports:
      - "3000:3000" # Gitea 的 Web UI 端口,也是通过http 克隆项目的端口
      - "2222:22" # 如果这里使用22端口. 拉取项目的时候可以省去端口号.因为通过ssh key clone项目用的是22端口

启动

需要注意的时候, git要使用22端口.默认情况下22端口被宿主机的ssh占用.所以需要修改宿主机下的Port 22 为其他端口, 修改后切记放行新的ssh端口,防止无法ssh .systemctl resetart sshd 重新启动sshd

docker-compose up -d

特别注意

如果启动后访问 https://git.xxx.com, 自动跳转到其他的域名,可能的解决方案是:

编辑 /etc/nginx/sites-available/default

直接注释掉server_name _;

然后重载Nginx配置

启动成功后,访问http://宿主机IP:3000访问web控制台.注册一个管理员

需要注意的是,如果端口改成非22端口了,比如2222.那么初始化安装的时候, [SSH Server Port]要修改ssh端口为2222,而不是默认的22 这里的修改的2222是指以后拉取项目用的端口地址,而不是容器的内部端口,内部端口仍然是22

注册好管理员后, 通过命令行把注册禁用掉

docker exec -it gitea bash

vi /data/gitea/conf/app.ini

# 找到 DISABLE_REGISTRATION, 将值从false,改为true.

修改完后,退出docker容器. 重启gitea docker restart gitea

ssh key clone

gitea 默认使用3071长度的ssh key拉取项目.所以Windows或者Linux默认的2048无法使用.

生成3071长度的密钥

3071 表示 位长的 RSA 密钥

ssh-keygen -t rsa -b 3071 

生成之后, 登录gitea web控制台将公钥添加到SSH / GPG Kyes 中 就可以正常clone项目了

补充说明

通过ssh拉取项目

推荐搭建gitea的时候使用22端口

  • 使用22端口拉取项目 git clone git@git服务器IP/项目组或者用户名/work-record.git
  • 使用2222端口拉取项目 git clone ssh://git@git服务器IP:2222/项目组或者用户名/work-record.git

docker anylink搭建

生成web控制台登录密码

nooqu6aifahsh5Ae为web控制台登录密码

docker run -it --rm stilleshan/anylink:0.9.3 tool -p nooqu6aifahsh5Ae

生成 jwt secret

docker run -it --rm stilleshan/anylink:0.9.3 tool -s

docker-compose搭建Nextcloud

docker-compose.yml

version: '3.9'

services:
  nextcloud:
    image: nextcloud:latest
    container_name: nextcloud
    ports:
      - "8080:80"  # 将主机的 8080 端口映射到容器的 80 端口
    volumes:
      - nextcloud_data:/var/www/html
      - ./config/config.php:/var/www/html/config/config.php
    environment:
      - MYSQL_HOST=mysql5.7.28 # 使用你的 MySQL 容器名称作为主机名
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud_user
      - MYSQL_PASSWORD=Aphu2jieChie6mo2
    networks:
      - mysql_default

networks:
  mysql_default:
    external: true

volumes:
  nextcloud_data:

./config/config.php配置

支持HTTPS域名访问,输入自己的域名

  'trusted_domains' => 
  array (
    0 => 'nextcloud.mydomain.xyz',
  ),

赋予权限

docker exec -it nextcloud bash
chown -R www-data:www-data /var/www/html/config
chmod -R 755 /var/www/html/config
chown www-data:www-data /var/www/html/config/config.php
chmod 644 /var/www/html/config/config.php

然后使用Nginx转发即可, 最后重启Nginx,即可完成https访问.可以参考**Linux常用技巧篇的Nginx https配置**

彻底删除

docker rm -f nextcloud
docker volume ls
docker volume rm nextcloud_data
rm -rf ./nextcloud_data
docker rmi nextcloud:latest

基于阿里云盘webdav实现owncloud双备份

创建目录

mkdir -p /app/docker/aliyundrive-webdav

创建docker-compose.yml

cd /app/docker/aliyundrive-webdav && nano docker-compose.yml
version: '3.8'
services:
  aliyundrive-webdav:
    image: messense/aliyundrive-webdav
    container_name: aliyundrive-webdav
    restart: always
    # ports:
    #   - "28080:8080"
    environment:
      - REFRESH_TOKEN=${REFRESH_TOKEN} # REFRESH_TOKEN写在.env文件中,防止太长的字符串在docker-compose中被截断,注意这里实际上是对应access_token
      - WEBDAV_AUTH_USER=这里是webdav的网页登录用户名,自定义
      - WEBDAV_AUTH_PASSWORD=这里是webdav的网页登录密码,自定义
    env_file:
      - .env 

.env

nano .env
REFRESH_TOKEN=xxxx改成自己的token

启动aliyundrive-webdav

docker-compose up -d 

通过rclone webdav配置

rclone config
# 按照提示配置。选webdav。密码和密码就是上面配置的

挂载

假如上面配置的阿里云盘名叫aliyun_drive

mkdir /aliyun_drive_local && nohup rclone mount aliyun_drive:/ /aliyun_drive_local --vfs-cache-mode writes >> /tmp/aliyun_drive_local.log 2>&1 &

开机自动挂载

sudo nano /etc/systemd/system/rclone-mount.service

[Unit]
Description=Mount Aliyun Drive with Rclone
After=network-online.target

[Service]
Type=simple
ExecStart=/usr/bin/rclone mount aliyun_drive:/ /aliyun_drive_local --vfs-cache-mode writes
ExecStop=/bin/fusermount -u /aliyun_drive_local
Restart=on-failure
User=root
Group=root

[Install]
WantedBy=multi-user.target

sudo systemctl daemon-reload
sudo systemctl restart rclone-mount.service

安装inotify,用于监听owncloud文件变化

sudo apt update
sudo apt install inotify-tools

配置脚本sync_with_inotify.sh

nano /app/sync_with_inotify.sh

通过 inotifywait 实现对指定目录的实时监控,一旦检测到文件的创建、修改、删除或移动事件,就会触发 rclone sync 命令,将本地目录同步到远程存储(如阿里云盘)。它还包含一些优化措施,例如延迟处理、避免重复触发等

#!/bin/bash

LOCAL_DIR="/app/docker/owncloud/owncloud/data/files/admin/files"
LOG_FILE="/tmp/rclone_owncloud.log"

## 使用 inotifywait 监听本地文件夹变化
inotifywait -m -r -e create,modify,delete,move "$LOCAL_DIR" |
while read -r directory events filename; do
  echo "Detected $events on $filename"

  # 延迟执行,避免频繁触发
  sleep 10

  # 防止重复同步
  if pgrep -f "rclone sync" > /dev/null; then
    echo "Sync is already running, skipping this event."
    continue
  fi

  rclone sync "$LOCAL_DIR" aliyun_drive:/owncloud_backup \
    --exclude "*.d*" \
    --transfers 2 \
    --checkers 2 \
    --delete-during \
    --log-level DEBUG \
    --log-file "$LOG_FILE"
done
  • 命令解释

    • -m:开启持续监控模式。

    • -r:递归监听子目录中的变化。

    • -e create,modify,delete,move
      

      :监听以下事件:

      • create:文件或目录的创建。
      • modify:文件内容的修改。
      • delete:文件或目录的删除。
      • move:文件或目录的移动或重命名。
    • "$LOCAL_DIR":指定要监听的目录。

    功能:当监控的目录中发生指定的事件时,将事件信息通过管道传递到 while 循环中。

添加执行权限

chmod +x /app/sync_with_inotify.sh

作为服务启动

sudo nano /etc/systemd/system/sync_with_inotify.service
[Unit]
Description=Sync files with Aliyun Drive using rclone and inotify
After=network.target

[Service]
ExecStart=/bin/bash /app/sync_with_inotify.sh
Restart=always
RestartSec=10s
User=root
WorkingDirectory=/app
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target

重新加载 systemd 配置

sudo systemctl daemon-reload

启动并使服务开机启动

sudo systemctl start sync_with_inotify.service
sudo systemctl enable sync_with_inotify.service
sudo systemctl status sync_with_inotify.service
sudo systemctl restart sync_with_inotify.service
sudo systemctl stop sync_with_inotify.service

查看日志

journalctl -u sync_with_inotify.service -f

手动同步

多次同步不影响

rclone sync "/app/docker/owncloud-ok/files/files/" aliyun_drive:/owncloud_backup   --exclude "*.d*"   --transfers 2   --checkers 2   --delete-during   --log-level DEBUG   --log-file /app/rclone_owncloud.log

查看日志文件

tail -f /tmp/rclone_owncloud.log

需要将webdav的IP固定

避免重启服务后,IP变化....最终导致rclone中的webdav地址发生变化,无法连接到webdav

不想挂载时,卸载已挂载的文件夹

fusermount -uz /aliyun_drive_local

基于docker-compose安装fail2ban

安装rsyslog

fail2ban依赖rsyslog,安装并启动后,会产生日志文件 /var/log/auth.log

apt update
apt install rsyslog -y
rsyslogd

docker-compose.yml

mkdir -p /app/docker/fail2ban/
cd /app/docker/fail2ban/

cat <<EOF > docker-compose.yml
version: '3.8'

services:
  fail2ban:
    image: crazymax/fail2ban:latest
    container_name: fail2ban
    restart: always
    network_mode: host
    cap_add:
      - NET_ADMIN
      - NET_RAW
    volumes:
      - ./data:/data
      - /var/log:/var/log:ro
EOF

启动

docker-compose up -d

配置SSH规则

#内容如下
cat <<EOF > data/jail.d/sshd.conf
[sshd]
enabled = true
chain = INPUT
port = ssh
filter = sshd[mode=aggressive]
logpath = /var/log/auth.log
maxretry = 3
findtime = 60     # 1 分钟内
bantime = 31536000 # 封禁 365 天(31,536,000 秒)
EOF

重启启动

docker-compose restart

查看被ban的记录

docker exec fail2ban fail2ban-client status sshd

如下:

root@:/app/docker/fail2ban#  docker exec fail2ban fail2ban-client status sshd
Status for the jail: sshd
|- Filter
|  |- Currently failed:	0
|  |- Total failed:	0
|  `- File list:	/var/log/auth.log
`- Actions
   |- Currently banned:	3
   |- Total banned:	3
   `- Banned IP list:	123.58.207.155 92.255.85.107 92.255.85.253

解封IP

docker exec fail2ban fail2ban-client set sshd unbanip 1.1.1.1

ban一个ip

docker exec fail2ban fail2ban-client set sshd banip 103.167.64.9

解封所有

docker exec -it $(docker ps -q --filter name=fail2ban) fail2ban-client unban --all

查看有效的登录用户

grep -E '/bin/bash|/bin/zsh' /etc/passwd

显示当前登录到系统的用户信息

who/w

w 命令显示的是当前系统上已登录的用户会话信息

具体来说:

  • 它会列出 当前在线的所有用户(包括 SSH 登录、TTY、pts 终端等)
  • 还会显示每个会话的登录时间、空闲时间、正在运行的命令等信息
  • 不会显示已经退出的历史登录

显示系统中所有的登录和注销记录

last

who 与 last 的区别:

who:显示当前系统中正在登录的用户

实时信息,反映当前在线的用户。 不包括注销的历史记录。

last:显示所有的登录和注销历史记录

包括历史记录,反映所有曾经登录过的用户(包括已注销的)。 可以查看每个用户的登录时长和注销信息。

查看历史登录记录

last → 从 /var/log/wtmp 读取历史成功登录记录

lastb → 从 /var/log/btmp 读取失败登录记录(爆破痕迹)

检查是否被爆破成功(成功登录记录)

关键是找 "Accepted password""Accepted publickey",看是否有陌生 IP。

# 最近成功登录
sudo grep "Accepted" /var/log/auth.log | tail -n 50

更换ssh默认端口

sudo sed -i 's/^#Port .*/Port 50022/; s/^Port .*/Port 50022/' /etc/ssh/sshd_config
ufw allow 50022/tcp comment "ssh"
ufw delete allow ssh
ufw reload
systemctl restart sshd

允许指定的用户SSH

编辑vim /etc/ssh/sshd_config


# 只允许 root 用户登录,其他所有用户都会被拒绝
AllowUsers root

重启sshd

systemctl restart sshd

排查ssh不成功的原因

tail -f  /var/log/auth.log 

tail -n 40 /var/log/auth.log | grep sshd

docker-compose部署apollo 2.2.0

  • 创建文件夹
mkdir -p /app/docker/apollo
  • 最终目录结构如下:
tree
.
├── docker-compose.yml
└── sql
    ├── 01-apolloconfigdb.sql
    ├── 02-apolloconfigdb.sql
    ├── 03-init-user.sql
    └── 04-init-eureka-url.sql

2 directories, 5 files
  • 01-apolloconfigdb.sql 文件内容
services:
  apollo-db:
    image: mariadb:10.11
    container_name: apollo-db
    environment:
      MYSQL_ROOT_PASSWORD: xoopooth4gie6doo5Aechieteev9genu
      MYSQL_USER: apollo
      MYSQL_PASSWORD: apollo123
    volumes:
      - ./sql:/docker-entrypoint-initdb.d
      - db_data:/var/lib/mysql
    command:
      - --default-authentication-plugin=mysql_native_password
      - --character-set-server=utf8mb4
      - --collation-server=utf8mb4_unicode_ci
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-uapollo", "-papollo123", "--silent"]
      interval: 5s
      timeout: 10s
      retries: 10

  apollo-configservice:
    image: apolloconfig/apollo-configservice:2.2.0
    container_name: apollo-configservice
    depends_on:
      apollo-db:
        condition: service_healthy
    environment:
      SPRING_DATASOURCE_DRIVER_CLASS_NAME: com.mysql.cj.jdbc.Driver
      SPRING_DATASOURCE_URL: jdbc:mysql://apollo-db:3306/ApolloConfigDB?useSSL=false&characterEncoding=utf8
      SPRING_DATASOURCE_USERNAME: apollo
      SPRING_DATASOURCE_PASSWORD: apollo123
      EUREKA_INSTANCE_HOSTNAME: apollo-configservice
      EUREKA_INSTANCE_IP_ADDRESS: apollo-configservice
      EUREKA_CLIENT_SERVICE_URL_DEFAULTZONE: http://apollo-configservice:8080/eureka/
      EUREKA_SERVER_ENABLE_SELF_PRESERVATION: "false"
      EUREKA_SERVER_EVICTION_INTERVAL_TIMER_IN_MS: "5000"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
      interval: 30s
      timeout: 10s
      retries: 5

  apollo-adminservice:
    image: apolloconfig/apollo-adminservice:2.2.0
    container_name: apollo-adminservice
    depends_on:
      apollo-configservice:
        condition: service_healthy
    environment:
      SPRING_DATASOURCE_DRIVER_CLASS_NAME: com.mysql.cj.jdbc.Driver
      SPRING_DATASOURCE_URL: jdbc:mysql://apollo-db:3306/ApolloConfigDB?useSSL=false&characterEncoding=utf8
      SPRING_DATASOURCE_USERNAME: apollo
      SPRING_DATASOURCE_PASSWORD: apollo123
      EUREKA_CLIENT_SERVICE_URL_DEFAULTZONE: http://apollo-configservice:8080/eureka/
      EUREKA_INSTANCE_HOSTNAME: apollo-adminservice
      EUREKA_INSTANCE_IP_ADDRESS: apollo-adminservice
      EUREKA_CLIENT_REGISTER_WITH_EUREKA: "true"
      EUREKA_CLIENT_FETCH_REGISTRY: "true"
      # 显式覆盖所有可能的配置键(不同大小写和格式)
      EUREKA_CLIENT_SERVICEURL_DEFAULTZONE: http://apollo-configservice:8080/eureka/
      SPRING_CLOUD_CONFIG_ENABLED: "false"  # 禁用配置服务器覆盖
      SPRING_APPLICATION_JSON: '{"eureka":{"client":{"serviceUrl":{"defaultZone":"http://apollo-configservice:8080/eureka/"}}}}'  # 最高优先级
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8090/health"]
      interval: 30s
      timeout: 10s
      retries: 5

  apollo-portal:
    image: apolloconfig/apollo-portal:2.2.0
    container_name: apollo-portal
    depends_on:
      apollo-configservice:
        condition: service_healthy
    environment:
      SPRING_DATASOURCE_DRIVER_CLASS_NAME: com.mysql.cj.jdbc.Driver
      SPRING_DATASOURCE_URL: jdbc:mysql://apollo-db:3306/ApolloPortalDB?useSSL=false&characterEncoding=utf8
      SPRING_DATASOURCE_USERNAME: apollo
      SPRING_DATASOURCE_PASSWORD: apollo123
      APOLLO_PORTAL_ENVS: dev
      DEV_META: http://apollo-configservice:8080
      PRO_META: http://apollo-configservice:8080
      APOLLO_CONFIG_SERVICE: http://apollo-configservice:8080
    ports:
      - "8070:8070"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8070/health"]
      interval: 30s
      timeout: 10s
      retries: 5
    networks:
      - nginx_ngu_network  #此处是为了加入已经创建好的nginx网络中.用于nginx代理.可选
      - default

networks:
  nginx_ngu_network:
    external: true

volumes:
  db_data:

  • sql/01-apolloconfigdb.sql

下载文件 https://github.com/apolloconfig/apollo/blob/master/scripts/sql/profiles/mysql-default/apolloconfigdb.sql

  • sql/02-apolloconfigdb.sql

下载文件 https://github.com/apolloconfig/apollo/blob/master/scripts/sql/profiles/mysql-default/apolloportaldb.sql

  • sql/03-init-user.sql
CREATE USER IF NOT EXISTS 'apollo'@'%' IDENTIFIED BY 'apollo123';
GRANT ALL PRIVILEGES ON ApolloConfigDB.* TO 'apollo'@'%';
GRANT ALL PRIVILEGES ON ApolloPortalDB.* TO 'apollo'@'%';
FLUSH PRIVILEGES
  • sql/04-init-eureka-url.sql

非常重要. apollo 2.2.0版本. apollo-adminservice默认的注册中心是http://localhost:8080/eureka/,启动后总是无法找到正常的apollo-configservice.用执行初始化sql的办法修改

UPDATE `ApolloConfigDB`.`ServerConfig`
SET `Value` = 'http://apollo-configservice:8080/eureka/'
WHERE `Key` = 'eureka.service.url';
  • 启动
docekr-compose up -d
  • 访问 http://localhost:8070

默认登录账户 apollo/admin, 尽快修改密码

docker搭建达梦数据库

Docker 安装

docker run -d -p 30236:5236 \
--restart=always \
--name dm8 \
--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 \
-e CASE_SENSITIVE=0 \
-e CHARSET=1 \
tommyyusky/dm8_20230808_rev197096_x86_rh6_64

默认账户

SYSDBA/SYSDBA001

达梦官网资料下载

达梦 JDBC 驱动下载

常用命令

修改数据库密码

ALTER USER CURRENT_USER IDENTIFIED BY eizeejee3oh REPLACE SYSDBA001;

# ALTER USER SYSDBA IDENTIFIED BY eizeejee3oh;

环境

root@x:~# cat /etc/issue
Debian GNU/Linux 12 \n \l

Fail2Ban 安装相关

# 安装
apt install fail2ban -y

# 启动进程
systemctl start fail2ban 

# 开机启动
systemctl enable fail2ban

查看状态

systemctl status fail2ban.service

发现没有启动成功,控制台如下:

× fail2ban.service - Fail2Ban Service
     Loaded: loaded (/lib/systemd/system/fail2ban.service; enabled; preset: enabled)
     Active: failed (Result: exit-code) since Mon 2024-08-05 03:41:24 UTC; 3 days ago
   Duration: 195ms
       Docs: man:fail2ban(1)
   Main PID: 1981 (code=exited, status=255/EXCEPTION)
        CPU: 160ms

Aug 05 03:41:24 lightsail systemd[1]: Started fail2ban.service - Fail2Ban Service.
Aug 05 03:41:24 lightsail fail2ban-server[1981]: 2024-08-05 03:41:24,878 fail2ban.configreader   [1981]: WARNING 'allowipv6' not defined in 'Definition'. Using default one: 'auto'
Aug 05 03:41:24 lightsail fail2ban-server[1981]: 2024-08-05 03:41:24,912 fail2ban                [1981]: ERROR   Failed during configuration: Have not found any log file for sshd jail
Aug 05 03:41:24 lightsail fail2ban-server[1981]: 2024-08-05 03:41:24,919 fail2ban                [1981]: ERROR   Async configuration of server failed
Aug 05 03:41:24 lightsail systemd[1]: fail2ban.service: Main process exited, code=exited, status=255/EXCEPTION

解决办法: vim /etc/fail2ban/jail.local

vim /etc/fail2ban/jail.local
#内容如下
[sshd]
enabled = true
port    = ssh
logpath = /var/log/auth.log
backend = auto

创建日志文件/var/log/auth.log

touch /var/log/auth.log

重启并且查看状态

systemctl restart fail2ban
systemctl status fail2ban

启动成功,控制台输出如下:

● fail2ban.service - Fail2Ban Service
     Loaded: loaded (/lib/systemd/system/fail2ban.service; enabled; preset: enabled)
     Active: active (running) since Thu 2024-08-08 09:23:46 UTC; 4s ago
       Docs: man:fail2ban(1)
   Main PID: 17051 (fail2ban-server)
      Tasks: 5 (limit: 2303)
     Memory: 14.0M
        CPU: 189ms
     CGroup: /system.slice/fail2ban.service
             └─17051 /usr/bin/python3 /usr/bin/fail2ban-server -xf start

Aug 08 09:23:46 lightsail systemd[1]: Started fail2ban.service - Fail2Ban Service.
Aug 08 09:23:46 lightsail fail2ban-server[17051]: 2024-08-08 09:23:46,319 fail2ban.configreader   [17051]: WARNING 'allowipv6' not defined in 'Definition'. Using default one: 'auto'
Aug 08 09:23:46 lightsail fail2ban-server[17051]: Server ready

Linux常用技巧

每次vim的时候总是粘贴不了.需要输入:set mouse-=a回车,才行

解决办法, vim ~/.vimrc 内容如下

set mouse-=a

保存后, souce ~/.vimrc, 再次编辑文件, 就可以粘贴了

apt安装ping

apt install iputils-ping

给泛解析加一个匹配不到的预留映射

vim *.nguone.eu.org.conf

server {
    listen 80;
    listen 443 ssl;
    server_name *.nguone.eu.org;
    ssl_certificate /etc/nginx/ssl/vaultwarden.crt;
    ssl_certificate_key /etc/nginx/ssl/vaultwarden.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
    ssl_prefer_server_ciphers on;
    # 可以选择进行适当的处理或返回404
    # 开启HSTS后能够提升到A+. SSL评估 https://myssl.com/
    add_header Strict-Transport-Security "max-age=31536000";
    return 404;
}

Nginx Docker 部署

创建网络

docker network create --driver=bridge --subnet=172.16.238.0/24 --gateway=172.16.238.1 my_docker_network
version: '3.8'

services:
  nginx:
    image: nginx:1.21.1
    container_name: nginx
    ports:
      - 80:80
      - 443:443
    volumes:
      - /app/docker/nginx/nginx:/etc/nginx
      - /root/.acme.sh/*.nguone.eu.org_ecc/fullchain.cer:/etc/nginx/ssl/vaultwarden.crt:ro
      - /root/.acme.sh/*.nguone.eu.org_ecc/*.nguone.eu.org.key:/etc/nginx/ssl/vaultwarden.key:ro     
    networks:
      - my_docker_network

networks:
  my_docker_network:
    external: true

Nginx https 配置

当前nginx版本

nginx -v
nginx version: nginx/1.21.1

vaultwarden.conf示例配置如下

server {
    listen 80; #侦听80端口,如果强制所有的访问都必须是HTTPs的,这行需要注销掉
    listen 443 ssl; 
    server_name vaultwarden.nguone.eu.org;
    ssl_certificate /etc/nginx/ssl/vaultwarden.crt;
    ssl_certificate_key /etc/nginx/ssl/vaultwarden.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
    ssl_prefer_server_ciphers on;

    client_max_body_size 1024m;
    # 开启HSTS后能够提升到A+. SSL评估 https://myssl.com/
    add_header Strict-Transport-Security "max-age=31536000";
    
    location / {
        proxy_set_header HOST $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://vaultwarden;
    }
}

添加一个http登录认证 配置如下:

server {
    listen 80; #侦听80端口,如果强制所有的访问都必须是HTTPs的,这行需要注销掉
    server_name work;
    client_max_body_size 1024m;
    # 开启HSTS后能够提升到A+. SSL评估 https://myssl.com/
    add_header Strict-Transport-Security "max-age=31536000";
    
    location / {
        # 启用 HTTP Basic Authentication
        auth_basic "Restricted Access";  # 提示信息
        auth_basic_user_file /etc/nginx/.htpasswd;  # 指定存放用户名和密码的文件        
	proxy_set_header HOST $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://host.docker.internal:3000;
    }
}

生成验证密码,保存在/etc/nginx/.htpasswd

密码错误, 会导致nginx提示500错误

htpasswd -c -b /etc/nginx/.htpasswd nguone AiQuaichei2Eer2C

location

location = /abc {
    add_header Content-Type text/plain;
    add_header X-Server-IP $server_addr always;

    return 200 'Success';
}

解释:

  • location = /abc:表示精确匹配 /abc,只有请求的 URI 正好是 /abc 时才会匹配这个块.其他以 /abc/ 开头的路径(比如 /abc/jlljlk)将不会匹配这个配置,将会返回404
  • 如果设置为/abc,那么访问/abc以及/abc开头的任何路径都会当做/abc处理
  • add_header Content-Type text/plain 表示返回的信息是纯文本
  • add_header X-Server-IP $server_addr always 强制在响应头信息中返回nginxIP

匹配进程的名字并且全部杀掉进程

如杀掉所有kafka进程

pgrep -f kafka | xargs kill -9

解释

  • pgrep -f kafka:查找所有匹配 kafka 的进程 PID。
  • xargs kill -9:将找到的 PID 传递给 kill -9,强制终止所有这些进程。

这个命令将会找到所有 Kafka 相关的进程,并使用 kill -9 发送信号强制终止它们。

注意事项

  • 确保匹配准确:确认 pgrep -f kafka 只会匹配到 Kafka 进程,避免误杀其他重要进程。
  • 检查进程:在执行命令前,可以运行 pgrep -f kafka 先查看将会被杀掉的进程。
  • 这种方式是一条命令的解决方案,但请务必在执行之前确认对系统的影响。

在不关闭shell的情况下重新启动Bash Shell

exec bash

主要作用

  • 应用配置更改
    • 当你修改了 ~/.bashrc 或其他 shell 配置文件(如 ~/.bash_profile)后,使用 exec bash 可以使这些更改立即生效,而无需重新登录或重启终端
  • 刷新环境
    • 有时需要重新加载环境变量或 shell 配置时,exec bash 会刷新当前 shell 的所有设置,使得新的环境变量或配置被加载

重置终端root@后的别名.

# 重置PS1
echo "export PS1='[\u@\h \W]\$ '" >> ~/.bashrc && exec bash

端口扫描

安装

sudo apt-get install nmap   # Debian/Ubuntu 系统
sudo yum install nmap       # CentOS/Red Hat 系统

扫描单个主机

nmap -sT 192.168.1.1

扫描整个网段

nmap -p 1-65535 192.168.1.0/24

查看硬盘类型

cat /sys/block/sda/queue/rotational
#如果输出是 1,则表示该磁盘是 旋转硬盘(HDD)。
#如果输出是 0,则表示该磁盘是 固态硬盘(SSD)。

查看所有自启服务列表

systemctl list-units --type=service

docker 容器安装telnet

# 查看操作系统信息
cat /etc/os-release

# alpine 安装telnet
apk add busybox-extras

grafana 重置admin密码

grafana-cli admin reset-admin-password <new password>

find跳过无权限目录

find / -path /proc -prune -o -name "*.jar" -print
# 等价于
find / -not -path "/proc/*" -name "*.jar" -print

/proc 目录 是一个虚拟文件系统,包含系统和进程的实时信息。

权限限制:某些 /proc 目录下的文件和进程信息只有 root 用户或进程的所有者才能访问,普通用户会遇到 Permission denied 错误。

解决方法:使用 -prune 排除 /proc 目录,避免遍历该目录时出现权限问题。

debian设置上海时区

sudo timedatectl set-timezone Asia/Shanghai

容器内运行arthas防止挂断

# 在openjdk8环境下运行 出现问题的解决方案
# export PATH=$PATH:/usr/lib/jvm/java-1.8-openjdk/bin

pid=1 ;\
touch /proc/${pid}/cwd/.attach_pid${pid} && \
  kill -SIGQUIT ${pid} && \
  sleep 2 &&
  ls /proc/${pid}/root/tmp/.java_pid${pid}

curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar

windows 多块网卡切换

检查路由表

route print

删除 WLAN(无线网卡)的默认路由

route delete 0.0.0.0 mask 0.0.0.0 172.20.10.1 if 14

删除以太网(Realtek PCIe GbE)的默认路由

route delete 0.0.0.0 mask 0.0.0.0 10.99.95.254

恢复默认路由

route add 0.0.0.0 mask 0.0.0.0 10.99.95.254 if 20 -p

设置上海时区

sudo timedatectl set-timezone Asia/Shanghai

查看磁盘使用情况

df -h /

开启4G的内存缓冲区

sudo fallocate -l 4G /swapfile && \

sudo chmod 600 /swapfile && \

sudo mkswap /swapfile && \

sudo swapon /swapfile && \

echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab && \

sudo sysctl vm.swappiness=10 && \

echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf

网络知识积累

局域网(LAN)常用的私有IP地址网段

通常包括以下三个主要的网段,它们是专门保留给私有网络使用的,不会在互联网中路由

  • 10.0.0.0/8 网段: 范围:10.0.0.0 - 10.255.255.255 子网掩码:255.0.0.0 可用地址数:16,777,216(即 2^24)

  • 172.16.0.0/12 网段: 范围:172.16.0.0 - 172.31.255.255 子网掩码:255.240.0.0 可用地址数:1,048,576(即 2^20)

  • 192.168.0.0/16 网段: 范围:192.168.0.0 - 192.168.255.255 子网掩码:255.255.0.0 可用地址数:65,536(即 2^16)

防火墙-firewalld

重载防火墙

firewall-cmd --reload

查看已开启的端口

firewall-cmd --zone=public --list-ports

防火墙-ufw

journalctl查看ssh连接日志

使用 journalctl 查看认证日志

sudo journalctl -u ssh

持续监控这些日志,可以使用 -f 选项,类似于 tail -f

sudo journalctl -u ssh -f

查看所有与认证相关的日志记录

sudo journalctl | grep ssh

查看登录成功的记录

sudo journalctl | grep ssh | grep 'Accepted'

查看被拒绝的记录

sudo journalctl | grep ssh | grep preauth

日志分析

Oct 16 06:10:01 amd2 sshd[7597]: Connection reset by invalid user admin 154.47.27.80 port 42672 [preauth]

对主机名为amd2的VPS进行ssh连接,invalid user 表示无效用户, 即使用不存在的用户admin进行ssh连接. preauth被拒绝 即 用户输入的用户名还未通过认证程序校验,系统已经发现这是一个无效用户并且连接已被重置

删除所有超过 1 秒的日志

sudo journalctl --vacuum-time=1s

清空日志文件(彻底清除)

sudo rm -rf /var/log/journal/*

Linux创建完整用户

创建用户

  • 创建用户
sudo useradd -m -s /bin/bash myuser
  • 设置用户密码
sudo passwd myuser

给用户赋予sudo权限

  • 添加用户到 sudo 组
# CentOS
sudo usermod -aG wheel myuser

# Debian
sudo usermod -aG sudo myuser

wheel组的用 配置无密码 sudo 权限

注意这是放行所有wheel组的用户, 无密码执行sudo

sudo visudo

找到这一行 %wheel ALL=(ALL) NOPASSWD: ALL 将前面的#去掉.

指定用户,配置无密码执行sudo权限

新增一行

# 指定用户不需要输入密码,执行sudo, 比如sudo -i 或者 sudo su - root
myuser ALL=(ALL) NOPASSWD:ALL

# 指定用户不需要输入密码,仅限于执行/bin/chmod
# myuser ALL=(ALL) NOPASSWD: /bin/chmod

ssh-keygen 生成最新的密钥对

ssh-keygen 生成最新的密钥对,通常建议使用 Ed25519 算法,因为它安全、速度快且体积小,是当前推荐的现代密钥类型

ssh-keygen -t ed25519 -C "your_email@example.com"

其他辅助性命令

  • 查看所有用户
cat /etc/passwd
  • 查看用户组
cat /etc/group
  • 查看用户的权限和组
id myuser

会输出类似于以下的信息

uid=1001(myuser) gid=1001(myuser) groups=1001(myuser),10(wheel)
  • 查看所有组
getent passwd
  • 使用 groups 命令查看当前用户的组
groups
  • 使用 getent 命令检查特定组
getent group docker
  • 将用户添加到 docker 组
sudo usermod -aG docker myuser

添加后, 执行sudo docker 命令可能提示无权限. 解决办法有两种:

  • 完全退出并重新登录
  • newgrp docker

删除一个用户

sudo userdel -r xxxx

禁用root执行ssh

谨慎操作,操作前至少要保证有1个非root用户可以正常ssh登录

vim /etc/ssh/sshd_config

末尾追加

# 只允许 myuser 用户登录,其他所有用户都会被拒绝
AllowUsers myuser

重启sshd

sudo systemctl restart sshd

此时再用root登录就会看到

2025-08-09T07:32:11.673498+08:00 xxxx sshd[1390595]: User root from 111.119.221.153 not allowed because not listed in AllowUsers

Linux历史记录

使用 HISTSIZE 和 HISTFILESIZE 将这两个环境变量设置为 0,这样将不会记录任何历史记录

以在你的 shell 配置文件(如 ~/.bashrc 或 ~/.bash_profile)中添加以下行

export HISTSIZE=0
export HISTFILESIZE=0

刷新终端

source ~/.bashrc

临时禁用历史记录

set +o history

临时启用历史记录

set -o history

删除历史文件

rm ~/.bash_history

Linux代理搭建和使用

sudo yum install squid
sudo systemctl start squid
sudo systemctl enable squid
  • 查看配置文件
cat /etc/squid/squid.conf

默认配置如下

http_port 8087
cache_mem 128 MB
cache_dir ufs /var/spool/squid 4096 16 256
cache_effective_user squid  #设置用户
cache_effective_group squid  #设置用户组
access_log /var/log/squid/access.log   #设置访问日志文件
cache_log /var/log/squid/cache.log  #设置缓存日志文件
cache_store_log /var/log/squid/store.log  #设置缓存记录文件
visible_hostname cdn.abc.com  #设置squid服务器主机名
cache_mgr root@root.com
acl all src 0.0.0.0/0.0.0.0  #设置访问控制列表,默认开启
http_access allow all
acl client dstdomain -i www.abc.com    #找到TAG: acl标签,在其最后添加下面内容
http_access deny client  #禁止所有客户机访问www.abc.com域名
acl client131 src 192.168.237.131  #禁止IP地址为192.168.237.131的客户机访问外网
http_access deny client131
acl client129 dst 192.168.237.129  #禁止所有用户访问IP地址为192.168.237.129的网站
http_access deny client129
acl client163 url_regex -i 163.com  #禁止所有用户访问域名中包含有163.com的网站
http_access deny client163
acl clientdate src 192.168.237.0/255.255.255.0  #禁止这个网段所有的客户机在周一到周五的18:00-21:00上网
acl worktime time MTWHF 18:00-21:00
http_access deny clientdate worktime
#acl clientxiazai urlpath_regex -i \.mp3$  \.exe$  \.zip$  \.rar$
#http_access deny clientxiazai  #禁止客户机下载*.mp3、*.exe、*.zip和*.rar类型的文件
  • 在需要代理的机器上执行
export http_proxy=http://instance1_ip:8087
export https_proxy=http://instance1_ip:8087

docker使用代理

sudo mkdir -p /etc/systemd/system/docker.service.d
sudo nano /etc/systemd/system/docker.service.d/http-proxy.conf

http-proxy.conf内容如下:

[Service]
Environment="HTTP_PROXY=http://instance1_ip:8087"
Environment="HTTPS_PROXY=http://instance1_ip:8087"
Environment="NO_PROXY=localhost,127.0.0.1"

重载系统守护进程并重启 Docker 服务

sudo systemctl daemon-reload
sudo systemctl restart docker

自签证书

特别注意openssl版本

低版本按以下命令生成的自签证书,有可能添加信任后浏览器仍然提示无法信息.当前环境版本OpenSSL 3.0.15

root@tw:~/ssl# openssl version
OpenSSL 3.0.15 3 Sep 2024 (Library: OpenSSL 3.0.15 3 Sep 2024)

低版本的openssl升级

apt update
apt install openssl -y

生成带有 Subject Alternative Name (SAN) 的自签名证书。现代浏览器(如 Chrome 和 Firefox)要求证书中必须明确设置 SAN,否则即使 CN 匹配也会拒绝连接。 使用openssl x509 -in work.xyz.me.crt -text -noout确认证书中是否有 SAN 字段

单域名

openssl req -x509 -nodes -days 36500 -newkey rsa:2048 \
    -keyout work.xyz.me.key -out work.xyz.me.crt \
    -out work.xyz.me.csr \
    -subj "/C=CN/ST=Shanghai/L=Shanghai/O=My Company/OU=IT Department/CN=work.xyz.me" \
    -addext "subjectAltName=DNS:work.xyz.me"

泛解析域名

openssl req -x509 -nodes -days 36500 -newkey rsa:2048 \
    -keyout work.xyz.me.key -out work.xyz.me.crt \
    -subj "/C=CN/ST=Shanghai/L=Shanghai/O=My Company/OU=IT Department/CN=*.xyz.me" \
    -addext "subjectAltName=DNS:*.xyz.me"

软路由安装

修改静态IP

特别注意,要添加网关,否则无法上网,ping外网不通 特别注意,要添加dns,否则无法解析域名 网关指向主路由IP 192.168.1.1(每个路由器可能不同,可以手机连接WIFI,网络详细中查看)

vi /etc/config/network,找到 config interface 'lan' 部分,按以下格式调整成自己的信息

config interface 'lan'
        option type 'bridge'
        option ifname 'eth0'
        option proto 'static'
        option ipaddr '192.168.1.100'
        option netmask '255.255.255.0'
        option gateway '192.168.1.1'
        option ip6assign '60'
        option dns '192.168.1.1'
        option dns '8.8.8.8'

修改好之后, 重启网络 service network restart

然后查看路由,没看到网关192.128.1.1,表示网关没有添加

root@OpenWrt:~# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 br-lan
root@OpenWrt:~# ip route
192.168.1.0/24 dev br-lan proto kernel scope link src 192.168.1.100

临时添加网关测试,如果能上网,通过修改/etc/config/network配置持久化即可

root@OpenWrt:~# ip route add default via 192.168.1.1
root@OpenWrt:~# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.1.1     0.0.0.0         UG    0      0        0 br-lan
192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 br-lan
root@OpenWrt:~# ip route
default via 192.168.1.1 dev br-lan proto static
192.168.1.0/24 dev br-lan proto kernel scope link src 192.168.1.100
root@OpenWrt:~# ping baidu.com
PING baidu.com (39.156.66.10): 56 data bytes
64 bytes from 39.156.66.10: seq=0 ttl=53 time=29.502 ms
64 bytes from 39.156.66.10: seq=1 ttl=53 time=29.328 ms
64 bytes from 39.156.66.10: seq=2 ttl=53 time=29.238 ms

opkg update报错解决

 rm -rf /etc/opkg/*

/etc/opkg.conf内容如下:

src/gz openwrt_base https://mirrors.tuna.tsinghua.edu.cn/openwrt/releases/18.06.9/packages/x86_64/base
src/gz openwrt_luci https://mirrors.tuna.tsinghua.edu.cn/openwrt/releases/18.06.9/packages/x86_64/luci
src/gz openwrt_packages https://mirrors.tuna.tsinghua.edu.cn/openwrt/releases/18.06.9/packages/x86_64/packages
src/gz openwrt_routing https://mirrors.tuna.tsinghua.edu.cn/openwrt/releases/18.06.9/packages/x86_64/routing

samba模板配置备份

[global]
	netbios name = |NAME| 
	interfaces = |INTERFACES|
	server string = |DESCRIPTION|
	unix charset = |CHARSET|
	workgroup = |WORKGROUP|

	## This global parameter allows the Samba admin to limit what interfaces on a machine will serve SMB requests.
	bind interfaces only = yes

	## time for inactive connections to-be closed in minutes
	deadtime = 15

	## disable core dumps
	enable core files = no

	## set security (auto, user, domain, ads)
	security = user

	## This parameter controls whether a remote client is allowed or required to use SMB encryption.
	## It has different effects depending on whether the connection uses SMB1 or SMB2 and newer:
    ## If the connection uses SMB1, then this option controls the use of a Samba-specific extension to the SMB protocol introduced in Samba 3.2 that makes use of the Unix extensions.
	## If the connection uses SMB2 or newer, then this option controls the use of the SMB-level encryption that is supported in SMB version 3.0 and above and available in Windows 8 and newer. 
	## (default/auto,desired,required,off)
	#smb encrypt = default

	## set invalid users
	invalid users = root

	## map unknow users to guest
	map to guest = Bad User

	## allow client access to accounts that have null passwords. 
	null passwords = yes

	## The old plaintext passdb backend. Some Samba features will not work if this passdb backend is used. (NOTE: enabled for size reasons)
	## (tdbsam,smbpasswd,ldapsam)
	passdb backend = smbpasswd

	## Set location of smbpasswd ('smbd -b' will show default compiled location)
	#smb passwd file = /etc/samba/smbpasswd 

	## LAN (IPTOS_LOWDELAY TCP_NODELAY) WAN (IPTOS_THROUGHPUT) WiFi (SO_KEEPALIVE) try&error for buffer sizes (SO_RCVBUF=65536 SO_SNDBUF=65536)
	socket options = IPTOS_LOWDELAY TCP_NODELAY

	## If this integer parameter is set to a non-zero value, Samba will read from files asynchronously when the request size is bigger than this value.
	## Note that it happens only for non-chained and non-chaining reads and when not using write cache.
	## The only reasonable values for this parameter are 0 (no async I/O) and 1 (always do async I/O).
	## (1/0)
	#aio read size = 0
	#aio write size = 0

	## If Samba has been built with asynchronous I/O support, Samba will not wait until write requests are finished before returning the result to the client for files listed in this parameter.
	## Instead, Samba will immediately return that the write request has been finished successfully, no matter if the operation will succeed or not.
	## This might speed up clients without aio support, but is really dangerous, because data could be lost and files could be damaged. 
	#aio write behind = /*.tmp/

	## lower CPU useage if supported and aio is disabled (aio read size = 0 ; aio write size = 0)
	## is this still broken? issue is from 2019 (NOTE: see https://bugzilla.samba.org/show_bug.cgi?id=14095 )
	## (no, yes)
	#use sendfile = yes

	## samba will behave as previous versions of Samba would and will fail the lock request immediately if the lock range cannot be obtained.
	#blocking locks = No

	## disable loading of all printcap printers by default (iprint, cups, lpstat)
	load printers = No
	printcap name = /dev/null

	## Enabling this parameter will disable Samba's support for the SPOOLSS set of MS-RPC's.
	disable spoolss = yes

	## This parameters controls how printer status information is interpreted on your system.
	## (BSD, AIX, LPRNG, PLP, SYSV, HPUX, QNX, SOFTQ)
	printing = bsd

	## Disable that nmbd is acting as a WINS server for unknow netbios names
	#dns proxy = No

	## win/unix user mapping backend
	#idmap config * : backend = tdb

	## Allows the server name that is advertised through MDNS to be set to the hostname rather than the Samba NETBIOS name.
	## This allows an administrator to make Samba registered MDNS records match the case of the hostname rather than being in all capitals.
	## (netbios, mdns)
	mdns name = mdns

	## Clients that only support netbios won't be able to see your samba server when netbios support is disabled.
	#disable netbios = Yes

	## Setting this value to no will cause nmbd never to become a local master browser.
	#local master = no

	## (auto, yes) If this is set to yes, on startup, nmbd will force an election, and it will have a slight advantage in winning the election. It is recommended that this parameter is used in conjunction with domain master = yes, so that nmbd can guarantee becoming a domain master. 
	#preferred master = yes

	## (445 139) Specifies which ports the server should listen on for SMB traffic.
	## 139 is netbios/nmbd
	#smb ports = 445 139

	## This is a list of files and directories that are neither visible nor accessible.
	## Each entry in the list must be separated by a '/', which allows spaces to be included in the entry. '*' and '?' can be used to specify multiple files or directories as in DOS wildcards.
	veto files = /Thumbs.db/.DS_Store/._.DS_Store/.apdisk/

	## If a directory that is to be deleted contains nothing but veto files this deletion will fail unless you also set the delete veto files parameter to yes.
	delete veto files = yes

################ Filesystem and creation rules ################
	## reported filesystem type (NTFS,Samba,FAT)
	#fstype = FAT

	## Allows a user who has write access to the file (by whatever means, including an ACL permission) to modify the permissions (including ACL) on it.
	#dos filemode = Yes

	## file/dir creating rules
	#create mask = 0666
	#directory mask = 0777
	#force group = root
	#force user = root
	#inherit owner = windows and unix
################################################################

kubernetes

Kubernetes 是一个开源的容器编排引擎,用来对容器化应用进行自动化部署扩缩和管理

搭建一个kubernetes集群

搭建一个kubernetes集群

安装工具kubectl

安装

curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

# 查看版本 
kubectl version --client

安装 bash-completion

apt-get install bash-completion -y && source /usr/share/bash-completion/bash_completion

全局启用启动 kubectl 自动补全功能

kubectl completion bash | sudo tee /etc/bash_completion.d/kubectl > /dev/null
sudo chmod a+r /etc/bash_completion.d/kubectl
source ~/.bashrc

安装集群:生产环境

安装netcat-openbsd

apt update && apt install netcat-openbsd -y

# 用于直观地看端口是否启用
root@tw:~# nc 127.0.0.1 443 -v
Connection to 127.0.0.1 443 port [tcp/https] succeeded!

安装 kubeadm

sudo apt-get update
# apt-transport-https 可能是一个虚拟包(dummy package);如果是的话,你可以跳过安装这个包
sudo apt-get install -y apt-transport-https ca-certificates curl gpg
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.31/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.31/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
ip route show | grep "default via" 
default via 10.140.0.1 dev ens4 proto dhcp src 10.140.0.7 metric 100

sudo kubeadm init --pod-network-cidr=192.168.0.0/16
cat /etc/kubernetes/kubelet.conf | grep server

重置k8s集群

sudo kubeadm reset
rm -rf /etc/cni/net.d
rm -rf $HOME/.kube/config
rm -rf /etc/kubernetes
docker run -d --name=rancher --privileged --network nginx_ngu_network --memory="2g"  rancher/rancher:latest 
dd if=/dev/zero of=/swapfile bs=1M count=2048
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
 docker logs --tail 10 nginx

列出所有命名空间下的所有的服务

可以看到端口

kubectl get svc --all-namespaces
NAMESPACE                         NAME                   TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                  AGE
cattle-fleet-local-system         fleet-agent            ClusterIP   None             <none>        <none>                   30m
cattle-provisioning-capi-system   capi-webhook-service   ClusterIP   10.101.178.158   <none>        443/TCP                  29m
cert-manager                      cert-manager           ClusterIP   10.103.216.116   <none>        9402/TCP                 35m
cert-manager                      cert-manager-webhook   ClusterIP   10.102.68.102    <none>        443/TCP                  35m
default                           kubernetes             ClusterIP   10.96.0.1        <none>        443/TCP                  3h46m
default                           nginx-service          NodePort    10.104.63.107    <none>        80:30001/TCP             79m
kube-system                       kube-dns               ClusterIP   10.96.0.10       <none>        53/UDP,53/TCP,9153/TCP   3h46m

删除服务

kubectl delete svc nginx-service -n default
kubectl delete deployment nginx -n default
root@tw:/app/docker/nginx/nginx/conf.d# kubectl get deployments -n default
No resources found in default namespace.

删除 Namespace

kubectl get namespace cattle-system -o json
kubectl patch namespace cattle-system -p '{"metadata":{"finalizers":null}}'
kubectl get namespaces
kubectl delete all --all -n cattle-system
kubectl get all -n cattle-system
kubectl delete namespace cattle-system --force --grace-period=0


kubectl get namespace cattle-system -o json > cattle-system.json
kubectl delete validatingwebhookconfiguration rancher.cattle.io
kubectl delete validatingwebhookconfiguration cert-manager-webhook

方法一:将服务类型修改为 LoadBalancer

如果您使用的是云环境(如 GCP、AWS、Azure),可以通过将服务类型改为 LoadBalancer 来使 Rancher 获得一个外部 IP 地址。

执行以下命令来修改 Rancher 服务类型:

bash


复制代码
kubectl -n cattle-system patch svc rancher -p '{"spec":{"type":"LoadBalancer"}}'

此时,您可以通过 EXTERNAL-IP 来访问 Rancher。例如:

bash


复制代码
kubectl -n cattle-system get svc rancher

您将看到 EXTERNAL-IP 字段已分配一个外部 IP 地址,您可以使用该 IP 地址在浏览器中访问 Rancher UI。

方法二:将服务类型修改为 NodePort

如果您没有负载均衡器或不希望使用它,您可以将服务类型修改为 NodePort,然后使用集群节点的外部 IP 和端口访问 Rancher。

执行以下命令来修改 Rancher 服务类型:

bash


复制代码
kubectl -n cattle-system patch svc rancher -p '{"spec":{"type":"NodePort"}}'

然后,使用以下命令查看端口映射:

bash


复制代码
kubectl -n cattle-system get svc rancher

您将看到类似如下的输出:

scss复制代码NAME      TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
rancher   NodePort   10.104.162.113 <none>        80:30001/TCP   1m

如果 Rancher 部署了多个 Pod,可以通过以下命令查看所有 Pod 的日志:

bash


复制代码
kubectl logs -n cattle-system -l app=rancher --follow

helm安装的rancher重置admin密码

cp /root/.kube/config .
KUBECONFIG=./config
kubectl --kubeconfig $KUBECONFIG -n cattle-system exec $(kubectl --kubeconfig $KUBECONFIG -n cattle-system get pods -l app=rancher --no-headers | head -1 | awk '{ print $1 }') -c rancher -- reset-password

kubectl get svc --namespace default等价于 kubectl get svc --namespace default

kubectl get svc --all-namespaces表示列出所有空间下的服务

# dokcer方式搭建
docker run -d --privileged -p 60080:80 -p 60443:443 -v ./rancher_data:/var/lib/rancher --restart=always --name rancher-2.7.1 rancher/rancher:v2.7.1


helm方式搭建
helm install rancher rancher-latest/rancher \
  --namespace cattle-system \
  --set hostname=k8s.nguone.eu.org  --set bootstrapPassword=Ni4phughiotieCoo
kubectl apply -f nginx-pvc.yaml
kubectl get pvc
kubectl apply -f nginx-deployment.yaml
kubectl apply -f nginx-service.yaml
kubectl delete pvc nginx-pvc
kubectl apply -f nginx-test-pod.yaml

让其他节点加入到

个体词

Snipaste_2024-03-17_15-03-53


Snipaste_2024-03-17_15-09-13

谓词

image-20240316193800496


Snipaste_2024-03-17_15-09-13

复合命题的谓词符号化

image-20240317153900159

总结

image-20240317154601408

量词

image-20240317163328581


image-20240317164001835


image-20240317164245933


image-20240317172252420

符号函数

image-20240319230733150


image-20240319231653347

自由变元和约束变元

image-20240319232853442


举例

image-20240319232951206

两个规则

image-20240319233415928


image-20240319233542920

闭式

image-20240319233842485

自反性与反自反性

image-20240322201310193


image-20240322202720992

对称性与反对称性

image-20240322203811955

传递性

image-20240322204714611

关系性质的保守性

image-20240322205723760


闭包求解

image-20240322210739778


利用关系运算求闭包

image-20240322211124678


哈斯图

image-20240323102227160


最大元和最小元

image-20240323102558810


极大元和极小元

image-20240323102819659


总结

image-20240323102851883

上下(确)界关系总结

image-20240323101852352


全序关系的哈斯图

image-20240323103917132


良序关系

image-20240323104132120

函数

image-20240323110337026


函数的数量

image-20240323105906443


关系和函数的差别

image-20240323110822356

函数类型

image-20240323113308689


函数的复合

image-20240323113555349


image-20240323114000363


保守性

image-20240323114342940

结点的度数

image-20240323145323439

通路与回路举例

image-20240323151838067


记号的简化

image-20240323151958280

无向树

image-20240323152759964

Python基础

基础语法

多行语句

反斜杠\用来连接多行代码

>>>str = "Hello" + \
   " World"
>>>print(str)
Hello World

注释

  1. 单行注释, 用#表示

    1. #这是一个单行注释
  2. 多行注释,用3个单引号或者双引号表示

    1. ```3个单引号
      表示的多行注释
      ```
      
    2. """3个双引号
      表示的多行注释
      """
      

同一行显示多条语句

>>> x=123;y=z=1
>>> x
123
>>> y
1

多个语句构成代码组

if True:  #结尾的冒号不能省略
    print('true')
elif 2>1:   # 特别注意,是elif,不是elseif
	print('2>1')
else :
   print('else')    

五个标准的数据类型

String(字符串)

str1 = "abc"     #,str2 定义多个字符串的时候,第一个字符串后直接跟逗号定义另一个字符串,在Python 3.11.2中,会报错.这里的#表示注释
str1 = str2 = 'abc'
str1 = """3a""";str2 = """3b"""
str = '''3a'''

[头下标:尾下标]

特别注意,包头不包尾

>>> str="""12345"""
>>> str[1:2]
'2'
>>> str[2:4]
'34'

Numbers(数字)

var1=var2=100

List(列表)

>>> list=['a','b','c','d']
>>> list[0] # 输出列表的第一个元素
'a'
>>> list[1:3] # 输出第二个至第三个元素
['b', 'c']
>>> list*2 #输出列表两次
['a', 'b', 'c', 'd', 'a', 'b', 'c', 'd']
>>> arr=[1,2,3]
>>> list+arr # 两个列表拼接在一起行成1个新的列表
['a', 'b', 'c', 'd', 1, 2, 3]
>>> list[2:] #输出从第3个元素开始的所有元素
['c', 'd']

Tuple(元组)

元组类似于列表,但是,元组不能二次赋值,相当于只读表


Dictionary(字典)


常用函数

北派经方学术

我个人是恨死了一位人称:天医星的叶天士, 由于此人是清朝明医, 再加上后来的吴鞠通加了一点油就出现温病派, 写了温病条辨一书, 也因此二人从此误导了中国人研习中医的领域

汉唐中医节选

内容来源于汉唐中医, 以及我的读后感总结行成

AIDS

我在临床上遇到的AIDS病人, 在未曾服用西药之前, 其所呈现出的症状都是阳明热症, 按照中医里论, 阳明无死症的原则, 我可以断定AIDS是无害的, 绝对不会致人于死的, 其结果与Dr Peter Duesberg 不谋而合, 是非常好治的一种疾病, 可是一旦服用AZT , DDI , DDC或鸡尾酒疗法的药物之后, 病人的病情立刻转变为厥阴症, 而此症多是死症, 所以我也敢说病人是死于药物的副作用, 并非死于AIDS的

总结: AIDS症状为阳明热症, 按照中医里论, 阳明无死症



如何保养自己

倪师经典比喻: 如同吃完饭要清洗碗快一样重要, 每天固定勤擦拭, 必然不生病

  1. 每天早上起床时, 足尚未踏地, 就先服用昨晚睡前准备好的六味地黄丸30粒, 并且使用事先备好的凉开水里面加一点盐
    1. 六味地黄丸号是相传两千年的丸剂, 但是一般世面上卖的都是用六味药等量来制作, 这是不正确的
  2. 每天晚睡前服用一些疏肝解毒的中药
    1. 我们接触的环境已经受到极高的污染
    2. 食物的种类太多, 很难去分辨其是否有受到污染
    3. 外面餐厅用膳, 也不知道他们加入多少味精或食物已经储存多久
  3. 中医认为大肠与肺为表里, 是故大肠有燥矢屯积, 则浊气必然反逆入肺
    1. 不但造成口臭
    2. 更且使皮肤变坏且粗造
    3. 长期服用六味地黄丸或是一些疏肝解毒中药的人是不会便秘的
  4. 请买些猪肥肉回来, 自己榨取些猪油来做饭菜
  5. 饥饿与过饱
    1. 就是时常保持一点点饿的状态远比时常胃肠胀满的状况要健康好多, 而且也不容易变老, 又长寿, 又不生病, 所以如果是上班足应该一天两餐就够了

总结:

  • 每天早上吃六味地黄丸, 水中加入少量盐(青盐或者海盐, 盐味咸, 咸味入肾)这是为了养肾;丸药,药缓力专
  • 每天晚上吃点疏肝解毒的药品, 帮助肝脏解毒; 现代人生活压力大, 疏肝解郁可以让身体舒适,防止长久肝气郁结导致的疾病
  • 少吃沙拉油, 会导致心血管疾病
  • 我国吃猪油有上千年的历史验证, 已经造就出许多百岁人瑞. 有条件吃猪油
  • 吃饭不要吃过饱,7~8分饱. 给身体减压, 减轻脏腑的负担


药罐子的中国人

  1. 高血压的药物控制
    1. 几乎所有降血压的药都是利尿剂, 会让你的肾功能下降, 而中医认为肾主骨, 其华在发, 开窍在耳, 司记忆, 主先天(寿命多长) , 这就是现在人们会得到骨质疏松症, 老人痴呆症, 掉头发, 听力减退, 寿命变短的原因, 性功能同时下降
    2. 更且因为西药都是属酸性, 而酸性会破坏血管壁组织, 容易造成血管破裂, 也就是说服用高血压药物的病患将更容易得到中风与心脏病, 不吃的病患反而不会得到这类疾病
  2. 血糖过高的病人
    1. 所有的西药都伤害肾脏, 因此服用降血糖的药越多就越容易得到心脏病.
    2. 中医认为只要肝脏好就不会有眼疾, 根本与高血糖无关, 由于服用西药或注射胰岛素会造成肝脏的损坏因此才会得到青光眼
    3. 血糖根本没有消失, 多余的血糖就开始屯积在你的脚部, 就好像糖积在杯底一样, 其结果就是双足溃烂, 你等着截肢吧
    4. 中药都是纯碱性, 在纯碱性的环境里是没有细菌与病毒的, 我们根本没有任何中药会让血糖上升的
  3. 胆固醇过高的人
    1. 我在临床上只是让病人停止吃零食三星期, 病人的胆固醇就降下200以上
  4. 三酸甘油脂过高的人
    1. 此类问题是因为吃油炸食物过多及过胖造成的
    2. 我开一些清肝的药给病人,三酸甘油脂就下降了, 因为肝是心之母, 一但肝脏代谢毒素功能下降, 自然有不干净的血进入心脏, 对心脏造成威胁, 从而引发心脏病
  5. 吃西方多种滋补营养药物的人---这类人是最无知而且愚昧的蠢蛋
    1. 从未有任何证据显示钙片可以帮助增强人体骨骼, 反而是吃多钙片会使骨骼更脆更容易造成骨质疏松症, 而且副作用是造成肾结石,而维他命C片更烂
    2. 妇女们服用它的目的是想皮肤美白, 但是结果是多服维他命C片会支援乳癌细胞的成长
    3. 我们应该多食用天然食物, 有机蔬果绝对是正确的
    4. 要美白多喝自然的橘子汁最好
  6. 服用阿斯匹林的人
    1. 有许多证据显示每天一片阿斯匹林你会有超过85%的机会得到胰脏癌, 因为它是一种强酸剂. 酸性对人体破坏最大
    2. 碱性体质最好, 不但长寿而且完全没有病痛
    3. 要成为碱性体质非常简单, 立刻停止喝咖啡不吃甜食, 拒绝冰淇淋可乐, 完全断绝糖果饼干类的零食, 多喝茶, 多吃自然有机蔬果
    4. 请记住在碱的环境里, 是没有病毒与细菌及癌细胞的
  7. 胃酸过高反逆食道的人
    1. 人工糖的颗粒极小, 会如同维他命片一样的喂食细菌及滤过性病毒, 它们吃了之后就排出酸性的粪便, 这就是胃酸的来源
  8. 服用女性贺尔蒙的太太们要注意
    1. 常被西医告知要服用贺尔蒙替代品, 否则会得到骨质疏松症, 这些胡说八道的话不知吓傻了多少无知的妇女
    2. 多吃则会得到骨质疏松症及心脏病乳癌等疾病
    3. 我从未听说有女人因为更年期不适而死的, 但是我却见到许多女人因为吃女性贺尔蒙而死于心脏病或乳癌的
  9. 乳房稍有硬块就急着做切片的无知妇女
  10. 喜欢吃止痛药的人要注意
    1. 目前市面上所有的止痛药都会伤到肝脏肾脏与心脏的
    2. 只要肝心肾一受伤, 立刻就会便秘睡不好
    3. 日子久了就开始掉发, 眼睛视力变差, 体力衰退, 容易抽筋
    4. 西药营养剂维他命吃多了都会掉发伤肝的(维他命A更是头号肝脏杀手) , 更何况止痛药
    5. 现在最新的医学研究已经证明了吃止痛药会有中风的危险, 许多刚生完小孩的妇女因为吃止痛药而得到中风
  11. 常服抗生素的人, 妇女必然小便失禁,男人必然性无能及心脏受损


一些Common Sense

  1. 健康的人,如果不运动,就会生病。由此可之,生病的人不多运动,结果就是死
  2. 同气相求,病人绝对不可以孤单独处。当病人住到医院时,必然是跟同样类型的病人住在一起,每天都跟许多无助的眼神对看,想想病人怎么会好呢? 如果是跟家人与亲朋好友住在一起,大家**每天都嘻嘻哈哈的过日子**,许多健康的人在一起,其中只有一个生病的人,其开心气氛当然会影响到病人,让病人常常都忘记自己是病人时,病情就已经好转了
  3. 找一位住在你家附近的有良心的医师。找到一位好心医师,很关心病人的医师最重要,不需要千里迢迢的找名医治疗,因为这位医师住在你家附近,随时可以提供最关心最贴心你的服务,这点很重要


北派传统中医判断身体是否健康

  1. 一觉到天亮
  2. 胃口正常
  3. 每天早上起床第一件事情就是大便上厕所
  4. 一天五到七次小便,小便的量大, 颜色要淡黄
  5. 永远都是头面身体冷, 手脚温热
  6. 男人女人都有, 叫做早上的阳反应, 女人早上起来的时候, 乳房很敏感, 男人阴茎会勃起

所以你们吃了中药以后, 这六个症状都出来了,代表你的病完全好了. 如果你们吃了中药以后, 本来脚是冷的, 后来变成冰的,就中药无效的明证, 那你们不要再吃中药了,赶快另请高明



女孩子月经期间感冒

还有要记得女孩子在月经的时候得到感冒, 所有的处方都不能用,什么麻黄汤, 桂枝汤, 葛根汤都不能用, 只能用一剂药, 叫小柴胡汤. 因为月经来的时候, 月经往下走, 走到子宫的时候, 正好得到感冒, 感冒的病毒从你外表直接进到子宫,根本不停留于肌表, 这时候桂枝麻黄发不到, 只有用和解的方法, 小柴胡汤一剂下去, 感冒的滤过性病毒跟着你的月经小便一起排出去



感冒辩证诊治

我们有大青龙, 小青龙,一个是寒咳, 一个是热咳. 感冒以后咳了好多黄痰出来, 胃口很好, 就用麻杏甘石汤, 麻黄, 杏仁, 石膏, 炙甘草四味药. 如果是咳嗽黄痰, 胃口不好, 外面发冷, 代表肺也得到了, 表症还有, 黄痰代表肺里面是热的, 叫做里热表寒, 病人发冷, 发烧, 头痛, 咳嗽, 这时麻黄汤不适合, 要用麻杏甘石汤, 加上桂枝, 生姜, 大枣, 七味药合在一起, 叫大青龙. 大青龙汤治表寒里热. 还有一种感冒的时候咳嗽, 但咳的是清痰, 不口渴, 全身痛, 叫里寒表寒, 痰是白的, 清的, 这时候要服小青龙. 所以并不是说大青龙比较强, 小青龙比较弱, 小青龙是表寒里寒时用, 大青龙是表寒里热时用. 里热里寒很简单, 看病人口渴不口渴, 口渴就是热, 不口渴就是寒. 痰是黄色的就是热, 痰是白色的就是寒.如果你的病进入阳明的时候, 有阳明经热和腑热两种情形发生. 经热就是全身发热, 阳明无寒症, 全是热症. 这时候有两种, 一种是便秘, 一种是没有便秘. 只有发热, 没有便秘, 就用白虎汤. 再者阳明有腑症, 如果便秘, 第一种叫大黄甘草汤, 大黄甘草汤是在胃的下方有屯积东西的时候, 便秘, 肚子痛, 病人呈现的症状是朝食暮吐, 早上吃进的烧饼油条, 到了傍晚吐出来还是烧饼油条, 就代表说这个东西堵在胃里面, 这时候大黄甘草两味药就可以治好. 如果是堵在十二指肠的时候, 我们就用调味承气汤, 就是炙甘草, 大黄, 芒硝, 堵在十二指肠, 病人会便秘, 恶心, 排气很多, 肚子中间的地方会痛. 再来是小承气(厚朴, 枳实, 大黄), 是堵在小肠, 我现在讲的病人小便都是黄的, 因为堵在小肠, 大肠里面没有东西, 所以不断的放屁, 只有放屁, 没有大便出来, 就用小承气把小肠清乾净. 进入大承气, 就是堵在大肠里面, 此时会连屁都不放出一个, 因为大肠里面都是大便, 就用厚朴, 枳实, 大黄, 再加上芒硝, 就便成了大承气. 芒硝能够攻坚, 把干燥的大便都打散排出来

小朋友一感冒, 喉咙痛, 葛根汤症

反复读



金枪不倒? 厦门男子勃起2周竟是肺癌作祟.

一个罕见的病例,提醒男性朋友要小心。大陆厦门一位32岁的健壮工人,因为阴茎连续勃起两周疼痛不堪而就医,最后发现是肺癌末期,住院40天后就离开人世。(阴茎部位是肝经所络,属于阴,强直就是实症,二者合并在一起,就是所谓阴实,金匮有云:阴实者死。 )

男性朋友要注意啰!阴茎异常勃起持续时间过长,可别沾沾自喜,小心恶性疾病上身。厦门一名32岁的码头工人,因为连续勃起两周,在小诊所找不出病因,最后因疼痛不堪,到大医院挂急诊,一检查才发现原来是肺癌惹祸。(第一: 西医发现又如何呢?只会死得更快而已,第二: 用中医的五行学说做诊断,就可以了解是金克木,金就是肺。也就是说不做检查就可以知道。 )

肺癌判断

  • 第一: 病人于寅时必自动醒来,无法安睡
  • 第二: 背后第三椎下有压痛点
  • 第三: 耳中肺点必有压痛,而且在同侧,等等这些都是经方家用来确诊是否有肺癌的问题

c158db09d408f06a847b13c1d45e96f

经方家的保健食品

醒世篇

转载于一般讨论论文区-醒世篇

我写此篇的目的, 是希望有缘读到此篇的读者, 一旦在面临生死决择时, 有多一个想法考虑, 如果因为此篇实际临床案例里的经验而救人一命, 也不枉我一番救世之心, 我将我所亲身经历的医案记录下来, 包含我内心的真实看法, 以及我面临病人为做生死决择时的天人交战的心情. 隐瞒病人名字是尊重个人隐私权, 事实上我的这些病人因为曾经都面对过一次死亡, 现在能够存活下来,他们根本已经不在乎任何事了, 他们连命都敢放在我的手中, 我怎么做或公布姓名他们也决不会反对, 但是尊重隐私权不单是法律更是我的医德, 我将隐瞒病人姓名, 使用代名, 希望读者理解 .

任何有志学习中医的青年才俊请记得, 要成为真正优秀中医不难, 必须精研黄帝内经做为诊断学及病理学的基础, 熟谙伤寒论及金匮的方义, 深研难经中的针灸理论, 多看明朝杨继洲的针灸大成, 犹记今年初收到一本中医学杂志来自美国新英格兰中医学校,它的封面就是一支针的针柄上放置艾草燃烧, 这是传统中医的大忌, 读过针灸大成都知道里面有一篇禁针歌诀写到---针而勿灸灸勿针, 针经为此常叮咛, 庸医针灸一起施, 徒施患者炮烙刑. 自古以来针灸并施一直是禁忌, 这杂志的封面却放上此自以为高明又花俏却不知道让明眼的传统中医一看就知此学校误导美国人的研究中医的心意, 这些人自称为传统中医, 实际上是既非正统中医又非正统西医出身, 嘴上又号称是传统中医, 既误了他人子弟又误导中医学入岐途, 这不是害人是什么? 我一定要告诉群众真正传统中医是什么, 以免大众被误导, 综观我国二十四史,文死谏, 武死战, 古代名臣皆敢冒着被皇帝杀头的生命危险, 直言相劝,务必使皇帝改变想法, 其结果都受到皇帝褒扬的, 我不再乎个人荣辱, 我一定要告诉世界上的无辜人民实话, 真正传统优秀的中医, 只用针与灸及中药的丸,散,膏,丹, 绝对没有用什么电针,雷射针灸,注射针灸之类, 有些更恶劣的中医为求达到效果, 还在中药里加入西药的安眠药及类固醇, 这些都是一些看不好病的中医用来蒙蔽世人的骗术, 害了病人还不算, 甚至还在教学时又误人子弟,真是可悲又可叹.

我写此篇的目的是要解开世人对中医的一大疑问, 就是到底正统优质中医可以治病治到什么程度? 我给大家下个定义,真正的正统中医,不但可以掌握一开始从诊断到治疗到自然恢复健康的全部过程, 并且可以知道如何预防同样的病再次发生.你如果是开业中医, 当你读到这篇时, 照理说你应该很兴奋有如此的医术可以救许多本来不用死的病人才对, 我相信你也可以做到而且甚至比我高明, 只是苦无发表机会, 但是你如果感觉是相反的, 变得很生气, 还要想办法打击我, 是没用的, 因为你根本不是人, 是连乌鸦都不如的蠢蛋, 我为什么如此说呢? 请想想世上有多少人受难于病痛中, 他们本来可以不用死的, 但是因为你从中阻扰, 你无法做到我能做到的, 于是病人冤死在你手上, 你可能不心疼, 因为他只是你的客人, 如果他是你的亲人如父母兄弟妻子等, 也因为你妒忌我而不转诊, 结果也冤死在不应该死的病上, 你仍不知悔改, 仍旧气我, 不气你自己不争气, 不好好多读书加强自己的能力, 不怪自己是学到用时方恨少, 连乌鸦都知道反哺之恩,你都不会, 居然会为了你自己的面子着想, 而眼睁睁的看着你的亲人含冤死去, ,你说你还是人吗?可能你是中医学校的教授, 你的口袋中仍然放着西医的降血压药与降血糖药, 而你口中却在说哪些中药可以降血压哪些可以降血糖,你如果以为你的医术不行别人不知道, 你完全错了, 病人吃了你的药心理很清楚的, 只是没有说出来, 他们只是因为不了解中医到底能够做多少, 有一天他们会知道的, 因为我会不断的写案例, 让世人知道, 总有一日大家会了解的.

我时常因为病人来访, 而中断撰写, 请读者见谅, 我实在忙坏了. 最近我加快速度要完成英文版的伤寒论及金匮, 我尽量赶, 只要ㄧ有时间我就会继续写完它的.

总结:

  • 必须精研黄帝内经做为诊断学及病理学的基础
  • 熟谙伤寒论及金匮的方义
  • 深研难经中的针灸理论.多看明朝杨继洲的针灸大成


禽流感与流感(民众不用惊慌.)

本文转载于 汉唐中医-流行性疾病讨论区-禽流感与流感(10/17/2005)

由于感冒是日常最普遍的疾病,所以单独罗列出来,作为参考

第一:桂枝汤症---病人出现有汗,怕风吹,头痛,有点发烧,肌肉有些酸痛时,就可以服用它,如有咳嗽气喘时加些厚朴杏仁就可以了.

第二:麻黄汤症---病人出现极度怕冷,发烧,身体疼痛,完全无汗时,请立刻服用它.

第三:葛根汤症---中医的寒温之争在此,温病派认为伤寒家没有治温病方,所以只有他们的寒凉药物才可以治温病,这是因为他们没有读通伤寒论导致的,而葛根汤就是经方中治疗温病的处方,病人出现项强,头痛,发热,有汗或是无汗都可以,喉咙痛时,就可以立刻服用它,尤其小孩子几乎都是葛根汤症,因为小孩好动成性,在身体出汗发热时得到的感冒,因此就出现病得自温热,这就是葛根汤症了.

第四: 麻杏甘石汤症---病人咳嗽不止,痰出黄粘,胃口尚好时,可以吃此方.

第五:大青龙汤症---病人出现怕冷,无汗,发烧,咳嗽重,咳出黄痰,身体痛,口渴重,喜喝冷水,没有胃口时,就吃大青龙汤,这就是SARS与禽流感的主要症状.

第六: 小青龙汤症---病人有怕冷,无汗,发烧,咳嗽重,出白痰,无渴,身体痛,没有胃口时,就可以用它了.

第七:小柴胡汤症---病人忽冷忽热,加上呕心,胸胁苦满时,请服用此方,还有女子月经期来时正好得到感冒,就喝此药,如有咳嗽气喘时加些厚朴杏仁就可以了.

第八: 大柴胡汤症---如果病人出现便秘,又有忽冷忽热,胸胁苦满,兼有发烧此时请用大柴胡汤.



原文如下:

禽流感与流感(10/17/2005)

    这波禽流感已经被西药厂利用来威胁民众的生命,其目的就是想赚大钱,但是使用的手段非常之恶劣,吃像非常难看,我有必要跟民众说清楚讲明白,以解除民众的忧心与疑虑,请大家安心愉快的过日子,我先归类西药厂最惯用的手段给大家看.

   首先他们在事前先使用毫无根据的数据,夸大死亡人数,其目的第一是要民众开始害怕,如果卫生署不理会西药厂时,民众就会怪政府,然后政府只好向西药厂屈服,去购买根本没用的疫苗与抗病毒的药,第二是当感染期过了,如果很少人死于流感,他们就说是疫苗有效,是抗病毒药物有效,如果还是死很多人,他们就会说是执行不当或是有别的感染源或是新变种病毒造成疫苗无效的,所以总之与他们是无关,反正好坏都是他们在自导自演中,民众是永远被隐瞒在鼓里,而他们也知道民众在事后是不会关心的,大家只在乎自己没有死,这就是他们最了解的人性弱点,因此他们一直在骗人而无人去揭穿他们.这是个世纪大骗局,目前正在上演中,中医认为百病风之始,感冒当然是问题,但是中医老早在二千前年以前已经将此问题解决了,但是中国人却不知道,居然还听信外国人的骗局,真是祸国殃民的大骗局. 这些专门以威胁手段来欺骗海峡两岸中国人的西药厂,都将名列我的黑名单中,他们将是我第一个要消灭的目标,我看看谁敢威胁我们中国人,非修理他们不可,哪天这些人得到时癌症落到我的手上,他们就知道厉害了,这次简直把我气炸了,赶快吃点中药消消火气去.

   亲爱的海峡两岸台湾与大陆民众们,大家不要惊慌,这一波的流行性感冒因为西药厂的利益介入,已经造成民众的恐慌,由于民众是无知与无辜的,所以有必要替民众解决这种疑虑恐慌,我国自古以来就有流感,汉朝医圣张仲景就是因为流感造成整个张氏家族损失三分之二的人口,因而他辞去南阳太守的职务,发奋图强研究医学,于是写下了名垂千古的伤寒杂病论就是经方,我使用经方至今从感冒到癌症,一一好转,尤其是治感冒时常都是一剂就好转,千年以来经方一直都是如此之快,孰知今日出现个西药厂,它们不断的制造疾病,不断的为打击人体抵抗力而不遗余力,因为只有当人体的抵抗力变差后才会生病,才会容易感冒,这样他们才有钱赚,他们希望全世界的人通通都生病,他们才高兴,所以他们一直鼓励西医使用各种抗生素与止痛药,打各种害人的疫苗,建议民众多吃害人的维他命,于是多年以后民众身体就越来越差了,不但很容易得到感冒,因为民众的免疫系统已经被西药破坏尽了,更且会只因为得到小感冒就出人命,这是个天大的笑话,为了全民福祉着想,我誓言一定要终结西药厂,让我们的下一代生活的健康快乐,永远免除来自疾病的威胁,现代人类最严重的癌症是来自西药厂不是来自人体,不清除它,民众将永远没有平安的日子可过,永远生活在这阴影威胁之下的.

   现在由汉唐中医为民众解决这问题吧,民众只要记住以下很简单的辨症法,然后依照这法则选用药物,而这些药物都是台湾与中国大陆的国家卫生署自己核准的药物,但是因为他们都是西医所以他们不会用,因此这药是由不懂得使用的人来核准的,现在请大家一起跟我进入经方的世界.

 第一:桂枝汤症---病人出现有汗,怕风吹,头痛,有点发烧,肌肉有些酸痛时,就可以服用它,如有咳嗽气喘时加些厚朴杏仁就可以了.

 第二:麻黄汤症---病人出现极度怕冷,发烧,身体疼痛,完全无汗时,请立刻服用它.

 第三:葛根汤症---中医的寒温之争在此,温病派认为伤寒家没有治温病方,所以只有他们的寒凉药物才可以治温病,这是因为他们没有读通伤寒论导致的,而葛根汤就是经方中治疗温病的处方,病人出现项强,头痛,发热,有汗(更正一点:或是无汗都可以,我忽略掉这一点了),喉咙痛时,就可以立刻服用它,尤其小孩子几乎都是葛根汤症,因为小孩好动成性,在身体出汗发热时得到的感冒,因此就出现病得自温热,这就是葛根汤症了.

 第四: 麻杏甘石汤症---病人咳嗽不止,痰出黄粘,胃口尚好时,可以吃此方.

 第五:大青龙汤症---病人出现怕冷,无汗,发烧,咳嗽重,咳出黄痰,身体痛,口渴重,喜喝冷水,没有胃口时,就吃大青龙汤,这就是

                               SARS与禽流感的主要症状.

 第六: 小青龙汤症---病人有怕冷,无汗,发烧,咳嗽重,出白痰,无渴,身体痛,没有胃口时,就可以用它了.

 第七:小柴胡汤症---病人忽冷忽热,加上呕心,胸胁苦满时,请服用此方,还有女子月经期来时正好得到感冒,就喝此药,如有咳嗽气喘时加些厚朴杏仁就可以了.

 第八: 大柴胡汤症---如果病人出现便秘,又有忽冷忽热,胸胁苦满时,兼有发烧此时请用大柴胡汤.

   以上八个经方是我国使用近二千年之有效处方治疗感冒,处方至今从未变更过,时常都是一剂知,二剂已的,民众只需按照上面所陈述的症状,就可以自行判定你自己或是亲人需要吃什么药了,保证当天就好了,不需要经过医师处方,反正他们也不会用,你去问他们也是白问,现在只能自求多福了,因为你们的卫生署不知道他们自己已经核准的科学中药如此之好,所以他们不知道如何教导民众,因此只好由我来代劳了,如果民众按照我的指示吃药仍然没好,请传真给我, 1 -321-454-9974 ,我一定替你治疗的,感冒会死人吗??? 真是让人笑掉大牙的事.传真时请说明你的症状,发烧?体痛?胃口?有无口渴?喜欢喝热水还是冷水?有无出汗?怕冷?怕热?有无咳嗽?咳出清痰还是黄痰?有无便秘? 读者只要说明清楚发病症状及病人体格大小等资料,并且请附上回传号码,我将立刻回传处方给你,你们自行去中药行买药就可以了,完全免费服务,我保证将你救回来的,但是你如果是因为笨,因注射疫苗之后才发生的感冒,恕我不治,因为你实在太笨了,少些笨蛋,政府就少些开销的.

  如何证明上面的中药绝对有用呢? 很简单,读者请买一些上面我说的药与克流感西药,然后去公园或是养鸡场,将中药与西药洒在地上,读者就会看到这些禽类将选择中药吃,绝对没有一只笨鸡或是笨鸟会去选择西药克流感吃的,这就是Mother Nature,就好像是当你家的猫或狗有病时,它们会去吃草,自己去找寻能够治病的药物,绝对不会去吃西药的,除非动物医师硬注射西药入体内,否则它们绝对不吃西药的,读者也可以将这两种药放在餐桌上过一夜,第二天早上你就会发现你家的蟑螂只吃中药,没有一只笨蟑螂会去吃克流感的,这就是蟑螂可以生存在地球十亿年以上而不被毁灭的真正原因,因为它们比人类聪明太多了,连他们都知道如何做选择.

  给疾病管制局的建议,请你们去购买桂枝汤与大青龙汤,将它们分开做两堆,置于户外,当你们看到有鸟类来吃大青龙汤时,这些就是被感染到禽流感的鸟,去吃桂枝汤的鸟就是没有得到禽流感的,此法也可以用在养鸡场,禽类吃了大青龙汤之后会排粪便出来,此时你们就可以去取些样本来化验,就知道我对否? 根本不需要赶尽杀绝的,这是削足适履的行为.

  大青龙汤处方如下: 麻黄三钱杏仁五钱石膏八钱炙甘草五钱桂枝五钱生姜二片红枣十二枚打碎(有做过心脏手术的病人不可以用麻黄,请改用荆芥五钱,防风三钱,浮萍三钱来取代麻黄.)

    用六碗水大火快煮成二碗,汤成后立刻关火,待温时空腹喝第一碗,如果一小时内汗出烧退咳止,就不须要喝第二碗,如果三小时内无出汗,就再喝第二碗,汗出时就不用再喝了,当身体出汗时须待静室中,等到出汗自然停止后,再出房间,切不可以出汗时吹到风,如此病毒将无法排尽,还会再发的. 成人每次一碗,小孩每次半碗,婴儿每次四分之一碗. 记住一旦汗出,就不用再喝第二碗了,因为已经好转了,再喝恐怕伤到津液. 一般病人在服药后第二天中午时会很饿,胃口大开,这表示正常了.

  一般市面上的科学中药成药,大家也可以去买仙丰GMP厂制造的很好用,这点卫生署还做的不错. 如果有民众真正得到了禽流感,西药是肯定失效的,当此生死存亡之时如果医师的态度是宁可眼睁睁的看到病人死去,也不给病人一丝生存机会不让病人服用经方时,你告诉卫生署是没用的,他们官官相护,所以请知道的人写传真给我,我统一集中起来一起骂,并且将他们打入恶质医师的行列,我必将让这些恶质医师遗臭万年,永世不得翻身,反正真正恶医师都知道我是谁,我也不担心他们怎么对付我,因为我比他们还会治病,之所以会如此是因为他们一直在专门研究如何吓病人,这是他们专业所在,而我却是一直在研究如何治疗疾病,而这却是我的专业所在,所以只有我能威胁他们,他们无法威胁我的,他们生病时也只有我知道如何救他们,读者说他们遇到我时该怎么办呢?早就说过了,我是鬼见愁,只有心里有鬼的才会真正愁我,真有佛心之人怎会愁我呢?

   此篇论文欢迎大家引用,济世救人是我辈职责所在,请大家告诉大家.但是要注明出处,谢谢.

美国汉唐中医倪海厦撰写于佛州

  

以下是经典方剂与现代中成药的对应关系:没有经过验证

  • 桂枝汤: 现代中成药: 桂枝颗粒、桂枝合剂 功效: 解肌发表,调和营卫,用于外感风寒表虚证。

  • 麻黄汤: 现代中成药: 麻黄碱片、感冒通片 功效: 发汗解表,宣肺平喘,用于外感风寒所致的咳嗽、气喘。

  • 葛根汤: 现代中成药: 葛根解表颗粒、葛根汤颗粒 功效: 解肌退热,生津,用于外感风寒、项背强痛、无汗等症。

  • 麻杏甘石汤: 现代中成药: 麻杏甘石合剂、清肺抑火丸 功效: 宣肺泄热,止咳平喘,用于肺热咳嗽、喘息等症。

  • 大青龙汤: 现代中成药: 大青龙颗粒 功效: 发汗解表,清热除烦,用于外感风寒、内有郁热的症状。

  • 小青龙汤: 现代中成药: 小青龙颗粒、小青龙口服液 功效: 解表散寒,温肺化饮,用于外感风寒,内有水饮的咳嗽、喘息。

  • 小柴胡汤: 现代中成药: 小柴胡颗粒、小柴胡口服液 功效: 和解表里,用于少阳证,如寒热往来、胸胁苦满、心烦喜呕等。

  • 大柴胡汤: 现代中成药: 大柴胡颗粒 功效: 和解少阳,内泻热结,用于少阳阳明合病,或肝胆热实,胃肠积滞等。

MySQL服务器常用操作

创建一个数据库

CREATE DATABASE nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

创建用户并授权

CREATE USER 'nextcloud_user'@'%' IDENTIFIED BY 'your_password';
GRANT ALL PRIVILEGES ON nextcloud.* TO 'nextcloud_user'@'%';
FLUSH PRIVILEGES;

注意事项

  1. 性能影响
    • utf8mb4_bin 因为逐字符比较和区分大小写,性能可能略低于 utf8mb4_general_ci
    • 选择排序规则时需要在性能和功能之间权衡。
  2. 文件系统的影响 即使数据库支持大小写敏感排序,文件系统(如 ext4NTFS)可能不区分大小写,这可能导致文件名冲突。

总结

  • 默认选择: utf8mb4_general_ci,除非明确需要区分大小写。
  • 如果需要大小写敏感,使用 utf8mb4_bin
  • 区分大小写的需求较为少见,但在文件名敏感的场景中可能是必要的。

MySQL-常用语句记录

按照子表的id升序查询出子表字段去重并且逗号隔开

GROUP_CONCAT(DISTINCT column_name ORDER BY column_name SEPARATOR ',')

举例

  • b.xxx 的值不区分大小写 select a.*, GROUP_CONCAT(DISTINCT b.xxx ORDER BY b.id ASC SEPARATOR ',') as bxxx from order a left join detail b a.id= b.o_id group by a.id

  • b.xxx的值区分大小写 select a.*, GROUP_CONCAT(DISTINCT BINARY b.xxx ORDER BY b.id ASC SEPARATOR ',') as bxxx from order a left join detail b a.id= b.o_id group by a.id


count(1) count(*) 和 count(name)的区别

count(1)和count(*)

在 MySQL 中,COUNT(*) 和 COUNT(1) 通常是等价的,因为它们都用来计算表中的行数,并且在大多数情况下,它们的性能和结果是一样的,且性能差异微乎其微

SELECT COUNT(*) FROM table;
SELECT COUNT(1) FROM table;

count(name)

  • 功能: 计算 name 列中非 NULL 的行数。如果 name 列包含 NULL 值,则这些 NULL 值不会被计入。
  • 性能: 由于需要考虑 name 列的 NULL 值,因此在某些情况下,性能可能会略逊色于 COUNT(*),但差别通常不大。

总结: 在大多数情况下,COUNT() 和 COUNT(1) 在 MySQL 中表现一致,你可以使用它们中的任何一个来计算行数。不过,**COUNT() 通常是更直观和推荐的选择**。


数据同步差异排查

场景: 从A库同步一张表A1到B库的B1, A表总共30001,B表30000条.找出没有同步过去的那一条

方案是查询出A表的所有ID,然后把所有id UNION ALL,在进行两个表的关联

SELECT ids.id
FROM (
SELECT  1 as id
UNION ALL SELECT  43581
UNION ALL SELECT  43583
.... 假设中间还有n条
UNION ALL SELECT  43607
UNION ALL SELECT  43609
) AS ids
left join shop_new ds on ds.id = ids.id
where ds.id is null
;

通过叶子结点找到上级树

返回的结果包含blood_id = 23的数据行

用途是, 通过叶子节点找所有上级,然后封装成链表的形式,代码相对复杂.所以可以换一个思路,先通过以下SQL找到上级树.然后从parent_id集合中排除blood_id集合,得到first_prent_id集合,表示当前节点所在上级树的第一层节点的id集合

然后遍历first_prent_id集合,通过Java查询以下的SQL的结果集中, 父id为**first_prent_id.get(i)**的数据,则取到了当前节点的下一级节点列表.

WITH RECURSIVE ancestors AS (
    SELECT id,blood_id,parent_id FROM blood_tree WHERE blood_id = 23
    UNION 
    SELECT p.id,p.blood_id,p.parent_id FROM blood_tree p
    JOIN ancestors a ON p.blood_id = a.parent_id
)
select * from ancestors;

解释:

  • CTE 表示递归表达式

  • WITH RECURSIVE ancestors AS (...) 定义了一个名为 ancestors(可以自定义) 的递归 CTE

  • 表达的意思是:

    • 以blood_id = 23的数据行row1为参考,查询所有blood_id=row1.parent_id的数据行rowM
    • 然后继续对rowM的每一行数据, 进行递归,查询blood_id=rowM.parent_id的所有数据行
    • 最后将这些数据UNION在一起.得到关于某个叶子节点的上级树

完整的Java代码如下:

    private List<BloodNodeResVo> getParentBloods(Integer bloodId) {
        List<BloodNodeResVo> treeList = new ArrayList<>();
        List<PtBloodTree> bloodTreeList = ptBloodTreeService.getParentTreeByBloodId(bloodId);
        if (CollectionUtils.isEmpty(bloodTreeList)) {
            return treeList;
        }
        //包括每一层的父节点
        Set<Integer> parentIds = bloodTreeList.stream().map(PtBloodTree::getParentId).collect(Collectors.toSet());
        //包括每一层的子节点
        Set<Integer> bloodIds = bloodTreeList.stream().map(PtBloodTree::getBloodId).collect(Collectors.toSet());
        //所有节点.用于后期批量一次性查SQL.
        Set<Integer> allBloodIds = new HashSet<>();
        allBloodIds.addAll(parentIds);
        allBloodIds.addAll(bloodIds);
        //父节点中移除所有的叶子节点.因为第一层的节点不再有父节点.所以第一层的节点也就不存在于子节点中
        parentIds.removeAll(bloodIds);
        List<PtBloodIdx> ptBloodIdxes = listByIds(allBloodIds);
        Map<Integer, PtBloodIdx> bloodIdxMap = Optional.ofNullable(ptBloodIdxes).orElse(new ArrayList<>()).stream().collect(Collectors.toMap(PtBloodIdx::getId, Function.identity(), (k1, k2) -> k1));
        //遍历第一层的节点
        for (Integer parentId : parentIds) {
            PtBloodIdx ptBloodIdx = bloodIdxMap.get(parentId);
            BloodNodeResVo bloodNodeResVo = new BloodNodeResVo();
            bloodNodeResVo.setBloodId(ptBloodIdx.getId());
            bloodNodeResVo.setBloodName(ptBloodIdx.getBloodName());
            bloodNodeResVo.setNumber(1);
            treeList.add(bloodNodeResVo);
            //获取子节点
            getChild(bloodTreeList, bloodNodeResVo, bloodIdxMap);
        }
        return treeList;
    }

    void getChild(List<PtBloodTree> bloodTreeList, BloodNodeResVo parent, Map<Integer, PtBloodIdx> bloodIdxMap) {
        bloodTreeList.stream().filter(p -> p.getParentId().equals(parent.getBloodId())).forEach(p -> {
            PtBloodIdx bloodIdx = bloodIdxMap.get(p.getBloodId());
            BloodNodeResVo child = new BloodNodeResVo();
            child.setBloodId(bloodIdx.getId());
            child.setBloodName(bloodIdx.getBloodName());
            parent.getChilds().add(child);
            //递归调用子节点的子节点
            getChild(bloodTreeList, child, bloodIdxMap);
        });
    }

通过父节点找到所有子下级树

返回的结果包含blood_id = 23的数据行

WITH RECURSIVE descendants AS (
    SELECT blood_id,parent_id,blood_level FROM blood_tree WHERE blood_id = 23
    UNION 
    SELECT p.blood_id,p.parent_id,p.blood_level FROM blood_tree p
    JOIN descendants a ON p.parent_id = a.blood_id
)
select * from descendants;

Java基础-易错点

List.remove

注意有两个重载方法remove(int)和remove(Object), 很容易混淆

案例:

Map<String, Integer> unionMap = new HashMap<>();
for (int i = 0; i < insertList.size(); i++) {
    CstGoods cstGoods = insertList.get(i);
    String unionKey = String.join("_", cstGoods.getSpCode(), cstGoods.getCostType(), String.valueOf(cstGoods.getCostScene()), cstGoods.getBgDate().toString(), cstGoods.getEdDate().toString());
    if (unionMap.containsKey(unionKey)) {
        unionMap.put(unionKey, i);
        //特别注意这一行
        Integer index = unionMap.get(unionKey);
        insertList.remove(index);
        i--;
    } else {
        unionMap.put(unionKey, i);
    }
}

本意是移除已经存在的列. 但是问题就出在list.remove. 如果remove方法的入参传入的是包装类型,自然就会执行remove(Object), 那么结果肯定是移除不了这个重复对象. 所以需要将Integer index = unionMap.get(unionKey); 改为 int index = unionMap.get(unionKey);.要不然会导致死循环

修正后的代码

Map<String, Integer> unionMap = new HashMap<>();
for (int i = 0; i < insertList.size(); i++) {
    CstGoods cstGoods = insertList.get(i);
    String unionKey = String.join("_", cstGoods.getSpCode(), cstGoods.getCostType(), String.valueOf(cstGoods.getCostScene()), cstGoods.getBgDate().toString(), cstGoods.getEdDate().toString());
    if (unionMap.containsKey(unionKey)) {
        unionMap.put(unionKey, i);
        //特别注意这一行
        int index = unionMap.get(unionKey);
        insertList.remove(index);
        i--;
    } else {
        unionMap.put(unionKey, i);
    }
}

Java 8 Stream API 之 removeIf


removeIf简化代码

  • 移除所有负数
List<Integer> numbers = Arrays.asList(1, -2, 3, -4, 5);
numbers.removeIf(n -> n < 0);
// 结果: [1, 3, 5]

  • 移除过期的订单
List<Order> orders = getOrders(); // 获取订单列表
orders.removeIf(order -> order.getExpiryDate().isBefore(LocalDate.now()));
// 移除所有过期的订单

  • 移除名称重复的用户
List<UserDTO> users = getUsers();
if (CollectionUtils.isNotEmpty(users)) {
    Set<String> uniqueNames = new HashSet<>();
    users.removeIf(u -> !uniqueNames.add(u.getName()));
}
return users;

Java 8 Stream API 之 map


  • map简化代码
//简化前
Map<Integer, PtBloodIdx> bloodIdxMap = listByIds(bloodIds).stream().collect(Collectors.toMap(PtBloodIdx::getId, Function.identity(), (k1, k2) -> k1));
for (PtBloodTree ptBloodTree : trees) {
    Integer bloodId = ptBloodTree.getBloodId();
    PtBloodIdx ptBloodIdx = bloodIdxMap.get(bloodId);
    if (ptBloodIdx == null) {
        continue;
    }
    ChildBloodTreeResVo res = new ChildBloodTreeResVo();
    res.setId(ptBloodIdx.getId());
    res.setBloodCode(ptBloodIdx.getBloodCode());
    res.setBloodName(ptBloodIdx.getBloodName());
    resList.add(res);
}
retrun resList;

//简化后
return trees.stream()
        .map(tree -> bloodIdxMap.get(tree.getBloodId()))
        .filter(Objects::nonNull)
        .map(ptBloodIdx -> {
            Integer bloodId = .getId();
            List<BloodNodeResVo> parentBloods = getParentBloods(bloodId);
            return ChildBloodTreeResVo.builder().id(bloodId).bloodCode(ptBloodIdx.getBloodCode()).bloodName(ptBloodIdx.getBloodName()).parentBloods(parentBloods).build();
        })
        .collect(Collectors.toList());

解释:

  • 通过第一个.map直接从tree转换成了PtBloodIdx
  • filter过滤后,只保留每一个不为null的对象
  • 第二个map开始组装最终的结果里的每一个对象

小技巧

文件拆分

将一个文件按照1000行拆分成一个新文件

场景: 一个文件中存在1万个ID,数据库每次in的时候只能查询1000个, 于是需要1000个ID作为一次拆分

打开git bash, 执行以下命令

# 1000表示1千行作为一次拆分, 文件保存在abc目录下, 新文件的前缀是shop_1000_
split -l 1000 shopIds.groovy abc/shop_1000_

每100KB拆分成一个新文件

split -b 100k shopIds.groovy abc/shop_1000_

Git常用操作

还原至master

--mixed和--hard

git reset 右面可选{--mixed, --hard}, 两者有本质的区别. --mixed默认

操作git reset --hard origin/mastergit reset --mixed origin/master
HEAD重置为 origin/master 指向的提交重置为 origin/master 指向的提交
暂存区(staging area)重置为远程 origin/master 的状态,丢弃所有已暂存的更改重置为远程 origin/master 的状态,丢弃所有已暂存的更改
工作目录(working directory)恢复为远程 origin/master 的状态,丢弃所有未提交的更改保留本地修改,但将其恢复为“未暂存”状态,不会丢失工作目录中的更改

两者的相同点:

  1. 都是为了把未推送到远程的代码状态还原到和远程状态
  2. 执行好,新增的文件,会回退到未暂存的状态,不会被删除.
    1. 删除的话需要执行git clean -fd,谨慎操作.执行后,本地未推送到远程的代码将会彻底丢失
      1. -f表示强制删除
      2. -d表示删除未跟踪的目录

两者的本质区别:

  1. --mixed是默认的, 操作比较柔和一点,还原后,项目的提交记录和远程保持一致了.但是本地已修改的代码不会丢弃.未推送到远程的代码代码还在本地,只是提交记录和远程保持一致了
  2. --hard不是默认的,需要指定, 操作很强硬, 执行后, 本地的已修改未推送到远程的代码会彻底丢弃

阿里云-数据服务概述-学习笔记

以下内容,大量引用于 阿里云

DataWorks数据服务模块是一个灵活轻量、安全稳定的数据API构建平台

  1. API构建平台
    1. 已有的API注册至平台统一管理
    2. 注册生成API

数据服务

相关概念

  • API(Application Programming Interface , 应用程序编程接口):API是让应用、软件、系统能够面向数据源进行数据交互的接口,数据服务API支持“读数据”的操作,可以从数据库、数据表中不断地进行数据查询
  • 函数:作为API过滤器,对API的请求参数返回参数进行加工处理。当使用函数作为API过滤器时,前置过滤器后置过滤器的函数类型需要保持一致,暂不支持对同一API的前置和后置过滤器选择不同的函数类型。

API分组

API分组是指针对某一个功能场景API集合,也是API网关对API的最小管理单元。在阿里云API市场中,一个API分组对应于一个API商品

一个业务流程下可以有多个API分组

  • 您需要确保当前业务流程下,无文件夹、API、函数和服务编排等其它文件,才能够成功删除业务流程。
  • 如果业务流程内存在其它文件,请您先删除所有的文件,再删除该业务流程。

数据服务错误代码表

错误代码描述语义
0success数据查询及返回结果成功。
1108110583query timeout请求查询超时,API在数据服务和数据库中的整体执行时长超过了API环境配置中所设置的超时时间,导致请求超时。
1108110519param miss请求参数缺失,当API设置了必填的请求参数,但实际请求中存在必填参数未传参。
1108110584api context failed依赖第三方获取上下文失败,上下文信息包括:数据源连接信息、数据源AK信息、租户信息等。
1108110622datasource query error查询数据源失败,可能原因包括:SQL语法错误、数据源未在系统内置10s超时上限内返回执行结果、超过数据源连接数限制等。
1108110703database connection error数据源连接失败。
1108113002rate limitAPI调用达到阈值上限,已被系统限流。目前API调用均使用公共服务资源组,公共服务资源组的阈值约为每租户200 QPS,超出该阈值将触发调用流量控制。

数据推送

将数据推送至Webhook

  1. 通过简单配置,实现定期将所需的业务数据推送至多个不同的Webhook
  2. 支持的推送渠道:钉钉群、飞书群、企业微信群以及Teams

数据推送服务使用限制

  • 数据推送功能推送至不同对象时的数据大小限制:
    • 推送目标为钉钉,推送数据大小不超过20KB
    • 推送目标为飞书,推送数据大小不超过20KB,图片小于10MB
    • 推送目标为企业微信,每个机器人发送的消息不能超过20条/分钟
    • 推送目标为Teams,推送大小不大于28KB
功能分类功能点向导模式脚本模式
查询对象单数据源、单数据表查询支持支持
单数据源、多数据表关联查询不支持支持
查询条件数值型等值查询支持支持
数值型范围查询支持支持
字符型精确匹配支持支持
字符型模糊匹配支持支持
查询结果字段值原样返回支持支持
字段值进行数学运算不支持支持
字段值进行聚合函数运算不支持支持
返回结果分页支持支持
查询逻辑mybatis标签不支持支持

API安全

IP白名单

100.64.0.0/10,11.193.102.0/24

生成API

参数描述
API模式包括向导模式脚本模式,此处选择向导模式
API名称支持中文、英文、数字、下划线(_),且只能以英文或中文开头,4~50个字符
API PathAPI存放的路径,即相对于服务host,API的请求路径。例如/user说明支持英文、数字、下划线(_)和连字符(-),且只能以( /) 开头,不得超过200个字符。
协议支持HTTPHTTPS。如果您需要通过HTTPS协议调用API,请您发布API至网关后,在API网关控制台绑定独立域名,并上传SSL证书。详情请参见支持HTTPS
请求方式支持GETPOST说明请求方式选择GET时,请求参数位置仅支持选择QUERY。当请求方式选择POST时,请求参数位置支持选择QUERYBODY
返回类型仅支持JSON返回类型。
可见范围包括工作空间私有工作空间:该API对本工作空间内的所有成员可见。私有:该API仅对API的负责人可见,且暂不支持授权。说明如果设置可见范围为私有,在目录树中,仅自己可见,工作空间内的其他成员不可见。
标签标签列表中选择相应的标签,详情请参见创建及管理API标签说明标签名称支持汉字、英文、数字和下划线(_),您最多可以设置5个标签,且每个标签不超过20个字符。
描述对API进行简要描述,不得超过2000个字符。
目标文件夹存放API的目录,可以在下拉列表选择已创建的业务流程,选定后,会生成API的存放路径。默认格式为:“业务流程/业务流程名称/API”,例如业务流程/ceshi/API。

后续会有一堆正则表达式, 建议用枚举管理起来

麻雀虽小,五脏俱全. 建议脏腑分明

配置过滤器

对入参和出参,进行二次加工

设置是否返回结果分页

高级配置区域,设置是否返回结果分页

  • 如果不开启返回结果分页,则API默认最多返回2000条记录。
  • 如果返回结果可能超过2000条,请开启返回结果分页功能,开启后,您可以进入右侧导航栏的服务资源组页面,根据资源组类型设置单页条数上限。

说明

当数据服务的API在编辑页面右侧导航栏的返回参数已经开启了返回结果分页,如果您在该API编辑页面的编写查询SQL区域,使用SQL语句配置了limit限制(即返回结果的条数限制),则该limit限制不生效,返回结果的条数限制仍然会以返回结果分页的配置内容为准。

开启返回结果分页后,会自动增加以下公共参数:

  • 公共请求参数

    • returnTotalNum:用于确定单次请求中是否要返回数据总条数。
    • pageNum:当前页号。
    • pageSize:页面大小,即每页记录数。
  • 公共返回参数

    • pageNum:当前页号。
    • pageSize:页面大小,即每页记录数。
    • totalNum:总记录数。

记录操作日志

什么时间,谁, 做了什么事情

通过条件控制返回结果按照不同的表字段进行排序

这块可以设计页面,按照设置的字段顺序排序. 页面支持切换顺序?????

  • var的值为1时,使用order by col01对结果进行排序。
  • var的值为2时,使用order by col02对结果进行排序。
  • var的值为3时,使用order by col01,col02对结果进行排序。
  • var的值为4时,使用order by col02,col01对结果进行排序。

注册API

入参

参数描述
API名称支持中文、英文、数字、下划线(_),且只能以英文或中文开头,4~50个字符。
API PathAPI存放的路径,例如/user。说明支持英文、数字、下划线(_)和连字符(-),且只能以( /) 开头,不得超过200个字符。
协议支持HTTPHTTPS协议。如果您需要通过HTTPS协议调用API,请您发布API至网关后,在API网关控制台绑定独立域名,并上传SSL证书。详情请参见支持HTTPS
请求方式支持GETPOSTPUTDELETE
返回类型支持JSONXML
可见范围包括工作空间私有工作空间:该API对本工作空间内的所有成员可见。私有:该API仅对API的负责人可见,且暂不支持授权。说明如果设置可见范围为私有,在目录树中,仅自己可见,工作空间内的其他成员不可见。
标签标签列表中选择相应的标签,详情请参见创建及管理API标签说明标签名称支持汉字、英文、数字和下划线(_),您最多可以设置5个标签,且每个标签不超过20个字符。
描述对API进行简要描述,不得超过2000个字符。
目标文件夹存放API的目录。

出参

参数描述
后台服务Host待注册API服务的Host,以**http://https://**开头,并且不包含Path。说明示例:假设您接口服务地址为http://xxx-cn-xxx.alicloudapi.com/user/info,可取http://xxx-cn-xxx.alicloudapi.com设为后台服务Host。具体的可根据您接口服务地址实际路径进行配置。
后台服务Path待注册API服务的Path,Path中支持参数,参数要放在**[]中,如/user/[userid]**。配置Path中的参数后,在注册API向导的第二步API参数配置环节,系统会自动在请求参数列表添加Path位置的参数。说明示例:假设您接口服务地址为http://xxx-cn-xxx.alicloudapi.com/user/info,可将/user/info设为后台服务Path。具体的可根据您接口服务地址实际路径进行配置。
后端超时设置后端超时时间。

需要接口请求链路,查看接口详情

API请求统计: ES

Aviator函数和正则表达式 适用场景对比

场景正则表达式Aviator
简单的字符串匹配和验证✔️ 非常适合❌ 过于复杂,不推荐使用
动态规则修改❌ 不支持✔️ 支持动态加载规则
多条件逻辑❌ 难以实现,表达式冗长且复杂✔️ 支持多条件逻辑
规则与代码分离❌ 不支持✔️ 规则可以存储在外部配置
可读性要求高❌ 正则表达式难以理解✔️ 表达式更易于理解
扩展性要求高❌ 仅限于正则的能力✔️ 支持复杂逻辑、动态函数调用

大数据与实时分析

Flink_CDC同步MySQL到StarRocks初体验

建议搭建初期, 使用官网提供的flink cdc sql在sql-client.sh中测试,根据错误提示添加对应的包

mkdir -p /app
wget https://archive.apache.org/dist/flink/flink-1.19.1/flink-1.19.1-bin-scala_2.12.tgz
tar -zxvf flink-1.19.1-bin-scala_2.12.tgz
cd flink-1.19.1
echo "execution.checkpointing.interval: 3000" >> /app/flink-1.19.1/conf/config.yaml
cd /app/flink-1.19.1/lib
# flink 1.19推荐下载3.3.0 connector包,如果直接使用flink,不使用dinky,完全没问题
# 由于我这边使用的dinky是1.2.3版本,3.3.0 connector包不兼容. 所以使用测试通过的包,如下
wget https://repo1.maven.org/maven2/com/ververica/flink-sql-connector-mysql-cdc/2.1.0/flink-sql-connector-mysql-cdc-2.1.0.jar
chmod +rwxrwxrwx flink-sql-connector-mysql-cdc-2.1.0.jar

wget https://repo1.maven.org/maven2/com/starrocks/flink-connector-starrocks/1.2.10_flink-1.19/flink-connector-starrocks-1.2.10_flink-1.19.jar
chmod +rwxrwxrwx flink-connector-starrocks-1.2.10_flink-1.19.jar
wget https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.27/mysql-connector-java-8.0.27.jar
chmod +rwxrwxrwx mysql-connector-java-8.0.27.jar
# 至此, 依赖包齐活
# flink默认是localhost访问,如果要允许其他IP访问.
# 需要修改 bind-host: localhost,localhost改为0.0.0.0 多处需要修改
# 需要修改 rest下的address为0.0.0.0

# 启动flink,执行1次增加1个task slot, 可以多次执行
# 每次启动的task slot 可以在config/config.yaml文件中修改numberOfTaskSlots的值
/app/flink-1.19.1/bin/start-cluster.sh

# 至此,flink准备完毕

安装MySQL和starrocks

docker-compose.yml

version: '2.1'
services:
  StarRocks:
    image: starrocks/allin1-ubuntu:3.2.6
    environment:
      # 如果没有指定密码,启动后进入容器后,执行ALTER USER 'root' IDENTIFIED BY 'eishees4saez3kaepei3Yi8am2oonguG';进行修改也行
      - STARROCKS_ROOT_PASSWORD=eishees4saez3kaepei3Yi8am2oonguG
    ports:
      - "8080:8080"
      - "9030:9030"
  MySQL:
    image: debezium/example-mysql:1.1
    ports:
      - "3306:3306"
    environment:
      - MYSQL_ROOT_PASSWORD=fiesug4Oji0be1ohk6oyae3EomaNg8uc
      - MYSQL_USER=mysqluser
      - MYSQL_PASSWORD=Aix5Airohth1ma3oSh3meHiijei6Usah

安装并启动

docker-compose up -d

安装dinky

经过发现这个版本的镜像,重启后不会报错.相对稳定

docker run -itd --network=nginx_ngu_network \
 --name dinky dinkydocker/dinky-standalone-server:1.1.0-flink1.18

dinky配置

docker exec -it dinky bash 
cd extends/flink1.19
wget https://repo1.maven.org/maven2/com/starrocks/flink-connector-starrocks/1.2.10_flink-1.19/flink-connector-starrocks-1.2.10_flink-1.19.jar
# 此处用的版本和flink中引用的不一样.但是经过测试,是完全兼容的,可放心食用
wget https://repo1.maven.org/maven2/com/ververica/flink-sql-connector-mysql-cdc/2.4.1/flink-sql-connector-mysql-cdc-2.4.1.jar
# 至此, dinky中的jar包配置完成
# 退出容器
exit
# 重启dinky
docker restart dinky

访问dinky http://localhost:8888

用户名: admin 密码 :dinky123!@#

登录后尽快修改密码

image-20250406152606018

新建任务并提交即可

image-20250406152659642

任务示例

CREATE TABLE IF NOT EXISTS `orders1_src` (
  `order_id` BIGINT NOT NULL,
  `dt` DATE NULL,
  `user_id` INT NULL,
  `good_id` INT NULL,
  PRIMARY KEY (`order_id`) NOT ENFORCED
)
with
  (
    'username' = 'root',
    'password' = 'taedohlahsoow7ebiath6Iaf2uokagah',
    'database-name' = 'tmp_test',
    'table-name' = 'orders1',
    'connector' = 'mysql-cdc',
    'hostname' = '172.20.0.10',
    'port' = '3306',
    'server-time-zone' = 'Asia/Shanghai',
    'debezium.poll.interval.ms' = '200', -- Binlog轮询间隔(200ms)
    'scan.incremental.snapshot.chunk.size' = '1000', -- 减少快照分块大小
    'heartbeat.interval' = '1s' -- 心跳间隔(保活连接)  .默认为0.如果设为 0,可能因连接闲置被数据库服务器关闭
  );

CREATE TABLE IF NOT EXISTS `orders1_sink` (
  `order_id` BIGINT NOT NULL,
  `dt` DATE NULL,
  `user_id` INT NULL,
  `good_id` INT NULL,
  `good_name` STRING NULL,
  PRIMARY KEY (`order_id`) NOT ENFORCED
)
with
  (
    'sink.max-retries' = '10',
    'password' = 'kuutooP2Daeghezi0thieyej5quiFace',
    'sink.properties.strip_outer_array' = 'true',
    'load-url' = '10.0.0.2:8030',
    'database-name' = 'quickstart',
    'jdbc-url' = 'jdbc:mysql://10.0.0.2:9030',
    'sink.properties.format' = 'json',
    'username' = 'root',
    'sink.buffer-flush.interval-ms' = '15000',
    'connector' = 'starrocks',
    'table-name' = 'orders1',
    'sink.properties.format' = 'json',
    'sink.properties.strip_outer_array' = 'true',
    'sink.properties.partial_update' = 'true',
    'sink.properties.columns' = 'order_id,dt,user_id,good_id',
    -- 关键参数:控制写入频率
    'sink.buffer-flush.interval-ms' = '1000', -- 1秒刷写一次
    'sink.buffer-flush.max-rows' = '64000', -- 每批次最多64000行
    'sink.properties.format' = 'json',
    'sink.properties.strip_outer_array' = 'true'
  );

insert into
  orders1_sink (order_id, dt, user_id, good_id)
select
  s.order_id,
  s.dt,
  s.user_id,
  s.good_id
from
  orders1_src s;

遇到的问题记录

1. dink提交任务,无异常,也没有执行成功

首选在dinky提交任务,因为直观简单. 如果遇到提交任务后,无异常,也没有执行成功的问题排查.在flink的sql-clent.sh中运行调试,会看到对应的错误日志

2. 如果选用的mysql镜像是mariadb:11.7.2,需要设置时区和binlog

  • 设置时区+8

  • 设置binlog

    • cd /etc/mysql/mariadb.conf.d
      cat > 61-binlog.cnf << 'EOF'
      [mysqld]
      # 启用二进制日志
      log_bin = mysql-bin
      # 设置二进制日志格式为 ROW
      binlog_format = ROW
      # 设置服务器ID(主从复制需要)
      server_id = 1
      EOF
      
    • 退出容器,并且重启即可 docker restart mariadb

其他

jps -l | grep -i flink | awk '{print $1}' | xargs kill -9

MySQL相关

-- 确认 binlog_format 已改为 ROW
SHOW VARIABLES LIKE 'binlog_format';

--是否开启binlog
SHOW VARIABLES LIKE 'log_bin';

-- 查看时区
SELECT @@global.time_zone, @@session.time_zone;

不要直接修改my.cnf , 从容器中在/etc/mysql看到my.cnf来自于my.cnf -> /etc/alternatives/my.cnf

配置在mariadb.conf.d下新增或修改

Flink-CDC同步多表关联数据优化

场景9张表关联, 主表数据3万不到.其他表多次关联, 其他关联表数据很少. 但是9次关联之后,一次完整同步需要耗时30分钟

环境

StarRocks版本

SHOW VARIABLES LIKE '%version%';
Variable_nameValue说明
version5.1.0表示当前 StarRocks 的 SQL 语法兼容性 基于 MySQL 5.1.0 协议
version_commentStarRocks version 2.5.10StarRocks 实际的数据库版本号

flink版本

flink --version

Version: 1.18.1

dinky版本

1.1.0

MySQL版本

|Variable_name|Value|
|-------------|-----|
|innodb_version|5.7.24|
|protocol_version|10|
|slave_type_conversions||
|version|10.2.21-MariaDB-log|
|version_comment|MariaDB Server|
|version_compile_machine|x86_64|
|version_compile_os|Linux|
|version_malloc_library|system|
|version_ssl_library|YaSSL 2.4.4|
|wsrep_patch_version|wsrep_25.23|

docker-compose部署调试环境

mdbook使用记录

使得mdbook在发布后支持数学公式

1. 根目录的book.toml中注释或者删除math相关的所有

2. 项目根目录与src平级的目录处, 新建theme目录,theme目录新建文件head.hbs,这个文件会被mdbook自动加载。

mdbook内容如下:

<script>
  window.MathJax = {
    tex: {inlineMath: [['$', '$'], ['\\(', '\\)']]}
  };
</script>
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
<script>
  function renderMath() {
    if (window.MathJax) {
      MathJax.typesetPromise();
    }
  }

  // 页面初次加载
  document.addEventListener("DOMContentLoaded", renderMath);

  // mdBook 切换章节时
  document.addEventListener("DOMContentLoaded", () => {
    const observer = new MutationObserver(renderMath);
    observer.observe(document.querySelector("#content"), { childList: true, subtree: true });
  });
</script>

mdbook 结合github action发布太慢优化

观察发现,github每次打包都要重新便宜mdbook,导致花费时间太长,所以优化mdbook.yml直接用已经打包的二进制包 样例:

name: Deploy mdBook site to Pages

on:
  push:
    branches: ["master"]
  workflow_dispatch:

permissions:
  contents: read
  pages: write
  id-token: write

concurrency:
  group: "pages"
  cancel-in-progress: false

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      # 直接下载你打好的 Linux 版 mdBook
      - name: Install mdBook (Chinese search fork)
        run: |
          curl -L -o mdbook https://github.com/zhangyinyuan/mdBook/releases/download/auto-build/mdbook-linux
          chmod +x mdbook
          sudo mv mdbook /usr/local/bin/

      - name: Setup Pages
        id: pages
        uses: actions/configure-pages@v5

      - name: Build with mdBook
        run: mdbook build

      - name: Upload artifact
        uses: actions/upload-pages-artifact@v3
        with:
          path: ./book  # 注意自己大号包之后的文件夹的名称, 由book.toml文件中的build-dir属性决定

  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    needs: build
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4

clash-verge

自动切换

image-20250825204055658

配置好之后,设置规则,即可

image-20250825204301936


网络设置

虚拟网卡模式TUN

image-20250825204423408

启用DNS覆写

image-20250825204459454

调整DNS相关属性

image-20250825204537365

image-20250825204735205

禁止idea粘贴文本自动格式化

禁止自动去掉末尾的空格(原汁原味保存)

img_v3_02q1_e8ba3454-2a4a-4e50-ada6-7f4ccdddbc6g


禁用EditorConfig

img_v3_02q1_9681d398-a672-4c1b-b6eb-a1da90c7387g


保存动作禁止格式化

image-20250924112236965