-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.json
More file actions
1 lines (1 loc) · 136 KB
/
Copy pathindex.json
File metadata and controls
1 lines (1 loc) · 136 KB
1
[{"categories":null,"content":"官方自带 go build -ldflags '-s -w' ","date":"2025-06-22","objectID":"/posts/binsize/:1:0","tags":null,"title":"go大小压缩","uri":"/posts/binsize/"},{"categories":null,"content":"upx 降低 https://github.com/upx/upx 要选择最新版本,有优化效果 upx -9 ./your-bin 这个推荐在服务端使用,客户端不可控(会遇到运行不起来case). ","date":"2025-06-22","objectID":"/posts/binsize/:2:0","tags":null,"title":"go大小压缩","uri":"/posts/binsize/"},{"categories":null,"content":"减少包依赖大小 ","date":"2025-06-22","objectID":"/posts/binsize/:3:0","tags":null,"title":"go大小压缩","uri":"/posts/binsize/"},{"categories":null,"content":"大小分析 https://github.com/Zxilly/go-size-analyzer # download go install github.com/Zxilly/go-size-analyzer/cmd/gsa@latest # 分析大小 gsa --web ./your-bin ","date":"2025-06-22","objectID":"/posts/binsize/:3:1","tags":null,"title":"go大小压缩","uri":"/posts/binsize/"},{"categories":null,"content":"依赖分析 go mod graph ","date":"2025-06-22","objectID":"/posts/binsize/:3:2","tags":null,"title":"go大小压缩","uri":"/posts/binsize/"},{"categories":null,"content":"Clickhouse作为一种数据仓库的产品. ","date":"2025-02-09","objectID":"/posts/clickhouse/:0:0","tags":null,"title":"Clickhouse","uri":"/posts/clickhouse/"},{"categories":null,"content":"优点 文档清晰且有AI问答工具. 入门难度很低,拥有Mysql的经验即可. 阿里云也有其产品可以购买,生产稳定,出问题概率低. 数据压缩,存储成本低. 索引速度快. 可以直接录入Mysql作为data source. 交互协议上支持Http协议,伪Mysql协议和原生高性能协议. ","date":"2025-02-09","objectID":"/posts/clickhouse/:1:0","tags":null,"title":"Clickhouse","uri":"/posts/clickhouse/"},{"categories":null,"content":"GUI推荐 DataGrip. ","date":"2025-02-09","objectID":"/posts/clickhouse/:2:0","tags":null,"title":"Clickhouse","uri":"/posts/clickhouse/"},{"categories":null,"content":"SQL操作 数据管理利用TTL特性进行数据回收. ","date":"2025-02-09","objectID":"/posts/clickhouse/:3:0","tags":null,"title":"Clickhouse","uri":"/posts/clickhouse/"},{"categories":null,"content":"数据分布 查询 select * from system.parts limit 10; # 目前转移的数据 select * from system.mutations; ","date":"2025-02-09","objectID":"/posts/clickhouse/:3:1","tags":null,"title":"Clickhouse","uri":"/posts/clickhouse/"},{"categories":null,"content":"计算表大小 SELECT total_bytes/total_rows, table,database, formatReadableSize(total_bytes) AS total_bytes_on_disk FROM system.tables WHERE table = 'table'; ","date":"2025-02-09","objectID":"/posts/clickhouse/:3:2","tags":null,"title":"Clickhouse","uri":"/posts/clickhouse/"},{"categories":null,"content":"表转移 RENAME TABLE database.exist_table TO database.old_table, database.new_table TO database.exist_table; ","date":"2025-02-09","objectID":"/posts/clickhouse/:3:3","tags":null,"title":"Clickhouse","uri":"/posts/clickhouse/"},{"categories":null,"content":"数据回收 ALTER TABLE database.table DROP PARTITION '20240925'; ","date":"2025-02-09","objectID":"/posts/clickhouse/:3:4","tags":null,"title":"Clickhouse","uri":"/posts/clickhouse/"},{"categories":null,"content":"修改TTL ALTER TABLE database.table MODIFY TTL timestamp + toIntervalMonth(2); ","date":"2025-02-09","objectID":"/posts/clickhouse/:3:5","tags":null,"title":"Clickhouse","uri":"/posts/clickhouse/"},{"categories":null,"content":"查看表结构 SELECT name AS field_name, table AS table_name, type AS field_type, comment AS field_comment FROM system.columns WHERE database = 'database' AND table = 'table'; ","date":"2025-02-09","objectID":"/posts/clickhouse/:3:6","tags":null,"title":"Clickhouse","uri":"/posts/clickhouse/"},{"categories":null,"content":"常用函数 ","date":"2025-02-09","objectID":"/posts/clickhouse/:4:0","tags":null,"title":"Clickhouse","uri":"/posts/clickhouse/"},{"categories":null,"content":"易读数量 formatReadableQuantity(count()) ","date":"2025-02-09","objectID":"/posts/clickhouse/:4:1","tags":null,"title":"Clickhouse","uri":"/posts/clickhouse/"},{"categories":null,"content":"时间切割 toStartOfInterval(toDateTime(timestamp), INTERVAL 1 day ) as interval1 ","date":"2025-02-09","objectID":"/posts/clickhouse/:4:2","tags":null,"title":"Clickhouse","uri":"/posts/clickhouse/"},{"categories":null,"content":"截取数据 substring(message, -20) ","date":"2025-02-09","objectID":"/posts/clickhouse/:4:3","tags":null,"title":"Clickhouse","uri":"/posts/clickhouse/"},{"categories":null,"content":"数据类型转换 toString ","date":"2025-02-09","objectID":"/posts/clickhouse/:4:4","tags":null,"title":"Clickhouse","uri":"/posts/clickhouse/"},{"categories":null,"content":"数据拼接 concat(a,'',toString(b)) ","date":"2025-02-09","objectID":"/posts/clickhouse/:4:5","tags":null,"title":"Clickhouse","uri":"/posts/clickhouse/"},{"categories":null,"content":"clickhouse 同步mysql数据 SET allow_experimental_database_materialized_mysql=1; CREATE DATABASE new_database ENGINE = MaterializedMySQL('host:3306','database', 'user', 'password') SETTINGS allows_query_when_mysql_lost=true, max_wait_time_when_mysql_unavailable=10000; -- drop database new_database; ","date":"2025-02-09","objectID":"/posts/clickhouse/:5:0","tags":null,"title":"Clickhouse","uri":"/posts/clickhouse/"},{"categories":null,"content":"mysql 服务端 default_authentication_plugin = mysql_native_password gtid_mode = on ","date":"2025-02-09","objectID":"/posts/clickhouse/:5:1","tags":null,"title":"Clickhouse","uri":"/posts/clickhouse/"},{"categories":null,"content":"mysql 表条件 MySQL中的每个表都应包含PRIMARY KEY,并且如果表中包含ENUM字段值超出范围(在ENUM签名中指定),则无法进行复制。 mysql ip白名单检查,机器ip白名单检查. ","date":"2025-02-09","objectID":"/posts/clickhouse/:5:2","tags":null,"title":"Clickhouse","uri":"/posts/clickhouse/"},{"categories":null,"content":"权限管理 GRANT SELECT ON database.* TO user; GRANT ALL ON database.* TO user; GRANT SELECT,INSERT ON database.* TO user; GRANT OPTIMIZE ON database.* TO user; GRANT CREATE ON database.* TO user; ","date":"2025-02-09","objectID":"/posts/clickhouse/:6:0","tags":null,"title":"Clickhouse","uri":"/posts/clickhouse/"},{"categories":null,"content":"写入 数据录入上建议低频且大批量写入. 磁盘满时,clickhouse则会写入失败. 磁盘写满可能会影响其他进程作业,比如TTL数据管理进程掉线,需要重启才能恢复正常. ","date":"2025-02-09","objectID":"/posts/clickhouse/:7:0","tags":null,"title":"Clickhouse","uri":"/posts/clickhouse/"},{"categories":null,"content":"背景 某次发版后,生产机器的内存相比之前相同负载条件下使用率高,业务无异常影响. 而后带来的影响是,数据库连接资源随着pod数量提升占用提高. ","date":"2024-08-14","objectID":"/posts/memprofiling/:1:0","tags":null,"title":"Go 内存泄漏排查","uri":"/posts/memprofiling/"},{"categories":null,"content":"间接处理 回滚版本 每隔固定时间定时重新发版 把所有依赖pkg升级至最新,把Go版本升级至最新 服务拆分,让业务链路保持简单. ","date":"2024-08-14","objectID":"/posts/memprofiling/:1:1","tags":null,"title":"Go 内存泄漏排查","uri":"/posts/memprofiling/"},{"categories":null,"content":"直接处理 排查内存泄漏与修复 ","date":"2024-08-14","objectID":"/posts/memprofiling/:1:2","tags":null,"title":"Go 内存泄漏排查","uri":"/posts/memprofiling/"},{"categories":null,"content":"思路 复现生产环境场景 在测试环境里,对比此次版本的功能改动点进行压测,难以压测的直接for循环将变动函数调用增加10倍来调试或者将time.ticker的频率放大10倍. 使用pyroscope分析 pyroscope https://pyroscope.io/ 是基于golang的pprof工具进行采集. 使用pprof go官方自带的工具 https://github.com/google/pprof 使用perf perf是个经典的分析工具, https://github.com/google/perf_data_converter 可以将perf的分析报告转化为pprof的格式进行分析 ","date":"2024-08-14","objectID":"/posts/memprofiling/:1:3","tags":null,"title":"Go 内存泄漏排查","uri":"/posts/memprofiling/"},{"categories":null,"content":"pprof着手分析 ","date":"2024-08-14","objectID":"/posts/memprofiling/:2:0","tags":null,"title":"Go 内存泄漏排查","uri":"/posts/memprofiling/"},{"categories":null,"content":"下载heap分析文件 接入pprof后,可用curl下载分析文件 curl -o heapfile http://localhost/debug/pprof/heap?seconds=30 . 上述命令可捕获30秒的堆文件分析. ","date":"2024-08-14","objectID":"/posts/memprofiling/:2:1","tags":null,"title":"Go 内存泄漏排查","uri":"/posts/memprofiling/"},{"categories":null,"content":"查看pprof官方自带文档 关于pprof的使用说明,请务必看完 https://github.com/google/pprof/blob/main/doc/README.md 该文讲述了 pprof字段 flat cum 代表的含义. 可通过web的方式进行UI交互或者cli方式交互. go tool pprof -http :8810 heapfile 调用图里面的颜色,矩形大小,矩形边缘粗细,虚线箭头和实线箭头的含义解释 可对比2个时间段的pprof文件,go tool pprof --base base.heap current.heap ","date":"2024-08-14","objectID":"/posts/memprofiling/:2:2","tags":null,"title":"Go 内存泄漏排查","uri":"/posts/memprofiling/"},{"categories":null,"content":"内存采样率控制 runtime.MemProfileRate 采样率控制. 假设runtime.MemProfileRate=N,那么采样为1/N进行.如果觉得采样率小了,可以在测试环境进行调整. ","date":"2024-08-14","objectID":"/posts/memprofiling/:2:3","tags":null,"title":"Go 内存泄漏排查","uri":"/posts/memprofiling/"},{"categories":null,"content":"空闲 Heap http://localhost/debug/pprof/heap?debug=1 有个HeapIdle指标. 下载go官方源码用IDE打开即可明白各个指标的含义,比如HeapIdle . HeapIdle = HeapSys - heapInUse 我们可以用htop查看go程序进程,其中htop里面的RES为真实的内存占用. HeapSys占了go程序的内存大头,理论上是接近go应用相关进程的RES. pprof工具是不会展示HeapIdle部分,因为HeapIdle是go应用可以复用的内存,我们可以手动runtime.GC()进行空闲Heap释放. ","date":"2024-08-14","objectID":"/posts/memprofiling/:2:4","tags":null,"title":"Go 内存泄漏排查","uri":"/posts/memprofiling/"},{"categories":null,"content":"背景 临时租赁服务器,进行灰度压测,进行大量并发cURL.测试机器压榨单机极限性能. ","date":"2024-05-29","objectID":"/posts/press_linux/:1:0","tags":null,"title":"linux压测配置优化","uri":"/posts/press_linux/"},{"categories":null,"content":"修改单进程句柄限制 ","date":"2024-05-29","objectID":"/posts/press_linux/:2:0","tags":null,"title":"linux压测配置优化","uri":"/posts/press_linux/"},{"categories":null,"content":"查看进程最大文件数 # 查看进程最大文件数 ulimit -n ","date":"2024-05-29","objectID":"/posts/press_linux/:2:1","tags":null,"title":"linux压测配置优化","uri":"/posts/press_linux/"},{"categories":null,"content":"修改进程最大文件数 ulimit -SHn 1048576 S 表示设置软限制(soft limit)。软限制是指系统允许进程使用的资源上限,但进程可以尝试超过这个限制。 H 表示设置硬限制(hard limit)。硬限制是指系统绝对允许进程使用的资源上限,即使进程尝试超过这个限制,系统也会阻止它。 n 表示设置进程可以打开的文件描述符的最大数量 # 防止重启后失效 echo ulimit -HSn 1048576 \u003e\u003e /etc/rc.local echo ulimit -HSn 1048576 \u003e\u003e/root/.bash_profile ","date":"2024-05-29","objectID":"/posts/press_linux/:2:2","tags":null,"title":"linux压测配置优化","uri":"/posts/press_linux/"},{"categories":null,"content":"ulimit影响因素 fs.nr_open;进程最大文件描述符数 fs.file-max;系统最大文件描述符数 ","date":"2024-05-29","objectID":"/posts/press_linux/:2:3","tags":null,"title":"linux压测配置优化","uri":"/posts/press_linux/"},{"categories":null,"content":"修改/etc/sysctl.conf # /etc/sysctl.conf fs.file-max = 1048576 fs.nr_open=1048576 ","date":"2024-05-29","objectID":"/posts/press_linux/:2:4","tags":null,"title":"linux压测配置优化","uri":"/posts/press_linux/"},{"categories":null,"content":"nf_conntrack_max 开启 防止配置net.nf_conntrack_max报错 # 校验conntrack是否开启 lsmod |grep conntrack # 开启 ip_conntrack modprobe ip_conntrack ","date":"2024-05-29","objectID":"/posts/press_linux/:3:0","tags":null,"title":"linux压测配置优化","uri":"/posts/press_linux/"},{"categories":null,"content":"/etc/sysctl.conf配置修改 # 套接字优化 # 每个套接字的缓冲区大小 net.core.optmem_max= 81920 # 套接字接收缓冲区大小 net.core.rmem_max=513920 # 套接字发送缓冲区大小 net.core.wmem_max=513920 # TCP 接收缓冲区大小 net.ipv4.tcp_rmem=4096 87380 16777216 # TCP 发送缓冲区大小 net.ipv4.tcp_wmem=4096 65536 16777216 # UDP 缓冲区范围 net.ipv4.udp_mem=188562 251418 377124 # 提高请求数优化 # 处于 TIME_WAIT 状态的连接数量 net.ipv4.tcp_max_tw_buckets=1048576 # 连接跟踪表的大小;控制整个系统的连接跟踪表大小 net.netfilter.nf_conntrack_max = 1048576 # 越小系统尽快释放它们所占用的资源 net.ipv4.tcp_fin_timeout = 10 # 越小系统尽快释放它们所占用的资源 net.netfilter.nf_conntrack_tcp_timeout_time_wait =30 # 端口复用 net.ipv4.tcp_tw_reuse = 1 #端口范围限制 net.ipv4.ip_local_port_range = 1024 65000 # 控制单个网络接口的连接跟踪表大小 net.nf_conntrack_max = 1048576 # 暂未确定 net.ipv4.tcp_tw_recycle = 1 net.ipv4.tcp_timestamps = 0 net.ipv4.tcp_window_scaling = 0 net.ipv4.tcp_sack = 0 net.core.netdev_max_backlog = 30000 net.ipv4.tcp_no_metrics_save=1 net.core.somaxconn = 65535 net.ipv4.tcp_syncookies = 0 net.ipv4.tcp_max_orphans = 262144 net.ipv4.tcp_max_syn_backlog = 262144 net.ipv4.tcp_synack_retries = 2 net.ipv4.tcp_syn_retries = 2 net.ipv4.tcp_tw_recycle = 1 # 长连接优化 # 缩短最后一次数据包到 Keepalive 探测包的间隔时间 net.ipv4.tcp_keepalive_time=600 # 减少Keepalive 探测失败后,一直到通知应用程序前的重试次数 net.ipv4.tcp_keepalive_probes=3 # 缩短发送 Keepalive 探测包的间隔时间 net.ipv4.tcp_keepalive_intvl=30 ","date":"2024-05-29","objectID":"/posts/press_linux/:4:0","tags":null,"title":"linux压测配置优化","uri":"/posts/press_linux/"},{"categories":null,"content":"修改后使其生效 /sbin/sysctl -p /etc/sysctl.conf /sbin/sysctl -w net.ipv4.route.flush=1 ","date":"2024-05-29","objectID":"/posts/press_linux/:4:1","tags":null,"title":"linux压测配置优化","uri":"/posts/press_linux/"},{"categories":null,"content":" Linux性能优化实战 笔记 https://time.geekbang.org/column/intro/100020901 ","date":"2024-05-25","objectID":"/posts/linux_debug/:0:0","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"模拟工具 ","date":"2024-05-25","objectID":"/posts/linux_debug/:1:0","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"stress stress 是一个 Linux 系统压力测试工具,这里我们用作异常进程模拟平均负载升高的场景 apk add stress-ng # 一个 CPU 使用率 100% stress --cpu 1 --timeout 600 # 模拟 I/O 压力 stress -i 1 --timeout 600 # 8个进程 stress -c 8 --timeout 600 ","date":"2024-05-25","objectID":"/posts/linux_debug/:1:1","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"sysbench sysbench 是一个多线程的基准测试工具,一般用来评估不同系统参数下的数据库负载情况 # 以10个线程运行5分钟的基准测试,模拟多线程切换的问题 $ sysbench --threads=10 --max-time=300 threads run ","date":"2024-05-25","objectID":"/posts/linux_debug/:1:2","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"ab ab(apache bench)是一个常用的 HTTP 服务性能测试工具 # 并发10个请求测试Nginx性能,总共测试100个请求 $ ab -c 10 -n 100 http://192.168.0.10:10000/ ","date":"2024-05-25","objectID":"/posts/linux_debug/:1:3","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"排查工具 ","date":"2024-05-25","objectID":"/posts/linux_debug/:2:0","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"uptime 系统负载 了解系统的负载情况 $ uptime 14:42 up 56 days, 18:09, 2 users, load averages: 1.48 2.10 2.48 #{{当前时间}} {{系统运行时间}} {{正在登录用户数}} {{过去1分钟的平均负载}} {{过去5分钟的平均负载}} {{过去15分钟的平均负载}} # 持续观察 -d 参数表示高亮显示变化的区域 watch -d uptime ","date":"2024-05-25","objectID":"/posts/linux_debug/:2:1","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"mpstat CPU mpstat 是一个常用的多核 CPU 性能分析工具,用来实时查看每个 CPU 的性能指标,以及所有CPU的平均指标 # -P ALL 表示监控所有CPU,后面数字5表示间隔5秒后输出一组数据 mpstat -P ALL 5 ","date":"2024-05-25","objectID":"/posts/linux_debug/:2:2","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"pidstat 进程 pidstat 是一个常用的进程性能分析工具,用来实时查看进程的 CPU、内存、I/O 以及上下文切换等性能指标 apk add sysstat # 间隔5秒后输出一组数据;-u 代表cpu指标 pidstat -u 5 1 # 每隔5秒输出1组数据; -w 查看每个进程上下文切换的情况 pidstat -w 5 # 每隔1秒输出1组数据(需要 Ctrl+C 才结束) # -w参数表示输出进程切换指标,而-u参数则表示输出CPU使用指标 $ pidstat -w -u 1 # 每隔1秒输出一组数据(需要 Ctrl+C 才结束) # -wt 参数表示输出线程的上下文切换指标 $ pidstat -wt 1 ","date":"2024-05-25","objectID":"/posts/linux_debug/:2:3","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"vmstat 系统性能 vmstat 是一个常用的系统性能分析工具,主要用来分析系统的内存使用情况,也常用来分析 CPU 上下文切换和中断的次数 cs(context switch)是每秒上下文切换的次数。 in(interrupt)则是每秒中断的次数。 r(Running or Runnable)是就绪队列的长度,也就是正在运行和等待CPU的进程数。 b(Blocked)则是处于不可中断睡眠状态的进程数。 cswch ,表示每秒自愿上下文切换(voluntary context switches)的次数 nvcswch ,表示每秒非自愿上下文切换(non voluntary context switches)的次数 apk add procps # 每隔5秒输出1组数据 vmstat 5 # 间隔1秒后输出1组数据 $ vmstat 1 1 # 每隔1秒输出1组数据(需要Ctrl+C才结束) $ vmstat 1 ","date":"2024-05-25","objectID":"/posts/linux_debug/:2:4","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"top user(通常缩写为 us),代表用户态 CPU 时间。注意,它不包括下面的 nice 时间,但包括了 guest 时间。 nice(通常缩写为 ni),代表低优先级用户态 CPU 时间,也就是进程的 nice 值被调整为 1-19 之间时的 CPU 时间。这里注意,nice 可取值范围是 -20 到 19,数值越大,优先级反而越低。 system(通常缩写为sys),代表内核态 CPU 时间。 idle(通常缩写为id),代表空闲时间。注意,它不包括等待 I/O 的时间(iowait)。 iowait(通常缩写为 wa),代表等待 I/O 的 CPU 时间。 irq(通常缩写为 hi),代表处理硬中断的 CPU 时间。 softirq(通常缩写为 si),代表处理软中断的 CPU 时间。 steal(通常缩写为 st),代表当系统运行在虚拟机中的时候,被其他虚拟机占用的 CPU 时间。 guest(通常缩写为 guest),代表通过虚拟化运行其他操作系统的时间,也就是运行虚拟机的 CPU 时间。 guest_nice(通常缩写为 gnice),代表以低优先级运行虚拟机的时间。 top运行时候按1 ,切换到每个 CPU 的使用率 VIRT 是进程虚拟内存的大小,只要是进程申请过的内存,即便还没有真正分配物理内存,也会计算在内。 RES 是常驻内存的大小,也就是进程实际使用的物理内存大小,但不包括 Swap 和共享内存。 SHR 是共享内存的大小,比如与其他进程共同使用的共享内存、加载的动态链接库以及程序的代码段等。 %MEM 是进程使用物理内存占系统总内存的百分比。 S列值意义 R 是 Running 或 Runnable 的缩写,表示进程在 CPU 的就绪队列中,正在运行或者正在等待运行。 D 是 Disk Sleep 的缩写,也就是不可中断状态睡眠(Uninterruptible Sleep),一般表示进程正在跟硬件交互,并且交互过程不允许被其他进程或中断打断。 Z 是 Zombie 的缩写,它表示僵尸进程,也就是进程实际上已经结束了,但是父进程还没有回收它的资源(比如进程的描述符、PID 等)。 S 是 Interruptible Sleep 的缩写,也就是可中断状态睡眠,表示进程因为等待某个事件而被系统挂起。当进程等待的事件发生时,它会被唤醒并进入 R 状态。 I 是 Idle 的缩写,也就是空闲状态,用在不可中断睡眠的内核线程上。硬件交互导致的不可中断进程用 D 表示,但对某些内核线程来说,它们有可能实际上并没有任何负载,用 Idle 正是为了区分这种情况。要注意,D 状态的进程会导致平均负载升高, I 状态的进程却不会。 T 或者 t,也就是 Stopped 或 Traced 的缩写,表示进程处于暂停或者跟踪状态. 向一个进程发送 SIGSTOP 信号,它就会因响应这个信号变成暂停状态(Stopped); 再向它发送 SIGCONT 信号,进程又会恢复运行 (如果进程是终端里直接启动的,则需要你用 fg 命令,恢复到前台运行)。 而当你用调试器(如 gdb)调试一个进程时,在使用断点中断进程后,进程就会变成跟踪状态, 这其实也是一种特殊的暂停状态,只不过你可以用调试器来跟踪并按需要控制进程的运行。 X,也就是 Dead 的缩写,表示进程已经消亡 ","date":"2024-05-25","objectID":"/posts/linux_debug/:2:5","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"perf 热点函数 类似于 top,它能够实时显示占用 CPU 时钟最多的函数或者指令,因此可以用来查找热点函数 perf top # -g开启调用关系分析,-p指定php-fpm的进程号21515 $ perf top -g -p 21515 # 记录性能事件,等待大约15秒后按 Ctrl+C 退出 $ perf record -g # 查看报告 $ perf report ","date":"2024-05-25","objectID":"/posts/linux_debug/:2:6","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"ps 进程 # 从所有进程中查找PID是24344的进程 $ ps aux | grep 24344 ","date":"2024-05-25","objectID":"/posts/linux_debug/:2:7","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"pstree 进程关系 用树状形式显示所有进程之间的关系 $ pstree | grep stress ","date":"2024-05-25","objectID":"/posts/linux_debug/:2:8","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"strace 跟踪syscall 跟踪进程系统调用的工具 strace -p 6082 ","date":"2024-05-25","objectID":"/posts/linux_debug/:2:9","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"sar 网络收发 是一个系统活动报告工具,既可以实时查看系统的当前活动,又可以配置保存和报告历史统计数据 # -n DEV 表示显示网络收发的报告,间隔1秒输出一组数据 $ sar -n DEV item解释 rxpck/s 和 txpck/s 分别表示每秒接收、发送的网络帧数,也就是 PPS rxkB/s 和 txkB/s 分别表示每秒接收、发送的千字节数,也就是 BPS ","date":"2024-05-25","objectID":"/posts/linux_debug/:2:10","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"hping3 安全 是一个可以构造 TCP/IP 协议数据包的工具,可以对系统进行安全审计、防火墙测试等 # -S参数表示设置TCP协议的SYN(同步序列号),-p表示目的端口为80 # -i u100表示每隔100微秒发送一个网络帧 # 注:如果你在实践过程中现象不明显,可以尝试把100调小,比如调成10甚至1 $ hping3 -S -p 80 -i u100 192.168.0.30 ","date":"2024-05-25","objectID":"/posts/linux_debug/:2:11","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"tcpdump 抓包 是一个常用的网络抓包工具,常用来分析各种网络问题 # -i eth0 只抓取eth0网卡,-n不解析协议名和主机名 # tcp port 80表示只抓取tcp协议并且端口号为80的网络帧 $ tcpdump -i eth0 -n tcp port 80 ","date":"2024-05-25","objectID":"/posts/linux_debug/:2:12","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"其他工具 execsnoop 专为短时进程设计的工具。它通过 ftrace 实时监控进程的 exec() 行为,并输出短时进程的基本信息,包括进程 PID、父进程 PID、命令行参数以及执行的结果 https://github.com/brendangregg/perf-tools/blob/master/execsnoop dstat 吸收了 vmstat、iostat、ifstat 等几种工具的优点 ","date":"2024-05-25","objectID":"/posts/linux_debug/:2:13","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"CPU # cpu个数 grep 'model name' /proc/cpuinfo | wc -l ","date":"2024-05-25","objectID":"/posts/linux_debug/:3:0","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"上下文切换 # -d 参数表示高亮显示变化的区域 watch -d cat /proc/interrupts ","date":"2024-05-25","objectID":"/posts/linux_debug/:3:1","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"系统的 CPU 使用率很高 碰到常规问题无法解释的 CPU 使用率情况时,首先要想到有可能是短时应用导致的问题. pstree会很有用,找到它们的父进程,再从父进程所在的应用入手,排查问题的根源 ","date":"2024-05-25","objectID":"/posts/linux_debug/:3:2","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"中断 例子: 硬中断: 把网卡的数据读到内存中,然后更新一下硬件寄存器的状态; 软中断: 被软中断信号唤醒后,需要从内存中找到网络数据,再按照网络协议栈,对数据进行逐层解析和处理,直到把它送给应用程序; ","date":"2024-05-25","objectID":"/posts/linux_debug/:4:0","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"硬中断 用来快速处理中断;在中断禁止模式下运行,主要处理跟硬件紧密相关的或时间敏感的工作 cat /proc/interrupts ","date":"2024-05-25","objectID":"/posts/linux_debug/:4:1","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"软中断 用来异步处理硬中断未完成的工作,包括网络收发、定时、调度、RCU锁等各种类型;通常以内核线程的方式运行 cat /proc/softirqs 存在item TIMER(定时中断) NET_RX(网络接收); SCHED(内核调度) RCU(RCU锁) ","date":"2024-05-25","objectID":"/posts/linux_debug/:4:2","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"内存 ","date":"2024-05-25","objectID":"/posts/linux_debug/:5:0","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"case1 写文件 通过读取随机设备,生成一个500MB大小的文件 dd if=/dev/urandom of=/tmp/file bs=1M count=500 Cache在不停地增长,而Buffer基本保持不变;Cache是文件读的缓存;Cache也会缓存写文件时的数据 ","date":"2024-05-25","objectID":"/posts/linux_debug/:5:1","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"case2 写磁盘 写磁盘用到了大量的Buffer ","date":"2024-05-25","objectID":"/posts/linux_debug/:5:2","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"case3 读取文件 Buffer保持不变,而Cache则在不停增长;Cache是对文件读的页缓存 ","date":"2024-05-25","objectID":"/posts/linux_debug/:5:3","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"case4 读磁盘 Buffer和Cache都在增长,但显然Buffer的增长快很多; ","date":"2024-05-25","objectID":"/posts/linux_debug/:5:4","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"磁盘性能指标 使用率,是指磁盘处理I/O的时间百分比。过高的使用率(比如超过80%),通常意味着磁盘 I/O 存在性能瓶颈。 饱和度,是指磁盘处理 I/O 的繁忙程度。过高的饱和度,意味着磁盘存在严重的性能瓶颈。当饱和度为 100% 时,磁盘无法接受新的 I/O 请求。 IOPS(Input/Output Per Second),是指每秒的 I/O 请求数。 吞吐量,是指每秒的 I/O 请求大小。 响应时间,是指 I/O 请求从发出到收到响应的间隔时间。 ","date":"2024-05-25","objectID":"/posts/linux_debug/:6:0","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"网络指标 带宽,表示链路的最大传输速率,单位通常为 b/s (比特/秒)。 吞吐量,表示单位时间内成功传输的数据量,单位通常为 b/s(比特/秒)或者 B/s(字节/秒)。吞吐量受带宽限制,而吞吐量/带宽,也就是该网络的使用率。 延时,表示从网络请求发出后,一直到收到远端响应,所需要的时间延迟。在不同场景中,这一指标可能会有不同含义。比如,它可以表示,建立连接需要的时间(比如 TCP 握手延时),或一个数据包往返所需的时间(比如 RTT)。 PPS,是 Packet Per Second(包/秒)的缩写,表示以网络包为单位的传输速率。PPS 通常用来评估网络的转发能力,比如硬件交换机,通常可以达到线性转发(即 PPS 可以达到或者接近理论最大值)。而基于 Linux 服务器的转发,则容易受网络包大小的影响。 网络的可用性(网络能否正常通信) 并发连接数(TCP连接数量) 丢包率(丢包百分比) 重传率(重新传输的网络包比例) ","date":"2024-05-25","objectID":"/posts/linux_debug/:7:0","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"工具 ifconfig netstat ss sar ping ","date":"2024-05-25","objectID":"/posts/linux_debug/:7:1","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"NAT 分类 静态 NAT,即内网 IP 与公网 IP 是一对一的永久映射关系; 动态 NAT,即内网 IP 从公网 IP 池中,动态选择一个进行映射; 网络地址端口转换 NAPT(Network Address and Port Translation),即把内网 IP 映射到公网 IP 的不同端口上,让多个内网 IP 可以共享同一个公网 IP 地址。 ","date":"2024-05-25","objectID":"/posts/linux_debug/:8:0","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"网络优化 ","date":"2024-05-25","objectID":"/posts/linux_debug/:9:0","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"提高网络的吞吐量 增大每个套接字的缓冲区大小 net.core.optmem_max; 增大套接字接收缓冲区大小 net.core.rmem_max 和发送缓冲区大小 net.core.wmem_max; 增大 TCP 接收缓冲区大小 net.ipv4.tcp_rmem 和发送缓冲区大小 net.ipv4.tcp_wmem 为 TCP 连接设置 TCP_NODELAY 后,就可以禁用 Nagle 算法; 为 TCP 连接开启 TCP_CORK 后,可以让小包聚合成大包后再发送(注意会阻塞小包的发送); 使用 SO_SNDBUF 和 SO_RCVBUF ,可以分别调整套接字发送缓冲区和接收缓冲区的大小。 ","date":"2024-05-25","objectID":"/posts/linux_debug/:9:1","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"请求数比较大 增大处于 TIME_WAIT 状态的连接数量 net.ipv4.tcp_max_tw_buckets,并增大连接跟踪表的大小 net.netfilter.nf_conntrack_max 减小 net.ipv4.tcp_fin_timeout 和 net.netfilter.nf_conntrack_tcp_timeout_time_wait ,让系统尽快释放它们所占用的资源 开启端口复用 net.ipv4.tcp_tw_reuse。这样,被 TIME_WAIT 状态占用的端口,还能用到新建的连接中。 增大本地端口的范围 net.ipv4.ip_local_port_range 。这样就可以支持更多连接,提高整体的并发能力 增加最大文件描述符的数量。你可以使用 fs.nr_open 和 fs.file-max ,分别增大进程和系统的最大文件描述符数;或在应用程序的 systemd 配置文件中,配置 LimitNOFILE ,设置应用程序的最大文件描述符数。 ","date":"2024-05-25","objectID":"/posts/linux_debug/:9:2","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"缓解 SYN FLOOD 增大 TCP 半连接的最大数量 net.ipv4.tcp_max_syn_backlog ,或者开启 TCP SYN Cookies net.ipv4.tcp_syncookies ,来绕开半连接数量限制的问题(注意,这两个选项不可同时使用) 减少 SYN_RECV 状态的连接重传 SYN+ACK 包的次数 net.ipv4.tcp_synack_retries ","date":"2024-05-25","objectID":"/posts/linux_debug/:9:3","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"长连接 缩短最后一次数据包到 Keepalive 探测包的间隔时间 net.ipv4.tcp_keepalive_time 缩短发送 Keepalive 探测包的间隔时间 net.ipv4.tcp_keepalive_intvl; 减少Keepalive 探测失败后,一直到通知应用程序前的重试次数 net.ipv4.tcp_keepalive_probes ","date":"2024-05-25","objectID":"/posts/linux_debug/:9:4","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"UPD优化 增大套接字缓冲区大小以及 UDP 缓冲区范围 增大本地端口号的范围 根据 MTU 大小,调整 UDP 数据包的大小,减少或者避免分片的发生 ","date":"2024-05-25","objectID":"/posts/linux_debug/:9:5","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"路由 在需要转发的服务器中,比如用作 NAT 网关的服务器或者使用 Docker 容器时,开启 IP 转发,即设置 net.ipv4.ip_forward = 1。 调整数据包的生存周期 TTL,比如设置 net.ipv4.ip_default_ttl = 64。注意,增大该值会降低系统性能。 开启数据包的反向地址校验,比如设置 net.ipv4.conf.eth0.rp_filter = 1。这样可以防止 IP 欺骗,并减少伪造 IP 带来的 DDoS 问题。 ","date":"2024-05-25","objectID":"/posts/linux_debug/:9:6","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"分片 调整 MTU(Maximum Transmission Unit)的大小 ","date":"2024-05-25","objectID":"/posts/linux_debug/:9:7","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":"ICMP 以禁止 ICMP 协议,即设置 net.ipv4.icmp_echo_ignore_all = 1 禁止广播 ICMP,即设置 net.ipv4.icmp_echo_ignore_broadcasts = 1 ","date":"2024-05-25","objectID":"/posts/linux_debug/:9:8","tags":null,"title":"linux排查","uri":"/posts/linux_debug/"},{"categories":null,"content":" # 下载 pip install supervisor # 初始化配置 echo_supervisord_conf \u003e /etc/supervisord.conf vim /etc/supervisord.conf append [program:process1] command=/root/process1 autorestart=true # 载入服务 supervisord -c /etc/supervisord.conf # 启动 supervisorctl start process1 # 停止 supervisorctl stop process1 # 更新了 /etc/supervisord.conf后 supervisorctl reload ","date":"2024-05-23","objectID":"/posts/supervisor/:0:0","tags":null,"title":"supervisor搭建","uri":"/posts/supervisor/"},{"categories":null,"content":"检查TCP端口连通性 nc -vz www.example.com 80 v是verbose mode 使用-z参数快速扫描端口状态,是否开放 ","date":"2024-04-27","objectID":"/posts/network_check/:1:0","tags":null,"title":"排查网络","uri":"/posts/network_check/"},{"categories":null,"content":"window下powershell Test-NetConnection -ComputerName 127.0.0.1 -Port 6379 ","date":"2024-04-27","objectID":"/posts/network_check/:1:1","tags":null,"title":"排查网络","uri":"/posts/network_check/"},{"categories":null,"content":"检查网络延时 mtr baidu.com -r 数字单位是ms,r是report的意思 ","date":"2024-04-27","objectID":"/posts/network_check/:2:0","tags":null,"title":"排查网络","uri":"/posts/network_check/"},{"categories":null,"content":"ping ping检查范围限于ICMP协议 ","date":"2024-04-27","objectID":"/posts/network_check/:3:0","tags":null,"title":"排查网络","uri":"/posts/network_check/"},{"categories":null,"content":"kill端口 window # 寻找占用80端口 netstat -ano |findstr 80 # kill进程 taskkill /f /pid 28020 ","date":"2024-04-27","objectID":"/posts/network_check/:4:0","tags":null,"title":"排查网络","uri":"/posts/network_check/"},{"categories":null,"content":"找到进程的启动命令 window环境 wmic process where \"processid=1323\" get processid,commandline ","date":"2024-04-27","objectID":"/posts/network_check/:4:1","tags":null,"title":"排查网络","uri":"/posts/network_check/"},{"categories":null,"content":"redis架构 目的: 针对不同的业务特性,选择合适的架构. ","date":"2024-04-27","objectID":"/posts/redis/:1:0","tags":null,"title":"Redis实操记录","uri":"/posts/redis/"},{"categories":null,"content":"单机模式 一台redis节点,适合本地使用. 若机器挂了则无解. ","date":"2024-04-27","objectID":"/posts/redis/:1:1","tags":null,"title":"Redis实操记录","uri":"/posts/redis/"},{"categories":null,"content":"主从模式 一台写节点,多台从节点,适合多读少写场景. 若写压力上来,则无解. ","date":"2024-04-27","objectID":"/posts/redis/:1:2","tags":null,"title":"Redis实操记录","uri":"/posts/redis/"},{"categories":null,"content":"哨兵模式 写节点自动转移,满足高可用.适合多读少写场景. 若写压力上来,则有瓶颈.写节点挂了会转移,写节点会故障一段时间. 若不彻底解决写压力,无法根治问题. ","date":"2024-04-27","objectID":"/posts/redis/:1:3","tags":null,"title":"Redis实操记录","uri":"/posts/redis/"},{"categories":null,"content":"集群模式 属于分布式架构,可以堆机器解决写压力. ","date":"2024-04-27","objectID":"/posts/redis/:1:4","tags":null,"title":"Redis实操记录","uri":"/posts/redis/"},{"categories":null,"content":"redis连接数 目的: 提高应用性能,避免频繁的创建和销毁连接. 使用redis连接池. 需要埋点redis连接池的命中率. 若空闲连接持续为空,则明显连接数不够用需要提升. 根据业务压测,确定redis连接数的合理范围. ","date":"2024-04-27","objectID":"/posts/redis/:2:0","tags":null,"title":"Redis实操记录","uri":"/posts/redis/"},{"categories":null,"content":"关闭连接 当应用关闭时,记得close连接. ","date":"2024-04-27","objectID":"/posts/redis/:2:1","tags":null,"title":"Redis实操记录","uri":"/posts/redis/"},{"categories":null,"content":"redis缓存策略 ","date":"2024-04-27","objectID":"/posts/redis/:3:0","tags":null,"title":"Redis实操记录","uri":"/posts/redis/"},{"categories":null,"content":"获取redis缓存策略 config get maxmemory-policy 默认是noeviction ","date":"2024-04-27","objectID":"/posts/redis/:3:1","tags":null,"title":"Redis实操记录","uri":"/posts/redis/"},{"categories":null,"content":"LRU与LFU算法 Least Recently Used :最近最少使用 Least Frequently Used : 最近最不常用 阿里云的redis策略是选择volatile-lru redis.conf maxmemory-policy volatile-lru ","date":"2024-04-27","objectID":"/posts/redis/:3:2","tags":null,"title":"Redis实操记录","uri":"/posts/redis/"},{"categories":null,"content":"查询redis的热点key lfu算法下可使用redis-cli --hotkeys,查询redis的热点key. ","date":"2024-04-27","objectID":"/posts/redis/:3:3","tags":null,"title":"Redis实操记录","uri":"/posts/redis/"},{"categories":null,"content":"线上排查 ","date":"2024-04-27","objectID":"/posts/redis/:4:0","tags":null,"title":"Redis实操记录","uri":"/posts/redis/"},{"categories":null,"content":"查找大key redis-cli --bigkeys ","date":"2024-04-27","objectID":"/posts/redis/:4:1","tags":null,"title":"Redis实操记录","uri":"/posts/redis/"},{"categories":null,"content":"设置慢日志 # 慢日志长度 CONFIG GET slowlog-max-len # 设置 慢日志长度 CONFIG SET slowlog-max-len 128 设置慢日志时间 # 单位时间为微妙 CONFIG SET slowlog-log-slower-than 10000 获取慢日志 # 获取5个数量 SLOWLOG get 5 # 过滤获取get操作相关的慢查询 redis-cli SLOWLOG get 128 |grep -A2 -B2 get ","date":"2024-04-27","objectID":"/posts/redis/:4:2","tags":null,"title":"Redis实操记录","uri":"/posts/redis/"},{"categories":null,"content":"生产优化 ","date":"2024-04-27","objectID":"/posts/redis/:5:0","tags":null,"title":"Redis实操记录","uri":"/posts/redis/"},{"categories":null,"content":"多线程模式 多线程模式,可利用多核CPU # 开启多线程模式 具体数字查询官网建议 io-threads 3 ","date":"2024-04-27","objectID":"/posts/redis/:5:1","tags":null,"title":"Redis实操记录","uri":"/posts/redis/"},{"categories":null,"content":"压测 redis-benchmark -d 128 -c 200 -n 1000000 -t set -q --threads 2 ","date":"2024-04-27","objectID":"/posts/redis/:5:2","tags":null,"title":"Redis实操记录","uri":"/posts/redis/"},{"categories":null,"content":"生产配置详解 https://xie.infoq.cn/article/906db4e8327990c309fc7554f ","date":"2024-04-27","objectID":"/posts/redis/:5:3","tags":null,"title":"Redis实操记录","uri":"/posts/redis/"},{"categories":null,"content":"调试模式 ","date":"2024-04-27","objectID":"/posts/redis/:6:0","tags":null,"title":"Redis实操记录","uri":"/posts/redis/"},{"categories":null,"content":"开放远程连接 # 允许其他主机连接 protected-mode no # bind 0.0.0.0 ","date":"2024-04-27","objectID":"/posts/redis/:6:1","tags":null,"title":"Redis实操记录","uri":"/posts/redis/"},{"categories":null,"content":"开启dump.db # 进行快照保存 save 900 1 save 300 10 save 60 10000 # 数据存放路径 dir ./ ","date":"2024-04-27","objectID":"/posts/redis/:6:2","tags":null,"title":"Redis实操记录","uri":"/posts/redis/"},{"categories":null,"content":"导入包 go get -u github.com/go-kratos/kratos/contrib/metrics/prometheus/v2 ","date":"2024-02-08","objectID":"/posts/gometrics/:1:0","tags":null,"title":"Go metrics","uri":"/posts/gometrics/"},{"categories":null,"content":"注册路由 // 导入pkg import \"github.com/prometheus/client_golang/prometheus/promhttp\" // http 服务注册此路由 router.Handle(\"/metrics\", promhttp.Handler()) ","date":"2024-02-08","objectID":"/posts/gometrics/:2:0","tags":null,"title":"Go metrics","uri":"/posts/gometrics/"},{"categories":null,"content":"验证是否引入metrics curl /metrics 可以看到默认的数据 ","date":"2024-02-08","objectID":"/posts/gometrics/:3:0","tags":null,"title":"Go metrics","uri":"/posts/gometrics/"},{"categories":null,"content":"定义一个指标 var _metricRequests = prometheus.NewCounterVec(prometheus.CounterOpts{ Namespace: \"server\", Subsystem: \"requests\", Name: \"code_total\", Help: \"The total number of processed requests\", }, []string{\"kind\", \"operation\", \"code\", \"reason\"}) ","date":"2024-02-08","objectID":"/posts/gometrics/:4:0","tags":null,"title":"Go metrics","uri":"/posts/gometrics/"},{"categories":null,"content":"注册该指标 import \"github.com/prometheus/client_golang/prometheus\" prometheus.MustRegister(_metricRequests) ","date":"2024-02-08","objectID":"/posts/gometrics/:5:0","tags":null,"title":"Go metrics","uri":"/posts/gometrics/"},{"categories":null,"content":"使用指标 var requests = prom.NewCounter(_metricRequests) requests.With(\"get\", \"/\", \"200\", \"OK\").Inc() ","date":"2024-02-08","objectID":"/posts/gometrics/:6:0","tags":null,"title":"Go metrics","uri":"/posts/gometrics/"},{"categories":null,"content":"验证定义指标是否生效 当我们使用完指标后 即可查看 # HELP server_requests_code_total The total number of processed requests # TYPE server_requests_code_total counter server_requests_code_total{code=\"200\",kind=\"get\",operation=\"/\",reason=\"OK\"} 1 ","date":"2024-02-08","objectID":"/posts/gometrics/:7:0","tags":null,"title":"Go metrics","uri":"/posts/gometrics/"},{"categories":null,"content":"具体代码 https://github.com/matteo-gz/gometrics ","date":"2024-02-08","objectID":"/posts/gometrics/:8:0","tags":null,"title":"Go metrics","uri":"/posts/gometrics/"},{"categories":null,"content":"这个办法是通过闲鱼APP上找人,利用UBL key解锁小米BL. 此方法需要消耗金钱,即购买UBL key的钱. 免费的方法为 https://github.com/MlgmXyysd/Xiaomi-HyperOS-BootLoader-Bypass ,但是无法解锁小米14之后的机型. ","date":"2023-12-30","objectID":"/posts/xiaomiunlock/:0:0","tags":null,"title":"小米解锁BL","uri":"/posts/xiaomiunlock/"},{"categories":null,"content":"准备工作 ","date":"2023-12-30","objectID":"/posts/xiaomiunlock/:1:0","tags":null,"title":"小米解锁BL","uri":"/posts/xiaomiunlock/"},{"categories":null,"content":"下载客户端 https://xiaomikey.net/ window环境需要 ","date":"2023-12-30","objectID":"/posts/xiaomiunlock/:1:1","tags":null,"title":"小米解锁BL","uri":"/posts/xiaomiunlock/"},{"categories":null,"content":"下载驱动 https://xiaomiflashtool.com/ 让xiaomikey客户端识别出小米手机, 理论上xiaomikey软件里面包含了xiaomiflash ","date":"2023-12-30","objectID":"/posts/xiaomiunlock/:1:2","tags":null,"title":"小米解锁BL","uri":"/posts/xiaomiunlock/"},{"categories":null,"content":"下载ADB https://developer.android.com/tools/releases/platform-tools 将路径追加尽系统path. adb devices ","date":"2023-12-30","objectID":"/posts/xiaomiunlock/:1:3","tags":null,"title":"小米解锁BL","uri":"/posts/xiaomiunlock/"},{"categories":null,"content":"准备刷机 ","date":"2023-12-30","objectID":"/posts/xiaomiunlock/:2:0","tags":null,"title":"小米解锁BL","uri":"/posts/xiaomiunlock/"},{"categories":null,"content":"小米手机进入开发者模式 点击系统版本 连续点击5次 即可进入开发者模式 ","date":"2023-12-30","objectID":"/posts/xiaomiunlock/:2:1","tags":null,"title":"小米解锁BL","uri":"/posts/xiaomiunlock/"},{"categories":null,"content":"开发者模式下进行USB调试 要求 必须登录小米账号 必须插入sim卡 必须使用移动网络 在开发者模式下 打开允许USB调试. 电脑插入手机,手机选择信任电脑的连接. ","date":"2023-12-30","objectID":"/posts/xiaomiunlock/:2:2","tags":null,"title":"小米解锁BL","uri":"/posts/xiaomiunlock/"},{"categories":null,"content":"adb进入fastboot模式 # 查看设备 adb devices # 进入fastboot adb reboot bootloader ","date":"2023-12-30","objectID":"/posts/xiaomiunlock/:2:3","tags":null,"title":"小米解锁BL","uri":"/posts/xiaomiunlock/"},{"categories":null,"content":"登录xiaomikey 打开软件,选择 unlock boot- ubl key. 点击 unlock bootloader 此时会读取fastboot模式下的小米手机信息. 此时会生成 UBL token. 将UBL token 兑换成 UBL key. 然后填入UBL key 点击apply ubl key 可解锁. 过程中确保网络能连接小米服务器. ","date":"2023-12-30","objectID":"/posts/xiaomiunlock/:2:4","tags":null,"title":"小米解锁BL","uri":"/posts/xiaomiunlock/"},{"categories":null,"content":"若操作失败 如果点击unlock bootloader后遇到duplicate token的话 再次进入fastboot,再次进行点击unlock bootloader重复过程 # 再次进入fastboot fastboot reboot bootloader ","date":"2023-12-30","objectID":"/posts/xiaomiunlock/:2:5","tags":null,"title":"小米解锁BL","uri":"/posts/xiaomiunlock/"},{"categories":null,"content":"fastboot模式 恢复至正常 fastboot reboot ","date":"2023-12-30","objectID":"/posts/xiaomiunlock/:2:6","tags":null,"title":"小米解锁BL","uri":"/posts/xiaomiunlock/"},{"categories":null,"content":"资料 ","date":"2023-12-13","objectID":"/posts/socks5/:1:0","tags":null,"title":"socks5 协议","uri":"/posts/socks5/"},{"categories":null,"content":"rfc1928 SOCKS Protocol Version 5 https://datatracker.ietf.org/doc/html/rfc1928 socks5目标: TCP 和 UDP 域中的客户端-服务器应用程序提供一个框架,以便方便、安全地使用网络防火墙的服务 ","date":"2023-12-13","objectID":"/posts/socks5/:1:1","tags":null,"title":"socks5 协议","uri":"/posts/socks5/"},{"categories":null,"content":"字节序 0x01234567 在字节顺序中表现 Big-Endian 0x100: 0x01 0x101: 0x23 0x102: 0x45 0x103: 0x67 Little-Endian 0x100: 0x67 0x101: 0x45 0x102: 0x23 0x103: 0x01 ","date":"2023-12-13","objectID":"/posts/socks5/:1:2","tags":null,"title":"socks5 协议","uri":"/posts/socks5/"},{"categories":null,"content":"rfc1929 Username/Password Authentication for SOCKS V5 https://datatracker.ietf.org/doc/html/rfc1929 ","date":"2023-12-13","objectID":"/posts/socks5/:1:3","tags":null,"title":"socks5 协议","uri":"/posts/socks5/"},{"categories":null,"content":"过程 ","date":"2023-12-13","objectID":"/posts/socks5/:2:0","tags":null,"title":"socks5 协议","uri":"/posts/socks5/"},{"categories":null,"content":"1.TCP连接 3次握手后,客户端 连接 服务端socks5端口1080 ","date":"2023-12-13","objectID":"/posts/socks5/:2:1","tags":null,"title":"socks5 协议","uri":"/posts/socks5/"},{"categories":null,"content":"2.协商环节 ","date":"2023-12-13","objectID":"/posts/socks5/:2:2","tags":null,"title":"socks5 协议","uri":"/posts/socks5/"},{"categories":null,"content":"2.1.客户端发送给服务端 X'05’ , X开头的数据都是十六进制 报文格式: +----+----------+----------+ |VER | NMETHODS | METHODS | +----+----------+----------+ | 1 | 1 | 1 to 255 | +----+----------+----------+ 字段解释: VER 版本号,X'05' NMETHODS 支持的认证方法数量 METHODS 支持的认证方法ID列表 最小3个byte长度: package socks5 var ( VER [1]byte NMETHODS [1]byte METHODS [1]byte ) 最大257byte长度: package socks5 var ( VER [1]byte NMETHODS [1]byte METHODS [255]byte ) ","date":"2023-12-13","objectID":"/posts/socks5/:2:3","tags":null,"title":"socks5 协议","uri":"/posts/socks5/"},{"categories":null,"content":"2.2.服务端响应客户端 +----+--------+ |VER | METHOD | +----+--------+ | 1 | 1 | +----+--------+ 报文格式: VER 版本号 METHOD 从客户端给定选择的认证方法里面选择其中一种. METHOD值: X'00' 无认证需要 X'01' GSSAPI X'02' 用户名,密码方式验证 X'03' to X'7F' IANA 分配 X'80' to X'FE' 私人方法保留 X'FF' 没有可接受的方法列表,此时认证失败,客户端必须关闭连接. 总共2个byte长度: package socks5 var ( VER [1]byte METHOD [1]byte ) ","date":"2023-12-13","objectID":"/posts/socks5/:2:4","tags":null,"title":"socks5 协议","uri":"/posts/socks5/"},{"categories":null,"content":"3.子协商 若服务端响应METHOD为X'02',则进行用户名密码校验 ","date":"2023-12-13","objectID":"/posts/socks5/:2:5","tags":null,"title":"socks5 协议","uri":"/posts/socks5/"},{"categories":null,"content":"3.1.用户名密码认证 ","date":"2023-12-13","objectID":"/posts/socks5/:2:6","tags":null,"title":"socks5 协议","uri":"/posts/socks5/"},{"categories":null,"content":"3.1.1.客户端发送 +----+------+----------+------+----------+ |VER | ULEN | UNAME | PLEN | PASSWD | +----+------+----------+------+----------+ | 1 | 1 | 1 to 255 | 1 | 1 to 255 | +----+------+----------+------+----------+ VER socks5版本 ULEN 用户名长度 UNAME 用户名 PLEN 密码长度 PASSWD 密码 最小长度5个字节 Ver byte Ulen byte Uname [1]byte Plen byte Passwd [1]byte 最大长度513字节 Ver byte Ulen byte Uname [255]byte Plen byte Passwd [255]byte ","date":"2023-12-13","objectID":"/posts/socks5/:2:7","tags":null,"title":"socks5 协议","uri":"/posts/socks5/"},{"categories":null,"content":"3.1.2.服务端响应 +----+--------+ |VER | STATUS | +----+--------+ | 1 | 1 | +----+--------+ STATUS X'00’ 表示成功 其他值则客户端必须关闭连接 长度为2byte VER [1]byte STATUS [1]byte ","date":"2023-12-13","objectID":"/posts/socks5/:2:8","tags":null,"title":"socks5 协议","uri":"/posts/socks5/"},{"categories":null,"content":"4.Requests请求 +----+-----+-------+------+----------+----------+ |VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT | +----+-----+-------+------+----------+----------+ | 1 | 1 | X'00' | 1 | Variable | 2 | +----+-----+-------+------+----------+----------+ VER: 协议版本 CMD: 命令 0x01: CONNECT 建立 TCP 连接 0x02: BIND 上报反向连接地址 0x03: 关联 UDP 请求 RSV: 保留字段,值为 0x00 ATYP: 地址类型 0x01: IPv4 0x03: 域名 fully-qualified domain name. 0x04:IPv6 DST.ADDR 期望目标地址 DST.PORT 期望目标端口 采用big-endian表示 type AddressType byte const ( IPV4 AddressType = 1 IPV6 AddressType = 4 DOMAIN AddressType = 3 IPv4len = 4 IPv6len = 16 ) type SocksReply struct { Ver byte Cmd byte Rsv byte Atyp AddressType DstAddr [addressLength]byte DstPort [2]byte } func addressLength(atyp AddressType) int { switch atyp { case IPV4: return net.IPv4len case IPV6: return net.IPv6len case DOMAIN: return toDstAddr(domain) } } // 255为域名最大长度 // 最大域名长度 https://en.wikipedia.org/wiki/Fully_qualified_domain_name // https://en.wikipedia.org/wiki/SOCKS //1 byte of name length followed by 1–255 bytes for the domain name // 比如域名长度为 200 ,则第一位值为200,后面是域名值 // The first octet of the address field contains the number of octets of name that follow, there is no terminating NUL octet. func toDstAddr(domain string) []byte { // 将域名转换为 []byte 类型 domainBytes := []byte(domain) // 计算域名的字节长度 domainLen := len(domainBytes) // 创建一个包含域名字节长度和域名字节的 []byte 类型的数组 dstAddr := make([]byte, 1+domainLen) // 将域名的字节长度写入 dstAddr 的第一个字节 dstAddr[0] = byte(domainLen) // 将域名的字节写入 dstAddr 的剩余字节 copy(dstAddr[1:], domainBytes) return dstAddr } 域名下最大长度为262字节,7(固定字段长度)+域名长度 ipv4最大长度为10字节 ipv4最大长度为22字节 ","date":"2023-12-13","objectID":"/posts/socks5/:2:9","tags":null,"title":"socks5 协议","uri":"/posts/socks5/"},{"categories":null,"content":"5.Replies +----+-----+-------+------+----------+----------+ |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT | +----+-----+-------+------+----------+----------+ | 1 | 1 | X'00' | 1 | Variable | 2 | +----+-----+-------+------+----------+----------+ VER 协议版本 REP 回复字段 X'00' 已成功 X'01' 通常的socks服务失败 X'02' 规则集内不允许 X'03' 网络不可达 X'04' 主机不可达 X'05' 连接已拒绝 X'06' TTL 过期 X'07' 命令不被支持 X'08' 地址类型不被支持 X'09' 至 X'FF' 没有定义 RSV ATYP BND.ADDR 服务绑定地址 BND.PORT 服务绑定端口 采用big-endian表示 ","date":"2023-12-13","objectID":"/posts/socks5/:2:10","tags":null,"title":"socks5 协议","uri":"/posts/socks5/"},{"categories":null,"content":"类型 ","date":"2023-12-13","objectID":"/posts/socks5/:3:0","tags":null,"title":"socks5 协议","uri":"/posts/socks5/"},{"categories":null,"content":"CONNECT 在对CONNECT请求的回复中,BND.PORT包含了服务器分配给连接目标主机的端口号,而BND.ADDR包含了对应的IP地址。 提供的BND.ADDR地址通常与客户端用来连接SOCKS服务器的IP地址不同,因为这样的服务器通常支持多个网络接口。 SOCKS服务器应该考虑DST.ADDR和DST.PORT以及客户端源地址和端口来评估CONNECT请求。 ","date":"2023-12-13","objectID":"/posts/socks5/:3:1","tags":null,"title":"socks5 协议","uri":"/posts/socks5/"},{"categories":null,"content":"BIND BIND请求用于那些需要client接受server连接的协议。 FTP就是一个典型示例,它使用 主 client-to-server 连接传输命令和状态报告, 但可能使用server-to-client连接按需传输数据(如LS、GET、PUT)。 在应用协议中,客户端应该只在使用 CONNECT 请求建立主连接后,才使用 BIND 请求建立次连接. SOCKS服务器应该在评估BIND请求时考虑 DST.ADDR和DST.PORT。 在BIND操作过程中,SOCKS服务器会向客户端发送两个回复。 第一个回复是在服务器创建并绑定新套接字后发送。 BND.PORT字段包含SOCKS服务器为监听传入连接分配的端口号。 BND.ADDR字段包含相关联的IP地址。 客户端通常会使用这些信息通过主或控制连接通知应用服务器会合地址。 第二个回复仅在待定传入连接成功或失败后发送。 在第二个回复中,BND.PORT和BND.ADDR字段包含连接主机的地址和端口号. ","date":"2023-12-13","objectID":"/posts/socks5/:3:2","tags":null,"title":"socks5 协议","uri":"/posts/socks5/"},{"categories":null,"content":"UDP ASSOCIATE UDP ASSOCIATE 请求用于在 UDP 中继进程 中建立一个关联,以便处理 UDP 数据报。 DST.ADDR 和 DST.PORT 字段包含客户端期望用于发送 UDP 数据报的地址和端口。 服务器可以根据这些信息限制对关联的访问。 如果客户端在发送 UDP ASSOCIATE 请求时没有这些信息,则必须使用端口号和地址全部为 0。 UDP 关联会在发起 UDP ASSOCIATE 请求的 TCP 连接终止时 终止。 在对 UDP ASSOCIATE 请求的响应中, BND.PORT 和 BND.ADDR 字段指示客户端必须将 UDP 请求消息发送到哪个端口/地址进行中继。 ","date":"2023-12-13","objectID":"/posts/socks5/:3:3","tags":null,"title":"socks5 协议","uri":"/posts/socks5/"},{"categories":null,"content":"基于 UDP 的客户端程序 基于 UDP 的客户端必须将数据包发送到 UDP 中继服务器, 端口号为 UDP ASSOCIATE 请求响应中 BND.PORT 字段指定的端口。 如果选定的认证方法支持封装来保证真实性、完整性和/或保密性,数据包必须使用相应的封装方法进行封装。 每个 UDP 数据包都携带一个 UDP 请求头,其中包含 +----+------+------+----------+----------+----------+ |RSV | FRAG | ATYP | DST.ADDR | DST.PORT | DATA | +----+------+------+----------+----------+----------+ | 2 | 1 | 1 | Variable | 2 | Variable | +----+------+------+----------+----------+----------+ RSV (Reserved):保留字段,必须设置为 0x0000。 FRAG (Fragment):片段标志,用于指示数据包是否被分片:Current fragment number 最高位: 0:表示数据包没有被分片。 1:表示数据包是分片的一部分。 其他位: 用于表示分片的顺序 范围为1-127 ATYP (Address Type):地址类型,指定目标地址的类型: 0x01:IPv4 地址。 0x03:域名。 0x04:IPv6 地址。 DST.ADDR (Destination Address):根据 ATYP 指定的类型,可以是 IP 地址或域名。 DST.PORT (Destination Port):目标端口号。 DATA (User Data):用户数据,封装后的实际数据内容。 ","date":"2023-12-13","objectID":"/posts/socks5/:4:0","tags":null,"title":"socks5 协议","uri":"/posts/socks5/"},{"categories":null,"content":"数据包转发 当 UDP 中继服务器决定转发一个 UDP 数据包时,它会默默地进行,不会通知请求客户端。 同样,它也会丢弃无法或不会转发的数据包。 ","date":"2023-12-13","objectID":"/posts/socks5/:4:1","tags":null,"title":"socks5 协议","uri":"/posts/socks5/"},{"categories":null,"content":"回复数据包处理 当 UDP 中继服务器从远程主机收到回复数据包时,它必须使用上述 UDP 请求头和任何与认证方法相关的封装对该数据包进行封装。 UDP 中继服务器必须从 SOCKS 服务器获取预计将发送数据包到 BND.PORT 的客户端的 IP 地址。 它必须丢弃来自任何除了记录在特定关联中的源 IP 地址之外的任何数据包。 ","date":"2023-12-13","objectID":"/posts/socks5/:4:2","tags":null,"title":"socks5 协议","uri":"/posts/socks5/"},{"categories":null,"content":"数据包分片 FRAG 字段指示数据包是否被分片: 最高位指示片段序列的结束。 X'00' 值表示该数据包是独立的。 1 到 127 之间的值指示片段在片段序列中的位置。 每个接收器都会有一个用于重新组装片段的队列和一个与这些片段相关的重新组装计时器。 当重新组装计时器过期或新到达的 FRAG 字段的值小于该片段序列中处理的最高 FRAG 值时,重新组装队列必须重新初始化并放弃相关的片段。 重新组装计时器必须至少为 5 秒。 建议应用程序尽可能避免数据包分片。 ","date":"2023-12-13","objectID":"/posts/socks5/:4:3","tags":null,"title":"socks5 协议","uri":"/posts/socks5/"},{"categories":null,"content":"不支持分片的实现 实现分片是可选的;不支持分片的实现必须丢弃任何 FRAG 字段不是 X'00' 的数据包。 ","date":"2023-12-13","objectID":"/posts/socks5/:4:4","tags":null,"title":"socks5 协议","uri":"/posts/socks5/"},{"categories":null,"content":"UDP 编程接口 一个支持 SOCKS 的 UDP 编程接口必须报告低于操作系统提供的实际空间的可用 UDP 数据包缓冲区大小: 如果 ATYP 为 X'01',则减少 10 + 与方法相关的字节。 如果 ATYP 为 X'03',则减少 262 + 与方法相关的字节。 如果 ATYP 为 X'04',则减少 20 + 与方法相关的字节。 ","date":"2023-12-13","objectID":"/posts/socks5/:4:5","tags":null,"title":"socks5 协议","uri":"/posts/socks5/"},{"categories":null,"content":"Project CS notes 100 go mistakes chinese arena docs coding ","date":"2023-09-13","objectID":"/about/:1:0","tags":null,"title":"关于","uri":"/about/"},{"categories":null,"content":"Tool prof – A WebUI tool for Golang pprof chatroom-gpt3 – chat room webUI with chatGPT ","date":"2023-09-13","objectID":"/about/:2:0","tags":null,"title":"关于","uri":"/about/"},{"categories":null,"content":"显卡挑选 原文which gpu for deep learning by Tim Dettmers - 2023/01/30 对此摘抄了 显卡工作原理 与 显卡关键因素 算力产品 AutoDL ","date":"2023-08-12","objectID":"/posts/gpu/:1:0","tags":null,"title":"显卡相关","uri":"/posts/gpu/"},{"categories":null,"content":"显卡工作原理 ","date":"2023-08-12","objectID":"/posts/gpu/:2:0","tags":null,"title":"显卡相关","uri":"/posts/gpu/"},{"categories":null,"content":"结论 许多人说GPU快是因为 matrix multiplication 矩阵乘法 和 convolution 卷积 高效,Tim Dettmers认为是memory bandwidth 内存带宽. ","date":"2023-08-12","objectID":"/posts/gpu/:2:1","tags":null,"title":"显卡相关","uri":"/posts/gpu/"},{"categories":null,"content":"内存带宽优点 CPU是延迟优化的,而GPU是带宽优化的.类比CPU是法拉利,GPU是大卡车, 在从 随机 A点 运货到 随机 B点 过程中, CPU可以快速获取 RAM Random Access Memory 中的一些memory,而GPU则更慢(latency 延迟 要高得多), 但是CPU需要多次来回才能完成其工作,而GPU可以一次获取更多memory 内存. CPU擅长快速获取少量内存(5 3 7), 而GPU擅长获取大量内存(矩阵乘法:(A*B)*C). 最好的CPU有大约 50GB/s,而最好的GPU有 750GB/s 的内存带宽. 如果计算操作需要的内存越多,GPU相对于CPU的优势就越明显.但是仍然存在可能会损害GPU性能的延迟. 一辆大卡车每次旅行可能都能拿起很多包裹,但问题是你要等很长时间,直到下一组包裹到达. 如果不解决这个问题,即使对于大量数据,GPU 也会非常慢.那么这个问题是如何解决的呢? ","date":"2023-08-12","objectID":"/posts/gpu/:2:2","tags":null,"title":"显卡相关","uri":"/posts/gpu/"},{"categories":null,"content":"线程并行 如果你要求一辆大卡车进行多次旅行来取包裹,一旦卡车离开进行下一次旅行,你总是会等待很长时间才能收到下一批包裹——卡车只是很慢. 但是,如果您现在使用由法拉利和大型卡车组成的车队(线程并行),并且你有很多包裹(大块内存如 matrix 矩阵)的工作,那么你将等待第一辆卡车, 但在那之后你将根本没有等待时间 — 卸载包裹需要花费大量时间,以至于所有卡车都将在卸载位置B排队,以便你始终可以直接访问你的包裹(memory). 这有效地隐藏了延迟,以便GPU提供高带宽,同时在线程并行性下隐藏其延迟 — 因此对于大块内存,GPU提供最佳的内存带宽, 同时几乎没有由于线程并行延迟而导致的缺点. 这是GPU在深度学习方面比CPU更快的第二个原因.作为旁注,你还将了解为什么更多线程对CPU没有意义:法拉利车队在任何情况下都没有真正的好处. ","date":"2023-08-12","objectID":"/posts/gpu/:2:3","tags":null,"title":"显卡相关","uri":"/posts/gpu/"},{"categories":null,"content":"其他优势 但GPU的优势并不止于此. 这是将内存从main memory (RAM)获取到芯片上的local memory (L1 cache 和 registers 寄存器)的第一步. 第二步对性能不太重要,但仍增加了GPU的领先优势. 所有执行的计算都发生在直接连接到执行单元(CPU内核,GPU stream processor 流处理器)的registers中. ","date":"2023-08-12","objectID":"/posts/gpu/:2:4","tags":null,"title":"显卡相关","uri":"/posts/gpu/"},{"categories":null,"content":"内存大小与访问速度均衡 通常,fast L1和register memory非常靠近执行引擎,并且你希望保持这些内存较小,以便快速访问. 与执行引擎的距离增加会大大降低内存访问速度,因此访问它的距离越大,它的速度就越慢. 如果你让你的内存越来越大,那么,反过来, 它访问它的内存会变慢(平均而言,在小商店里找到你想买的东西比在大商店里找到你想买的东西要快,即使你知道那件东西在哪里). 因此,register files的大小是有限的 - 我们在这里只是处于物理学的极限,每一纳米都很重要,我们希望保持它们很小. ","date":"2023-08-12","objectID":"/posts/gpu/:2:5","tags":null,"title":"显卡相关","uri":"/posts/gpu/"},{"categories":null,"content":"register比CPU大 GPU 的优势在于它有 a small pack of registers 可以提供给每个处理单元(流处理器或 SM Streaming Multiprocessor),且很多. 因此,我们总共可以拥有大量的register memory,特点是非常小,因此非常快. 这导致聚合GPU registers 大小比CPU大 30倍 以上,并且速度仍然是其两倍,这意味着高达 14MB 的 registers memory 以惊人的 80TB/s 的速度运行. 相比之下,CPU L1 cache 仅以大约 5TB/s 的速度运行,这非常慢,大小约为 1MB;CPU registers的大小通常约为 64-128KB,运行速度为 10-20TB/s. 当然,这种数字比较有点缺陷,因为registers的操作与 GPU registers略有不同(有点像苹果和橙子),但这里的大小差异比速度的差异更重要,而且确实有所不同. ","date":"2023-08-12","objectID":"/posts/gpu/:2:6","tags":null,"title":"显卡相关","uri":"/posts/gpu/"},{"categories":null,"content":"register利用率 作为旁注,GPU中的完全register利用率起初似乎很难实现,因为它是最小的计算单元,需要手动微调以获得良好的性能。 但是,NVIDIA 开发了有用的编译器工具,可以指示每个流处理器何时使用过多或过少的registers。 调整 GPU 代码以利用适量的registers和 L1 cache 以实现快速性能很容易。 这使得GPU比其他架构(如Xeon Phis)更具优势, 在Xeon Phis中,这种利用很难实现并且调试起来很痛苦,最终使得很难在Xeon Phi上最大化性能. ","date":"2023-08-12","objectID":"/posts/gpu/:2:7","tags":null,"title":"显卡相关","uri":"/posts/gpu/"},{"categories":null,"content":"cache和register加速矩阵运算 最终的意义是,你可以将大量数据存储在GPU的L1 caches 和 register files中,以便重复使用卷积和矩阵乘法的tiles. 例如,最优的矩阵乘法算法使用 64x32 到 96x64 大小的2个矩阵tiles存储在L1 cache中, 以及一个 16x16 到 32x32 大小的数字 register tile 来存储每个thread 线程 block的输出总和 (1个thread block = 最多1024个threads;每个流处理器有8个thread blocks,在整个GPU中总共有60个流处理器)。 如果你有一个100MB 的矩阵,你可以将它分割成的较小矩阵去适应你的 cache 和 registers, 然后以每秒10-80TB 的速度进行三个矩阵tiles的矩阵乘法运算,速度非常快! 这是GPU比CPU快得多的第三个原因,也是它们非常适用于深度学习的原因。 ","date":"2023-08-12","objectID":"/posts/gpu/:2:8","tags":null,"title":"显卡相关","uri":"/posts/gpu/"},{"categories":null,"content":"瓶颈 请记住,较慢的内存始终是性能瓶颈的主要因素。 如果 95% 的内存移动发生在registers 中 (80TB/s),且5% 发生在main memory 中 (0.75TB/s), 那么你仍然将大部分时间花在main memory的内存访问上(大约是六倍). ","date":"2023-08-12","objectID":"/posts/gpu/:2:9","tags":null,"title":"显卡相关","uri":"/posts/gpu/"},{"categories":null,"content":"总结 因此,按重要性排序: 高带宽main memory 在线程并行性下隐藏内存访问延迟 大而快速的register和易于编程的L1 memory是使GPU非常适合深度学习的组件。 ","date":"2023-08-12","objectID":"/posts/gpu/:2:10","tags":null,"title":"显卡相关","uri":"/posts/gpu/"},{"categories":null,"content":"显卡关键因素 ","date":"2023-08-12","objectID":"/posts/gpu/:3:0","tags":null,"title":"显卡相关","uri":"/posts/gpu/"},{"categories":null,"content":"Tensor Cores Tensor Cores是执行非常高效矩阵乘法的微小核心. 由于任何深度神经网络中最昂贵的部分是矩阵乘法,因此Tensor Cores非常有用. 总之,它们是如此强大,以至于我不推荐任何没有Tensor Cores的 GPU. 重要性解释 举例: A*B=C 矩阵乘法 设定: 所有矩阵的大小为 32×32 要完全理解这个例子,你必须理解周期的概念。 如果处理器以 1GHz 运行,它每秒可以执行 10^9 个周期。 每个周期都代表一个计算的机会。但是,大多数情况下,操作需要的时间超过一个周期。 因此,我们本质上有一个队列,下一个操作需要等待下一个操作完成。这也称为操作的延迟。 下面是操作的一些重要延迟周期计时。这些时间可能会因每代GPU而异。这些数字适用于缓存相对较慢的Ampere GPU。 Global memory access (up to 80GB): ~380 cycles 周期 L2 cache: ~200 cycles L1 cache or Shared memory access (up to 128 kb per Streaming Multiprocessor): ~34 cycles Fused multiplication and addition, a*b+c (FFMA): 4 cycles Tensor Core matrix multiply: 1 cycle 每个操作总是由a pack of 32 threads 执行.这个 pack 被称为 a warp of threads. Warps通常以同步模式操作,即warp内的线程必须等待彼此。 GPU上的所有内存操作都经过warps优化。 例如,从global memory加载数据以32*4bytes的粒度进行,恰好是32 floats, 即每个warp中的每个线程恰好一个float。 在一个流处理器(SM)中,可以拥有最多32 warps,即1024个线程,这相当于与一个CPU核心等价的GPU部件。 一个SM的资源被分配给所有活动的warps。这意味着有时我们希望运行较少的warps, 以便每个warp拥有更多的 registers/shared memory/Tensor Core. 对于以下两个示例,我们假设具有相同的计算资源。 对于这个 32×32 矩阵乘法的小例子,我们使用 8 个 SM(大约是 RTX 3090 型号显卡 的 10%)和每个 SM 8 warps。 为了了解周期延迟如何与每个 SM 的线程数和每个 SM 的共享内存等资源一起发挥作用,我们现在看一下矩阵乘法的示例。 虽然以下示例大致遵循了有和没有Tensor Core的矩阵乘法计算步骤的顺序,但请注意,这些是非常简化的示例。 矩阵乘法的真实案例涉及更大的共享内存tiles和略有不同的计算模式。 无Tensor Core的矩阵乘法 如果我们想做一个 A*B=C 矩阵乘法,其中每个矩阵的大小为 32×32, 那么我们希望将我们重复访问的内存加载到共享内存中,因为它的延迟大约低五倍(200 个周期 vs 34 个周期)。 共享内存中的memory block 通常称为 a memory tile 或者 a tile。 通过使用 2*32 warps,可以将两个 32×32 floats 加载到共享内存tile 中并行发生。 我们有 8 个 SM,每个 SM 有 8 warps,因此由于并行化,我们只需要从全局内存到共享内存进行一次顺序加载,这需要 200 个周期。 要进行矩阵乘法,我们现在需要从共享内存 A 和共享内存 B 加载 32 个数字的vector,并执行a fused multiply-and-accumulate (FFMA). 然后将输出存储在 registers C中。我们划分工作,以便每个SM执行8倍点积(32×32)来计算8个C输出。 为什么这正好是 8(旧算法中的 4)是非常技术性的。 我推荐Scott Gray关于矩阵乘法的博客文章来理解这一点。 这意味着我们有 8 次共享内存访问,每次访问 34 个周期和 8 个 FFMA 操作(32 个并行),每个操作花费 4 个周期。 因此,我们总共有以下成本: 200 cycles (global memory) + 834 cycles (shared memory) + 84 cycles (FFMA) = 504 cycles 有Tensor Core的矩阵乘法 使用Tensor Core,我们可以在一个周期内执行 4×4 矩阵乘法。 为此,我们首先需要将内存放入Tensor Core。与上述类似,我们需要从全局内存(200 个周期)中读取并存储在共享内存中。 要进行 32×32 矩阵乘法,我们需要执行 8×8=64 Tensor Core运算。单个 SM 有 8 个Tensor Core。 因此,有了 8 SMs,我们就有了 64 个Tensor Core——正是我们需要的数量! 我们可以通过 1 次内存传输(34 个周期)将数据从共享内存传输到Tensor Core,然后执行这 64 个并行Tensor Core操作(1 个周期)。 这意味着Tensor Core矩阵乘法的总成本,在这种情况下,为: 200 cycles (global memory) + 34 cycles (shared memory) + 1 cycle (Tensor Core) = 235 cycles. 因此,我们通过Tensor Core将矩阵乘法成本从 504 个周期显着降低到 235 个周期。在这种简化的情况下,Tensor Core降低了共享内存访问和 FFMA 操作的成本。 此示例经过简化,例如,通常每个线程都需要计算在将数据从全局内存传输到共享内存时要读取和写入的内存。 通过新的Hooper (H100)架构,我们还拥有Tensor内存加速器(TMA)在硬件中计算这些索引,从而帮助每个线程专注于更多的计算而不是计算索引。 使用Tensor Core和异步副本 (RTX 30/RTX 40) 和 TMA (H100) 进行矩阵乘法 RTX 30 Ampere 和 RTX 40 Ada 系列 GPU 还支持在全局内存和共享内存之间执行异步传输。 H100 Hopper GPU 通过引入Tensor Memory Accelerator(TMA) 单元进一步扩展了这一点。 TMA 单元结合了异步副本和索引计算,可同时进行读取和写入,因此每个线程不再需要计算下一个要读取的元素,每个线程可以专注于执行更多的矩阵乘法计算。 这看起来如下。 TMA 单元将内存从全局内存获取到共享内存(200 个周期) 。数据到达后,TMA 单元从全局内存异步获取下一个数据块。发生这种情况时,线程从共享内存加载数据,并通过Tensor Core执行矩阵乘法。 线程完成后,它们等待 TMA 单元完成下一次数据传输,然后重复序列。 因此,由于异步性质,TMA 单元读取的第二个全局内存已经在线程处理当前共享内存tile时进行。 这意味着,第二次读取只需要 200 – 34 – 1 = 165 个周期。 由于我们执行许多读取,因此只有第一次内存访问会很慢,所有其他内存访问将与 TMA 单元部分重叠。 因此,平均而言,我们将时间减少了 35 个周期。 165 个周期(等待异步复制完成)+ 34 个周期(共享内存)+ 1 个周期(Tensor Core)= 200 个周期。 这使矩阵乘法又加速了 15%。 从这些例子中,可以清楚地看出为什么下一个属性,内存带宽,对于配备Tensor Core的GPU如此重要。 由于全局内存是迄今为止使用Tensor Core进行矩阵乘法的最大循环成本,因此如果可以减少全局内存延迟,我们甚至会拥有更快的 GPU。 我们可以通过增加存储器的时钟频率(每秒更多的周期,但也有更多的热量和更高的能量需求) 或通过增加可以在任何时间传输的元素数量(总线宽度)来做到这一点。 ","date":"2023-08-12","objectID":"/posts/gpu/:3:1","tags":null,"title":"显卡相关","uri":"/posts/gpu/"},{"categories":null,"content":"Memory Bandwidth 从上一节中,我们已经看到Tensor Core非常快。 事实上,速度如此之快,以至于它们在等待全局内存中的内存到达时大部分时间都处于空闲状态。 例如,在 GPT-3 大小的训练期间,它使用巨大的矩阵——越大,对Tensor Core越好——我们的Tensor Core TFLOPS 利用率约为 45-65%, 这意味着即使对于大型神经网络大约 50% 的时间,Tensor Core也是空闲的。 这意味着,当将两个 GPU 与Tensor Core进行比较时,每个 GPU 性能的最佳指标之一是它们的内存带宽。 例如,A100 GPU 的内存带宽为 1,555 GB/s,而 V100 的内存带宽为 900 GB/s。 因此,A100 与 V100 加速的基本估计值为 1555/900 = 1.73 倍。 ","date":"2023-08-12","objectID":"/posts/gpu/:3:2","tags":null,"title":"显卡相关","uri":"/posts/gpu/"},{"categories":null,"content":"L2 Cache / Shared Memory / L1 Cache / Registers 由于内存传输到Tensor Core是性能的限制因素,因此我们正在寻找其他 GPU 属性,以便更快地将内存传输到Tensor Core。 L2 Cache、Shared Memory、L1 Cache和使用的Registers数量都是相关的。 要了解内存层次结构如何实现更快的内存传输,它有助于了解如何在 GPU 上执行矩阵乘法。 为了执行矩阵乘法,我们利用 GPU 的内存层次结构,从慢速全局内存到更快的 L2 Cache, 再到快速的本地Shared Memory,再到闪电般的Registers。 但是,内存越快,它就越小。 虽然从逻辑上讲,L2 和 L1 内存是相同的,但 L2 Cache更大,因此检索缓存行需要遍历的平均物理距离更大。 你可以将 L1 和 L2 Cache视为要在其中检索物料的有组织的仓库。 你知道物品在哪里,但对于较大的仓库来说,去那里平均需要更长的时间。 这是 L1 和 L2 Cache之间的本质区别。大=慢,小=快。 对于矩阵乘法,我们可以将这种分层分离为越来越小的内存块,从而越来越快地执行非常快的矩阵乘法。 为此,我们需要将大矩阵乘法分成较小的子矩阵乘法。这些块称为memory tiles,或通常简称为tiles。 我们在本地Shared Memory中对这些较小的tiles执行矩阵乘法,该内存速度快且接近流式多处理器 (SM) — 相当于 CPU 内核。 使用Tensor Core,我们更进一步:我们获取每个tile并将这些tiles的一部分加载到Tensor Core中, 该Tensor Core由registers直接寻址。 L2 Cache中的矩阵内存tile比global GPU memory (GPU RAM) 快 3-5 倍, Shared Memory比global GPU memory快 ~7-10 倍,而Tensor Core的registers比global GPU memory快 ~200 倍。 拥有更大的tiles意味着我们可以重用更多的内存。 我在我的TPU vs GPU博客文章中详细写过这一点。事实上,你可以看到TPU的每个Tensor Core都有非常非常大的tiles。 因此,TPU 可以在每次从全局内存传输时重用更多的内存,这使得它们在矩阵乘法方面的效率比 GPU 高一些。 每个tile大小取决于每个流式处理多处理器(SM)的内存量以及所有 SM 中的 L2 cache量。我们在以下体系结构上具有以下共享内存大小: Volta (Titan V): 128kb shared memory / 6 MB L2 Turing (RTX 20s series): 96 kb shared memory / 5.5 MB L2 Ampere (RTX 30s series): 128 kb shared memory / 6 MB L2 Ada (RTX 40s series): 128 kb shared memory / 72 MB L2 我们看到 Ada 具有更大的二级缓存,允许更大的tile尺寸,从而减少了全局内存访问。 例如,在BERT大型训练期间 ,任何矩阵乘法的输入和权重矩阵都整齐地适合 Ada 的 L2 缓存(but not other Us). 因此,数据只需要从全局内存加载一次,然后数据就可以通过 L2 缓存获得,这使得 Ada 的这种架构的矩阵乘法速度提高了大约 1.5 – 2.0 倍。 对于较大的模型,训练期间的加速较低,但存在某些sweetspots,这可能会使某些模型更快。批量大小大于 8 的inference 也可以从较大的 L2 caches中受益匪浅。 ","date":"2023-08-12","objectID":"/posts/gpu/:3:3","tags":null,"title":"显卡相关","uri":"/posts/gpu/"},{"categories":["personal preference"],"content":"杂项 ","date":"2023-08-11","objectID":"/posts/win/:1:0","tags":null,"title":"Window偏好优化","uri":"/posts/win/"},{"categories":["personal preference"],"content":"默认展开win11的右键收缩菜单 How to Get Back Classic (Full) Context Menu in Windows 11 reg add HKCU\\Software\\Classes\\CLSID\\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\\InprocServer32 /ve /d \"\" /f ","date":"2023-08-11","objectID":"/posts/win/:1:1","tags":null,"title":"Window偏好优化","uri":"/posts/win/"},{"categories":["personal preference"],"content":"window图标快捷箭头优化 How to remove arrows from shortcuts in Windows 11 REG ADD \"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Icons\" /v 29 /t REG_SZ /d \"\" /f ","date":"2023-08-11","objectID":"/posts/win/:1:2","tags":null,"title":"Window偏好优化","uri":"/posts/win/"},{"categories":["personal preference"],"content":"分辨率 参考来源 【硬件科普】换了更高分辨率的显示器,软件界面反而模糊-Windows缩放详解 针对27寸 2K屏幕 ","date":"2023-08-11","objectID":"/posts/win/:2:0","tags":null,"title":"Window偏好优化","uri":"/posts/win/"},{"categories":["personal preference"],"content":"DSR调整 Nvidia control panel \u003e\u003e 3D settings \u003e\u003e Manage 3D settings \u003e\u003e global settings \u003e\u003e DSR-Factors 选择2.25x DL ","date":"2023-08-11","objectID":"/posts/win/:2:1","tags":null,"title":"Window偏好优化","uri":"/posts/win/"},{"categories":["personal preference"],"content":"显示设置调整 display resolution 选择 3840x2160 Scale 选择 250% ","date":"2023-08-11","objectID":"/posts/win/:2:2","tags":null,"title":"Window偏好优化","uri":"/posts/win/"},{"categories":["personal preference"],"content":"字体 参考来源 如何在 Windows 上享受更棒的字体渲染 https://sspai.com/post/52557 ","date":"2023-08-11","objectID":"/posts/win/:3:0","tags":null,"title":"Window偏好优化","uri":"/posts/win/"},{"categories":["personal preference"],"content":"安装字体 https://github.com/adobe-fonts/source-han-serif/releases 下载 Language Specific OTFs Simplified Chinese (简体中文) 解压后点击文件安装字体 ","date":"2023-08-11","objectID":"/posts/win/:3:1","tags":null,"title":"Window偏好优化","uri":"/posts/win/"},{"categories":["personal preference"],"content":"设置默认字体 https://github.com/Tatsu-syo/noMeiryoUI/releases 下载软件后,启动选择字体 All fonts \u003e\u003e - font name: source han sans sc medium - style: medium - size: 9 - character set: ansi apply all and exit ","date":"2023-08-11","objectID":"/posts/win/:3:2","tags":null,"title":"Window偏好优化","uri":"/posts/win/"},{"categories":["personal preference"],"content":"设置macType https://github.com/snowie2000/mactype/releases 下载安装,启动MacWiz.exe 选择服务加载 下一步选择配置文件 下载并选择 https://github.com/fython/MacType-SourceHanSerif 下的SourceHanSerif/Default.ini ","date":"2023-08-11","objectID":"/posts/win/:3:3","tags":null,"title":"Window偏好优化","uri":"/posts/win/"},{"categories":null,"content":"简介 一个语言模型,类似chatGPT. 可以本地部署, 下面列下规格 7b 需要6~8GB显存 13b 需要13~16GB显存 70b 需要48GB显存,可以2张4090 ","date":"2023-08-09","objectID":"/posts/llama/:1:0","tags":null,"title":"llama2模型 类chatGPT产品体验","uri":"/posts/llama/"},{"categories":null,"content":"安装 ","date":"2023-08-09","objectID":"/posts/llama/:2:0","tags":null,"title":"llama2模型 类chatGPT产品体验","uri":"/posts/llama/"},{"categories":null,"content":"申请和下载模型 点击 https://huggingface.co/meta-llama 选择模型 Llama2-chat,13B 下载 将会跳转到Facebook公司的申请界面,勾选协议,提交申请 平替方案 如果觉得麻烦 下载这个GGML模型 https://huggingface.co/TheBloke/Firefly-Llama2-13B-v1.2-GGML firefly-llama2-13b-v1.2.ggmlv3.q6_K.bin 文件链接 https://huggingface.co/TheBloke/Firefly-Llama2-13B-v1.2-GGML/blob/main/firefly-llama2-13b-v1.2.ggmlv3.q6_K.bin ","date":"2023-08-09","objectID":"/posts/llama/:2:1","tags":null,"title":"llama2模型 类chatGPT产品体验","uri":"/posts/llama/"},{"categories":null,"content":"python虚拟环境 # 创建python虚拟环境 python -m venv ./venv # 进行python虚拟环境 ./venv/Script/activate ","date":"2023-08-09","objectID":"/posts/llama/:2:2","tags":null,"title":"llama2模型 类chatGPT产品体验","uri":"/posts/llama/"},{"categories":null,"content":"安装pytorch with cuda # https://pytorch.org/get-started/locally/ pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 ","date":"2023-08-09","objectID":"/posts/llama/:2:3","tags":null,"title":"llama2模型 类chatGPT产品体验","uri":"/posts/llama/"},{"categories":null,"content":"安装ui # 安装ui git clone https://github.com/oobabooga/text-generation-webui.git # 进入ui目录 cd text-generation-webui # 安装ui依赖 pip install -r requirements.txt # 修复bitsandbytes bug pip uninstall bitsandbytes pip install bitsandbytes-windows # 启动UI python server.py ","date":"2023-08-09","objectID":"/posts/llama/:2:4","tags":null,"title":"llama2模型 类chatGPT产品体验","uri":"/posts/llama/"},{"categories":null,"content":"使用 ","date":"2023-08-09","objectID":"/posts/llama/:3:0","tags":null,"title":"llama2模型 类chatGPT产品体验","uri":"/posts/llama/"},{"categories":null,"content":"实操llama2 GGML 13B q6_K 将模型放入ui目录下的models文件夹, 重启服务python server.py cli界面会有一个url 打开本地web,来到首页 ","date":"2023-08-09","objectID":"/posts/llama/:3:1","tags":null,"title":"llama2模型 类chatGPT产品体验","uri":"/posts/llama/"},{"categories":null,"content":"操作页面 载入模型 点击Model选项卡,点击刷新模型图标按钮,下拉模型,选择load按钮, 点击save settings 选择聊天模型 点击session选项卡,选择mode:chat,然后apply and restart 开始聊天 在input框内部输入你的问题,点击generate 开始对话 ","date":"2023-08-09","objectID":"/posts/llama/:3:2","tags":null,"title":"llama2模型 类chatGPT产品体验","uri":"/posts/llama/"},{"categories":null,"content":"总结 用英文交流回复还行,用中文就太慢了 ","date":"2023-08-09","objectID":"/posts/llama/:4:0","tags":null,"title":"llama2模型 类chatGPT产品体验","uri":"/posts/llama/"},{"categories":null,"content":"简介 一个音频转文本的模型 https://github.com/openai/whisper ","date":"2023-08-08","objectID":"/posts/whisper/:1:0","tags":null,"title":"音频转文字 Whisper","uri":"/posts/whisper/"},{"categories":null,"content":"依赖 python ffmpeg ","date":"2023-08-08","objectID":"/posts/whisper/:1:1","tags":null,"title":"音频转文字 Whisper","uri":"/posts/whisper/"},{"categories":null,"content":"命令行使用 ","date":"2023-08-08","objectID":"/posts/whisper/:2:0","tags":null,"title":"音频转文字 Whisper","uri":"/posts/whisper/"},{"categories":null,"content":"验证GPU 在venv环境下 输入whisper -h –device # 如果默认是cpu 则证明cuda安装失败 # 这样也能验证cuda是否安装了 python -c \"import torch; print(torch.version.cuda)\" 重装torch gpu版本 # 卸载纯cpu版 pip uninstall torch # clean cache pip cache purge # copy from https://pytorch.org/get-started/locally/ pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 再次验证 whisper -h –device # 如果默认是cuda 则证明成功 运行demo whisper {vocieFile} --model large-v2 --model_dir {modelPath} \\ --ourput_dir {outputDir} --output_format txt --device cuda --language Chinese ","date":"2023-08-08","objectID":"/posts/whisper/:2:1","tags":null,"title":"音频转文字 Whisper","uri":"/posts/whisper/"},{"categories":null,"content":"界面版 界面版 https://github.com/Const-me/Whisper 用的模型是 https://huggingface.co/ggerganov/whisper.cpp/tree/main 执行任务速度有所提升,但是损失了辨别成功率 ","date":"2023-08-08","objectID":"/posts/whisper/:3:0","tags":null,"title":"音频转文字 Whisper","uri":"/posts/whisper/"},{"categories":null,"content":"声音提取器 非常的强大,用于人声,BGM提取 https://github.com/Anjok07/ultimatevocalremovergui ","date":"2023-08-08","objectID":"/posts/whisper/:3:1","tags":null,"title":"音频转文字 Whisper","uri":"/posts/whisper/"},{"categories":null,"content":"CPP版本构建 项目 https://github.com/ggerganov/whisper.cpp 在window上下载Visual Studio 2022 安装cuda ","date":"2023-08-08","objectID":"/posts/whisper/:4:0","tags":null,"title":"音频转文字 Whisper","uri":"/posts/whisper/"},{"categories":null,"content":"小问题 编译有GPU版本会遇到CUDA compile problems on Windows, Cmake error: No CUDA toolset found 根据文中提示,我这边的实操是 将 C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v11.8\\extras\\visual_studio_integration\\MSBuildExtensions 里面的文件全拷贝到 C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\MSBuild\\Microsoft\\VC\\v170\\BuildCustomizations 目录下 ","date":"2023-08-08","objectID":"/posts/whisper/:4:1","tags":null,"title":"音频转文字 Whisper","uri":"/posts/whisper/"},{"categories":null,"content":"编译 接下来进入到项目目录 mkdir build cd build cmake -DCMAKE_BUILD_TYPE=Release -DWHISPER_CUBLAS=1 .. cmake --build . --config Release 在build\\bin\\Release下就有main.exe了 mp3转wav ffmpeg -i input.mp3 -ar 16000 -ac 1 -c:a pcm_s16le output.wav wav转字幕 ./main -m {模型.bin} -f {.wav文件} -otxt {输出文件名} -l auto ","date":"2023-08-08","objectID":"/posts/whisper/:4:2","tags":null,"title":"音频转文字 Whisper","uri":"/posts/whisper/"},{"categories":null,"content":"简介 旨在个人快速回忆Stable Diffusion相关关系 ","date":"2023-08-08","objectID":"/posts/stablediffusionwebui/:1:0","tags":null,"title":"咒语生成图片 Stable Diffusion web UI","uri":"/posts/stablediffusionwebui/"},{"categories":null,"content":"Stable Diffusion 是一个深度学习,文转图模型. Stable Diffusion web UI 即面向用户提供界面操作工具, 链接为 https://github.com/AUTOMATIC1111/stable-diffusion-webui 其中该界面为英语,支持汉化插件 https://github.com/VinsonLaro/stable-diffusion-webui-chinese ","date":"2023-08-08","objectID":"/posts/stablediffusionwebui/:1:1","tags":null,"title":"咒语生成图片 Stable Diffusion web UI","uri":"/posts/stablediffusionwebui/"},{"categories":null,"content":"PyTorch 官网 https://pytorch.org/ 是一个深度学习的框架 我的安装选择 OS: Windows package: pip language: python compute Platform: CUDA ","date":"2023-08-08","objectID":"/posts/stablediffusionwebui/:1:2","tags":null,"title":"咒语生成图片 Stable Diffusion web UI","uri":"/posts/stablediffusionwebui/"},{"categories":null,"content":"教程 https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki ","date":"2023-08-08","objectID":"/posts/stablediffusionwebui/:1:3","tags":null,"title":"咒语生成图片 Stable Diffusion web UI","uri":"/posts/stablediffusionwebui/"},{"categories":null,"content":"启动 下载完web UI后,运行webui-user.bat即可 在运行过程避免不了报错,很考验python debug能力。 初始化 设置webui-user.bat参数 set PYTHON= #python文件路径 set GIT= # git文件路径 set VENV_DIR= # venv目录 set COMMANDLINE_ARGS=--xformers # 启动参数 将python,git的bin path 加入系统环境变量下的path。 另外确保安装了Microsoft Visual C++ Redistributable vc_redist.x64.exe 安装过程需要网络稳定,需要下载很多pkg 缓存冲突解决 直接删除./venv/lib/site-packages/下冲突的包,重新运行脚本. 或者命令行搞定 # 卸载具体包 pip uninstall 具体包 # clean cache pip cache purge 模型位置 一般放入./models/Stable-diffusion/ ","date":"2023-08-08","objectID":"/posts/stablediffusionwebui/:2:0","tags":null,"title":"咒语生成图片 Stable Diffusion web UI","uri":"/posts/stablediffusionwebui/"},{"categories":null,"content":".bat window平台下.bat脚本语法 :: 这是注释 ","date":"2023-08-08","objectID":"/posts/stablediffusionwebui/:2:1","tags":null,"title":"咒语生成图片 Stable Diffusion web UI","uri":"/posts/stablediffusionwebui/"},{"categories":null,"content":"venv 是Python的一个模块,用于创建隔离的Python环境。 虚拟环境允许你在同一台计算机上同时管理多个Python项目,每个项目都有自己独立的Python解释器和库。 这对于避免不同项目之间的依赖冲突非常有用,因为每个虚拟环境都有自己的依赖安装 # 创建虚拟环境 python3 -m venv myenv # 激活虚拟环境 .\\venv\\Scripts\\activate # 脱离环境 deactivate ","date":"2023-08-08","objectID":"/posts/stablediffusionwebui/:2:2","tags":null,"title":"咒语生成图片 Stable Diffusion web UI","uri":"/posts/stablediffusionwebui/"},{"categories":null,"content":"pip pip 是 Python 包管理器,用于在 Python 环境中安装、升级和管理各种第三方库和工具 # 安装numpy包 pip install numpy # 升级包 pip install --upgrade package_name # 卸载包 pip uninstall package_name # 搜索包 pip search package_name # 展示安装包 pip list -v # 按文件要求安装包 pip install -r requirements.txt ","date":"2023-08-08","objectID":"/posts/stablediffusionwebui/:2:3","tags":null,"title":"咒语生成图片 Stable Diffusion web UI","uri":"/posts/stablediffusionwebui/"},{"categories":null,"content":"使用 ","date":"2023-08-08","objectID":"/posts/stablediffusionwebui/:3:0","tags":null,"title":"咒语生成图片 Stable Diffusion web UI","uri":"/posts/stablediffusionwebui/"},{"categories":null,"content":"模型 https://civitai.com/ https://huggingface.co/ ","date":"2023-08-08","objectID":"/posts/stablediffusionwebui/:3:1","tags":null,"title":"咒语生成图片 Stable Diffusion web UI","uri":"/posts/stablediffusionwebui/"},{"categories":null,"content":"prompt https://tags.novelai.dev/ https://prompthero.com/ ","date":"2023-08-08","objectID":"/posts/stablediffusionwebui/:3:2","tags":null,"title":"咒语生成图片 Stable Diffusion web UI","uri":"/posts/stablediffusionwebui/"},{"categories":null,"content":"文生图产品 https://www.midjourney.com/ https://lexica.art/ ","date":"2023-08-08","objectID":"/posts/stablediffusionwebui/:3:3","tags":null,"title":"咒语生成图片 Stable Diffusion web UI","uri":"/posts/stablediffusionwebui/"},{"categories":null,"content":"目的 Go Kitex提供了自定义模板生成代码,使用起来挺方便的. 有望改造成支持公司内部go代码生成工具 https://www.cloudwego.io/zh/docs/kitex/tutorials/code-gen/custom_tpl/ ","date":"2023-08-07","objectID":"/posts/gencode/:1:0","tags":null,"title":"关于Go代码生成","uri":"/posts/gencode/"},{"categories":null,"content":"处理要素 ","date":"2023-08-07","objectID":"/posts/gencode/:2:0","tags":null,"title":"关于Go代码生成","uri":"/posts/gencode/"},{"categories":null,"content":"cli工具整合 这里推荐2个包,封装了cli和参数解析 https://github.com/spf13/cobra https://github.com/spf13/pflag ","date":"2023-08-07","objectID":"/posts/gencode/:2:1","tags":null,"title":"关于Go代码生成","uri":"/posts/gencode/"},{"categories":null,"content":"基本数据对象定义 提供了文件生成时的数据渲染对象 PackageInfo 模板渲染使用html/template语法 ","date":"2023-08-07","objectID":"/posts/gencode/:2:2","tags":null,"title":"关于Go代码生成","uri":"/posts/gencode/"},{"categories":null,"content":"额外参数在context中解析 cli传递参数过多会带来复杂性,需要额外的.json文件数据提供在上下文中解析. ","date":"2023-08-07","objectID":"/posts/gencode/:2:3","tags":null,"title":"关于Go代码生成","uri":"/posts/gencode/"},{"categories":null,"content":"多模板文件定义 通过指定目录加载其下所有模板文件 模板文件格式为.yaml 生成的文件路径也支持变量解析. 其中能独立定义新增代码部分 ","date":"2023-08-07","objectID":"/posts/gencode/:2:4","tags":null,"title":"关于Go代码生成","uri":"/posts/gencode/"},{"categories":null,"content":"统一入口 初始化和更新行为都为同一命令,减少处理成本 ","date":"2023-08-07","objectID":"/posts/gencode/:2:5","tags":null,"title":"关于Go代码生成","uri":"/posts/gencode/"},{"categories":null,"content":"额外点 多任务并行处理文件生成 跨平台支持 ","date":"2023-08-07","objectID":"/posts/gencode/:2:6","tags":null,"title":"关于Go代码生成","uri":"/posts/gencode/"},{"categories":null,"content":"设计考虑 以下是个人的建议,随便看看了解下 ","date":"2023-08-07","objectID":"/posts/component/:1:0","tags":null,"title":"go pkg包设计","uri":"/posts/component/"},{"categories":null,"content":"context支持 一般入参数context是第一个参数,提供了timeout机制 ","date":"2023-08-07","objectID":"/posts/component/:1:1","tags":null,"title":"go pkg包设计","uri":"/posts/component/"},{"categories":null,"content":"logger接口定义 在组件的初始化时,将使用方的日志实例进行接口约束, 要求实现其debug,error级别method. 可以参考gorm的logger设计 ","date":"2023-08-07","objectID":"/posts/component/:1:2","tags":null,"title":"go pkg包设计","uri":"/posts/component/"},{"categories":null,"content":"hook注入 方便使用方对metric的收集,可以参考redis hook设计 ","date":"2023-08-07","objectID":"/posts/component/:1:3","tags":null,"title":"go pkg包设计","uri":"/posts/component/"},{"categories":null,"content":"布局了解 这里只是提供参考建议 go官方 https://github.com/golang-standards/project-layout 知道internal目录对内部系统的保护 链接 https://go.dev/doc/go1.4#internalpackages ","date":"2023-08-07","objectID":"/posts/component/:1:4","tags":null,"title":"go pkg包设计","uri":"/posts/component/"},{"categories":null,"content":"跨平台支持 查看支持平台 go tool dist list 条件编译约束 //go:build (linux \u0026\u0026 386) || (darwin \u0026\u0026 !cgo) https://pkg.go.dev/cmd/go#hdr-Build_constraints ","date":"2023-08-07","objectID":"/posts/component/:1:5","tags":null,"title":"go pkg包设计","uri":"/posts/component/"},{"categories":null,"content":"linters集成 https://golangci-lint.run/ 提高代码质量 ","date":"2023-08-07","objectID":"/posts/component/:1:6","tags":null,"title":"go pkg包设计","uri":"/posts/component/"},{"categories":null,"content":"版本约束 具体查看 https://go.dev/ref/mod#versions ","date":"2023-08-07","objectID":"/posts/component/:1:7","tags":null,"title":"go pkg包设计","uri":"/posts/component/"},{"categories":null,"content":"依赖注入 https://github.com/google/wire 使得依赖关系变得整洁 ","date":"2023-08-07","objectID":"/posts/component/:1:8","tags":null,"title":"go pkg包设计","uri":"/posts/component/"},{"categories":null,"content":"参数配置 Functional Options Pattern,代码优雅 ","date":"2023-08-07","objectID":"/posts/component/:1:9","tags":null,"title":"go pkg包设计","uri":"/posts/component/"},{"categories":null,"content":"IDL https://protobuf.dev/ 利用protobuf提供接口和配置的定义. ","date":"2023-08-07","objectID":"/posts/component/:1:10","tags":null,"title":"go pkg包设计","uri":"/posts/component/"},{"categories":null,"content":"验证项目得分 https://goreportcard.com/ 评估项含 gofmt go vet go lint gocyclo ","date":"2023-08-07","objectID":"/posts/component/:1:11","tags":null,"title":"go pkg包设计","uri":"/posts/component/"},{"categories":null,"content":"总体架构分层 接入层,无状态 逻辑层 存储层 这里是参考了陌陌设计 ","date":"2023-08-07","objectID":"/posts/im/:0:0","tags":null,"title":"聊天系统设计调研","uri":"/posts/im/"},{"categories":null,"content":"连接层 这里有2种方案选择 WebSocket MQTT 关于MQTT,有EMQX中间件. 消息上线可以走HTTP接口,即客户端发给服务端消息 消息下行可以走EMQX订阅主题,即服务端推送消息给客户端 连接层属于无状态,支持水平扩展. ","date":"2023-08-07","objectID":"/posts/im/:1:0","tags":null,"title":"聊天系统设计调研","uri":"/posts/im/"},{"categories":null,"content":"逻辑层 通用消息格式定制 以及业务路由分发决策 设计规则 ","date":"2023-08-07","objectID":"/posts/im/:2:0","tags":null,"title":"聊天系统设计调研","uri":"/posts/im/"},{"categories":null,"content":"不丢消息 需要业务ACK机制 ","date":"2023-08-07","objectID":"/posts/im/:2:1","tags":null,"title":"聊天系统设计调研","uri":"/posts/im/"},{"categories":null,"content":"消息去重 服务端与客户端都需要做到 ","date":"2023-08-07","objectID":"/posts/im/:2:2","tags":null,"title":"聊天系统设计调研","uri":"/posts/im/"},{"categories":null,"content":"时序一致性 可以用snowflake算法. 利用局部性原理减少id生成器压力,有利于水平扩展 ","date":"2023-08-07","objectID":"/posts/im/:2:3","tags":null,"title":"聊天系统设计调研","uri":"/posts/im/"},{"categories":null,"content":"缓存设计 由于实时系统,基本上有一层cache,类似内核系统的buffer。 多级缓冲,面向c端场景的话一般链路不会太长,而且要考虑数据回种,分布式一致性挑战. 大概local cache -\u003e redis (读写分离)-\u003e database(读写分离) ","date":"2023-08-07","objectID":"/posts/im/:2:4","tags":null,"title":"聊天系统设计调研","uri":"/posts/im/"},{"categories":null,"content":"其他考虑场景 接入APP推送 接入风控 数据多端同步 多条消息打包与压缩格式设计 万人大群的数据扇出 明星突发性空降某频道 数据埋点监控 系统自动扩容 ","date":"2023-08-07","objectID":"/posts/im/:2:5","tags":null,"title":"聊天系统设计调研","uri":"/posts/im/"},{"categories":null,"content":"存储层 ","date":"2023-08-07","objectID":"/posts/im/:3:0","tags":null,"title":"聊天系统设计调研","uri":"/posts/im/"},{"categories":null,"content":"离线消息 如果需求量不大,Mysql即可以解决. 聊天应用的读写比例大概是1:1. 数据库 Cassandra Discord公司有在用.偏向AP场景 HBase Facebook公司有在用.偏向CP场景 个人想法 前期用Mysql,但是封装一层接口,为后期数据库迁移作准备. 大数据库选择要还看云数据库商支持程度,说不定还有其他云产品合适. ","date":"2023-08-07","objectID":"/posts/im/:3:1","tags":null,"title":"聊天系统设计调研","uri":"/posts/im/"},{"categories":null,"content":"对象存储 minio ","date":"2023-08-07","objectID":"/posts/im/:3:2","tags":null,"title":"聊天系统设计调研","uri":"/posts/im/"},{"categories":null,"content":"消息队列 rabbitMQ比较适合业务, 但是追求高吞吐的kafka,自己必须封装多一层机制来保证业务的一致性. 后续有的话再更新 ","date":"2023-08-07","objectID":"/posts/im/:3:3","tags":null,"title":"聊天系统设计调研","uri":"/posts/im/"},{"categories":null,"content":"记录下自己使用下来的go微服务框架,kratos go-zero kitex. ","date":"2023-07-18","objectID":"/posts/goframe/:0:0","tags":null,"title":"go微服务框架使用总结","uri":"/posts/goframe/"},{"categories":null,"content":"kratos bilibili公司出品的框架,当年公司内部代码泄漏,现在开源优化已经到了v2版本. 参考了DDD,Clean Architecture 设计理念. 项目结构清晰,每一层级的角色定位清晰,没有全局变量污染,还引入了wire进行依赖倒置. data层暴露了clean up函数对资源句柄进行回收. 框架层与业务层解耦,框架生命周期感知清晰. 组件开放接口设计,扩展性强 服务使用的是GRPC+Protocol Buffer, 同一服务进程下暴露了GRPC端口和HTTP端口. HTTP是通过protoc组件protoc-gen-go-http反射路由到同一RPC方法. 框架整体设计比较轻量,适合自己组合微服务方案. ","date":"2023-07-18","objectID":"/posts/goframe/:1:0","tags":null,"title":"go微服务框架使用总结","uri":"/posts/goframe/"},{"categories":null,"content":"总结 适合团队有架构组的人使用,前期需要自己组合方案,整合组件.后期基本完善,使用体验良好. HTTP层建议使用gin框架,因为protoc-gen-go-http适合开发阶段调试用,重度需求满足不了,自己做适配一路都是新坑. ","date":"2023-07-18","objectID":"/posts/goframe/:1:1","tags":null,"title":"go微服务框架使用总结","uri":"/posts/goframe/"},{"categories":null,"content":"Go-zero 一个公司CTO主推项目,加入了CNCF. HTTP单独部署一个项目,路由方法定义通过编写.api后缀文件(Go-zero定义的语法)实现. 他们的设计理念是实用性. ","date":"2023-07-18","objectID":"/posts/goframe/:2:0","tags":null,"title":"go微服务框架使用总结","uri":"/posts/goframe/"},{"categories":null,"content":"总结 生产上能用。对于定制化业务,直接fork他们官方的cli工具,然后公司内部修改维护该仓库. ","date":"2023-07-18","objectID":"/posts/goframe/:2:1","tags":null,"title":"go微服务框架使用总结","uri":"/posts/goframe/"},{"categories":null,"content":"Kitex 字节跳动公司的开源项目,分RPC框架Kitex和HTTP框架Hertz. 2个框架是2个团队的产物,设计规范不一致. 框架替换原有了go/net设计,实现高性能.(生产稳定性需要查阅官方资料验证) IDL支持Thrift,官方对Thrift的支持度很高,因为他们内部使用Thrift,但也支持Protobuf. 他们的设计理念是高性能 ","date":"2023-07-18","objectID":"/posts/goframe/:3:0","tags":null,"title":"go微服务框架使用总结","uri":"/posts/goframe/"},{"categories":null,"content":"总结 Kitex只是cloudwego组织下子项目,Thrift不是特别吸引我, 希望cloudwego/netpoll能封装成一个适配性高组件. ","date":"2023-07-18","objectID":"/posts/goframe/:3:1","tags":null,"title":"go微服务框架使用总结","uri":"/posts/goframe/"},{"categories":null,"content":"主机游戏 steam的单机游戏体验过一段时间后,随后了解到还有塞尔达传说王国之泪这样的游戏存在,有别于艾尔登法环这种 但是他只能在任天堂的switch上可以下载游玩,有别于pc游戏是主机游戏来的. ","date":"2023-05-06","objectID":"/posts/switchgame/:1:0","tags":null,"title":"体验switch游戏","uri":"/posts/switchgame/"},{"categories":null,"content":"模拟器 pc上也存在着模拟switch游戏环境的模拟软件,yuzu模拟器和ryujinx模拟器,接下来我将体验下ryujinx模拟器上游玩主机游戏 ","date":"2023-05-06","objectID":"/posts/switchgame/:2:0","tags":null,"title":"体验switch游戏","uri":"/posts/switchgame/"},{"categories":null,"content":"ryujinx模拟器体验 ","date":"2023-05-06","objectID":"/posts/switchgame/:3:0","tags":null,"title":"体验switch游戏","uri":"/posts/switchgame/"},{"categories":null,"content":"下载 下载模拟器https://github.com/Ryujinx/release-channel-master/releases 我选了当前最新的1.1.762版本 https://github.com/Ryujinx/release-channel-master/releases/download/1.1.762/test-ava-ryujinx-1.1.762-win_x64.zip ","date":"2023-05-06","objectID":"/posts/switchgame/:3:1","tags":null,"title":"体验switch游戏","uri":"/posts/switchgame/"},{"categories":null,"content":"先决 下载安装后,看了一眼官网wikihttps://github.com/Ryujinx/Ryujinx/wiki 在模拟器的目录下新建portable目录,需要导入任天堂switch相关的Keys和Firmware,即密钥和系统固件的意思,2者的版本还必须一致. ","date":"2023-05-06","objectID":"/posts/switchgame/:3:2","tags":null,"title":"体验switch游戏","uri":"/posts/switchgame/"},{"categories":null,"content":"游戏格式 接下来就是导入游戏包xci格式的,就可以在模拟器的目录上看到该游戏,点击游玩即可。 游戏DLC或者游戏更新包之类的安装文件大多是nsp格式的,在游戏上进行管理导入即可。 switch游戏的外挂是金手指这个称呼,可以搜switch对应game的cheat code主题。 ","date":"2023-05-06","objectID":"/posts/switchgame/:3:3","tags":null,"title":"体验switch游戏","uri":"/posts/switchgame/"},{"categories":null,"content":"总结 模拟器比较吃cpu资源,很多时候成为瓶颈.相比于switch游戏画面和帧数比较高,而且还可以开作弊码,省去重复的游戏体验。 switch的优势就是携带游玩方便,类似手机于pc的存在,但是steam deck是linux系统也可以安装模拟器,也有这个优势. 另一个就是switch可以联网官方服务器游玩比较方便,但是局域网联机游玩模拟器似乎也能做到。 随着一款游戏的了解,我慢慢发现任天堂的理念是以游戏趣味性为主导,switch设备为游戏圈子所建立的生态, 其他游戏像是一座座高山,但是switch游戏就像一条弯弯曲曲的河流那样的存在 ","date":"2023-05-06","objectID":"/posts/switchgame/:4:0","tags":null,"title":"体验switch游戏","uri":"/posts/switchgame/"},{"categories":null,"content":"介绍 Synergy是一个模拟键盘和鼠标的软件,我的win和mac都启动时可以用一套键鼠操控。 mac作为Synergy的客户端时,win作为Synergy的服务端使用。 ","date":"2023-05-06","objectID":"/posts/synergy/:1:0","tags":null,"title":"Synergy启动在登录前","uri":"/posts/synergy/"},{"categories":null,"content":"背景 目前Synergy在登录前软件没有启动,只有登录后启动,导致登录时无法输入密码,因为我的键盘鼠标连接在win上。下面是解决办法 ","date":"2023-05-06","objectID":"/posts/synergy/:2:0","tags":null,"title":"Synergy启动在登录前","uri":"/posts/synergy/"},{"categories":null,"content":"原理 软件在mac未登录前是root的身份运行,登录后才是选择的用户,在root身份下将软件加入mac的Launch Daemons就可以解决了 ","date":"2023-05-06","objectID":"/posts/synergy/:3:0","tags":null,"title":"Synergy启动在登录前","uri":"/posts/synergy/"},{"categories":null,"content":"实操 synergy的存放位置是 /Applications/Synergy.app/Contents/MacOS/synergy 运行命令行启动 open /Applications/Synergy.app/Contents/MacOS/synergy 时,可以看到启动参数 /Applications/Synergy.app/Contents/MacOS/synergyc -f --no-tray --debug INFO --name \"mac\" \"192.168.50.59:24800\" 修改为Launch Daemons的配置 \u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e \u003c!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\"\u003e \u003cplist version=\"1.0\"\u003e \u003cdict\u003e \u003ckey\u003eLabel\u003c/key\u003e \u003cstring\u003ecom.example.hello\u003c/string\u003e \u003ckey\u003eProgramArguments\u003c/key\u003e \u003carray\u003e \u003cstring\u003e/Applications/Synergy.app/Contents/MacOS/synergyc\u003c/string\u003e \u003cstring\u003e-f\u003c/string\u003e \u003cstring\u003e--no-tray\u003c/string\u003e \u003cstring\u003e--debug\u003c/string\u003e \u003cstring\u003eINFO\u003c/string\u003e \u003cstring\u003e--name\u003c/string\u003e \u003cstring\u003emac\u003c/string\u003e \u003cstring\u003e192.168.50.59:24800\u003c/string\u003e \u003c/array\u003e \u003ckey\u003eKeepAlive\u003c/key\u003e \u003ctrue/\u003e \u003c/dict\u003e \u003c/plist\u003e ProgramArguments对象下是cli启动参数 然后以root身份 放入 /Library/LaunchDaemons/ 下,文件名随便起一个com.example.synergy.plist 这样重启后,就可以在mac上输入密码,当键盘连接在win上时候,因为synergy已经生效 ","date":"2023-05-06","objectID":"/posts/synergy/:4:0","tags":null,"title":"Synergy启动在登录前","uri":"/posts/synergy/"},{"categories":null,"content":"总结 # 敲root密码 sudo su # 切目录 cd /Library/LaunchDaemons/ #创建文件 touch com.example.synergy.plist # 将xml的配置内容放入com.example.synergy.plist # 接着重启 而xml的内容是通过open /Applications/Synergy.app/Contents/MacOS/synergy看到的 ","date":"2023-05-06","objectID":"/posts/synergy/:5:0","tags":null,"title":"Synergy启动在登录前","uri":"/posts/synergy/"},{"categories":null,"content":"每当兴冲冲下一个好玩的游戏,进入却发现手柄识别不了,或者识别不全。 一个杂牌的手柄属实是折腾人,网上兜了一圈,方法很多,但是适用自己电脑情况的还是很少。 最佳的解决方案就是买个微软的xbox手柄。 次一点的解决方案就是用软件模拟出xbox360的手柄,然后进入游戏就可以正常游玩了。下面重点写下如何达成 ","date":"2023-02-21","objectID":"/posts/steam/:0:0","tags":null,"title":"Steam游戏无法识别北通手柄","uri":"/posts/steam/"},{"categories":null,"content":"xOutput使用 ","date":"2023-02-21","objectID":"/posts/steam/:1:0","tags":null,"title":"Steam游戏无法识别北通手柄","uri":"/posts/steam/"},{"categories":null,"content":"前提 首先来个前提,游戏必须安装在无中文路径,各种微软的游戏依赖库安装齐全。网络问题的话,下个uu加速器处理下 我自己的电脑系统是win11 我使用的模拟软件是xOutput https://github.com/csutorasa/XOutput ","date":"2023-02-21","objectID":"/posts/steam/:1:1","tags":null,"title":"Steam游戏无法识别北通手柄","uri":"/posts/steam/"},{"categories":null,"content":"配置 下载安装后,打开xOutput,手柄录入键位映射,把手柄的所有按键都输入一边, 然后方向轴看是否录入是否正确(我遇到一个右键上下的位置对调了,然后这个键位勾选反转就行),接下来下拉绑定选择北通的控制器,然后保存配置。 (这个的使用搜b站的视频比较方便,文字描述这里写不下.) ","date":"2023-02-21","objectID":"/posts/steam/:1:2","tags":null,"title":"Steam游戏无法识别北通手柄","uri":"/posts/steam/"},{"categories":null,"content":"使用 接下来再关闭,以管理员权限打开xOutput(这点很重要!!)再点击开始,启用这个模拟的控制器 这时一般window的设备管理器,会识别出2个手柄设备,一个是北通自己的原有手柄,另一个是模拟出来的xbox360手柄 此时我们点开steam,通用的手柄管理一般也会识别出2个手柄。 配置steam 这时游戏启用steam手柄输入。 手柄设置那里关闭 playstation,任天堂switch相关。 勾选通用,xbox,xbox扩展支持就行。 这时打开游戏就能完了。如果失败,重启电脑,必须控制软件打开的先后顺序, 先打开 xOutput 以管理员权限, 再打开steam, 再打开游戏。 ","date":"2023-02-21","objectID":"/posts/steam/:1:3","tags":null,"title":"Steam游戏无法识别北通手柄","uri":"/posts/steam/"},{"categories":null,"content":"心得 接下来是坑总结 设备管理器确保是2个,一个北通自带,一个虚拟出来的。我之前安装了ds4windows,勾选了隐藏北通的控制器,导致xOutput失效。 管理员权限运行xOutput这点也很重要 ","date":"2023-02-21","objectID":"/posts/steam/:2:0","tags":null,"title":"Steam游戏无法识别北通手柄","uri":"/posts/steam/"},{"categories":null,"content":"其他软件 x360ce 这个软件我也试过,用起来时灵时不灵。 如果问题还没解决,可以搜下其他的模拟xbox360的软件 https://alternativeto.net/software/x360ce/ 具体可以看这篇文章,我就是在这个文章找到xOutput的 ","date":"2023-02-21","objectID":"/posts/steam/:2:1","tags":null,"title":"Steam游戏无法识别北通手柄","uri":"/posts/steam/"},{"categories":null,"content":"推荐 用了steam 这么久,发现2个好用软件, 一个是steam账号切换器 可以方便的管理多个steam账号,但是记住限制切号器的网络,可以用火绒来控制软件的网络 另一个是msi afterburner 可以用来显示游戏的帧率,显卡内存占用等等 ","date":"2023-02-21","objectID":"/posts/steam/:2:2","tags":null,"title":"Steam游戏无法识别北通手柄","uri":"/posts/steam/"},{"categories":null,"content":"克隆项目 https://github.com/Graylog2/docker-compose ","date":"2022-12-13","objectID":"/posts/graylog/:0:1","tags":null,"title":"Graylog搭建","uri":"/posts/graylog/"},{"categories":null,"content":"配置文件 cd open-core cp .env.example .env 修改.env #.env GRAYLOG_PASSWORD_SECRET=\"你的16位密码\" # 密钥= echo -n 你的16位密码 | shasum -a 256 GRAYLOG_ROOT_PASSWORD_SHA2=\"密钥\" 修改docker-compose.yml # graylog.environment - 位置 GRAYLOG_HTTP_EXTERNAL_URI: \"https://你的域名.com/graylog\" ","date":"2022-12-13","objectID":"/posts/graylog/:0:2","tags":null,"title":"Graylog搭建","uri":"/posts/graylog/"},{"categories":null,"content":"启动 docker-compose up -d 配置域名 sudo vi /etc/hosts x.x.x.x graylog 配置nginx location /graylog/ { proxy_pass http://graylog:9000/; proxy_redirect off; proxy_http_version 1.1; proxy_set_header Connection \"\"; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; proxy_connect_timeout 2s; proxy_read_timeout 90s; proxy_send_timeout 90s; } location /graylog1/ { proxy_pass http://graylog:12201/; proxy_redirect off; proxy_http_version 1.1; proxy_set_header Connection \"\"; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; proxy_connect_timeout 2s; proxy_read_timeout 90s; proxy_send_timeout 90s; } ","date":"2022-12-13","objectID":"/posts/graylog/:0:3","tags":null,"title":"Graylog搭建","uri":"/posts/graylog/"},{"categories":null,"content":"访问 账号admin 启动http input system.input.GELF HTTP 测试 curl --location --request POST 'https://你的域名/graylog1/gelf' \\ --header 'Content-Type: application/json' \\ --data-raw '{\"short_message\":\"111\", \"host\":\"172.3.3.3\", \"facility\":\"test\", \"_foo\":\"bar\"}' ","date":"2022-12-13","objectID":"/posts/graylog/:0:4","tags":null,"title":"Graylog搭建","uri":"/posts/graylog/"},{"categories":null,"content":"什么是汇编? ruanyifeng-汇编语言入门教程 Decode360’s Blog-汇编基础入门知识 ","date":"2022-09-20","objectID":"/posts/asm/:1:0","tags":null,"title":"汇编学习","uri":"/posts/asm/"},{"categories":null,"content":"汇编学习 ","date":"2022-09-20","objectID":"/posts/asm/:2:0","tags":null,"title":"汇编学习","uri":"/posts/asm/"},{"categories":null,"content":"学习材料 Princeton大学汇编教程 Assembly1 Assembly2 AssemblyFunctions 这个pdf做的非常浅显易懂 tcoline.com-汇编语言 tcoline.com-汇编语言 这个网站的教程也不错,纯中文 w3c教程 https://www.w3cschool.cn/assembly/ 函数调用原理 https://gitbook.coder.cat/function-call-principle/ ","date":"2022-09-20","objectID":"/posts/asm/:2:1","tags":null,"title":"汇编学习","uri":"/posts/asm/"},{"categories":null,"content":"学习记录 目录 编程语言级别:c语言-\u003e汇编语言-\u003e机器语言 x86-64汇编介绍 冯诺伊曼架构介绍 主存 寄存器 汇编函数调用过程 主存 0000000000000000 ... TEXT RODATA DATA BSS HEAP STACK ... FFFFFFFFFFFFFFFF ","date":"2022-09-20","objectID":"/posts/asm/:2:2","tags":null,"title":"汇编学习","uri":"/posts/asm/"},{"categories":null,"content":"备注 Data Registers RAX: register accumulator // R\"注册\"意思 RBX:register base RCX:register count RDX:register data Data Registers item detail RAX: register accumulator // R\"register\" x “extended” [0,63] EAX: extended accumulator // E “extended|enhanced” [0,31] AX: accumulator // [0,15] AH :accumulator higher // [8,15] AL :accumulator lower // [0,7] cont. RSI: register source index (source for data copies) RDI: register destination index (destination for data copies) RBP: register base pointer (start of stack) RSP: register stack pointer (current location in stack, growing downwards) Pointer Registers IP:Instruction Pointer // 要执行的下一条指令的偏移地址 SP:Stack Pointer // 供程序堆栈内的偏移值 BP:Base Pointer // 主要有助于引用传递给子程序的参数变量 Index Registers SI:Source Index //字符串操作的源索引 DI:Destination Index // 字符串操作的目标索引 Control Registers - common flag bits OF:Overflow Flag DF:Direction Flag IF:Interrupt Flag TF:Trap Flag SF:Sign Flag ZF:Zero Flag AF:Auxiliary Carry Flag PF:Parity Flag CF:Carry Flag 参考来源 x86/amd64 指令索引 X86-64 架构指南 X86 64 Register and Instruction Quick Start https://www.tutorialspoint.com/assembly_programming/assembly_registers.htm ","date":"2022-09-20","objectID":"/posts/asm/:2:3","tags":null,"title":"汇编学习","uri":"/posts/asm/"},{"categories":null,"content":"工具 Compiler Explorer Compiler Explorer可以在线将go代码转为asm ","date":"2022-09-20","objectID":"/posts/asm/:2:4","tags":null,"title":"汇编学习","uri":"/posts/asm/"},{"categories":null,"content":"golang原生的mysql包是https://github.com/go-sql-driver/mysql 其中DSN (Data Source Name)格式username:password@protocol(address)/dbname?param=value 字段 介绍 username 数据库账号名 password 数据库密码 protocol 协议,tcp, address 数据库host地址 dbname 数据库名,此项为可选项 param 参数支持多个,且区分大小写 参数 默认 介绍 allowAllFiles false allowCleartextPasswords false allowNativePasswords true allowOldPasswords false charset 常用,字符集 checkConnLiveness true collation utf8mb4_general_ci clientFoundRows false columnsWithAlias false interpolateParams false loc UTC 常用,时区 maxAllowedPacket 4194304 multiStatements false parseTime false readTimeout 0 执行读开始计算时间,超过则中断 rejectReadOnly false serverPubKey none timeout OS default tls false writeTimeout 0 其他参数的填写则设置为系统变量,string要用单引号圈起来且url.QueryEscape处理 设置函数 SetMaxOpenConns 为最大连接数 SetMaxIdleConns 为最大空闲数,SetMaxIdleConns\u003c=SetMaxOpenConns,一般不推荐用 SetConnMaxLifetime 为最大空闲时间,一般小于mysql系统的wait_timeout ","date":"2022-09-02","objectID":"/posts/gomysql/:0:0","tags":null,"title":"golang-mysql包","uri":"/posts/gomysql/"},{"categories":null,"content":"mysql配置 查询慢日志相关 slow_query_log 是否开启了慢日志 long_query_time 超过多少s开始记录 slow_query_log_file 慢日志位置 select @@global.slow_query_log,@@global.long_query_time,@@global.slow_query_log_file ","date":"2022-09-02","objectID":"/posts/gomysql/:0:1","tags":null,"title":"golang-mysql包","uri":"/posts/gomysql/"},{"categories":null,"content":"原文链接:https://golang.org/s/go11sched 以下是原文 ","date":"2022-08-04","objectID":"/posts/scalablegoschedulerdesigndoc/:0:0","tags":null,"title":"Scalable Go Scheduler Design Doc 中文翻译","uri":"/posts/scalablegoschedulerdesigndoc/"},{"categories":null,"content":"Scalable Go Scheduler Design Doc Dmitry Vyukov dvyukov@google.com May 2, 2012 该文档假定您对Go 语言 和当前的 goroutine 调度程序实现有一定的了解。 ","date":"2022-08-04","objectID":"/posts/scalablegoschedulerdesigndoc/:1:0","tags":null,"title":"Scalable Go Scheduler Design Doc 中文翻译","uri":"/posts/scalablegoschedulerdesigndoc/"},{"categories":null,"content":"当前调度程序的问题 当前的 goroutine 调度器限制了用 Go 编写的并发程序的可扩展性,特别是高吞吐量服务器和并行计算程序。 Vtocc 服务器在 8 核机器上最多可使用 70% 的 CPU,而性能分析显示 14% 用于runtime.futex(). 通常,调度程序可能会禁止用户在性能至关重要的情况下使用惯用的细粒度并发。 当前实现有什么问题: 单一全局互斥锁(Sched.Lock)和集中状态。互斥锁保护所有与 goroutine 相关的操作(创建、完成、重新调度等)。 Goroutine (G) 切换 (G.nextg)。工作线程 (M’s) 经常在彼此之间切换可运行的 goroutine,这可能会导致延迟增加和额外开销。每个 M 必须能够执行任何可运行的 G,尤其是刚刚创建 G 的 M。 每个M内存缓存(M.mcache)。内存缓存和其他缓存(堆栈分配)与所有 M 相关联,而它们只需要与 M 正在运行的 Go 代码相关联(在 syscall 内部阻塞的 M 不需要 mcache)。运行的 Go 代码的M 与所有 M 之间的比率可以高达 1:100。这会导致过多的资源消耗(每个 MCache 最多可吸收 2M)和较差的数据局部性。 活跃的线程阻塞中或解除阻塞中。在存在syscalls的情况下,工作线程经常义阻塞和已解除阻塞。这增加了很多开销。 ","date":"2022-08-04","objectID":"/posts/scalablegoschedulerdesigndoc/:1:1","tags":null,"title":"Scalable Go Scheduler Design Doc 中文翻译","uri":"/posts/scalablegoschedulerdesigndoc/"},{"categories":null,"content":"设计 Processors 总体思路是将 P(Processors)的概念引入运行时,并在Processors之上实现work-stealing scheduler。 M 代表操作系统线程(就像现在一样)。 P 表示执行 Go 代码所需的资源。 当 M 执行 Go 代码时,它有一个关联的 P。 当 M 空闲或在 syscall 中时,它不需要 P。 正好有 GOMAXPROCS P。所有 P 都组织成一个数组,这是工作窃取的要求。GOMAXPROCS 更改涉及stop/start the world以调整 P 数组的大小。 sched 中的一些变量被分散并移动到 P。M 中的一些变量被移动到 P(与 Go 代码的主动执行相关的变量)。 struct P { Lock; G *gfree; // freelist, moved from sched G *ghead; // runnable, moved from sched G *gtail; MCache *mcache; // moved from M FixAlloc *stackalloc; // moved from M uint64 ncgocall; GCStats gcstats; // etc ... }; P *allp; // [GOMAXPROCS] 还有一个空闲 P 的无锁列表: P *idlep; // lock-free list 当一个 M 愿意开始执行 Go 代码时,它必须从列表中取出一个 P。当 M 结束执行 Go 代码时,它将 P 归还到列表中。因此,当 M 执行 Go 代码时,它必须有一个关联的 P。这种机制取代了 sched.atomic (mcpu/mcpumax)。 ","date":"2022-08-04","objectID":"/posts/scalablegoschedulerdesigndoc/:1:2","tags":null,"title":"Scalable Go Scheduler Design Doc 中文翻译","uri":"/posts/scalablegoschedulerdesigndoc/"},{"categories":null,"content":"Scheduling 当一个新的 G 被创建或者一个已经存在的 G 变为可运行时,它会被放进到当前 P 的可运行 goroutines 列表中。当 P 执行完 G 时,它首先尝试从自己的可运行 goroutines 列表中取出一个 G;如果列表为空,则 P 选择一个随机牺牲者(另一个 P)并尝试从中窃取一半可运行的 goroutine。 ","date":"2022-08-04","objectID":"/posts/scalablegoschedulerdesigndoc/:1:3","tags":null,"title":"Scalable Go Scheduler Design Doc 中文翻译","uri":"/posts/scalablegoschedulerdesigndoc/"},{"categories":null,"content":"Syscalls/M Parking and Unparking 当一个 M 创建一个新的 G 时,它必须确保有另一个 M 来执行 G(如果不是所有的 M 都处于忙碌中)。同样,当一个 M 进入 syscall 时,它必须确保有另一个 M 来执行 Go 代码。 有两种选择,我们可以立即阻塞和非阻塞M,或者使其部分自旋。这是性能和消耗不必要的 CPU 资源之间的内在冲突。这个想法是使用自旋且消耗CPU资源。但是,它不应该影响以 GOMAXPROCS=1 时 的运行程序(command line utilities, appengine,等)。 自旋分两层: (1)一个空闲的 M 关联 P 自旋 ,寻找新的 G, (2)一个 M 没关联 P 自旋,等待可用的 P。 最多有 GOMAXPROCS 个自旋 M((1)和(2))。当有类型 (2) 的空闲 M 时,类型 (1) 的空闲 M 不会阻塞。 当一个新的 G 被生成,或者 M 进入syscall,或者 M 从空闲到忙碌的转换时,它确保至少有 1 个自旋中 M(或者所有的 P 都忙碌中)。这确保了没有可运行的 G 可以以其他方式运行;同时避免过多的M 进行阻塞或解除阻塞。 自旋行为主要是被动的(OS驱动, sched_yield()),但可能包括一点主动自旋(循环消耗CPU)(需要调查和调整)。 ","date":"2022-08-04","objectID":"/posts/scalablegoschedulerdesigndoc/:1:4","tags":null,"title":"Scalable Go Scheduler Design Doc 中文翻译","uri":"/posts/scalablegoschedulerdesigndoc/"},{"categories":null,"content":"Termination/Deadlock Detection Termination/Deadlock Detection(解除/死锁检查)在分布式系统中更成问题。一般的想法是仅在所有 P 都空闲时进行检查(空闲 P 的全局原子计数器),这允许进行涉及每个 P 状态聚合的更昂贵的检查。 还没有细节。 ","date":"2022-08-04","objectID":"/posts/scalablegoschedulerdesigndoc/:1:5","tags":null,"title":"Scalable Go Scheduler Design Doc 中文翻译","uri":"/posts/scalablegoschedulerdesigndoc/"},{"categories":null,"content":"LockOSThread 此功能不是性能关键的。 锁定的 G 变得不可运行(Gwaiting)。M 立即将 P 返回到空闲列表,唤醒另一个 M 并阻塞。 锁定的 G 变为可运行的(并到达 runq 的头部)。当前 M 将自己的 P 和锁定的 G 移交给与锁定的 G 关联的 M,并解锁它。当前 M 变为空闲。 ","date":"2022-08-04","objectID":"/posts/scalablegoschedulerdesigndoc/:1:6","tags":null,"title":"Scalable Go Scheduler Design Doc 中文翻译","uri":"/posts/scalablegoschedulerdesigndoc/"},{"categories":null,"content":"Idle G 空闲的G;此功能不是性能关键的。 有一个(或单个?)空闲 G 的全局队列。寻找工作的 M 在几次不成功的窃取尝试后检查队列。 ","date":"2022-08-04","objectID":"/posts/scalablegoschedulerdesigndoc/:1:7","tags":null,"title":"Scalable Go Scheduler Design Doc 中文翻译","uri":"/posts/scalablegoschedulerdesigndoc/"},{"categories":null,"content":"实施计划 目标是将整个事情分成可以独立审查和提交的最小部分。 引入 P 结构体(暂时为空);实现 allp/idlep 容器(idlep 对于初学者来说是互斥保护的);将 P 与运行 Go 代码的 M 相关联。仍然保留全局互斥锁和原子状态。 将 G freelist 移至 P。 将mcache移动到P。 将stackalloc移动到P。 将 ncgocall/gcstats 移至 P。 去中心化运行队列,实现工作窃取。消除 G 切换。仍在全局互斥锁下。 移除全局互斥体,实现分布式 termination detection,LockOSThread。 实施自旋,而不是提示进行阻塞/解除阻塞中.。 该计划可能行不通,有很多未探索的细节。 ","date":"2022-08-04","objectID":"/posts/scalablegoschedulerdesigndoc/:1:8","tags":null,"title":"Scalable Go Scheduler Design Doc 中文翻译","uri":"/posts/scalablegoschedulerdesigndoc/"},{"categories":null,"content":"潜在的进一步改进 尝试LIFO调度,这将提高局部性。但是,它仍然必须提供一定程度的公平性并优雅地处理让出的 goroutine。 在goroutine第一次运行之前不要分配G和堆栈。对于一个新创建的 goroutine,我们只需要 callerpc、fn、narg、nret 和 args,也就是大约 6 个单词。这将允许创建大量运行到完成的 goroutine,显着降低内存开销。 Without 3 更好的G-to-P局部性。尝试将未阻塞的 G 排入上次运行的 P 队列。 P-to-M的更好的局部化。尝试在上次运行的同一 M 上执行 P。 M创建节约。调度程序很容易被迫每秒创建数千个 M,直到操作系统拒绝创建更多线程。必须及时创建 M 直到 k*GOMAXPROCS,之后可以通过计时器添加新的 M。 ","date":"2022-08-04","objectID":"/posts/scalablegoschedulerdesigndoc/:1:9","tags":null,"title":"Scalable Go Scheduler Design Doc 中文翻译","uri":"/posts/scalablegoschedulerdesigndoc/"},{"categories":null,"content":"散记 GOMAXPROCS 不会因为这项工作而消失。 原文结束 若翻译细节有错,还望指出 futex 了解 https://developer.aliyun.com/article/6043 ","date":"2022-08-04","objectID":"/posts/scalablegoschedulerdesigndoc/:1:10","tags":null,"title":"Scalable Go Scheduler Design Doc 中文翻译","uri":"/posts/scalablegoschedulerdesigndoc/"},{"categories":null,"content":" 学习go的源码编译 下载源码仓库 git clone git@github.com:golang/go.git 我选择了其中一个分支 release-branch.go1.18 git checkout release-branch.go1.18 目录结构 $ tree -d -L 2 . ├── api ├── bin ├── doc ├── lib │ └── time ├── misc │ ├── android │ ├── arm │ ├── cgo │ ├── chrome │ ├── ios │ ├── linkcheck │ ├── reboot │ ├── swig │ ├── trace │ └── wasm ├── pkg │ ├── darwin_arm64 │ ├── include │ ├── obj │ └── tool ├── src │ ├── archive │ ├── bufio │ ├── builtin │ ├── bytes │ ├── cmd │ ├── compress │ ├── container │ ├── context │ ├── crypto │ ├── database │ ├── debug │ ├── embed │ ├── encoding │ ├── errors │ ├── expvar │ ├── flag │ ├── fmt │ ├── go │ ├── hash │ ├── html │ ├── image │ ├── index │ ├── internal │ ├── io │ ├── log │ ├── math │ ├── mime │ ├── net │ ├── os │ ├── path │ ├── plugin │ ├── reflect │ ├── regexp │ ├── runtime │ ├── sort │ ├── strconv │ ├── strings │ ├── sync │ ├── syscall │ ├── testdata │ ├── testing │ ├── text │ ├── time │ ├── unicode │ ├── unsafe │ └── vendor └── test ├── abi ├── alias3.dir ├── asmhdr.dir ├── bench ├── chan ├── closure3.dir ├── closure5.dir ├── codegen ├── ddd2.dir ├── dwarf ├── fixedbugs ├── import2.dir ├── import4.dir ├── interface ├── intrinsic.dir ├── ken ├── linkname.dir ├── method4.dir ├── oldescape_linkname.dir ├── retjmp.dir ├── runtime ├── stress ├── syntax ├── typeparam └── uintptrescapes.dir 94 directories 假设我要编译src/cmd/trace这个pkg #进入目录 cd src/cmd/trace # run下 go run ./... 此时是编译失败的,在项目根目录执行./src/make.bash脚本, 将会在./bin目录生成调试源码用的编译器, 再将GOROOT变量指向项目根目录,此时再编译就正常了 ","date":"2022-08-04","objectID":"/posts/my-gosrc-build-post/:0:0","tags":null,"title":"go源码编译","uri":"/posts/my-gosrc-build-post/"},{"categories":null,"content":"初始化 准备工作 work flow github page github page hugo hugo官网 教程 如何使用Hugo在GitHub Pages上搭建免费个人网站 自动化教程 Hugo使用Github Action自动部署博客到Github Pages ","date":"2022-08-04","objectID":"/posts/my-first-post/:1:0","tags":null,"title":"创建自己的github博客","uri":"/posts/my-first-post/"},{"categories":null,"content":"配置主题 选择 LoveIt主题 https://github.com/dillonzq/LoveIt 文档 https://hugoloveit.com/zh-cn/theme-documentation-basics/ ","date":"2022-08-04","objectID":"/posts/my-first-post/:2:0","tags":null,"title":"创建自己的github博客","uri":"/posts/my-first-post/"},{"categories":null,"content":"设置网站logo ","date":"2022-08-04","objectID":"/posts/my-first-post/:3:0","tags":null,"title":"创建自己的github博客","uri":"/posts/my-first-post/"},{"categories":null,"content":"设计logo 代码来源 https://github.com/kasuganosoras/logo-maker 生成logo图片网站 https://logomaker.akkariin.com/youtube.html or 自己魔改透明背景 设计完之后 利用logo图片生成Favicon https://favicon.io/ ","date":"2022-08-04","objectID":"/posts/my-first-post/:3:1","tags":null,"title":"创建自己的github博客","uri":"/posts/my-first-post/"},{"categories":null,"content":"配置网站Favicon 将favicon_io.zip 文件解压到 ./static/下 ","date":"2022-08-04","objectID":"/posts/my-first-post/:3:2","tags":null,"title":"创建自己的github博客","uri":"/posts/my-first-post/"},{"categories":null,"content":"配置网站logo 配置 config.toml [params.header.title] logo = \"/images/your logo.png\" logo的真实位置在 ./static/images/your logo.png ","date":"2022-08-04","objectID":"/posts/my-first-post/:3:3","tags":null,"title":"创建自己的github博客","uri":"/posts/my-first-post/"},{"categories":null,"content":"设置SEO ","date":"2022-08-04","objectID":"/posts/my-first-post/:4:0","tags":null,"title":"创建自己的github博客","uri":"/posts/my-first-post/"},{"categories":null,"content":"google google search console https://search.google.com/search-console/about ","date":"2022-08-04","objectID":"/posts/my-first-post/:4:1","tags":null,"title":"创建自己的github博客","uri":"/posts/my-first-post/"},{"categories":null,"content":"bing bing Webmaster https://www.bing.com/webmasters/about ","date":"2022-08-04","objectID":"/posts/my-first-post/:4:2","tags":null,"title":"创建自己的github博客","uri":"/posts/my-first-post/"},{"categories":null,"content":"\u003c!DOCTYPE HTML\u003e YouTube Logo YouTube Logo 自定义你的 YouTube 风格 Logo 左侧字体内容 右侧字体内容 左侧字体大小(px) 右侧字体大小(px) 加粗字体 启用 禁用 背景宽度(px) 背景高度(px) 左侧颜色 右侧颜色 You Tube 点击下载图片 你也可以右键另存为或复制到剪切板 ","date":"0001-01-01","objectID":"/posts/logo-maker/:0:0","tags":null,"title":"","uri":"/posts/logo-maker/"}]