搭建redis服务器的记录.part1

背景

因为迁移上云的原因,所以需要把老虚拟机关掉,发现有一个老虚拟机上就一个redis什么都没有。
故决定搭建一个公用的redis

搭建公用redis的思路

  • 多租户
  • 集群稳定
  • 配置够顶

创建命令

1
docker run --name redis-main -d -p 6379:6379   -v /root/redis-data:/data   -v /root/redis-conf/redis.acl:/usr/local/etc/redis/redis.acl   redis:7.4.1 redis-server   --aclfile /usr/local/etc/redis/redis.acl   --appendonly yes   --appendfsync everysec   --save "60 1000"   --bind 0.0.0.0```

每个部分的详细解释:

  • -p 6379:6379:这将容器内部的6379端口映射到宿主机的6379端口,使得外部可以通过宿主机的6379端口访问到容器中的Redis服务。
  • -v /root/redis-data:/data:这将宿主机的/root/redis-data目录挂载到容器的/data目录,通常用于持久化存储Redis的数据。
  • -v /root/redis-conf/redis.acl:/usr/local/etc/redis/redis.acl:这将宿主机的/root/redis-conf/redis.acl文件挂载到容器的/usr/local/etc/redis/redis.acl路径,用于配置Redis的ACL(访问控制列表)。
  • redis:7.4.1:指定要使用的Redis镜像的名称和版本,这里是redis镜像的7.4.1版本。
  • redis-server:这是在容器内启动Redis服务的命令。
  • --aclfile /usr/local/etc/redis/redis.acl:指定Redis的ACL配置文件路径。
  • --appendonly yes:启用Redis的AOF(Append Only File)持久化模式,即所有的写操作都会被记录到AOF文件中。
  • --appendfsync everysec:设置AOF持久化的同步策略为每秒同步一次到磁盘。
  • --save "60 1000":设置RDB(Redis Database)持久化的触发条件,即在60秒内至少有1000个键被修改时,自动触发RDB持久化。
  • --bind 0.0.0.0:将Redis服务绑定到所有网络接口,使得容器内的Redis服务可以从任何IP地址访问。

redis.acl格式

1
2
3
user default on >passwordforuser ~* +@all
user user1 on >password123 ~user1:* +@all -@admin
user user2 on >password345 ~user2:* +@all -@admin

以上命令创建了默认用户和user1,user2两个租户。其中默认用户拥有全部的权限,主要包含了@admin系列权限。
@admin权限包含了redis-cli里运行的acl命令系列,可以更改其他人权限。
需要注意的点是租户一定不能赋予@admin权限。

redis实例的查看工具

我是用redis insight,就官方提供的gui界面。里面连上对应的实例之后,左下角有cli窗口,可以进行各种测试。

redis多租户的效果

使用key的时候需要加入账户名同名前缀
用管理员账号查看大概就是下面的效果
img.png

增加一个新的租户的操作

  • 编辑redis.acl文件,增加一行,指定用户名和password
  • docker restart redis-main

后续要做的工作

  • 集群化等后续再说
  • 等需要做集群了再申请多的机器

记录一次docker文件夹占满文件系统的排查过程

故障现象

早晨起来发现gitlab上的一些CICD流程运行失败了。因为未改动CICD脚本,故怀疑是runner机器故障。

关键步骤

登录机器检查磁盘占用

-h``` 直接确认根目录已经100%占用了,故确定是磁盘满了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

#### 检查docker情况
因为对docker的磁盘占用有一些预期,所以直接检查docker是否镜像占用过多。
```docker image prune```
先尝试用上面最温柔的方式清理一些数据,然后```df -h```检查磁盘空间占用变少,重新尝试在gitlab上运行流水线成功,确认磁盘问题。

#### 磁盘占用情况
```bash
[root@TJnetwork ~]# df -h
文件系统 容量 已用 可用 已用% 挂载点
devtmpfs 4.0M 0 4.0M 0% /dev
tmpfs 7.6G 0 7.6G 0% /dev/shm
tmpfs 3.1G 297M 2.8G 10% /run
tmpfs 4.0M 0 4.0M 0% /sys/fs/cgroup
/dev/mapper/openeuler-root 63G 36G 24G 61% /
tmpfs 7.6G 0 7.6G 0% /tmp
/dev/sda2 974M 138M 770M 16% /boot
/dev/sda1 599M 6.2M 593M 2% /boot/efi
/dev/mapper/openeuler-home 31G 414M 29G 2% /home
/dev/sdb 1007G 124G 832G 13% /data

上面是当时的截图。根目录占用很高,data目录占用很低,所以尝试把docker的根目录迁移到/data目录下。

docker配置的更改

保证目标文件夹有权限,我直接使用777权限。 如果文件夹权限不对docker进程会启动失败。
docker的配置文件一般在/etc/docker/daemon.json

1
2
3
4
5
[root@TJnetwork lib]# cat /etc/docker/daemon.json
{
"data-root": "/data/docker-data",
"registry-mirrors" : [ "https://dockerpull.com", "https://register.liberx.info", "https://huecker.io", "https://dockerhub.timeweb.cloud", "https://dockerhub1.beget.com", "https://noohub.ru" ]
}

核心就是data-root的目录,重启之后数据都存在/data/docker-data上了。

后续核心命令

现在虽然硬盘加到1T,但是早晚也会满,弄一个计划任务,每天运行一次docker的清理命令。

1
docker image prune -a --filter "until=720h"

使用linux下常用的定时命令
crontab -e
加入如下规则,每天运行一次docker镜像清理命令
0 0 * * * docker image prune -a --filter "until=720h"

在服务器上方便的跑一次性golang脚本

场景描述

有一个跑的时间非常长的任务,大概需要连续跑20h,这个任务是一次性的,不值得去配置什么CICD

思路

golang手熟所以使用golang去完成了,曾经思考是不是用其他脚本语言会更好?
但是对于这种一次性的需求,显然哪个语言熟练度高就用哪个语言了。
最好的方式应该是使用交叉编译,打包一个可执行文件,扔到服务器上去运行即可。
或者也可以在一个有运行环境的服务器上。

最后手头有一个没有golang环境,但是有docker环境的,不清楚linux版本的测试机器。决定使用docker的方式来运行这个脚本。

配置

  • 任何ssh工具(我是用mobaXterm)
  • 一台具有docker环境的机器

具体过程

登录到运行机器上,先通过ssh工具把代码传到机器上。
然后cd到代码所在的文件夹,直接运行以下语句:

1
docker run -it --rm -v $(pwd):/app -w /app golang:1.20 bash

你将获得一个一次性的,以当前目录挂载到app文件夹下的golang容器,需要注意的是,因为用了rm的选项,一旦退出当前ssh会话,容器就被销毁了。

如果需要一个真正的,后台一直运行的任务,需要用如下命令

1
docker run -d --rm -v $(pwd):/app -w /app golang:1.20 bash -c 'while true; do echo "The script is running at: $(date)"; sleep 1; done'

其中单引号里的语句替换成真正的生产实际语句。

golang的google源没办法使用,记得先换成使用命令换成国内源

1
export GOPROXY=https://goproxy.cn,direct

最后的命令应该组成类似于

1
docker run -d --rm -v $(pwd):/app -w /app golang:1.20 bash -c 'export GOPROXY=https://goproxy.cn,direct;go run main.go'

附上一段我自己用的main.go测试文件

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

import (
"fmt"
"time"
)

func main() {
for {
// 获取当前时间
currentTime := time.Now().Format(time.RFC3339)
// 打印当前时间
fmt.Printf("The script is running at: %s\n", currentTime)
// 等待 1 秒
time.Sleep(1 * time.Second)
}
}

CSP基础

业务场景

希望能集成一个weda开发出来的页面到开放平台上

实现方式

1
<iframe src="https://lowcode-7gcbyr6cba0c6868-1312402421.tcloudbaseapp.com/app-v9spncjv/production/index" width="600" height="720" frameborder="0" allowfullscreen></iframe>

通过iframe实现,虽然对iframe也不算很了解,但是简单的本地测试没问题

遇到问题

push到生产环境之后,浏览器直接报无法加载,console中类似报错,例子中用的script,实际是iframe

1
Refused to load the script 'http://xxxxx' because it violates the following Content Security Policy directive: "script-src 'self' 'unsafe-eval' 'unsafe-inline'

定位问题

之前做等保认证时,好像配置过csp(Content Security Policy),当时不知道具体作用根据需要就配置了下,现在重新梳理下

CSP作用

我们都应该听说过XSS(跨站脚本攻击);它可能是最常见、危害最大的网络安全漏斗。大约十年前吧,W3C 网络应用安全工作组为防御 XSS、点击劫持等代码注入攻击,推荐 CSP 成为计算机安全标准,以阻止恶意内容在受信网页环境中执行;之后几乎所有的现代浏览器都支持了这一策略。

实现方式

配置在响应的标头里或者html网页的meta里的一串字符串,如下所示

1
Content-Security-Policy: style-src 'unsafe-inline' 'self'; script-src blob: 'unsafe-inline' 'self';

我因为要引入https://lowcode-7gcbyr6cba0c6868-1312402421.tcloudbaseapp.com/这个网页作为iframe的源头,
就应该在iframe-src或者default-src中配置这个地址

遇到一些不明确的问题

一开始偷懒不想改nginx里的配置,在meta中直接添加了https://lowcode-7gcbyr6cba0c6868-1312402421.tcloudbaseapp.com/,
但是效果跟预期不一致,不清楚响应的标头和meta里都配置出现了什么问题

最后的解决方式

nginx里的csp直接删掉,下次等保再说吧

参考的网络资源

CSP基础学习

git迁移项目到新命名空间

迁移一个项目到新的命名空间

工作需要迁移了一个项目到新的命名空间,因为项目用到了Gitlab自带的镜像仓库,所以在迁移的时候报错了。
删除镜像仓库中的所有镜像之后,就能够正常转移项目到新的命名空间了。

本地代码仓库指向新的远程仓库

以下为示例操作步骤:

假设当前远程仓库地址为 https://github.com/old-user/old-repo.git,新仓库地址为 https://github.com/new-user/new-repo.git

  1. 查看当前远程仓库地址:

    1
    git remote -v

    输出:

    1
    2
    origin  https://github.com/old-user/old-repo.git (fetch)
    origin https://github.com/old-user/old-repo.git (push)
  2. 修改远程仓库地址:

    1
    git remote set-url origin https://github.com/new-user/new-repo.git
  3. 验证更改:

    1
    git remote -v

    输出应当为:

    1
    2
    origin  https://github.com/new-user/new-repo.git (fetch)
    origin https://github.com/new-user/new-repo.git (push)

完成这些步骤后,你的本地 Git 仓库将会与新的远程仓库地址关联。

mp4非常见编码转常见编码

mp4里编码不同的坑

利用工具从微信视频号下载的下来的视频默认是mp4格式
众所周知mp4格式里的编码千千万
HVC1编码就是windows播放器默认不支持的格式
用Potplayer查看视频信息能看到具体的编码格式如下:

1
2
3
4
5
6
7
8
[视频信息]
视频编码: HVC1 - Native D3D9 DXVA VLD Decoder - Intel(R) UHD Graphics 750
输入格式: HVC1(24 bits)
输入尺寸: 1080 × 1920(1:0.56)
输出格式: dxva
输出尺寸: 1080 × 1920(1:0.56)
帧率: 29.998
BitRate: 未知

关于HVC1搜索到如下帖子:

1
2
HEVC是国际化265编码标准
HVC1是在HEVC的基础上衍生出来的非官方编码,所以苹果设备仅支持HVC1编码视频播放,不支持HEVC

原文地址

转换mp4编码

简单搜索找到一个开源的converter,HandBrake
一路傻瓜下一步安装即可,一切默认,转换出来就是最普通的mp4视频。
用windows自带播放器和powerpoint测试都能正常播放。

检查了一下视频的信息如下:

1
2
3
4
5
6
7
8
[视频信息]
视频编码: AVC1 - 内置 FFmpeg 解码器(h264, Thread Frame)
输入格式: AVC1(24 bits)
输入尺寸: 1080 × 1080(1:0.75)
输出格式: YUY2(16 bits)
输出尺寸: 1080 × 1080(1:0.75)
帧率: 29.996
BitRate: 未知

Handbrake软件下载地址

校级反代知多少

反向代理

我们学校有一个官方维护的反向代理,比较典型的官网就是通过这台反向代理来访问的。
那如何从外界来判断是否走了学校的反代呢
首先从ip判断

1
2
3
4
5
6
7
8
9
10
> nslookup www.tongji.edu.cn
Server: 202.120.190.11
Address: 202.120.190.11#53

Non-authoritative answer:
Name: www.tongji.edu.cn
Address: 192.168.66.4
Name: www.tongji.edu.cn
Address: 192.168.67.3

可以看到对于校内地址来讲192.168.66.4和192.168.67.3就是走了校级反代的。
如果在外网想判断是否走了校级反代,可以看202开头的ip地址。

第二种判断方式从报错页面判断
从浏览器访问https://www.tongji.edu.cn/xxxxx 这个明显不存在的页面,可以看到学校的反向代理统一提供了错误处理页面,如果出现了这个页面,说明这个网址也是走了校级反代的。
错误画面

哪些网站应该使用校级反代呢

校级反代提供了两点非常好的地方
第一是定期更新ssl证书,不用你去每年更新https证书,由校级反代的维护者来统一更新
第二是支持ipv6,提高了ipv6的使用率

比较典型的就是各个学院的官网等静态页面,非常适合由校级反代来统一维护

什么情况不适合校级反代呢

  • 访问量很大,并发很高,需要在网关层面做特殊优化
  • 涉及到大文件或者流媒体等的传输,需要在网关层面做优化
  • 涉及到实时对话等,打开特殊端口的网站
  • 需要灵活自定义二级目录的映射关系的网站

学校的ntp服务器配置解释

ntp服务器

学校提供ntp服务器用来校内同步

学校的ntp服务器的ip为

1
192.168.150.1

推荐使用的ntp服务器列表

阿里 腾讯 校内 三个足够

  • ntp.aliyun.com
  • time1.cloud.tencent.com
  • 192.168.150.1

其中有一些打印机和门屏没有被授予外网权限,才被迫使用学校内的ntp服务器。
从层级和准确度上来看,阿里和腾讯的更加优秀。

使用工具

使用chrony而不是ntp,参考这篇文章 同步时间,为什么我选 Chrony 而不是 NTP ?

核心用法

先检查系统中是否存在chrony或者ntp服务

1
sudo ps aux | grep -E "ntpd|chronyd"

安装chrony

1
yum install chrony

开启服务,开机自自动,检查服务状态三连

1
2
3
systemctl start chronyd.service
systemctl enable chronyd.service
systemctl status chronyd.service

编辑配置文件,在ubuntu上文件路径是/etc/chrony/chrony.conf

1
vi /etc/chrony.conf

注释掉初始的pool.ntp.org iburst

1
2
3
4
5
6
# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (https://www.pool.ntp.org/join.html).
# pool pool.ntp.org iburst
server ntp.aliyun.com minpoll 4 maxpoll 10 iburst
server 192.168.150.1 minpoll 4 maxpoll 10 iburst
server time1.cloud.tencent.com minpoll 4 maxpoll 10 iburst

重启服务

1
systemctl restart chronyd.service

使用chrony相关命令检查

1
2
chronyc tracking
chronyc -n sources -v

参考的网络资源

同步时间,为什么我选 Chrony 而不是 NTP ?
国内常用NTP服务器地址
阿里云NTP指南

联通云docker版nginx断流之迷

问题描述

学校新给的云主机,本质就是ecs
安装docker版的nginx之后出现断流现象
具体现象描述如下:
在云主机内访问校内其他资源,典型命令如下:

1
curl http://nic.pages.tongji.edu.cn/developerhub-frontend/static/index.css

是可以的。但是进入到docker容器内部,使用同样的命令去访问资源,会有一定概率卡死,这个原因未知。

附上一个测试脚本以备后续使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/bin/bash

url="http://nic.pages.tongji.edu.cn/developerhub-frontend/static/img/bg.jpg"
total_requests=50
success_count=0
total_time=0

for ((i=1; i<=$total_requests; i++)); do
start_time=$(date +%s.%N)
response=$(curl -s -o /dev/null -w "%{http_code}" "$url")
end_time=$(date +%s.%N)

if [ "$response" == "200" ]; then
success_count=$((success_count+1))
fi

request_time=$(echo "$end_time - $start_time" | bc)
total_time=$(echo "$total_time + $request_time" | bc)

echo "Request $i: Response $response Time $request_time"
done

average_time=$(echo "scale=2; $total_time / $total_requests" | bc)
success_rate=$(echo "scale=2; ($success_count * 100) / $total_requests" | bc)

echo "Average Response Time: $average_time seconds"
echo "Success Rate: $success_rate%"

解决方案

使用docker网络模式里的host模式,也算是比较常见的解决方案

1
docker run -d --net=host git.tongji.edu.cn:5050/nic/nic-tool/developerplatform/nginx:latest

根因分析

不知道具体原因,只能大概猜想一下是网卡原因导致的

git文件变更之谜

git文件变更之谜

背景

今天从其他小伙伴那里拿到一个压缩包,里面有大量的文件大概700+,这个压缩包里面的文件之前已经上传过git了。
我这一次就是要找出压缩包中和旧版本压缩包中文件不同的部分。

操作

直接全选ctrl+a ctrl+c ctrl+v拷贝所有文件到项目对应路径下。
打开vscode一看傻眼,发现变更700+,几乎所有文件都被识别为需要更新。
随便打开一个文件的对比,发现肉眼不可见,基本可以确定要么是文件权限出现了变动,要么是回车导致的。

文件变化

通过git diff .\keycloak\themes\README.txt命令
拿到结果是warning: in the working copy of 'keycloak/themes/README.txt', LF will be replaced by CRLF the next time Git touches it
确实是因为unix系统和windows系统里回车不同导致的。
可以确定小伙伴是linux用户无疑了,而我这边是windows。

转换lf=》crlf

正常来说使用notepad++类似的文本编辑软件正则替换即可,但是我们现在要面对700+的文件,最直接的方式还是使用命令行工具。
linux下用过dos2unix,unix2dos类似的工具,搜索了一下windows下也有可用的实现。
unix2dos官网下载。
get-childitem -path . -filter '*.*' -recurse | foreach-object {dos2unix $_.Fullname}
官网给出了powershell可以直接使用的命令。
一顿运行之后,发现有2个js脚本没有替换成功,手工revert掉解决问题,收工。