使用腾讯云香港轻量服务器和COS构建图床

起因 因为有存储图片的需求,所以一直在寻找一种可靠的自建图床的方式,也尝试了很多种方案。 使用 Minio + 大盘鸡自建 优点:免费,开源。 缺点:需要自己维护,如果经常迁移服务器很不方便,另外如果需要存储大量图片的话,需要大硬盘机器。目前能找到最便宜的是 1TB 硬盘的机器,价格是 5 刀一个月。 使用 Wasabi 日本区域 优点:7 刀一个月,1TB 存储空间和 1TB 流量,速度还可以。 缺点:感觉还是有点贵。 使用 Vultr 对象存储新加坡区域 优点:5 刀一个月,1TB 存储空间和 1TB 流量。 缺点:新加坡国内访问还是有点慢。 B2 云存储 没尝试,也是 5 刀一个月,1TB 存储空间和 1TB 流量,不过没有国内访问速度好点的节点。 方案选择 不考虑国内对象存储+CDN 的方式一个是价格太贵,另一个是有很多被 DDOS 然后产生天价账单的案例。 刚好最近迁移到了腾讯云香港轻量,老实说,尝试了各种商家的 VPS,各个地区包括美西、日本,最后还是选择了更稳定的大厂。 然后腾讯云香港轻量内网访问同区域 COS 是不收费的,另外直接暴露 COS 有被刷流量风险,所以最终选择通过轻量服务器中转的方式。 目前轻量上行限制 30M,暂时也够用了。 费用 COS 的存储费用还是很低的,请求费用也比较低,贵的是流量费用,所以通过轻量服务器中转的方式也比较便宜。 后续看需求吧,如果费用太高的话,也会考虑买一台香港大盘鸡进行自建。 中转方案 因为目前服务器使用的是 Caddy,使用 https://github.com/lindenlab/caddy-s3-proxy 这个插件可以直接代理 S3,而 COS 也兼容 S3。 后续更新 发现腾讯云香港轻量稳定倒是很稳定,但是磁盘 IO 太拉了,动不动 100% 然后机器都 ssh 不上去,果断退款了。目前继续使用 Minio 自建。 ...

March 6, 2023

iOS App技术支持网址(URL)

如果您在使用过程中有问题请留言或发邮件我。 邮箱地址:long2ice@gmail.com 谢谢! If you have any questions, please leave a message or send me an email. Email:long2ice@gmail.com Thank you!

January 11, 2023

分享一个不错的Uptime开源监控项目

简介 之前一直使用gatus来监控一些服务,但是最近发现了一个更强大的开源项目uptime-kuma,web 界面功能更加丰富,遂决定转向uptime-kuma。 项目地址 https://github.com/louislam/uptime-kuma 安装 最方便的方式就是使用docker-compose。 version: "3" services: uptime-kuma: image: louislam/uptime-kuma container_name: uptime-kuma volumes: - uptime-kuma-data:/app/data - /var/run/docker.sock:/var/run/docker.sock restart: always network_mode: host volumes: uptime-kuma-data: 支持多种类型监控 http ping tcp dns docker … 支持多种类型告警 飞书 邮件 Telegram 企业微信 webhook … 最后 总的使用下来还是非常不错的。

September 25, 2022

Golang+xterm.js打造webssh

起因 最近在开发中涉及到了 webssh 的需求,于是就有了这篇文章,主要是记录一下开发过程中遇到的问题,以及解决方案。 技术架构 Golang Fiber Vue xterm.js 方案 主要是希望前端通过 websocket 连接后端,后端通过 ssh 连接远程服务器,然后将两者的数据流进行转发,这样就实现了 webssh 的功能。 前端部分代码 <template> <div id="xterm" class="xterm" /> </template> <script> import "xterm/css/xterm.css"; import { Terminal } from "xterm"; import { FitAddon } from "xterm-addon-fit"; import { AttachAddon } from "xterm-addon-attach"; export default { name: "Terminal", props: { url: { type: String, default: "", }, visible: { type: Boolean, default: false, }, }, watch: { visible: { handler(value) { if ( value && this.socket !== undefined && this.socket.readyState === 3 ) { this.initSocket(); } }, }, wsUrl: { handler(value) { this.initSocket(); }, }, }, mounted() { this.initSocket(); }, beforeDestroy() { this.socket.close(); this.term.dispose(); }, methods: { initTerm() { const term = new Terminal({ fontSize: 14, cursorBlink: true, }); const attachAddon = new AttachAddon(this.socket); const fitAddon = new FitAddon(); term.loadAddon(attachAddon); term.loadAddon(fitAddon); term.open(document.getElementById("xterm")); fitAddon.fit(); term.focus(); this.term = term; }, initSocket() { this.socket = new WebSocket(this.url); this.socketOnClose(); this.socketOnOpen(); this.socketOnError(); }, socketOnOpen() { this.socket.onopen = () => { // 链接成功后 this.initTerm(); }; }, socketOnClose() { this.socket.onclose = () => { this.$emit("terminalClose"); this.term.dispose(); }; }, socketOnError() { this.socket.onerror = () => { // console.log('socket 链接失败') }; }, }, }; </script> <style scoped> .xterm { height: 600px; } </style> 后端部分代码 package api import ( "context" "github.com/gofiber/websocket/v2" "github.com/google/uuid" "github.com/helloyi/go-sshclient" log "github.com/sirupsen/logrus" "gitlab.com/merico-dev/DevOpsPublic/brooder/db" "gitlab.com/merico-dev/DevOpsPublic/brooder/services" "golang.org/x/crypto/ssh" "io" ) type WsReaderWriter struct { *websocket.Conn } func (w *WsReaderWriter) Write(p []byte) (n int, err error) { writer, err := w.Conn.NextWriter(websocket.TextMessage) if err != nil { return 0, err } defer writer.Close() return writer.Write(p) } func (w *WsReaderWriter) Read(p []byte) (n int, err error) { var msgType int var reader io.Reader for { msgType, reader, err = w.Conn.NextReader() if err != nil { return 0, err } if msgType != websocket.TextMessage { continue } return reader.Read(p) } } func Shell(c *websocket.Conn) { uid, err := uuid.Parse(c.Params("uid")) if err != nil { log.Error(err) } mc := db.Client.Machine.GetX(context.Background(), uid) service, err := services.NewSSHService(mc.MachineIP) if err != nil { log.Error(err) } config := &sshclient.TerminalConfig{ Term: "xterm", Height: 40, Weight: 80, Modes: ssh.TerminalModes{ ssh.ECHO: 1, ssh.TTY_OP_ISPEED: 14400, ssh.TTY_OP_OSPEED: 14400, }, } rw := &WsReaderWriter{c} if err = service.Client().Terminal(config).SetStdio(rw, rw, rw).Start(); err != nil { log.Error(err) } }

September 24, 2022

如何优化Python Docker镜像大小

一直以来,使用普通方式打包的 Python 项目的 Docker 镜像都非常大,大概有一个多 G 的样子,比如下面这个例子。 FROM python:3 RUN mkdir -p /telsearch WORKDIR /telsearch COPY pyproject.toml poetry.lock /telsearch/ RUN pip3 install poetry ENV POETRY_VIRTUALENVS_CREATE false RUN poetry install --no-root --no-dev COPY . /telsearch 足足有 1.5 个 G,非常的浪费磁盘空间,那么,有没有什么方法可以减小镜像大小呢? 答案就是 Docker 的多阶段构建,官方文档在这里:https://docs.docker.com/develop/develop-images/multistage-build/。 FROM python:3.9 as builder RUN mkdir -p /telsearch WORKDIR /telsearch COPY pyproject.toml poetry.lock /telsearch/ ENV POETRY_VIRTUALENVS_CREATE false RUN pip3 install pip --upgrade && pip3 install poetry --upgrade --pre && poetry install --no-root --only main FROM python:3.9-slim WORKDIR /telsearch COPY --from=builder /usr/local/lib/python3.9/site-packages /usr/local/lib/python3.9/site-packages COPY --from=builder /usr/local/bin/ /usr/local/bin/ COPY . /telsearch CMD ["uvicorn" ,"telsearch.app:app", "--host", "0.0.0.0"] 使用了新的方式打包之后,镜像大小减小到了 284MB,减小了非常之多。 ...

September 10, 2022